fix: preserve capability preflight across safe reads (Closes #469) #502

Merged
sysadmin merged 2 commits from fix/issue-469-preflight-read-survival into master 2026-07-08 03:01:49 -05:00
Owner

Summary

Closes #469.

Preserves resolved capability preflight state across interleaved read-only whoami calls when the identity/workspace state remains clean, while still consuming capability proof after a mutation and failing closed on missing or mismatched capability proof.

Changes

  • gitea_mcp_server.py — tracks the resolved task, preserves capability proof through safe whoami reads, adds explicit task mismatch checks, and passes mutation task names into preflight verification paths.
  • tests/test_preflight_read_survival.py — regression tests for resolve -> safe read -> mutation, missing capability, task mismatch, proof consumption, and dirty whoami recovery.

Validation

/Users/jasonwalker/Development/Gitea-Tools/venv/bin/python -m py_compile gitea_mcp_server.py tests/test_preflight_read_survival.py
# passed

/Users/jasonwalker/Development/Gitea-Tools/venv/bin/python -m pytest tests/test_preflight_read_survival.py tests/test_resolve_task_capability.py tests/test_mcp_server.py::TestPreflightVerification -q
# 35 passed

git diff --check prgs/master...HEAD
# passed

git diff --cached --check
# passed

Full suite:

/Users/jasonwalker/Development/Gitea-Tools/venv/bin/python -m pytest tests/ -q
# 1 failed, 1768 passed, 6 skipped, 1 warning, 33 subtests passed

The failure is pre-existing on clean prgs/master:

git worktree add --detach branches/baseline-master-issue-469-20260708 prgs/master
/Users/jasonwalker/Development/Gitea-Tools/venv/bin/python -m pytest tests/test_mcp_server.py::TestMergePR::test_merge_blocked_on_stale_approval_head -q
# same failure: AssertionError: None is not true

Temporary baseline worktree was removed after proof.

Branch / lock

  • Branch: fix/issue-469-preflight-read-survival
  • Head: 3bce0a55fb53456f5b946785c1f8711f254967b0
  • Implementation worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/issue-469-preflight-read-survival
  • Lock guard worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/issue-469-lock-base-20260708

LLM Handoff Metadata

  • LLM-Agent-SHA: llm-3bce0a55fb53
  • LLM-Role: implementer
  • Authenticated-Gitea-User: jcwalker3
  • MCP-Profile: prgs-author
  • Branch: fix/issue-469-preflight-read-survival
  • Worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/issue-469-preflight-read-survival
  • Self-review allowed: no
## Summary Closes #469. Preserves resolved capability preflight state across interleaved read-only `whoami` calls when the identity/workspace state remains clean, while still consuming capability proof after a mutation and failing closed on missing or mismatched capability proof. ## Changes - `gitea_mcp_server.py` — tracks the resolved task, preserves capability proof through safe `whoami` reads, adds explicit task mismatch checks, and passes mutation task names into preflight verification paths. - `tests/test_preflight_read_survival.py` — regression tests for resolve -> safe read -> mutation, missing capability, task mismatch, proof consumption, and dirty whoami recovery. ## Validation ```bash /Users/jasonwalker/Development/Gitea-Tools/venv/bin/python -m py_compile gitea_mcp_server.py tests/test_preflight_read_survival.py # passed /Users/jasonwalker/Development/Gitea-Tools/venv/bin/python -m pytest tests/test_preflight_read_survival.py tests/test_resolve_task_capability.py tests/test_mcp_server.py::TestPreflightVerification -q # 35 passed git diff --check prgs/master...HEAD # passed git diff --cached --check # passed ``` Full suite: ```bash /Users/jasonwalker/Development/Gitea-Tools/venv/bin/python -m pytest tests/ -q # 1 failed, 1768 passed, 6 skipped, 1 warning, 33 subtests passed ``` The failure is pre-existing on clean `prgs/master`: ```bash git worktree add --detach branches/baseline-master-issue-469-20260708 prgs/master /Users/jasonwalker/Development/Gitea-Tools/venv/bin/python -m pytest tests/test_mcp_server.py::TestMergePR::test_merge_blocked_on_stale_approval_head -q # same failure: AssertionError: None is not true ``` Temporary baseline worktree was removed after proof. ## Branch / lock - Branch: `fix/issue-469-preflight-read-survival` - Head: `3bce0a55fb53456f5b946785c1f8711f254967b0` - Implementation worktree: `/Users/jasonwalker/Development/Gitea-Tools/branches/issue-469-preflight-read-survival` - Lock guard worktree: `/Users/jasonwalker/Development/Gitea-Tools/branches/issue-469-lock-base-20260708` ## LLM Handoff Metadata - LLM-Agent-SHA: llm-3bce0a55fb53 - LLM-Role: implementer - Authenticated-Gitea-User: jcwalker3 - MCP-Profile: prgs-author - Branch: fix/issue-469-preflight-read-survival - Worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/issue-469-preflight-read-survival - Self-review allowed: no
jcwalker3 added 2 commits 2026-07-08 02:25:06 -05:00
Read-only gitea_whoami calls no longer clear a valid capability proof when
whoami was already verified clean. Capability is consumed on mutation (one
resolve per mutation), and verify_preflight_purity rejects task mismatches.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Prevents cross-test leakage that masked the missing-capability fail-closed case.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Owner

repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #502
issue: #469
reviewer_identity: sysadmin
profile: prgs-reviewer
session_id: 51615-7dddf5865aec
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr502-issue-469
phase: claimed
candidate_head: 3bce0a55fb
target_branch: master
target_branch_sha: b3edd53
last_activity: 2026-07-08T07:50:05Z
expires_at: 2026-07-08T09:50:05Z
blocker: none

<!-- mcp-review-lease:v1 --> repo: Scaled-Tech-Consulting/Gitea-Tools pr: #502 issue: #469 reviewer_identity: sysadmin profile: prgs-reviewer session_id: 51615-7dddf5865aec worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/review-pr502-issue-469 phase: claimed candidate_head: 3bce0a55fb53456f5b946785c1f8711f254967b0 target_branch: master target_branch_sha: b3edd53 last_activity: 2026-07-08T07:50:05Z expires_at: 2026-07-08T09:50:05Z blocker: none
sysadmin approved these changes 2026-07-08 02:51:03 -05:00
sysadmin left a comment
Owner

APPROVE — PR #502 @ 3bce0a55fb53456f5b946785c1f8711f254967b0

Reviewer: sysadmin / prgs-reviewer (not author jcwalker3; self-review check passed, self_author:false).

Scope

Preserves resolved capability preflight across interleaved read-only whoami calls without weakening mutation authorization. Closes #469.

Verified in code

  • Diff limited to gitea_mcp_server.py (+122/−30) and tests/test_preflight_read_survival.py (+106). No unrelated files; secret/artifact scan clean.
  • Capability proof preserved across whoami only when whoami has no violation and no new tracked dirty delta; otherwise _clear_preflight_capability_state() runs. Fail-closed behavior intact.
  • Capability state cleared after every mutation (end of verify_preflight_purity) → proof cannot replay across mutations (#469 AC3).
  • Task-mismatch fails closed: resolve_task_capability(task A) → mutation for task B raises Pre-flight task mismatch. resolved_task is threaded from gitea_resolve_task_capability into all gated mutations (AC5).
  • Missing capability still fails closed with the original preflight-order error (AC4).
  • No relaxation of who may mutate; exact-capability gates unchanged (AC7-equivalent).

Validation (isolated reviewer worktree branches/review-pr502-issue-469 @ 3bce0a5)

  • Targeted: test_preflight_read_survival.py + test_resolve_task_capability.py + TestPreflightVerification35 passed.
  • Full suite: 1768 passed, 6 skipped, 1 failed.
  • The single failure (TestMergePR::test_merge_blocked_on_stale_approval_head) is pre-existing on clean prgs/master (b3edd53) — reproduced on a baseline worktree; not introduced by #502 (which touches no merge-stale-approval code).
  • git diff --check clean; py_compile ok.

Duplicate / supersession note

PR #490 (Closes #470) contains #502's two #469 commits plus a #470 contract/docs layer and is currently mergeable:false (conflicts with master). #502 is the canonical landing vehicle for the core #469 fix. Recommend superseding #490 (reconciler close) after this lands, and salvaging #470's explicit-message/runbook layer as a small follow-up on merged #502 if still wanted.

Handoff

Do not merge in this reviewer session. Hand to a merger-capable session pinned to reviewed head 3bce0a55fb53456f5b946785c1f8711f254967b0.

## APPROVE — PR #502 @ `3bce0a55fb53456f5b946785c1f8711f254967b0` **Reviewer:** sysadmin / prgs-reviewer (not author `jcwalker3`; self-review check passed, `self_author:false`). ### Scope Preserves resolved capability preflight across interleaved read-only `whoami` calls without weakening mutation authorization. Closes #469. ### Verified in code - Diff limited to `gitea_mcp_server.py` (+122/−30) and `tests/test_preflight_read_survival.py` (+106). No unrelated files; secret/artifact scan clean. - Capability proof preserved across `whoami` only when whoami has no violation and no new tracked dirty delta; otherwise `_clear_preflight_capability_state()` runs. Fail-closed behavior intact. - Capability state cleared after every mutation (end of `verify_preflight_purity`) → proof cannot replay across mutations (#469 AC3). - Task-mismatch fails closed: `resolve_task_capability(task A)` → mutation for task B raises `Pre-flight task mismatch`. `resolved_task` is threaded from `gitea_resolve_task_capability` into all gated mutations (AC5). - Missing capability still fails closed with the original preflight-order error (AC4). - No relaxation of who may mutate; exact-capability gates unchanged (AC7-equivalent). ### Validation (isolated reviewer worktree `branches/review-pr502-issue-469` @ `3bce0a5`) - Targeted: `test_preflight_read_survival.py` + `test_resolve_task_capability.py` + `TestPreflightVerification` → **35 passed**. - Full suite: **1768 passed, 6 skipped, 1 failed**. - The single failure (`TestMergePR::test_merge_blocked_on_stale_approval_head`) is **pre-existing on clean `prgs/master`** (`b3edd53`) — reproduced on a baseline worktree; not introduced by #502 (which touches no merge-stale-approval code). - `git diff --check` clean; `py_compile` ok. ### Duplicate / supersession note PR #490 (Closes #470) contains #502's two #469 commits **plus** a #470 contract/docs layer and is currently `mergeable:false` (conflicts with master). #502 is the canonical landing vehicle for the core #469 fix. Recommend superseding #490 (reconciler close) after this lands, and salvaging #470's explicit-message/runbook layer as a small follow-up on merged #502 if still wanted. ### Handoff Do **not** merge in this reviewer session. Hand to a merger-capable session pinned to reviewed head `3bce0a55fb53456f5b946785c1f8711f254967b0`.
Owner

repo: Scaled-Tech-Consulting/Gitea-Tools
pr: #502
issue: #469
reviewer_identity: sysadmin
profile: prgs-merger
session_id: 51615-7dddf5865aec
worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/merge-pr502-issue-469
phase: claimed
candidate_head: 3bce0a55fb
target_branch: master
target_branch_sha: b3edd53
last_activity: 2026-07-08T08:01:21Z
expires_at: 2026-07-08T10:01:21Z
blocker: none

<!-- mcp-review-lease:v1 --> repo: Scaled-Tech-Consulting/Gitea-Tools pr: #502 issue: #469 reviewer_identity: sysadmin profile: prgs-merger session_id: 51615-7dddf5865aec worktree: /Users/jasonwalker/Development/Gitea-Tools/branches/merge-pr502-issue-469 phase: claimed candidate_head: 3bce0a55fb53456f5b946785c1f8711f254967b0 target_branch: master target_branch_sha: b3edd53 last_activity: 2026-07-08T08:01:21Z expires_at: 2026-07-08T10:01:21Z blocker: none
sysadmin merged commit ce61e424f6 into master 2026-07-08 03:01:49 -05:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

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