Capability map, resolver, and router can disagree on review-task roles; role-stamp mismatch escapes as unhandled internal_error in submit path #723

Closed
opened 2026-07-16 17:32:11 -05:00 by jcwalker3 · 5 comments
Owner

Product defects exposed by incident #722

Two distinct code defects allowed commit 970e68b to strand formal reviews and to fail with an unactionable error. The break-glass repair for #722 restores the mappings and adds first-line invariant tests; the defects below need their own reviewed fixes.

Defect A — no invariant ties the capability map to configured profiles or the router

task_capability_map.py is documented as "the single source of truth; regression tests assert tool gates cannot drift from it", but nothing asserts:

  1. Profile coverage: for every role-exclusive formal-review task, at least one enabled configured profile satisfies both the required permission and the required role. After 970e68b, review_pr/approve_pr/request_changes_pr required role=merger while every merger profile forbids the review permissions → matching_configured_profile: [] and a repository-wide review lockout that no test named directly.
  2. Map ↔ router agreement: role_session_router.REVIEWER_TASKS still said reviewer while the map said merger. Two authorities, no consistency test.
  3. Runtime-context consistency: _build_runtime_task_capabilities reports permission-only allowed_in_current_session/matching_configured_profiles (no role-exclusive filter), so gitea_get_runtime_context reported review_pr as allowed while gitea_resolve_task_capability fail-closed the same task in the same session.

Defect B — capability/preflight disagreement surfaces as generic internal_error

Observed on PR #721 (reviewer session, prgs-reviewer):

  1. gitea_resolve_task_capability("review_pr") stamps _preflight_resolved_role via record_preflight_check(...) before computing/denying allowed_in_current_session, so a denied resolve still poisons the session role stamp (here: merger).
  2. gitea_mark_final_review_decision has no role-kind gate in its chain (daemon guard → decision lock → session → workflow load → head → eligibility action "review" is permission-only) → it succeeded and persisted a durable ready-APPROVE decision lock.
  3. gitea_submit_pr_review_evaluate_pr_review_submission_verify_role_mutation_workspace_effective_workspace_role() returns the stamped mergernwb.assess_namespace_mutation_workspace(role_kind="merger", ...) blocks against the reviewer session → raise RuntimeError(...) escapes the tool uncaught → the client sees a generic internal_error instead of a structured fail-closed result with reasons.

Net effect: mark/submit half-completed states with no actionable error. Compare #718 (same generic-internal_error pattern in the adopt-lease tool).

Suggested acceptance criteria

  • AC1: A test fails if any role-exclusive task's (permission, role) pair has no enabled profile in the canonical role-profile shape satisfying both.
  • AC2: A test fails if any task in REVIEWER_TASKS has required_role(task) != "reviewer" (and equivalents for MERGER_TASKS).
  • AC3: record_preflight_check must not stamp a resolved role for a task the resolve denied (or the stamp must carry the denial), so a later mutation preflight fails closed with structured reasons instead of raising.
  • AC4: _evaluate_pr_review_submission converts workspace/role-binding failures into result["reasons"] (fail closed) rather than propagating exceptions as internal_error.
  • AC5: gitea_get_runtime_context task capabilities apply the same role-exclusive filter as the resolver, or explicitly label their view as permission-only.

References

## Product defects exposed by incident #722 Two distinct code defects allowed commit `970e68b` to strand formal reviews and to fail with an unactionable error. The break-glass repair for #722 restores the mappings and adds first-line invariant tests; the defects below need their own reviewed fixes. ### Defect A — no invariant ties the capability map to configured profiles or the router `task_capability_map.py` is documented as "the single source of truth; regression tests assert tool gates cannot drift from it", but nothing asserts: 1. **Profile coverage:** for every role-exclusive formal-review task, at least one enabled configured profile satisfies both the required permission and the required role. After `970e68b`, `review_pr`/`approve_pr`/`request_changes_pr` required `role=merger` while every merger profile forbids the review permissions → `matching_configured_profile: []` and a repository-wide review lockout that no test named directly. 2. **Map ↔ router agreement:** `role_session_router.REVIEWER_TASKS` still said `reviewer` while the map said `merger`. Two authorities, no consistency test. 3. **Runtime-context consistency:** `_build_runtime_task_capabilities` reports permission-only `allowed_in_current_session`/`matching_configured_profiles` (no role-exclusive filter), so `gitea_get_runtime_context` reported `review_pr` as allowed while `gitea_resolve_task_capability` fail-closed the same task in the same session. ### Defect B — capability/preflight disagreement surfaces as generic `internal_error` Observed on PR #721 (reviewer session, prgs-reviewer): 1. `gitea_resolve_task_capability("review_pr")` stamps `_preflight_resolved_role` via `record_preflight_check(...)` **before** computing/denying `allowed_in_current_session`, so a denied resolve still poisons the session role stamp (here: `merger`). 2. `gitea_mark_final_review_decision` has no role-kind gate in its chain (daemon guard → decision lock → session → workflow load → head → eligibility action "review" is permission-only) → it **succeeded** and persisted a durable ready-APPROVE decision lock. 3. `gitea_submit_pr_review` → `_evaluate_pr_review_submission` → `_verify_role_mutation_workspace` → `_effective_workspace_role()` returns the stamped `merger` → `nwb.assess_namespace_mutation_workspace(role_kind="merger", ...)` blocks against the reviewer session → `raise RuntimeError(...)` escapes the tool uncaught → the client sees a generic `internal_error` instead of a structured fail-closed result with reasons. Net effect: mark/submit half-completed states with no actionable error. Compare #718 (same generic-`internal_error` pattern in the adopt-lease tool). ### Suggested acceptance criteria - AC1: A test fails if any role-exclusive task's (permission, role) pair has no enabled profile in the canonical role-profile shape satisfying both. - AC2: A test fails if any task in `REVIEWER_TASKS` has `required_role(task) != "reviewer"` (and equivalents for `MERGER_TASKS`). - AC3: `record_preflight_check` must not stamp a resolved role for a task the resolve denied (or the stamp must carry the denial), so a later mutation preflight fails closed with structured reasons instead of raising. - AC4: `_evaluate_pr_review_submission` converts workspace/role-binding failures into `result["reasons"]` (fail closed) rather than propagating exceptions as `internal_error`. - AC5: `gitea_get_runtime_context` task capabilities apply the same role-exclusive filter as the resolver, or explicitly label their view as permission-only. ### References - Incident: #722 (root cause, timeline, break-glass authorization) - Regressive commit: `970e68bddb510aef1b2c4de58981f03ed570e98e` - Stranded review: PR #721 @ `80f59b334e6671b08006725292c08a8e8b6c823f`, comments 11891/11893/11895 - Related: #718, #685, #664, #671
jcwalker3 added the mcpstatus:readyworkflow-hardeningsafetytype:bug labels 2026-07-16 17:32:11 -05:00
Author
Owner

