Commit Graph
100 Commits
Author SHA1 Message Date
sysadminandClaude Fable 5 c2fc2683b9 fix(recovery): address PR #703 review findings F1-F6 (#702)
Fixes the six defects from the formal REQUEST_CHANGES review at
889931d553:

- F1: run sanctioned stale-binding recovery in
  gitea_resolve_task_capability BEFORE the terminal launcher probe, so a
  worktree removed mid-session can no longer wedge mutation resolution on
  'missing cwd' before recovery runs. The fail-closed probe block now also
  carries the binding classification evidence.
- F2: _resolve_preflight_workspace_path resolves with the same
  verify_paths existence checks as the canonical mutation context, and
  _get_workspace_porcelain returns a synthetic tracked-dirty sentinel when
  the workspace is missing or git fails — an uninspectable workspace can
  never read as clean/empty porcelain.
- F3: the orphaned_expired_superseded_head cleanup matrix now requires
  affirmative safe worktree evidence (worktree_clean=true or
  worktree_exists=false), aligned with the sibling orphaned_owner_missing
  gate and the diagnosis path; unknown evidence fails closed.
- F4: reviewer-session-lease shadows and stale-binding audit records are
  recovery-critical kinds exempt from the 4h session-state TTL; they
  persist until a sanctioned clear terminally reconciles them.
- F5: session-lease shadows are keyed by lease session id (collision-safe
  identity) with a list_states enumeration API; concurrent same-profile
  sessions can no longer overwrite or misattribute each other's crash
  evidence. Legacy single-slot records remain readable.
- F6: the durable audit record is persisted (status=pending) BEFORE the
  environment binding is cleared; if audit persistence fails the clear
  does not happen and the failure is reported explicitly.

30 new regression tests cover deleted-worktree recovery ordering, missing/
deleted/symlinked/mid-evaluation path changes, unknown-evidence cleanup,
TTL boundary (before/at/after), interleaved and reconnected concurrent
sessions, and audit-write failure/retry/idempotence/ordering.

Issue #704 dotenv load-path prevention is intentionally NOT included.

Full suite: 2695 passed, 6 skipped, 161 subtests passed.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-13 16:40:58 -04:00
sysadminandClaude Fable 5 889931d553 feat(recovery): stale worktree binding demotion and crash-orphan lease recovery (Closes #702)
An unhandled daemon crash skips teardown: the durable reviewer lease
comment survives, the in-memory session lease dies, and the
auto-reconnected daemon inherits a stale GITEA_ACTIVE_WORKTREE from its
parent environment (PR #701 / branches/review-pr-654 incident).

AC2 — safe clear/re-bind of stale bindings:
- new stale_binding_recovery.py: classifies the active env binding
  (corroborated / unverified_inherited / provably_stale_missing_path /
  superseded_by_session_lease) and produces a fail-closed recovery plan;
  only provably stale bindings are clear-eligible
- gitea_resolve_task_capability and daemon boot run the sanctioned
  recovery (durable audit via session state); runtime context surfaces
  the classification read-only
- namespace_workspace_binding.resolve_namespace_workspace(verify_paths=…)
  demotes env-bound worktrees whose path no longer exists; mutation and
  runtime-context resolution always verify

AC3 — recoverable lease cleanup after unexpected exit:
- durable session-lease shadow (KIND_REVIEWER_SESSION_LEASE) written on
  sanctioned record/heartbeat, removed on sanctioned clear; a crash
  leaves provable orphan evidence (owner pid + session id)
- assess_crashed_session_lease_orphan derives tri-state
  owner_process_alive: only a dead recorded owner pid proves exit; PID
  liveness is never ownership proof
- diagnose/cleanup wrappers consume the shadow instead of passing
  owner_process_alive=None
- new classification orphaned_expired_superseded_head: an expired
  superseded-head lease with no terminal review stops being a permanent
  ambiguous/wait; post-expiry it unlocks fresh acquisition, and guarded
  cleanup becomes eligible only with owner-exit evidence + clean/absent
  worktree + controller authorization + confirmation. Pre-expiry
  behavior is unchanged (fail-closed wait, no steal).

Validation: tests/test_issue_702_stale_binding_lease_recovery.py (29
tests covering lost in-session leases, old-head leases, runtime/worktree
mismatch, managed reconnect, safe expiry); full suite 2665 passed,
6 skipped, 161 subtests.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-13 14:35:15 -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
sysadmin 9340dc7009 Merge pull request 'feat: discover merged cleanup worktree aliases (Closes #532)' (#571) from feat/issue-532-merged-cleanup-worktree-aliases into master 2026-07-09 08:05:33 -05:00
sysadmin 8e7a69800a Merge pull request 'feat: require canonical next-action state comments (Closes #495)' (#499) from feat/issue-495-canonical-next-action-comments into master 2026-07-09 08:02:14 -05:00
sysadmin b14b1a9663 Merge pull request 'feat(#496): enforce canonical state comment validation before posting' (#497) from feat/issue-496-canonical-comment-validator into master 2026-07-09 07:57:47 -05:00