docs(remediation): bank D-34 — a context reset silently strips a seat's credential identity

rev-974 finished its RM-02 review and could not post it: pr-review.sh failed with
'Gitea token not found'. Verified — with MOSAIC_GIT_IDENTITY unset the token does not
resolve; with it set it resolves. The token file was correct throughout.

My own context reset wiped the seat's exported identity and my rehydration brief did not
re-establish it. git config mosaic.gitIdentity is persistent and per-worktree;
MOSAIC_GIT_IDENTITY is ephemeral and per-context. rev-974 works from ~/agent-work with no
git-config fallback, so it had no warning and the loss surfaced only when it next needed
a credential.

Intersection of two banked findings, created by acting on one: D-31 prescribes rotation,
D-11a requires identity coherence, and nothing said rotation is a credential-affecting
operation. The fix for one failure introduced another.

RM-34: rotation must re-establish AND verify seat identity before handing over work.
RM-50: prefer the durable binding (mosaic.gitIdentity in the seat's repo) so identity
survives a reset by construction. Interim: every rehydration brief re-exports identity.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
mos-dt-0
2026-08-01 00:51:21 -05:00
co-authored by Claude Opus 5
parent 73a313301b
commit 9e205e8201
+36
View File
@@ -221,6 +221,42 @@ reviewer, and no other seat holds mosaicstack write. Flagged to the coordinator
busy lane. Not blocking today — RM-02's code blockers are independently disqualifying — but the next
otherwise-clean PR meets this.
### D-34 — a context reset silently strips a seat's credential identity
`rev-974` completed its RM-02 review, then **could not post it**:
`pr-review.sh … → "Gitea token not found for review post"`. It stopped per the wrapper-failure gate
rather than reaching for a raw CLI — correctly.
Diagnosed rather than guessed:
| environment | `get_gitea_token git.mosaicstack.dev` |
| -------------------------------------------------- | ------------------------------------- |
| `MOSAIC_GIT_IDENTITY` unset (a freshly-reset seat) | **FAILS** — empty |
| `MOSAIC_GIT_IDENTITY=rev-974` | resolves, 40 chars |
The token file was present and correct throughout. **The orchestrator's own context reset wiped the
seat's exported identity**, and the rehydration brief did not re-establish it. The seat had posted
reviews 6164 earlier the same night because that export was still live.
**The split that makes this invisible:** `git config mosaic.gitIdentity` is **persistent and
per-worktree**; `MOSAIC_GIT_IDENTITY` is **ephemeral and per-context**. A seat working inside a
configured worktree survives a reset by falling back to git config. `rev-974` works from `~/agent-work`,
which carries no such config — so it had **no fallback and no warning**, and the loss surfaced only at
the moment it next tried to act on a credential.
**This is the intersection of two banked findings, and it was created by acting on one of them.** D-31
prescribes rotation as the response to context exhaustion; D-11a establishes that identity must cohere.
**Rotating a seat is a credential-affecting operation** — and nothing in the rotation procedure said so.
The fix for one failure quietly introduced another.
**Requirements.** RM-34 (rotation daemon): a reset must **re-establish seat identity as part of the
rotation**, not leave it to the rehydration prose — and must **verify** it (resolve a token, or assert
the identity is set) before the seat is handed work. RM-50: prefer the **durable** binding — set
`mosaic.gitIdentity` in each seat's working repo so identity survives a context reset by construction,
rather than depending on an env var that a reset destroys. Interim: **every rehydration brief re-exports
the seat identity**, and a rotated seat's first credential-touching action is treated as unverified until
it succeeds once.
### D-33 — the tool used for "full step scans" silently prunes a step in its default output
`coder-mos1` reported a **9/9** child-step scan of pipeline #2186 using `-f json`. My scan of the same