Author claim — issue #723 (comment-based; label tools degraded)

Claiming this issue for implementation. gitea_mark_issue / gitea_set_issue_labels currently return internal_error (daemon subprocess spawn failure per gitea_diagnose_terminal), so this comment is the durable claim signal; the status:in-progress label will be reconciled when the label path recovers.

Branch: fix/issue-723-capability-role-invariants
Worktree: branches/fix-issue-723-capability-role-invariants (fresh from master 67e4a2b5e96b680a1dcb90a20c2ebf87357a3b1f, clean)

Live corroboration of Defect B this session (2026-07-17 ~04:30Z): gitea_acquire_reviewer_pr_lease, gitea_mark_issue, and gitea_set_issue_labels all surfaced generic internal_error while an underlying subprocess spawn failure was the real cause — the same unactionable-error pattern this issue names in AC4.

Canonical Issue State

STATE: claimed for implementation by prgs-author at master 67e4a2b5e9
WHO_IS_NEXT: author
NEXT_ACTION: implement AC1-AC5 with tests in branches/fix-issue-723-capability-role-invariants, run full suite, open the implementing PR
NEXT_PROMPT:

Role: AUTHOR (continuation). Repo: prgs / Scaled-Tech-Consulting / Gitea-Tools. Issue #723.
Continue in branches/fix-issue-723-capability-role-invariants: AC1 profile-coverage invariant, AC2 map/router agreement tests, AC3 no role stamp on denied resolve, AC4 structured fail-closed reasons in _evaluate_pr_review_submission instead of escaping RuntimeError, AC5 runtime-context role-exclusive filter or explicit permission-only labeling. Full suite green, open PR, stop (no self-review or merge).

WHAT_HAPPENED: author picked up the issue after reproducing the Defect B internal_error pattern live; existing first-line invariant tests from the #722 break-glass repair (tests/test_task_capability_role_invariants.py at ba79154) will be extended rather than duplicated
WHY: two authorities (capability map, router) plus permission-only runtime reporting can silently disagree, and role-stamp mismatches escape as unactionable internal_error; fail-closed structured reasons are required
RELATED_PRS: implementing PR to follow from branch fix/issue-723-capability-role-invariants
BLOCKERS: none for implementation; label-claim tooling degraded (internal_error) documented above
VALIDATION: pending — focused invariant/resolver/submission suites plus full suite will be recorded in the PR
LAST_UPDATED_BY: prgs-author (jcwalker3), 2026-07-17

[THREAD STATE LEDGER]
what is true now: issue #723 remains open and is claimed by prgs-author via this comment; worktree branches/fix-issue-723-capability-role-invariants exists clean at master 67e4a2b5.
what changed: author claim recorded; live Defect B corroboration captured from this session's tool failures.
what is blocked: only the label-based claim signal; classification below. Implementation proceeds now.
who/what acts next: author implements AC1-AC5 in the named worktree.
Server-side decision state: no review or merge decision exists for this issue; implementation not yet delivered
Local verdict/state: fresh clean worktree at master head; no local edits yet
Next actor: author
Required action: implement AC1-AC5 with tests, validate, open PR
Blocker classification: environment/tooling blocker
Do not do: do not modify the #722 break-glass invariant tests' intent; do not self-review or merge the eventual PR; do not touch capability behavior beyond the five acceptance criteria

