Commit Graph
100 Commits
Author SHA1 Message Date
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
sysadmin 553f745f23 feat(guard): native MCP transport binding and contaminated-review quarantine (Closes #695)
Bind mutation/credential paths to a process-local native MCP runtime so env
spoofing, direct imports, and offline helpers cannot reconstruct session gates
after native transport failure. Quarantine contaminated formal reviews under
controller authority and honor quarantine in review feedback, merge eligibility,
merge mutation, and canonical handoff validation. Add regression coverage for
the second (PR #694 / review 427) incident class.
2026-07-13 21:48:28 -04:00
sysadmin cc3ad0870a Merge pull request 'fix(validator): align final-report validator with canonical schema (Closes #698)' (#705) from fix/issue-698-report-validator-schema into master 2026-07-13 17:26:11 -05:00
sysadminandClaude Fable 5 ee90a5e7a2 fix(validator): align final-report validator with canonical schema (Closes #698)
Fixes the final-report validator defects from Issue #698 (original lead
plus the independent reproduction recorded during the PR #703 formal
review, comment 11246):

- Legacy fields: the review/merger required-field tables no longer demand
  'Pinned reviewed head', 'Scratch worktree used', 'Worktree path',
  'Worktree dirty', 'Mutations', 'Next', 'Issue/PR', 'Branch/SHA', or
  'Files changed' — names the canonical review-merge-final-report schema
  forbids or replaces. The canonical names ('Reviewed head SHA', 'Review
  worktree path/dirty', 'Safe next action', mutation categories) are
  required instead, with backward-compatible aliases where the schema
  permits them.
- Structured proof: workflow-load helper results are recognized in
  colon, key=value, and JSON renderings; validation pass proof is
  accepted anywhere in the Validation field value (for example
  'focused 50 passed; full 2665 passed').
- Mutation inference: review mutations are inferred only from
  authoritative evidence (performed=true and not gated); read-only
  diagnostics and pre-API rejections no longer count as mutations.
- Lease release vs cleanup: canonical reviewer lease release (release
  tool call or terminal phase=released marker) is lease lifecycle, not
  post-merge cleanup, and no longer triggers the branch/worktree cleanup
  checklist; genuine delete/remove claims still require full proof.
- Blocked reports: a legitimately blocked run that states an explicit
  'Reviewed/Candidate head SHA: none' with no verdict, merge, or started
  validation owes no head proofs; approval-time and merge-time live-head
  proofs are demanded only once the corresponding phase begins, and a
  report that states no head at all still fails closed.
- action_log robustness: malformed (non-dict) entries and non-list logs
  are reported as clear sanitized findings (position and type only, no
  content echo) instead of crashing with AttributeError; a defective
  validator rule now fails closed with a sanitized block finding rather
  than raising a secondary exception.

27 new regression tests, including canonical fixtures modeled on the
PR #703 formal-review handoff and the blocked preflight report from the
prior #698 reproductions. Two legacy-field test fixtures updated to the
canonical schema. Full suite: 2663 passed, 6 skipped, 161 subtests.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-13 17:37:13 -04:00
sysadmin 237656702f Merge pull request 'feat(lease): guarded cleanup for obsolete reviewer comment leases (Closes #691)' (#692) from fix/issue-691-obsolete-reviewer-lease-cleanup into master 2026-07-12 22:28:59 -05:00
sysadmin 6d86db793b feat(lease): guarded cleanup for obsolete reviewer comment leases (Closes #691)
Add fail-closed assessment and MCP tool for expired/superseded-head
comment-backed reviewer leases that lack a control-plane lease_id.

- assess_obsolete_reviewer_comment_lease_cleanup eligibility matrix
- diagnose classifications: foreign_active_current_head,
  foreign_expired_current_head, foreign_completed_superseded_head,
  foreign_expired_superseded_head, orphaned_owner_missing,
  ambiguous_conflicting_evidence
- gitea_cleanup_obsolete_reviewer_comment_lease with confirmation
  CLEANUP OBSOLETE REVIEWER LEASE <n> and controller_recovery_authorized
- preserve audit history via append-only phase=released marker
- never repoint, transfer validation, use PID ownership, or steal
  active current-head foreign leases
- regression for PR #688 lease comment 10749 after recorded expiry
2026-07-12 23:09:20 -04:00
sysadmin 56f1230a10 Merge pull request 'feat(guard): harden workflow against unattributed root WIP and pytest-disabled production guards (Closes #683)' (#684) from fix/issue-683-workflow-guard-hardening into master 2026-07-12 18:58:55 -05:00
sysadmin d302602567 feat(guard): harden workflow against unattributed root WIP and pytest-disabled production guards (Closes #683)
Add shared workflow_scope_guard with typed blockers (blocker_kind +
exact_next_action) and force-on production enforcement under pytest.
Wire root/branches/scope checks through verify_preflight_purity and
mutation entrypoints (create_issue, comment_issue) without adopting the
rejected 300a4ca patterns (test-mode early-return, porcelain *.py filter).

Regression suite covers out-of-scope issue ownership, root diagnostic
edits, worktree bind success path, force-on under pytest, porcelain
integrity, monkeypatch resistance, real entrypoint fail-closed proof,
and durable failure recording.
2026-07-12 13:15:58 -04:00
sysadmin 22698c1b5f Merge pull request 'feat(guard): block direct stable-branch pushes from MCP workflow sessions (Closes #671)' (#677) from fix/issue-671-block-stable-branch-push into master 2026-07-11 20:05:45 -05:00
sysadmin de27053f74 Merge pull request 'fix: residual preflight/worktree/test-isolation remediations after #673' (#676) from fix/issue-675-residual-preflight-remediation into master 2026-07-11 19:15:56 -05:00
sysadminandClaude Opus 4.8 5933d87647 feat(guard): block direct stable-branch pushes from MCP workflow sessions (Closes #671)
Prevention hardening for the #670 incident (bare direct-to-master commit
2fa97c26 and the PR #654 merger stable-branch push attempt). Worker sessions
must never publish stable branches directly; stable updates land only through
sanctioned Gitea merge tooling or an authorized reconciler path.

New pure module stable_branch_push_guard.py:
- classify_push_command: detects git push <remote> <stable-ref> equivalents
  including refspecs (HEAD:<ref>, +refs/heads/x:refs/heads/<ref>), --force,
  --delete/:<ref>, and --dry-run/-n no-op probes (dry-run still proves intent).
  Fetch/pull and feature-branch pushes are never flagged; sanctioned
  gitea_merge_pr / API merge is not a push.
- assess_root_checkout_local_commit: detects control-checkout commits not on an
  issue feature branch (branches/ worktrees exempt).
- redact_command: strips URL userinfo/token assignments before logging.
- build_contamination_record + assess_contamination_gate: durable marker shape
  and fail-closed gate (reconciler-exempt; comment/lock stay allowed for handoff).

Server wiring (gitea_mcp_server.py, mcp_session_state.py):
- KIND_STABLE_BRANCH_CONTAMINATION durable session marker (per profile identity).
- _enforce_stable_branch_contamination_gate wired into verify_preflight_purity
  so review/merge/close/completion mutations fail closed while contaminated.
- gitea_record_stable_branch_push_attempt: classify + mark on detection.
- gitea_audit_stable_branch_contamination: reconciler-only inspect/clear; a
  worker session can never self-clear.

Tests (AC5): no-op dry-run push, real direct push, sanctioned Gitea merge,
fetch-only, root-checkout local commit, feature-branch push allowed, gate
block/reconciler-exempt, redaction. 51 new tests; full suite 2596 passed.

Docs: llm-project-workflow SKILL.md — universal rule, blocker class, and a
dedicated "Stable Branch Push Protection" section (worker sessions must never
push stable branches directly).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-11 20:07:40 -04:00
sysadmin 72b18143f8 fix(preflight): unify review worktree regex, resolve Web UI NameError, and fix test isolation 2026-07-11 19:49:16 -04:00
sysadmin 8886ce201f fix(preflight): bypass workspace checks in test mode and mock subprocess in alignment tests 2026-07-11 19:49:16 -04:00
sysadmin bee24e2b10 Merge pull request 'fix(test): remediate repository-wide regressions (Closes #673)' (#674) from fix/issue-673-remediate-regressions into master 2026-07-11 18:16:05 -05:00
sysadmin a7aac0df1d fix(test): remediate repository-wide regressions (Closes #673) 2026-07-10 18:09:19 -04:00
sysadmin ec903b0d61 Merge pull request 'feat: lifecycle role/hazard labels and canonical state mapping (#603)' (#654) from feat/issue-603-lifecycle-labels into master 2026-07-10 15:43:47 -05:00
sysadminandClaude Opus 4.8 f34319852e feat: lifecycle role/hazard labels and canonical state mapping (#603)
Add orthogonal role:* (single-active owner) and hazard:* (additive warning)
lifecycle labels plus status:changes-requested, folding the #603 state:*
vocabulary into the canonical status:* set rather than a conflicting parallel
prefix.

- issue_workflow_labels.py: ROLE_/HAZARD_ specs + frozensets; role/hazard
  transition maps and helpers (transition_role_labels, add/clear_hazard_label,
  canonical_role_label, canonical_hazard_label, is_discussion,
  is_implementation_candidate, requires_blocking_reason); state:* -> status:*
  synonym transitions; assess_issue_labels surfaces role/hazard dims and flags
  multiple active role labels
- docs/label-taxonomy.md: role, hazard, state->canonical migration, and
  allocator cross-check sections
- tests: role/hazard/discussion/blocking-reason/state-synonym coverage
- manage_labels.py seeds the new labels automatically via CANONICAL_LABEL_SPECS

Labels remain advisory; control-plane leases (#601) and live PR state stay the
source of truth for mutations (#603 AC2).

Closes #603

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-10 16:17:31 -04:00
sysadmin 2fa97c26fb fix(mcp): load dotenv relative to project root 2026-07-10 15:22:18 -04:00
sysadmin 5ab5fe8583 Merge pull request 'fix: paginate repository-label inventory for gitea_set_issue_labels (Closes #627)' (#629) from fix/issue-627-set-issue-labels-pagination into master
Closes #627

Merges paginated repository-label inventory for gitea_set_issue_labels so later-page labels are not falsely rejected during full-set replacement.
2026-07-10 12:54:23 -05:00
sysadmin f32aaaa3b5 fix: paginate repository-label inventory for gitea_set_issue_labels (#627)
Replace single-page GET labels?limit=100 with api_get_all-backed
_repo_label_id_map so later-page labels (e.g. type:feature,
workflow-hardening) are not falsely rejected during full-set replacement.

Also add post-mutation verification, fix related MCP/CLI label inventory
call sites, and add multi-page regression tests for the #601 reconciler
failure mode.

Closes #627
2026-07-10 13:05:27 -04:00
sysadmin 5347b313ea Merge pull request 'feat: first-class control-plane lease lifecycle (Closes #601)' (#625) from feat/issue-601-first-class-leases into master 2026-07-10 11:23:29 -05:00
sysadmin 1be4600261 fix: address #625 REQUEST_CHANGES for lease reclaim test and EOF blank line
- Update MCP expired-lock recovery test for sticky expired ownership
  (live pid + present worktree still fail closed under #601 reclaim rules)
- Remove trailing blank line at EOF in control_plane_db.py
2026-07-10 11:54:05 -04:00
sysadmin 780ef0b1be feat: first-class control-plane lease lifecycle (Closes #601)
Make active leases queryable workflow state with canonical adopt, release,
expire/reclaim, and abandon operations on the #613 control-plane DB substrate.

- lease_lifecycle.py: policy, proof gates, safe_next_action vocabulary
- control_plane_db: schema v3 provenance columns + list/inspect/adopt/abandon
- MCP tools: gitea_*_workflow_lease(s) for list/inspect/adopt/release/expire/abandon/reclaim
- issue_lock_store: sanctioned reclaim of expired author locks (dead pid / missing wt)
- Tests cover lifecycle, foreign steal refusal, allocator compatibility, merger handoff
2026-07-10 11:30:53 -04:00
sysadmin a654cda058 fix: import Any from typing to resolve IDE/compiler diagnostic warnings 2026-07-10 10:27:21 -04:00
sysadmin ab1c2d7973 Merge pull request 'feat: Sentry/GlitchTip incident bridge via incident_links (Closes #612)' (#623) from feat/issue-612-incident-bridge into master 2026-07-10 08:36:47 -05:00
sysadmin 6a179aeb85 feat: Sentry/GlitchTip incident bridge via incident_links (Closes #612)
Add phase-1 observability bridge that turns provider observations into
normal Gitea issues and control-plane incident_links rows. Dry-run is
default; apply creates/links through sanctioned Gitea issue paths only.
Raw incidents remain non-assignable; the #600 allocator sees bridge work
only as ordinary Gitea issues. Builds on #613 substrate and #600 allocator.

Closes #612
2026-07-10 03:18:54 -04:00
sysadmin f20c8436aa Merge pull request 'feat: controller-owned allocator API on control-plane DB (Closes #600)' (#622) from feat/issue-600-controller-allocator-api into master 2026-07-10 02:11:59 -05:00
sysadmin db5d14184f feat: controller-owned allocator API on control-plane DB (Closes #600)
Add gitea_allocate_next_work and allocator_service routing policy on top of
the #613 ControlPlaneDB substrate. Workers get atomic assign+lease results
(or wait/no_safe_work/terminal-path outcomes) without self-selecting work
via file locks or comment-only leases. #612 remains downstream.

Closes #600
2026-07-10 02:54:20 -04:00
sysadmin 10228e1c06 Merge pull request 'feat: control-plane DB substrate for atomic assign/lease (Closes #613)' (#619) from feat/issue-613-allocator-db-substrate into master 2026-07-10 01:44:19 -05:00
sysadmin d8b2b8f1a7 Merge pull request 'fix: head-scope durable #332 review-decision locks (Closes #620)' (#621) from fix/issue-620-head-scoped-review-locks into master
Reviewed-on: #621
2026-07-10 01:12:57 -05:00
sysadmin 9e1d5c5649 fix: head-scope durable #332 review-decision locks (#620)
Prior REQUEST_CHANGES on head A no longer blocks formal re-review on
head B of the same open PR. Locks store reviewed head SHA, hard-stop and
mark_ready/submit gates allow a fresh decision boundary when the live
head differs, and same-head duplicates remain fail-closed. Open-PR lock
cleanup stays forbidden (#594); assessment reports locked vs current
head and stale_by_head / fresh_review_on_current_head_allowed.

Closes #620
2026-07-10 01:04:37 -04:00
sysadmin 2429d9d2e8 fix: fail closed on conflicting incident_links observation metadata
Legacy NULL-scope dedupe only compared Gitea targets, so duplicate rows
with the same provider key and issue but different fingerprint/status/
event_count/etc. collapsed to the lowest link_id and silently dropped
observation data. Migration now compares all meaningful observation
fields and refuses to discard conflicts (#619 RC3 / #613).
2026-07-09 23:04:17 -04:00
sysadmin 16cd871fbd fix: safe incident_links migration order; require PR head pin
Address remaining PR #619 blockers on head 783ea88:

- Deduplicate legacy NULL-scope incident_links before normalizing to ''
- Fail closed when duplicate rows disagree on Gitea target
- Require non-empty expected_head_sha for PR assign and mutation
2026-07-09 22:51:27 -04:00
sysadmin 783ea88a01 fix: fail closed on stale/terminal assignments; canonicalize incident_links
Address REQUEST_CHANGES on PR #619:

- require_valid_assignment rejects terminal work states and head drift
- incident_links scope keys normalize NULL/blank to '' for UNIQUE
- remove trailing whitespace in control-plane-db-substrate.md
2026-07-09 22:41:25 -04:00
sysadmin 036b78e31e feat: control-plane DB substrate for atomic assign/lease (Closes #613)
Add SQLite single-writer MVP control plane per the allocator ADR:
sessions, work_items (issue/pr only), atomic assign+lease, mutation
gates, terminal-lock index, and provider-neutral incident_links.

DB coordinates concurrency; Gitea remains assignable work; raw
Sentry/GlitchTip incidents are never work items. #600 and #612 build on
this substrate.
2026-07-09 22:27:51 -04:00
sysadmin 08c3488d7c Merge pull request 'docs: ADR for MCP allocator, control-plane DB, and incident bridge (#613)' (#614) from docs/issue-613-allocator-control-plane-observability-adr into master 2026-07-09 21:10:27 -05:00
sysadmin 4f2fd9a8b1 fix(mcp): resolve default remote mapping and connection check bugs 2026-07-09 20:26:58 -04:00
sysadmin 4185ee1417 docs: ADR for MCP allocator, control-plane DB, and incident bridge
Canonical architecture for #613#600#612: DB coordinates, Gitea
records, Sentry/GlitchTip observe; allocator assigns only Gitea issues/PRs.

Refs: #600 #612 #613
2026-07-09 20:00:59 -04:00
sysadmin ae6a3ae00c Merge pull request 'feat: diagnose live MCP namespace EOF health and block merge (#543)' (#587) from feat/issue-543-mcp-namespace-health-check into master 2026-07-09 18:46:52 -05:00
sysadmin 2fde92ad25 Implement review drafts saving and resuming (#609) 2026-07-09 19:08:28 -04:00
sysadmin ebd06b73c9 fix: address PR #587 REQUEST_CHANGES for MCP namespace health (#543)
- Distinguish client_namespace vs offline_spawn probe sources; only IDE
  client probes prove namespace health and feed mutation gates.
- Record assessments in session; gate gitea_submit_pr_review and
  gitea_merge_pr when client-namespace health is unhealthy/non-proven.
- Mark test_mcp_conn.py offline-only; align recovery docs to client
  reconnect (no PID-kill/config-touch as canonical recovery).
- Rebase onto current master so #590 ledger isolation keeps
  TestMergePR.test_unknown_profile_blocks green.
2026-07-09 18:44:04 -04:00
sysadmin af9f1c5944 style: fix trailing newline in mcp_namespace_health.py 2026-07-09 18:39:41 -04:00
sysadminandClaude Opus 4.8 f83d2c2027 docs: add MCP namespace client is closing: EOF recovery runbook (#543)
Adds docs/mcp-namespace-eof-recovery.md documenting the correct recovery
path when a Gitea MCP namespace (gitea-author/reviewer/merger/tools)
returns `client is closing: EOF`.

Satisfies acceptance criterion 7 of #543: symptom, root cause (closed
client transport vs a live-but-stale process), the sanctioned
reconnect/relaunch sequence, diagnostics to capture, and how
test_mcp_conn.py reproduces the registered-vs-callable gap. Distinguishes
this transport-close failure from the ps-based stale-runtime family in
#531/#544 and reinforces the no-direct-import guard (#558).

Docs-only; no code or test behavior changed.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-09 18:39:41 -04:00
sysadminandClaude Opus 4.8 93781af7e9 feat: enforce live-namespace block in review/merge state machine (#543 AC5)
The namespace health check (05fdcee) classified a false-ready namespace but
only returned an advisory blocks_merge_workflow flag; nothing in the merge
gate consumed it. Wire it in so a broken live namespace hard-blocks merge.

- review_merge_state_machine.assess_workflow_blockers: add live_namespace_broken
  blocker (registered-in-FastMCP but not callable-through-namespace).
- assess_state_advancement: forward **blocker_kwargs so can_approve/can_merge/
  workflow_status honor the full blocker set (also fixes latent drop of
  mcp_reconnect_failed/stale_capability_state through those paths).
- gitea_assess_review_merge_state_machine tool: accept live_namespace_broken and
  thread it through all state-machine calls.
- Tests: prove can_merge/workflow_status/tool block on live_namespace_broken even
  with every review state + pre-merge gate satisfied; bridge classify verdict.
- Docs: enforcement section wiring blocks_merge_workflow -> live_namespace_broken.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-09 18:39:41 -04:00
sysadmin 314615ec2c feat: diagnose live MCP namespace EOF health 2026-07-09 18:39:41 -04:00
sysadmin 52013791d4 Merge pull request 'feat: canonical validation wording, baseline proof, and closure gate (Closes #529)' (#598) from feat/issue-529-canonical-validation-wording into master 2026-07-09 17:30:52 -05:00
sysadmin 2ac7519792 Merge pull request 'fix: enforce merger role boundaries (Closes #539)' (#596) from fix/issue-539-role-boundary-hard-stops into master 2026-07-09 17:07:54 -05:00
sysadmin a32c68e24b Merge pull request 'feat: diagnose reviewer lease handoff next actions (Closes #599)' (#608) from feat/issue-599-reviewer-lease-handoff into master 2026-07-09 16:47:23 -05:00
sysadmin 7186718cfd Merge pull request 'fix: isolate review-mutation ledger from host session-state (Closes #590)' (#592) from fix/issue-590-ledger-isolation into master 2026-07-09 16:32:02 -05:00
sysadmin 964505654f feat: diagnose reviewer lease handoff next actions (#599)
Add read-only diagnose_reviewer_pr_lease_handoff and MCP tool
gitea_diagnose_reviewer_pr_lease_handoff so open-PR foreign leases,
instructed-lease replacement, reclaimable release, and worktree
binding mismatch return a canonical next_action without steal paths.

Closes #599
2026-07-09 17:31:14 -04:00
sysadmin 008cd3fd74 fix: keep tests free of host MCP stale-runtime probes (#590)
patch.dict(os.environ, clear=True) also drops PYTEST_CURRENT_TEST, which
re-enables live MCP process health checks against operator daemons and
makes merge-gate unit tests environment-dependent. Stub the diagnostic
in conftest so unit tests stay isolated.
2026-07-09 17:20:09 -04:00
sysadmin 11ffe0f9dd fix: isolate review-mutation ledger from host session-state (#590)
Tests that call patch.dict(os.environ, clear=True) dropped
GITEA_MCP_SESSION_STATE_DIR and re-adopted the operator host cache
under ~/.cache/gitea-tools/session-state. A residual terminal
request_changes mutation then tripped the #332 hard-stop before
test_unknown_profile_blocks could assert the empty-profile gate.

- Pin mcp_session_state.default_state_dir / DEFAULT_STATE_DIR to a
  per-test temp dir in conftest (still honors an explicit env override)
- Clear the decision lock at the start of each TestMergePR test
- Add regression coverage for env-clear isolation

Closes #590
2026-07-09 17:19:29 -04:00
sysadmin 683649424b Merge pull request 'feat: auto-restart Gitea MCP namespaces when stale or git HEAD advances (#591)' (#593) from feat/issue-591-auto-restart-mcp into master 2026-07-09 15:46:34 -05:00
sysadmin ac531dda05 Merge pull request 'feat: canonical cleanup for stale #332 review decision locks (Closes #594)' (#595) from feat/issue-594-stale-decision-lock-cleanup into master 2026-07-09 15:01:27 -05:00
sysadmin 2941ec529c fix: enforce merger role boundaries (Closes #539) 2026-07-09 15:41:07 -04:00
sysadmin b98e8dfa1a test: harden session-state isolation for #594 decision-lock suite
Pin per-test durable session-state so patch.dict(clear=True) cannot adopt
host ~/.cache review-decision locks, and clear the merge-test ledger in
setUp. Keeps active #332 hard-stop coverage while making TestMergePR
deterministic without manual host cache cleanup.

Aligned with #590 / PR #592 isolation approach.
2026-07-09 15:24:41 -04:00
sysadmin 86651a3d05 docs: expand #594 stale decision-lock cleanup guidance
Add allowed/forbidden workflow steps to the review-merge skill and
document the #594 cleanup gate on the Safety-and-Gates wiki page.
2026-07-09 15:21:21 -04:00
sysadmin 3f3f880147 feat: canonical cleanup for stale #332 review decision locks (#594)
Durable review-decision locks (#559) can outlive the PR they protect.
When the last terminal mutation references a PR that is already
merged/closed, expose gitea_cleanup_stale_review_decision_lock so a
reviewer can clear the lock with identity/profile gates and a durable
audit trail — without weakening #332 for open PRs or deleting
session-state files by hand.

Also auto-clear same-profile locks after a successful merge of the
approved PR, and document allowed vs forbidden cleanup.

Closes #594
2026-07-09 15:18:48 -04:00
sysadmin 6094069ef6 feat: auto-restart Gitea MCP namespaces when stale or git HEAD advances (closes #591) 2026-07-09 14:20:05 -04:00
sysadmin 6913ac98f1 Merge pull request 'feat: block vague-reference issue creation with content preflight (Closes #582)' (#586) from feat/issue-582-issue-content-preflight into master 2026-07-09 13:20:02 -05:00
sysadmin faf36b5bdf Merge pull request 'feat: merge-report lease proof fields and handoff audit (Closes #535)' (#585) from feat/issue-535-lease-proof-report into master 2026-07-09 13:16:19 -05:00
sysadmin 05b4f13e96 Merge pull request 'fix: control-plane guide org/repo params after #530 guard (Closes #588)' (#589) from fix/issue-588-guide-repo-guard into master 2026-07-09 12:49:24 -05:00
sysadmin 57b2023611 fix: control-plane guide org/repo params and local repo alignment (#588)
#530's remote/repo guard blocked mcp_get_control_plane_guide(remote=prgs)
because the bare default resolves to Timesheet while local git is
Gitea-Tools, and remediation told callers to pass org/repo on a tool that
did not accept those parameters.

- Accept optional org/repo on mcp_get_control_plane_guide
- Prefer local git remote org/repo when bare defaults mismatch (read-only guide)
- Keep mutation tools fail-closed on bare mismatch
- Align remediation text with tools that accept org/repo

Closes #588
2026-07-09 13:17:27 -04:00
sysadminandClaude Opus 4.8 5debfcf178 feat: block vague-reference issue creation with content preflight (Closes #582)
Add a pre-create content gate to gitea_create_issue that fails closed with
BLOCKED + DIAGNOSE when the title/body is a vague reference to out-of-band
draft content ("the drafted issue", "the prepared issue", "the issue we
discussed", "the previous draft") and no durable source pointer (existing
issue/PR/comment, checked-in file, URL, or scratchpad path) is present.

- issue_content_gate.py: assess_issue_content / pre_create_issue_content_gate
  with vague-phrase detection, durable-source-pointer escape hatch, and a
  domination check so long specific bodies are not falsely blocked.
- gitea_create_issue: runs the gate after preflight purity, before duplicate
  search; new allow_incomplete_content override (off by default). Title-only
  creation stays allowed (no empty-body requirement) to preserve behavior.
- tests/test_issue_content_gate.py: unit + MCP integration coverage.
- create-issue.md: documents the enforced preflight with valid/invalid
  prompt examples.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-09 13:07:53 -04:00
sysadmin 27d75facd4 Merge pull request 'feat: reconciler supersession close path for PRs/issues (Closes #525)' (#583) from feat/issue-525-reconciler-supersession-close into master 2026-07-09 11:58:06 -05:00
sysadmin 2b4c291f12 feat: merge-report lease proof fields and handoff audit (#535)
Surface lease_proof_source / recovery reason from sanctioned session
provenance on gitea_merge_pr results, and block final reports that claim
manual/seeded/injected lease proof without MCP adoption evidence.

Closes #535
2026-07-09 12:56:12 -04:00
sysadmin b0ae1605c3 feat: add reconciler supersession close gate 2026-07-09 12:36:50 -04:00
sysadmin c738e5b10d Merge pull request 'fix: resolve reviewer lease identity via host not remote alias (Closes #578)' (#581) from fix/issue-578-reviewer-lease-identity into master 2026-07-09 11:21:29 -05:00
sysadmin fe9faec741 test: cover reviewer lease identity host resolution 2026-07-09 12:09:40 -04:00
sysadmin 7f2a5a3d3c fix: resolve reviewer lease identity via host not remote alias
_authenticated_username expects a host for auth/API calls. Lease
acquire/adopt/gate/release paths passed the remote alias (prgs), so
identity resolved empty and same-identity release fail-closed across
sessions — blocking author conflict-fix pushes after REQUEST_CHANGES.

Pass resolved host h from _resolve into _authenticated_username.
2026-07-09 12:09:40 -04:00
sysadmin 946d6c2f81 Merge pull request 'Web UI: Test coverage and CI checks (#436)' (#457) from feat/issue-436-ci-coverage into master 2026-07-09 11:06:55 -05:00
sysadmin 64b83cd1fb test: keep webui CI hermetic offline 2026-07-09 11:59:23 -04:00
sysadmin 23535e30bc feat(webui): test coverage and CI gate (#436)
Add consolidated MVP route/read-only tests, path-filter helpers, and
scripts/test-webui plus scripts/ci-webui-check for Jenkins path-filtered
runs on PRs touching web UI surfaces.

Closes #436
2026-07-09 11:59:23 -04:00
sysadmin 351ef3899b Merge pull request 'Web UI: Auth and deployment boundary (#435)' (#456) from feat/issue-435-auth-deployment into master 2026-07-09 10:58:52 -05:00
sysadmin 1334b0b320 fix: restore ISSUE_LOCK_FILE import and fail-closed public bind
Conflict resolution left webui/lease_loader.py importing ISSUE_LOCK_FILE
from merged_cleanup_reconcile (not exported); import from
issue_lock_provenance instead. Validate WEBUI_HOST before loading the
full app stack so 0.0.0.0 refuse exits immediately.

Addresses reviewer findings on PR #456 / issue #435.
2026-07-09 11:52:24 -04:00
sysadmin 975674d7f5 feat(webui): auth and deployment boundary (#435)
Add bind-host assessment that refuses 0.0.0.0/:: without override,
warns on non-loopback binds, and documents internal-only MVP serving.
Health endpoint exposes deployment metadata; docs cover Access/VPN/WARP
and runtime env assumptions without embedding secrets in the client.

Closes #435
2026-07-09 11:50:40 -04:00
sysadmin 8d1098f916 Merge pull request 'feat: guard merged branch cleanup path' (#516) from feat/issue-514-branch-delete-guard into master 2026-07-09 10:45:05 -05:00
sysadmin 49aa3b2812 Merge pull request 'Web UI: Gated action framework (#434)' (#455) from feat/issue-434-gated-actions into master 2026-07-09 10:39:28 -05:00
sysadmin 94004f05ac Merge pull request 'fix: newest reviewer lease marker wins so release ends prior claims (Closes #577)' (#579) from fix/issue-577-reviewer-lease-newest-wins into master 2026-07-09 10:38:22 -05:00
sysadmin 8d6d3cb014 fix: refine terminal preflight check to avoid false-positive PATH blocks on server 2026-07-09 11:31:48 -04:00
sysadmin f558b80cc8 test: cover explicit git -C terminal probe 2026-07-09 10:43:42 -04:00
sysadmin 223cde1b94 feat: terminal launcher diagnostics and mutation preflight (Closes #556)
Add categorize-and-probe helpers for shell spawn failures, expose
gitea_diagnose_terminal, and fail closed on mutation capability resolve
when the terminal launcher is unhealthy (BLOCKED + DIAGNOSE). Document
the operator path in the workflow runbooks.
2026-07-09 10:29:03 -04:00
sysadmin 9b96085d8d fix: newest lease marker wins so release ends prior claims
find_active_reviewer_lease walked past terminal markers and re-armed
older claimed leases after gitea_release_reviewer_pr_lease. Treat the
newest marker as authoritative (append-only ledger).

Closes #577
2026-07-09 10:09:38 -04:00
sysadmin ddb1dd941b Merge remote-tracking branch 'prgs/master' into feat/issue-434-gated-actions
# Conflicts:
#	docs/webui-local-dev.md
#	tests/test_webui_skeleton.py
#	webui/app.py
2026-07-09 09:38:20 -04:00
sysadmin d7c29afde5 Merge remote-tracking branch 'prgs/master' into feat/issue-514-branch-delete-guard
# Conflicts:
#	gitea_mcp_server.py
2026-07-09 09:35:55 -04:00
sysadmin cc4b95839d Merge pull request 'feat: add BLOCKED + DIAGNOSE default rule + blocker report template (closes #552)' (#554) from issue-552-blocked-diagnose into master 2026-07-09 08:30:35 -05:00
sysadmin 325e0bb44c Merge pull request 'feat: require Controller Handoff plus Thread State Ledger (Closes #507)' (#511) from feat/issue-507-controller-thread-ledger into master 2026-07-09 08:27:44 -05:00
sysadmin cf130ed0fc fix: resolve test suite regressions and conn helper discovery error 2026-07-09 09:25:08 -04:00
sysadmin cd83b7588f Merge pull request 'feat: add worktree hygiene dashboard to web UI (Closes #432)' (#453) from feat/issue-432-worktree-hygiene into master 2026-07-09 08:24:34 -05:00
sysadmin b3bc459423 fix: drop obsolete worktrees stub assertion after #432 implement 2026-07-09 09:23:19 -04:00
sysadmin e2ef8fbda0 fix: resolve docs conflict for PR #453 after #452
Merge both audit (#431) and worktree hygiene (#432) route/docs lines.
2026-07-09 09:22:53 -04:00
sysadmin 5cf44d78e6 Merge pull request 'feat: add final-report audit paste tool to web UI (Closes #431)' (#452) from feat/issue-431-audit-paste into master 2026-07-09 08:22:13 -05:00
sysadmin 254ccf5821 Merge pull request 'feat: mount canonical gitea-workflow skill for Codex and MCP inventory (Closes #551)' (#565) from feat/issue-551-codex-gitea-workflow into master 2026-07-09 08:14:31 -05:00
sysadmin a8177c2e73 Merge remote-tracking branch 'prgs/master' into feat/issue-507-controller-thread-ledger
# Conflicts:
#	docs/llm-workflow-runbooks.md
#	final_report_validator.py
2026-07-09 09:13:51 -04:00
sysadmin e8f93e93d7 Merge remote-tracking branch 'prgs/master' into feat/issue-551-codex-gitea-workflow
# Conflicts:
#	docs/llm-workflow-runbooks.md
2026-07-09 09:12:44 -04:00
sysadmin 7acd55d2d2 Merge remote-tracking branch 'prgs/master' into feat/issue-514-branch-delete-guard
# Conflicts:
#	final_report_validator.py
2026-07-09 09:12:33 -04:00
sysadmin b52fa2060f Merge pull request 'Clarify and enforce reviewer-vs-merger role boundaries (#483)' (#486) from feat/issue-483-role-boundaries into master 2026-07-09 08:09:47 -05:00
sysadmin 932b280a27 Merge pull request 'feat: block direct MCP imports and unsanctioned keychain access (Closes #558)' (#566) from feat/issue-558-block-direct-imports into master 2026-07-09 08:08:43 -05:00
sysadmin c35f713291 Merge master into issue-552-blocked-diagnose to resolve conflicts 2026-07-09 09:06:59 -04:00