Commit Graph
892 Commits
Author SHA1 Message Date
sysadmin ec2433f13b Merge pull request 'fix(mcp): make capability resolver side-effect free (Closes #685)' (#724) from fix/issue-685-side-effect-free-resolver into master 2026-07-17 13:05:51 -05:00
sysadmin 899ef8ec7f Merge branch 'master' into fix/issue-685-side-effect-free-resolver
Resolve gitea_resolve_task_capability conflict by keeping both #685
runtime_reconnect_required blocker and #702 stale_binding_recovery
annotation. Keep resolve-path stale-binding assessment report-only
(auto_recover=False) so capability resolution never mutates env or
session state. Preserve #725 merger-lease and #728 PR-sync code from
master. Regression: resolve uses report-only binding assessment.
2026-07-17 14:04:45 -04:00
sysadmin 58d6b5844f Merge pull request 'feat(controller): route outdated and conflicting PRs through synchronization lifecycle' (#728) from feat/issue-727-pr-sync-status into master 2026-07-17 12:58:35 -05:00
sysadmin c1c61e9b15 Merge branch 'master' into feat/issue-727-pr-sync-status
Resolve task_capability_map conflict by keeping PR-sync entries and #725
merger-lease map entries. Fix author ownership for PR #728 (issue #727):
prove lock via linked issue/session/branch instead of issue_number==pr_number.
Add regression tests for 727/728 ownership and unrelated issue rejection.
2026-07-17 13:57:22 -04:00
sysadmin fca3296883 Merge pull request 'fix(mcp): acquire merger PR lease with structured capability resolution (Fixes #718)' (#725) from issue-718-fix-merger-lease into master 2026-07-17 12:52:21 -05:00
jcwalker3 d7b0b0e772 Merge branch 'master' into feat/issue-727-pr-sync-status 2026-07-17 12:30:54 -05:00
sysadmin 83bc7246ff fix(mcp): forward explicit org/repo into lease/review anti-stomp
_verify_role_mutation_workspace dropped org/repo, so anti-stomp resolved bare
remote=prgs to Timesheet and failed closed wrong_repo on Gitea-Tools. Forward
explicit org/repo for merger/reviewer lease acquire, adopt, review, merge, and
lease release. Add regression for merger acquire forwarding.

Fixes #718
Refs #723
2026-07-17 13:30:52 -04:00
sysadmin 29c2cf2ef6 fix(mcp): fail closed when merger lease cannot resolve live PR head
gitea_acquire_merger_pr_lease previously continued when GET /pulls returned
an empty head SHA. Fail closed so exact-head scoping never proceeds with an
unresolvable live head. Add regression coverage for empty head payloads.

Fixes #718
Refs #723
2026-07-17 13:25:34 -04:00
jcwalker3 4a160e0e0c Merge branch 'master' into issue-718-fix-merger-lease 2026-07-17 12:21:36 -05:00
sysadmin 14d885b2d2 Merge pull request 'feat: preserve and resume prepared review verdict drafts (#609)' (#611) from feat/issue-609-prepared-review-verdict-resume into master 2026-07-17 12:19:50 -05:00
jcwalker3 a3dbf668fd Merge branch 'master' into feat/issue-609-prepared-review-verdict-resume 2026-07-17 12:15:31 -05:00
sysadmin fb9191e559 Merge pull request 'feat(recovery): stale worktree binding demotion and crash-orphan lease recovery (Closes #702)' (#703) from fix/issue-702-stale-binding-lease-recovery into master 2026-07-17 10:55:44 -05:00
jcwalker3 07083eae09 Merge branch 'master' into fix/issue-702-stale-binding-lease-recovery 2026-07-17 10:33:46 -05:00
jcwalker3 d867acd9db Merge branch 'master' into feat/issue-609-prepared-review-verdict-resume 2026-07-17 10:33:33 -05:00
jcwalker3 a19af4de22 Merge pull request 'feat: common anti-stomp preflight before every mutation tool (Closes #604)' (#680) from feat/issue-604-anti-stomp-preflight into master
Reviewed-on: #680
Reviewed-by: sysadmin <[email protected]>

Operator break-glass merge record

PR #680 was independently assessed at head `7c77df0c527f06ae4196e010e65537d361805a7b`.

* Gitea reports the PR open and mergeable.
* The focused anti-stomp suite passed: 43 tests.
* The technical review found the change approve-worthy.
* The previous approval is stale because it applies to an earlier head.
* A fresh formal approval could not be submitted because every MCP namespace remained bound to pre-#694 startup SHA `f65069d…`, while live master is `3e78db5…`.

This is an operator-authorized break-glass merge caused by stale MCP runtime parity, not an unresolved code finding. Proceeding with **Create merge commit** only if the PR head remains exactly `7c77df0c527f06ae4196e010e65537d361805a7b`, Gitea still reports it mergeable, and no new blocking checks or feedback appear.
2026-07-17 10:33:13 -05:00
jcwalker3 751403d12b Merge branch 'master' into feat/issue-604-anti-stomp-preflight 2026-07-17 10:31:22 -05:00
jcwalker3 3e78db5d28 Merge pull request 'fix(review): cross-PR decision-lock isolation and recovery diagnosis (Closes #693)' (#694) from fix/issue-693-review-decision-lock-recovery into master
Reviewed-on: #694
Reviewed-by: sysadmin <[email protected]>
2026-07-17 10:25:21 -05:00
jcwalker3 e33d8874a5 merge(master): resolve gitea_mcp_server.py conflict for PR #703
Keep #702 boot-time stale GITEA_ACTIVE_WORKTREE recovery and #606 Sentry
init side-by-side in the daemon entrypoint. No force-push; merge commit only.
2026-07-17 11:10:59 -04:00
sysadmin 98fbfb3de7 feat(pr-sync): native assess and author update-by-merge lifecycle
Prevent approved PRs from stalling when master advances. Add
gitea_assess_pr_sync_status and gitea_update_pr_branch_by_merge with
head/base pinning, author-only updates, conflict handoff, and approval
invalidation after head changes. Wire task capability map, sequential
controller routing in review-merge workflow, and hermetic AC tests.
2026-07-17 10:42:53 -04:00
jcwalker3 8814c04e3a Merge branch 'master' into feat/issue-609-prepared-review-verdict-resume 2026-07-17 09:32:42 -05:00
jcwalker3 7c77df0c52 Merge branch 'master' into feat/issue-604-anti-stomp-preflight 2026-07-17 09:32:35 -05:00
jcwalker3 c54f41c38d Merge branch 'master' into fix/issue-693-review-decision-lock-recovery 2026-07-17 09:32:27 -05:00
jcwalker3 f34ec86b90 Merge branch 'master' into fix/issue-685-side-effect-free-resolver 2026-07-17 09:32:07 -05:00
jcwalker3 7cb65028fd Merge branch 'master' into issue-718-fix-merger-lease 2026-07-17 09:31:59 -05:00
jcwalker3 f65069d22d Merge pull request 'feat(observability): optional self-hosted Sentry instrumentation for MCP workflow failures (Closes #606)' (#679) from feat/issue-606-sentry-observability into master
Reviewed-on: #679
Reviewed-by: sysadmin <[email protected]>

Operator break-glass merge of PR #679 authorized because the native MCP
gitea_adopt_merger_pr_lease path returned non-retryable internal_error
despite an authoritative active reviewer lease. PR #679 was formally
approved by Review #446 at exact head
78cc37a977 and was conflict-free and
mergeable. No LLM received credentials or used a direct API/CLI fallback.
2026-07-17 09:30:26 -05:00
jcwalker3 9617b64a77 Merge branch 'master' into feat/issue-606-sentry-observability 2026-07-17 09:29:49 -05:00
sysadmin 4f894009f6 fix(mcp): complete merger lease acquire + structured capability resolve (#718, #723)
Harden gitea_acquire_merger_pr_lease with required candidate_head, live-head
match, and fail-closed POST handling. Add capability-map aliases for reviewer
and merger lease acquire/adopt. Make unknown tasks return structured
unknown_task (no ValueError escape). Expand tests for roles, head scoping,
aliases, and unknown_task.

Closes #718. Addresses #723 resolver unknown_task and lease task mapping.
2026-07-17 10:09:36 -04:00
sysadmin acf2eaec01 fix(pr-694): resolve master merge conflicts for #693 decision-lock isolation
Preserve #693 classification/correction helpers and integrate master
#709 recovery provenance APIs; keep both capability-map entry sets.
2026-07-17 08:44:32 -04:00
sysadmin e8ca5202a0 fix(pr-680): resolve master merge conflicts for anti-stomp preflight
Integrate #604 anti-stomp kwargs and preflight into #683 production
guard structure; keep both lease and quarantine capability-map entries.
2026-07-17 07:44:36 -04:00
sysadmin 99640f90d0 fix(pr-611): resolve master merge conflicts for #609 draft feature
Preserve KIND_REVIEW_DRAFT and draft-resume tests while integrating
master recovery-critical session kinds and RECOVERY_CRITICAL_KINDS.
2026-07-17 06:44:40 -04:00
sysadmin 1421fa8568 Fix #718: Implement gitea_acquire_merger_pr_lease
This implements the native merger lease acquisition tool to allow a merger session to acquire its own lease when a reviewer lease does not exist or has expired, unblocking #679 adoption.
2026-07-17 01:30:12 -04:00
sysadmin 9e144db75c merge(master): resolve conflicts for PR #703 onto current master
Preserve #702 recovery kinds (session lease shadow, stale-binding audit)
and instance_id shadow keys while integrating master #709/#720
decision-lock archive, irrecoverable provenance, and TTL-exempt
KIND_DECISION_LOCK. Keep list_states (#702) and cross-profile load APIs
(#709).
2026-07-16 22:16:24 -04:00
sysadmin c780ded653 fix(mcp): make capability resolver side-effect free (Closes #685)
Stale-runtime detection remains fail-closed, but gitea_resolve_task_capability
must never touch mcp_config.json, spawn recovery threads, or call os._exit.

- Remove _trigger_mcp_auto_restart from the read-only diagnostics path
- Return blocker_kind=runtime_reconnect_required with mutation_performed=false
- Keep exact_safe_next_action pointing at IDE/client reconnect when stale
- Add regression suite across author/reviewer/merger/reconciler profiles
2026-07-16 21:21:39 -04:00
sysadmin 67e4a2b5e9 Merge pull request 'fix(session): keep KIND_DECISION_LOCK durable past generic 4h TTL (Closes #720)' (#721) from fix/issue-720-expired-decision-lock into master 2026-07-16 19:48:07 -05:00
sysadminandClaude Opus 4.8 ba7915452e fix(capability-map): restore reviewer role on 10 review tasks (break-glass, incident #722)
EXCEPTIONAL OPERATOR-AUTHORIZED BREAK-GLASS RECOVERY - incident #722.

Commit 970e68b ("fix: adopt_merger_pr_lease requires merger role") was an
unreviewed direct push that flipped 11 task_capability_map.py entries to
role="merger" instead of the intended 1. Merger profiles forbid the review
permissions, so no configured profile could resolve review_pr / approve_pr /
request_changes_pr (matching_configured_profile was empty repository-wide)
and no fix PR could be formally reviewed. The operator resolved the catch-22
with a one-time break-glass authorization recorded on issue #722
(comment 11918); this commit is the authorized minimum and nothing more.

Changes:
- task_capability_map.py restored to blob 02826af (the preserved intended
  correction, local commit c071f8a1): the 10 regressive entries return to
  role="reviewer"; adopt_merger_pr_lease keeps role="merger"; merge_pr is
  untouched.
- tests/test_task_capability_role_invariants.py added (#723 AC1/AC2):
  profile-coverage invariant for formal review tasks, map/router agreement,
  merger-only adopt_merger_pr_lease and merge_pr, merger profiles cannot
  hold review permissions.

Validation: focused role-mapping tests 72 passed (+22 subtests); full suite
2900 passed, 6 skipped, 1 known warning, 195 subtests.

Recovery step 1 for incident #722; code-defect follow-ups tracked in #723.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01EnHNSVQvJ8nCk7KZ9kL4Ym
2026-07-16 18:38:17 -04:00
jcwalker3andsysadmin 293808b42d docs: ADR for stable MCP control runtime vs dev runtime (#615) (#616)
Co-authored-by: jcwalker3 <[email protected]>
2026-07-16 14:58:43 -05:00
sysadmin 970e68bddb fix: adopt_merger_pr_lease requires merger role 2026-07-16 15:52:58 -04:00
sysadmin 80f59b334e fix(session): keep KIND_DECISION_LOCK durable past generic 4h TTL (Closes #720)
Terminal review-decision ledgers are recovery-critical provenance, not
disposable session cache. A generic four-hour TTL previously made
fresh_review_on_current_head_allowed unreachable after age expiry on open
PRs (PR #616 / review 443 reproduction).

- Classify KIND_DECISION_LOCK as RECOVERY_CRITICAL so load/mark_final work
  after >4h without hand-editing session-state files
- Stamp kind + recovery_critical on save for compatibility
- Add inspect_state_envelope so assessment reports on-disk evidence instead
  of silent "no lock" when TTL would hide non-critical kinds
- Surface disk_inspect on stale decision-lock cleanup assessment

Preserves same-head #332 hard-stop, #620 head-scoped fresh review, #594
moot cleanup, and #709 irrecoverable authorization (no ordinary-profile
permission grant).
2026-07-16 15:47:52 -04:00
sysadmin 77746b08fc Merge pull request 'feat(profiles): support reconciler cleanup capability and migration (Closes #687)' (#688) from feat/issue-687-reconciler-branch-delete into master 2026-07-16 03:23:03 -05:00
sysadmin 1c37e62014 fix(cleanup): harden readback scope and ownership fail-closed (#687)
Require branch-scoped post-delete not-found (not generic/repo/host 404),
emit consistent top-level cleanup fields, fail closed on ownership inventory
errors, never auto-reclaim expired control-plane leases, include active
comment-backed reviewer leases, apply the same gates to reconcile_merged_cleanups,
and match ownership with normalized host identity.
2026-07-16 01:21:18 -04:00
sysadmin 137426f7ad fix(cleanup): post-delete readback and active ownership gates (#687)
Require authoritative not-found readback after merged-PR branch DELETE, and
block cleanup when active author/reviewer/merger/controller/reconciler
session, lease, or worktree-binding ownership still uses the target branch.
2026-07-16 00:57:30 -04:00
sysadmin 5b0d7aed0a Merge pull request 'fix: map Gitea auth failures to structured MCP tool errors (Closes #699)' (#701) from fix/issue-699-structured-auth-mcp-errors into master 2026-07-15 23:48:06 -05:00
sysadmin 1ab384adc9 Merge pull request 'fix(workflow): cross-profile decision-lock cleanup and irrecoverable provenance (Closes #709)' (#710) from fix/issue-709-decision-lock-cross-profile into master 2026-07-15 21:24:42 -05:00
sysadminandClaude Opus 4.8 573e721437 fix(workflow): fail-closed key version, strict incident evidence, archive-gated clear (#709)
Address formal review 438 REQUEST_CHANGES on PR #710 (F6/F7/F8).

F6 — HMAC key-version validation fails closed:
- verify_authorization_artifact validates key_version BEFORE any MAC work, so an
  attacker-chosen version can never select the signing key.
- Require exactly one nonempty, well-formed key-version field; missing, empty,
  unknown, malformed, duplicated (including identical-valued and nested
  aliases), and mismatched versions all fail. No versionless legacy fallback.
- Artifact version must equal the configured active version; production now
  requires GITEA_IRRECOVERABLE_AUTH_HMAC_KEY_VERSION explicitly (an implicit
  default made rotation ambiguous). Version stays inside the signed material.

F7 — strictly canonical incident evidence:
- Replace substring/first-match parsing with an exact schema: marker on line 1,
  every field once, fixed order, no duplicate/unknown/empty/conflicting fields
  in or outside the signed block. The parsed body is re-rendered and compared
  for exact equality before acceptance.
- content_digest now binds the full recovery scope: repository identity, PR,
  decision-lock identity, destroyed subject, recovery action, recorded and
  expected head, incident issue, evidence author, minting actor, key version,
  nonce and issued_at.
- Actor identity is the immutable user id with login consistency; conflicting
  ids/logins and display-name-only identities fail closed. Edited comments are
  rejected. The independent-author rule is preserved and enforced by stable id.
- build_canonical_incident_body is the single source of the accepted format and
  refuses to emit ambiguous evidence.

F8 — archival is a prerequisite for clearing terminal evidence:
- _clear_decision_lock_for_profile no longer swallows archive failures. It
  requires a successful write plus a durable read-back matching the PR/head,
  and otherwise returns a structured, retry-safe failure that retains the lock
  and records actionable recovery evidence.
- Fixes a latent bug the read-back exposed: the archive payload inherited the
  source lock's session_profile_lock, so save_state keyed the archive under the
  reviewer profile instead of the archive identity and it never read back.

Adversarial regressions added for every listed case: key-version missing/empty/
unknown/malformed/duplicate/rotation/wrong-key-after-restart, reordered fields,
duplicate identical and conflicting fields, conflicting actor ids/names,
digest-preserving substitution, decision-lock and recovery-action substitution,
cross-PR/repo/org/remote/head replay, archive exception/timeout/false/empty/
partial-readback with proof the lock survives, exactly-one permitted clear, and
retry after archive failure. No existing assertion was weakened.

Validation: focused 150 passed in three module orders; full tests/ 2809 passed,
6 skipped, 1 warning (pre-existing StarletteDeprecationWarning in
tests/test_webui_audit.py:8), 161 subtests passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-15 13:55:06 -04:00
sysadminandGrok 4.5 2b359e0c26 fix(workflow): durable HMAC, dedicated mint capability, head-exact approve match (#709)
Address formal review 435 REQUEST_CHANGES on PR #710:
- F4: require durable GITEA_IRRECOVERABLE_AUTH_HMAC_KEY (fail closed; no ephemeral
  per-process secret); bind key_version into HMAC; cross-process verify works
- F5: dedicated gitea.decision_lock.irrecoverable_recovery only; reject reconciler
  equivalence; authoritative incident body + author + content_digest; reject
  self-authored incident evidence
- F3 residual: lock_targets_merged_pr_approval requires recorded-head match when
  expected_head_sha is provided (legacy no-head approve no longer primary-clears)

Co-Authored-By: Grok 4.5 (xAI) <[email protected]>
2026-07-14 02:13:47 -04:00
sysadminandGrok 4.5 9cb12ee0f4 fix(workflow): non-forgeable irrecoverable auth, merger consumer, exact-scope cleanup (#709)
Address formal review 434 REQUEST_CHANGES on PR #710:
- F1: replace caller operator_authorized with server-side HMAC auth artifacts
- F2: implement fail-closed merger consumption for prior-provenance only
- F3: enforce remote/org/repo/head on cross-profile load and clear

Co-Authored-By: Grok 4.5 (xAI) <[email protected]>
2026-07-14 01:36:39 -04:00
sysadmin ec5cf67771 fix(workflow): cross-profile decision-lock cleanup and irrecoverable provenance (#709)
Prevent merger-local empty decision locks from standing in for reviewer
terminal cleanup, refuse silent re-init overwrite of unresolved terminal
evidence, record post-merge recovery-required state when audit fails, and
add a truthful irrecoverable-provenance path that never claims applied=true.

Closes #709
2026-07-14 00:54:33 -04:00
sysadmin 1eafb757a9 Merge pull request 'feat(guard): native MCP transport binding and contaminated-review quarantine (Closes #695)' (#696) from fix/issue-695-native-transport-quarantine into master 2026-07-13 21:10:11 -05:00
sysadmin 576349d545 fix(guard): pin session-state authority and reject direct-import mutation (#695)
Close remaining AC1/AC2/AC6-8 gaps after REQUEST_CHANGES and the PR #701
recurrence: GITEA_ALLOW_DIRECT_MCP_IMPORT never authorizes mutations;
production transport bind pins GITEA_MCP_SESSION_STATE_DIR so redirected
dirs cannot forge independent decision locks; mark/submit fail closed
offline; quarantine continues to void contaminated merge eligibility.

Regression tests reproduce the PR #701 direct-import + state-dir override
sequence. Full suite: 2665 passed, 6 skipped.

Closes #695 (remediation on PR #696)
2026-07-13 21:48:28 -04:00
sysadmin ae6f0b74db fix(guard): close allow_test_bootstrap and basename entrypoint bypasses (#695)
Remove the public allow_test_bootstrap production seam so caller-controlled
flags cannot forge native mutation provenance. Bind provenance to the resolved
canonical entrypoint path plus a live stdio transport bind; basename-only
mcp_server.py stack frames and import-only launch no longer authorize
mutations. Test-mode install_test_native_runtime is pytest-only and cannot
reach production Gitea mutation endpoints. Add AC9 regressions for both
reviewer-found bypasses and related spoof vectors.

Refs: PR #696 REQUEST_CHANGES at 253269c; issue #695 comments 11002/11005.
2026-07-13 21:48:28 -04:00