## Author claim — issue #723 (comment-based; label tools degraded) Claiming this issue for implementation. `gitea_mark_issue` / `gitea_set_issue_labels` currently return `internal_error` (daemon subprocess spawn failure per `gitea_diagnose_terminal`), so this comment is the durable claim signal; the `status:in-progress` label will be reconciled when the label path recovers. Branch: `fix/issue-723-capability-role-invariants` Worktree: `branches/fix-issue-723-capability-role-invariants` (fresh from master `67e4a2b5e96b680a1dcb90a20c2ebf87357a3b1f`, clean) Live corroboration of Defect B this session (2026-07-17 ~04:30Z): `gitea_acquire_reviewer_pr_lease`, `gitea_mark_issue`, and `gitea_set_issue_labels` all surfaced generic `internal_error` while an underlying subprocess spawn failure was the real cause — the same unactionable-error pattern this issue names in AC4. ## Canonical Issue State STATE: claimed for implementation by prgs-author at master 67e4a2b5e96b680a1dcb90a20c2ebf87357a3b1f WHO_IS_NEXT: author NEXT_ACTION: implement AC1-AC5 with tests in branches/fix-issue-723-capability-role-invariants, run full suite, open the implementing PR NEXT_PROMPT: ```text Role: AUTHOR (continuation). Repo: prgs / Scaled-Tech-Consulting / Gitea-Tools. Issue #723. Continue in branches/fix-issue-723-capability-role-invariants: AC1 profile-coverage invariant, AC2 map/router agreement tests, AC3 no role stamp on denied resolve, AC4 structured fail-closed reasons in _evaluate_pr_review_submission instead of escaping RuntimeError, AC5 runtime-context role-exclusive filter or explicit permission-only labeling. Full suite green, open PR, stop (no self-review or merge). ``` WHAT_HAPPENED: author picked up the issue after reproducing the Defect B internal_error pattern live; existing first-line invariant tests from the #722 break-glass repair (tests/test_task_capability_role_invariants.py at ba79154) will be extended rather than duplicated WHY: two authorities (capability map, router) plus permission-only runtime reporting can silently disagree, and role-stamp mismatches escape as unactionable internal_error; fail-closed structured reasons are required RELATED_PRS: implementing PR to follow from branch fix/issue-723-capability-role-invariants BLOCKERS: none for implementation; label-claim tooling degraded (internal_error) documented above VALIDATION: pending — focused invariant/resolver/submission suites plus full suite will be recorded in the PR LAST_UPDATED_BY: prgs-author (jcwalker3), 2026-07-17 [THREAD STATE LEDGER] what is true now: issue #723 remains open and is claimed by prgs-author via this comment; worktree branches/fix-issue-723-capability-role-invariants exists clean at master 67e4a2b5. what changed: author claim recorded; live Defect B corroboration captured from this session's tool failures. what is blocked: only the label-based claim signal; classification below. Implementation proceeds now. who/what acts next: author implements AC1-AC5 in the named worktree. Server-side decision state: no review or merge decision exists for this issue; implementation not yet delivered Local verdict/state: fresh clean worktree at master head; no local edits yet Next actor: author Required action: implement AC1-AC5 with tests, validate, open PR Blocker classification: environment/tooling blocker Do not do: do not modify the #722 break-glass invariant tests' intent; do not self-review or merge the eventual PR; do not touch capability behavior beyond the five acceptance criteria
Author
Owner

Implementation delivered — PR creation pending tooling recovery

AC1–AC5 are implemented, tested, committed, and pushed. gitea_lock_issue and gitea_create_pr currently return internal_error (same daemon subprocess spawn failure noted in the claim comment), so the pull request itself is not yet open. No raw-API bypass was used.

Branch: fix/issue-723-capability-role-invariants
Head: bc9366c (pushed to prgs)
Worktree: branches/fix-issue-723-capability-role-invariants

Changes:

  • task_capability_map.ROLE_EXCLUSIVE_TASKS shared constant; resolver inline copy removed (AC1/AC5 drift surface gone)
  • AC3: denied resolve no longer stamps _preflight_resolved_role; stale stamps cleared via _clear_resolved_capability_stamp
  • AC4: _evaluate_pr_review_submission returns structured reasons + blocker_kind=workspace_role_binding instead of letting RuntimeError escape as generic internal_error
  • AC5: _build_runtime_task_capabilities applies the resolver's role-exclusive filter (entries labeled role_filtered/permission_only); matching_configured_profiles honors declared roles
  • Tests: tests/test_issue_723_role_stamp_and_submission.py (new) + extensions to tests/test_task_capability_role_invariants.py

Test evidence: focused 22 passed (+48 subtests); adjacent suites 72 passed; full suite 2929 passed / 6 skipped / 221 subtests (single pre-existing Starlette warning, #682).

Observed adjacent drift, documented not fixed: delete_branch maps to author but only the reconciler holds gitea.branch.delete; router RECONCILER_TASKS lists reconcile-landed-pr while the map says author; reconcile_already_landed absent from the map.

Canonical Issue State

STATE: implementation complete on pushed branch fix/issue-723-capability-role-invariants at head bc9366c; pull request not yet open because PR-creation tooling returns internal_error
WHO_IS_NEXT: author
NEXT_ACTION: retry gitea_lock_issue + gitea_create_pr for branch fix/issue-723-capability-role-invariants once the MCP daemon subprocess spawn failure clears (client reconnect or daemon restart), then hand off to an independent reviewer
NEXT_PROMPT:

Role: AUTHOR (continuation). Repo: prgs / Scaled-Tech-Consulting / Gitea-Tools. Issue #723.
Branch fix/issue-723-capability-role-invariants is pushed at head bc9366c with full-suite test evidence recorded. Run gitea_lock_issue(723, fix/issue-723-capability-role-invariants) then gitea_create_pr(head=fix/issue-723-capability-role-invariants, base=master) with the prepared PR body, and stop (no self-review or merge).

WHAT_HAPPENED: author implemented AC1-AC5 with new and extended tests, ran the full suite green, committed bc9366c, and pushed the branch; lock/create-PR tools failed with internal_error so the PR remains to be opened
WHY: the shared role-exclusive constant plus stamp/structured-error fixes close both defects; the PR step is mechanically prepared and needs only working tooling
RELATED_PRS: implementing PR to be opened from fix/issue-723-capability-role-invariants
BLOCKERS: gitea_lock_issue and gitea_create_pr return internal_error (daemon subprocess spawn failure); comment path unaffected
VALIDATION: full suite 2929 passed / 6 skipped / 221 subtests in the worktree; focused suites recorded above
LAST_UPDATED_BY: prgs-author (jcwalker3), 2026-07-17

[THREAD STATE LEDGER]
what is true now: branch fix/issue-723-capability-role-invariants carries the complete AC1-AC5 implementation at pushed head bc9366c with the full test suite green; no pull request exists yet for it.
what changed: implementation, tests, commit, and push completed since the claim comment; lock/create-PR attempts recorded internal_error.
what is blocked: only the lock + PR-creation step; classification below.
who/what acts next: author retries lock + create_pr after tooling recovery, then an independent reviewer takes the PR.
Server-side decision state: no review or merge decision exists; no PR is open for this branch
Local verdict/state: worktree clean at bc9366c; all changes committed and pushed
Next actor: author
Required action: retry gitea_lock_issue then gitea_create_pr for the pushed branch after MCP daemon recovery
Blocker classification: environment/tooling blocker
Do not do: do not open the PR via raw API bypass; do not self-review or merge; do not rework the branch while the PR step is pending

## Implementation delivered — PR creation pending tooling recovery AC1–AC5 are implemented, tested, committed, and pushed. `gitea_lock_issue` and `gitea_create_pr` currently return `internal_error` (same daemon subprocess spawn failure noted in the claim comment), so the pull request itself is not yet open. No raw-API bypass was used. Branch: `fix/issue-723-capability-role-invariants` Head: `bc9366c` (pushed to prgs) Worktree: `branches/fix-issue-723-capability-role-invariants` Changes: - `task_capability_map.ROLE_EXCLUSIVE_TASKS` shared constant; resolver inline copy removed (AC1/AC5 drift surface gone) - AC3: denied resolve no longer stamps `_preflight_resolved_role`; stale stamps cleared via `_clear_resolved_capability_stamp` - AC4: `_evaluate_pr_review_submission` returns structured `reasons` + `blocker_kind=workspace_role_binding` instead of letting RuntimeError escape as generic `internal_error` - AC5: `_build_runtime_task_capabilities` applies the resolver's role-exclusive filter (entries labeled `role_filtered`/`permission_only`); `matching_configured_profiles` honors declared roles - Tests: `tests/test_issue_723_role_stamp_and_submission.py` (new) + extensions to `tests/test_task_capability_role_invariants.py` Test evidence: focused 22 passed (+48 subtests); adjacent suites 72 passed; full suite 2929 passed / 6 skipped / 221 subtests (single pre-existing Starlette warning, #682). Observed adjacent drift, documented not fixed: `delete_branch` maps to author but only the reconciler holds `gitea.branch.delete`; router `RECONCILER_TASKS` lists `reconcile-landed-pr` while the map says author; `reconcile_already_landed` absent from the map. ## Canonical Issue State STATE: implementation complete on pushed branch fix/issue-723-capability-role-invariants at head bc9366c; pull request not yet open because PR-creation tooling returns internal_error WHO_IS_NEXT: author NEXT_ACTION: retry gitea_lock_issue + gitea_create_pr for branch fix/issue-723-capability-role-invariants once the MCP daemon subprocess spawn failure clears (client reconnect or daemon restart), then hand off to an independent reviewer NEXT_PROMPT: ```text Role: AUTHOR (continuation). Repo: prgs / Scaled-Tech-Consulting / Gitea-Tools. Issue #723. Branch fix/issue-723-capability-role-invariants is pushed at head bc9366c with full-suite test evidence recorded. Run gitea_lock_issue(723, fix/issue-723-capability-role-invariants) then gitea_create_pr(head=fix/issue-723-capability-role-invariants, base=master) with the prepared PR body, and stop (no self-review or merge). ``` WHAT_HAPPENED: author implemented AC1-AC5 with new and extended tests, ran the full suite green, committed bc9366c, and pushed the branch; lock/create-PR tools failed with internal_error so the PR remains to be opened WHY: the shared role-exclusive constant plus stamp/structured-error fixes close both defects; the PR step is mechanically prepared and needs only working tooling RELATED_PRS: implementing PR to be opened from fix/issue-723-capability-role-invariants BLOCKERS: gitea_lock_issue and gitea_create_pr return internal_error (daemon subprocess spawn failure); comment path unaffected VALIDATION: full suite 2929 passed / 6 skipped / 221 subtests in the worktree; focused suites recorded above LAST_UPDATED_BY: prgs-author (jcwalker3), 2026-07-17 [THREAD STATE LEDGER] what is true now: branch fix/issue-723-capability-role-invariants carries the complete AC1-AC5 implementation at pushed head bc9366c with the full test suite green; no pull request exists yet for it. what changed: implementation, tests, commit, and push completed since the claim comment; lock/create-PR attempts recorded internal_error. what is blocked: only the lock + PR-creation step; classification below. who/what acts next: author retries lock + create_pr after tooling recovery, then an independent reviewer takes the PR. Server-side decision state: no review or merge decision exists; no PR is open for this branch Local verdict/state: worktree clean at bc9366c; all changes committed and pushed Next actor: author Required action: retry gitea_lock_issue then gitea_create_pr for the pushed branch after MCP daemon recovery Blocker classification: environment/tooling blocker Do not do: do not open the PR via raw API bypass; do not self-review or merge; do not rework the branch while the PR step is pending
jcwalker3 added status:pr-open and removed status:ready labels 2026-07-19 22:22:47 -05:00
Author
Owner

CTH: Author Handoff

Status: implementation_complete_pending_review
Next owner: reviewer
Current blocker: none
Decision: PR #766 is ready for independent review at pinned head 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5.
Proof: native author identity and lock passed; local and remote heads match; required validation completed with two pristine-base-matched unrelated failures.
Next action: independent reviewer reviews PR #766 at the pinned head.
Ready-to-paste prompt: Review PR #766 for issue #723 at head 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5; validate the role-stamp/runtime/workspace-binding invariants and submit the appropriate independent verdict.

Canonical Issue State

STATE: implementation complete pending independent review on PR #766 at head 4b8a9219d8
WHO_IS_NEXT: reviewer
NEXT_ACTION: review PR #766 at exactly 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5; the author must not review, approve, request changes, or merge
NEXT_PROMPT:

Review PR #766 for issue #723 as an independent reviewer. Pin head 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5, validate the shared role-exclusive map, denied-stamp clearing, structured workspace_role_binding failures, runtime capability_view filtering, and baseline evidence, then submit the appropriate review verdict.

WHAT_HAPPENED: reconstructed #723 against current master from archive/capability-role-invariants-bc9366c and archive/role-poisoning-dfb5ebd; committed and pushed the implementation; opened PR #766 with Closes #723
WHY: capability mapping, resolver stamps, runtime reporting, and workspace-role failures must agree and fail closed without poisoning later permitted operations
RELATED_PRS: PR #766
BLOCKERS: none; two unrelated full-suite failures were reproduced with identical signatures on pristine detached base fcf6981b1b
VALIDATION: focused #723/resolver/invariant 47 passed plus 78 subtests; review/lease 270 passed; runtime/profile/workspace/repository/preflight 418 passed plus 119 subtests; expanded focused/lease 81 passed plus 78 subtests; full suite 3711 passed, 6 skipped, 491 subtests with exactly two base-matched failures; diff check and python3 compile passed
LAST_UPDATED_BY: prgs-author (jcwalker3), 2026-07-19

Archive preservation: archive/capability-role-invariants-bc9366c remains bc9366c394b4bc5ab35d90ae5cbaad879ab5e612; archive/role-poisoning-dfb5ebd remains dfb5ebd0af.

## CTH: Author Handoff Status: implementation_complete_pending_review Next owner: reviewer Current blocker: none Decision: PR #766 is ready for independent review at pinned head `4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5`. Proof: native author identity and lock passed; local and remote heads match; required validation completed with two pristine-base-matched unrelated failures. Next action: independent reviewer reviews PR #766 at the pinned head. Ready-to-paste prompt: Review PR #766 for issue #723 at head `4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5`; validate the role-stamp/runtime/workspace-binding invariants and submit the appropriate independent verdict. ## Canonical Issue State STATE: implementation complete pending independent review on PR #766 at head 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5 WHO_IS_NEXT: reviewer NEXT_ACTION: review PR #766 at exactly 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5; the author must not review, approve, request changes, or merge NEXT_PROMPT: ```text Review PR #766 for issue #723 as an independent reviewer. Pin head 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5, validate the shared role-exclusive map, denied-stamp clearing, structured workspace_role_binding failures, runtime capability_view filtering, and baseline evidence, then submit the appropriate review verdict. ``` WHAT_HAPPENED: reconstructed #723 against current master from archive/capability-role-invariants-bc9366c and archive/role-poisoning-dfb5ebd; committed and pushed the implementation; opened PR #766 with Closes #723 WHY: capability mapping, resolver stamps, runtime reporting, and workspace-role failures must agree and fail closed without poisoning later permitted operations RELATED_PRS: PR #766 BLOCKERS: none; two unrelated full-suite failures were reproduced with identical signatures on pristine detached base fcf6981b1ba4d8d5072357ba13be0fdb6baa07ff VALIDATION: focused #723/resolver/invariant 47 passed plus 78 subtests; review/lease 270 passed; runtime/profile/workspace/repository/preflight 418 passed plus 119 subtests; expanded focused/lease 81 passed plus 78 subtests; full suite 3711 passed, 6 skipped, 491 subtests with exactly two base-matched failures; diff check and python3 compile passed LAST_UPDATED_BY: prgs-author (jcwalker3), 2026-07-19 Archive preservation: archive/capability-role-invariants-bc9366c remains bc9366c394b4bc5ab35d90ae5cbaad879ab5e612; archive/role-poisoning-dfb5ebd remains dfb5ebd0afd97fafc8c120176f1bcf8226e6fa96.
sysadmin removed the status:pr-open label 2026-07-20 00:01:30 -05:00
Owner

[THREAD STATE LEDGER] PR #766 / Issue #723 — reconciliation cleanup completed after merge performed

What is true now:

  • PR state: closed, merge performed at 2026-07-19T23:38:50-05:00, merge_commit_sha d12adabeb1
  • Issue state: closed
  • Current head SHA: d12adabeb1 (master; PR head was 4b8a9219d8)
  • Server-side decision state: no review verdict and no merge operation performed in this cycle; reconciliation mutations only
  • Local verdict/state: control checkout clean on master at d12adabe, 0/0 versus prgs/master
  • Latest known validation: ancestor proof git merge-base --is-ancestor 4b8a9219 prgs/master returned true; branch-scoped post-delete readback returned not_found

What changed:

  • Stale status:pr-open label removed from this issue; labels now mcp, safety, type:bug, workflow-hardening
  • Remote branch fix/issue-723-role-stamp-invariants deleted via gitea_cleanup_merged_pr_branch and verified absent
  • Local worktree branches/fix-issue-723-role-stamp-invariants removed (clean, non-forced); local branch fix/issue-723-role-stamp-invariants safe-deleted with git branch -d
  • Merger worktree branches/merge-pr-766-4b8a921 removed (clean, detached at 4b8a9219, ancestor of master)
  • Merger lease for PR #766: assessed via gitea_cleanup_post_merge_moot_lease (apply=false) — no active lease remained, so no lease mutation was required

What is blocked:

  • Blocker classification: no blocker

Who/what acts next:

  • Next actor: controller
  • Required action: select the next eligible workflow phase from live state in a fresh run
  • Do not do: do not treat branch fix/issue-723-capability-role-invariants (bc9366c394) or local branch issue-723-role-poisoning as cleanup targets — neither is an ancestor of master and both were preserved
  • Resume from: master d12adabeb1

Canonical Issue State

STATE:
closed

WHO_IS_NEXT:
controller

NEXT_ACTION:
Start a fresh controller iteration and select the next eligible workflow phase from live state.

NEXT_PROMPT:
Run one fresh Gitea-Tools controller iteration at master d12adabeb1. Do not reuse any state from the PR #766 reconciliation cycle.

WHAT_HAPPENED:
Reconciler cycle removed the residual artifacts of PR #766: stale label, remote source branch, author worktree plus its local branch, and merger worktree.

WHY:
PR #766 reached its terminal state with merge performed, and its head SHA is an ancestor of master, so its branch, worktrees, and open-PR label carry no remaining workflow meaning.

RELATED_DISCUSSION:
none

RELATED_PRS:

BRANCH:
none — fix/issue-723-role-stamp-invariants deleted remotely and locally

HEAD_SHA:
d12adabeb1

VALIDATION:
Ancestor proof true; post-delete readback not_found; worktree snapshot reconciles 28 to 26 directories and 21 to 19 registered worktrees with exactly two logged removals; control checkout clean and 0/0 versus prgs/master.

BLOCKERS:
none

LAST_UPDATED_BY:
sysadmin / prgs-reconciler / 2026-07-20

[THREAD STATE LEDGER] PR #766 / Issue #723 — reconciliation cleanup completed after merge performed What is true now: - PR state: closed, merge performed at 2026-07-19T23:38:50-05:00, merge_commit_sha d12adabeb1cf7810b1286ca8871a9b680646021c - Issue state: closed - Current head SHA: d12adabeb1cf7810b1286ca8871a9b680646021c (master; PR head was 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5) - Server-side decision state: no review verdict and no merge operation performed in this cycle; reconciliation mutations only - Local verdict/state: control checkout clean on master at d12adabe, 0/0 versus prgs/master - Latest known validation: ancestor proof `git merge-base --is-ancestor 4b8a9219 prgs/master` returned true; branch-scoped post-delete readback returned not_found What changed: - Stale `status:pr-open` label removed from this issue; labels now mcp, safety, type:bug, workflow-hardening - Remote branch fix/issue-723-role-stamp-invariants deleted via gitea_cleanup_merged_pr_branch and verified absent - Local worktree branches/fix-issue-723-role-stamp-invariants removed (clean, non-forced); local branch fix/issue-723-role-stamp-invariants safe-deleted with `git branch -d` - Merger worktree branches/merge-pr-766-4b8a921 removed (clean, detached at 4b8a9219, ancestor of master) - Merger lease for PR #766: assessed via gitea_cleanup_post_merge_moot_lease (apply=false) — no active lease remained, so no lease mutation was required What is blocked: - Blocker classification: no blocker Who/what acts next: - Next actor: controller - Required action: select the next eligible workflow phase from live state in a fresh run - Do not do: do not treat branch fix/issue-723-capability-role-invariants (bc9366c394b4bc5ab35d90ae5cbaad879ab5e612) or local branch issue-723-role-poisoning as cleanup targets — neither is an ancestor of master and both were preserved - Resume from: master d12adabeb1cf7810b1286ca8871a9b680646021c ## Canonical Issue State STATE: closed WHO_IS_NEXT: controller NEXT_ACTION: Start a fresh controller iteration and select the next eligible workflow phase from live state. NEXT_PROMPT: Run one fresh Gitea-Tools controller iteration at master d12adabeb1cf7810b1286ca8871a9b680646021c. Do not reuse any state from the PR #766 reconciliation cycle. WHAT_HAPPENED: Reconciler cycle removed the residual artifacts of PR #766: stale label, remote source branch, author worktree plus its local branch, and merger worktree. WHY: PR #766 reached its terminal state with merge performed, and its head SHA is an ancestor of master, so its branch, worktrees, and open-PR label carry no remaining workflow meaning. RELATED_DISCUSSION: none RELATED_PRS: - #766 BRANCH: none — fix/issue-723-role-stamp-invariants deleted remotely and locally HEAD_SHA: d12adabeb1cf7810b1286ca8871a9b680646021c VALIDATION: Ancestor proof true; post-delete readback not_found; worktree snapshot reconciles 28 to 26 directories and 21 to 19 registered worktrees with exactly two logged removals; control checkout clean and 0/0 versus prgs/master. BLOCKERS: none LAST_UPDATED_BY: sysadmin / prgs-reconciler / 2026-07-20
Owner

Branch disposition — LANDED_EQUIVALENT (supervised reconciler)

Profile: prgs-reconciler / sysadmin
Date: 2026-07-20
Scope: Issue #723 only; no source mutation; no PR create/review/merge.

Candidate

Field Value
Branch fix/issue-723-capability-role-invariants
HEAD bc9366c394b4bc5ab35d90ae5cbaad879ab5e612
Worktree branches/fix-issue-723-capability-role-invariants
Worktree state registered, clean; remote tracking prgs/… [gone]
Unique commits vs master 1 (parent 67e4a2b… is on master)
Open PR using this branch none (open inventory complete: only #767 / #607)
Live lock/lease none (durable #723 lock points at historical fix/issue-723-role-stamp-invariants, lease expired, PID dead)

Landed implementation proof (#723)

Field Value
Superseding PR #766 (merged)
PR branch fix/issue-723-role-stamp-invariants
Reviewed/landed head 4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5
Merge commit d12adabeb1cf7810b1286ca8871a9b680646021c
Issue #723 closed

Equivalence evidence (not “one unique commit ⇒ keep”)

  1. Candidate is an earlier rewrite (2026-07-17) of the same AC surface as PR #766 (2026-07-19). Different stable patch-id:
    • candidate bc9366c… patch-id: 70807be553f826cb1c2b76a486cb4cd8c28c1fb6
    • landed 4b8a921… patch-id: 9a6c7f14dcd74b97afe8ba2ff1a8442f7240fa93
  2. Same production mechanisms exist on master as on the candidate:
    • _clear_resolved_capability_stamp (AC3)
    • workspace_role_binding structured fail-closed (AC4)
    • ROLE_EXCLUSIVE_TASKS + role_filtered / permission_only runtime views (AC1/AC5)
  3. Candidate ROLE_EXCLUSIVE_TASKS is a strict subset of master/landed (16 ⊆ 26); master adds lease/update tasks — not missing exclusive tasks relative to the candidate.
  4. Landed #766 test suite covers the same AC intents with renamed/stronger cases and more coverage (merger-lease binding failure, unexpected resolver/verifier failures, complete exclusive-set pin, profile satisfiability). Landed also touches tests/test_resolve_task_capability.py (absent from candidate commit).
  5. Durable history: PR #766 body cites worktree/branch fix-issue-723-role-stamp-invariants @ 4b8a921… as the reviewed implementation; issue closed after merge d12adab…. Candidate branch is a non-PR orphan WIP, not the merged subject.

Disposition

LANDED_EQUIVALENT

Strict obsolete subset / superseded rewrite of the final #766 implementation. No author PR should be opened for this candidate. AC behavior required by #723 is on master via #766; the unique commit is not unpublished required work.

Cleanup decision (this iteration)

  • No worktree/branch deletion performed.
  • gitea_cleanup_merged_pr_branch targets merged PR #766 source fix/issue-723-role-stamp-invariants, not this orphan …-capability-role-invariants ref.
  • gitea_reconcile_superseded_by_merged_pr requires a target PR; candidate has no PR.
  • Physical deletion awaits a sanctioned orphan-equivalent cleanup that accepts this disposition proof.

Preservation

  • Preserved: branches/fix-issue-723-capability-role-invariants and branch fix/issue-723-capability-role-invariants
  • Untouched: #607/#767, #681, #695, and all other worktrees

Canonical Issue State

STATE:
closed; implementation landed via PR #766; orphan branch fix/issue-723-capability-role-invariants at bc9366c dispositioned LANDED_EQUIVALENT and preserved pending sanctioned orphan-equivalent cleanup

WHO_IS_NEXT:
controller

NEXT_ACTION:
Stop. No author recovery PR for this candidate. Optional later: reclaim disk only via a sanctioned orphan cleanup that consumes this disposition (subset ROLE_EXCLUSIVE proof + PR #766 merge d12adab / head 4b8a921).

NEXT_PROMPT:

No author/reviewer action required for Issue #723 candidate fix/issue-723-capability-role-invariants.
Do not open a PR while #767 occupies the author WIP slot.
Do not touch #607/#767, #681, #695, or other worktrees.
If reclaiming disk: only remove branches/fix-issue-723-capability-role-invariants after a sanctioned cleanup tool accepts this LANDED_EQUIVALENT disposition.

WHAT_HAPPENED:
Supervised reconciler compared clean candidate bc9366c against merged PR #766 (4b8a921 / merge d12adab). Candidate is an earlier non-identical rewrite; master fully supersets its ROLE_EXCLUSIVE set and AC production paths; landed tests supersede/rename cand coverage and add more. Disposition LANDED_EQUIVALENT; worktree preserved (no orphan cleanup consumer).

WHY:
Git uniqueness alone is not unpublished AC work. Final accepted path is PR #766 branch/head; candidate is a superseded WIP rewrite.

RELATED_PRS:
#766 (landed Closes #723, merge d12adab, head 4b8a921); #767 (open #607 — author WIP; not touched); #722 (incident context for #723)

BLOCKERS:
none for #723 completion; orphan worktree cleanup blocked only by lack of a sanctioned orphan-equivalent cleanup consumer

VALIDATION:

  • whoami: sysadmin / prgs-reconciler, identity_match=true
  • control master == prgs/master @ edaeede…, clean
  • candidate clean, registered, HEAD bc9366c; remote branch gone
  • unique commits master..bc9366c = 1; parent on master
  • patch-id cand != landed (expected rewrite); ROLE_EXCLUSIVE cand ⊆ master
  • master has _clear_resolved_capability_stamp, workspace_role_binding, ROLE_EXCLUSIVE_TASKS, role_filtered/permission_only
  • open PR inventory complete: only #767
  • no live lock/lease on candidate branch

LAST_UPDATED_BY:
prgs-reconciler / sysadmin / supervised branch-disposition iteration 2026-07-20

## Branch disposition — LANDED_EQUIVALENT (supervised reconciler) **Profile:** prgs-reconciler / sysadmin **Date:** 2026-07-20 **Scope:** Issue #723 only; no source mutation; no PR create/review/merge. ### Candidate | Field | Value | |-------|--------| | Branch | `fix/issue-723-capability-role-invariants` | | HEAD | `bc9366c394b4bc5ab35d90ae5cbaad879ab5e612` | | Worktree | `branches/fix-issue-723-capability-role-invariants` | | Worktree state | registered, clean; remote tracking `prgs/…` **[gone]** | | Unique commits vs master | **1** (parent `67e4a2b…` is on master) | | Open PR using this branch | **none** (open inventory complete: only #767 / #607) | | Live lock/lease | **none** (durable #723 lock points at historical `fix/issue-723-role-stamp-invariants`, lease expired, PID dead) | ### Landed implementation proof (#723) | Field | Value | |-------|--------| | Superseding PR | **#766** (merged) | | PR branch | `fix/issue-723-role-stamp-invariants` | | Reviewed/landed head | `4b8a9219d85bc99b6abeebb4dc9db3e344bc27e5` | | Merge commit | `d12adabeb1cf7810b1286ca8871a9b680646021c` | | Issue #723 | **closed** | ### Equivalence evidence (not “one unique commit ⇒ keep”) 1. Candidate is an **earlier rewrite** (2026-07-17) of the same AC surface as PR #766 (2026-07-19). Different stable patch-id: - candidate `bc9366c…` patch-id: `70807be553f826cb1c2b76a486cb4cd8c28c1fb6` - landed `4b8a921…` patch-id: `9a6c7f14dcd74b97afe8ba2ff1a8442f7240fa93` 2. Same production mechanisms exist on master as on the candidate: - `_clear_resolved_capability_stamp` (AC3) - `workspace_role_binding` structured fail-closed (AC4) - `ROLE_EXCLUSIVE_TASKS` + `role_filtered` / `permission_only` runtime views (AC1/AC5) 3. Candidate `ROLE_EXCLUSIVE_TASKS` is a **strict subset** of master/landed (16 ⊆ 26); master adds lease/update tasks — not missing exclusive tasks relative to the candidate. 4. Landed #766 test suite covers the same AC intents with renamed/stronger cases and **more** coverage (merger-lease binding failure, unexpected resolver/verifier failures, complete exclusive-set pin, profile satisfiability). Landed also touches `tests/test_resolve_task_capability.py` (absent from candidate commit). 5. Durable history: PR #766 body cites worktree/branch `fix-issue-723-role-stamp-invariants` @ `4b8a921…` as the reviewed implementation; issue closed after merge `d12adab…`. Candidate branch is a non-PR orphan WIP, not the merged subject. ### Disposition **LANDED_EQUIVALENT** Strict obsolete subset / superseded rewrite of the final #766 implementation. **No author PR** should be opened for this candidate. AC behavior required by #723 is on master via #766; the unique commit is not unpublished required work. ### Cleanup decision (this iteration) - **No worktree/branch deletion performed.** - `gitea_cleanup_merged_pr_branch` targets merged PR **#766** source `fix/issue-723-role-stamp-invariants`, not this orphan `…-capability-role-invariants` ref. - `gitea_reconcile_superseded_by_merged_pr` requires a **target PR**; candidate has **no PR**. - Physical deletion awaits a sanctioned orphan-equivalent cleanup that accepts this disposition proof. ### Preservation - Preserved: `branches/fix-issue-723-capability-role-invariants` and branch `fix/issue-723-capability-role-invariants` - Untouched: #607/#767, #681, #695, and all other worktrees ## Canonical Issue State STATE: closed; implementation landed via PR #766; orphan branch fix/issue-723-capability-role-invariants at bc9366c dispositioned LANDED_EQUIVALENT and preserved pending sanctioned orphan-equivalent cleanup WHO_IS_NEXT: controller NEXT_ACTION: Stop. No author recovery PR for this candidate. Optional later: reclaim disk only via a sanctioned orphan cleanup that consumes this disposition (subset ROLE_EXCLUSIVE proof + PR #766 merge d12adab / head 4b8a921). NEXT_PROMPT: ```text No author/reviewer action required for Issue #723 candidate fix/issue-723-capability-role-invariants. Do not open a PR while #767 occupies the author WIP slot. Do not touch #607/#767, #681, #695, or other worktrees. If reclaiming disk: only remove branches/fix-issue-723-capability-role-invariants after a sanctioned cleanup tool accepts this LANDED_EQUIVALENT disposition. ``` WHAT_HAPPENED: Supervised reconciler compared clean candidate bc9366c against merged PR #766 (4b8a921 / merge d12adab). Candidate is an earlier non-identical rewrite; master fully supersets its ROLE_EXCLUSIVE set and AC production paths; landed tests supersede/rename cand coverage and add more. Disposition LANDED_EQUIVALENT; worktree preserved (no orphan cleanup consumer). WHY: Git uniqueness alone is not unpublished AC work. Final accepted path is PR #766 branch/head; candidate is a superseded WIP rewrite. RELATED_PRS: #766 (landed Closes #723, merge d12adab, head 4b8a921); #767 (open #607 — author WIP; not touched); #722 (incident context for #723) BLOCKERS: none for #723 completion; orphan worktree cleanup blocked only by lack of a sanctioned orphan-equivalent cleanup consumer VALIDATION: - whoami: sysadmin / prgs-reconciler, identity_match=true - control master == prgs/master @ edaeede…, clean - candidate clean, registered, HEAD bc9366c; remote branch gone - unique commits master..bc9366c = 1; parent on master - patch-id cand != landed (expected rewrite); ROLE_EXCLUSIVE cand ⊆ master - master has _clear_resolved_capability_stamp, workspace_role_binding, ROLE_EXCLUSIVE_TASKS, role_filtered/permission_only - open PR inventory complete: only #767 - no live lock/lease on candidate branch LAST_UPDATED_BY: prgs-reconciler / sysadmin / supervised branch-disposition iteration 2026-07-20
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#723