Files
stack/docs/scratchpads/1045-mosaic-cred.md
T
2026-08-05 19:52:33 -05:00

14 KiB

MC-CRED-01 / stack #1045 scratchpad

Last updated: 2026-08-05

Successor remediation (be-coder-07, PR #1059 review id 89)

Objective: close the four exact-head rev-974 blockers without weakening any assertion, repair canonical-image test portability, and refresh the narrowed cooperative-concurrency claims and PR metadata. The provider-fetched starting head is 12958610cbafaa54a3db95327a7c3453d9111669 at merge-base 85d2108e4ed15c744ad3b87a5b629e7b2d39405a.

Plan:

  1. Preserve the journal-lock release assertion while replacing Alpine-invalid /usr/bin/true with canonical /bin/true.
  2. Replace cross-system atomicity claims with exact all-or-verified-compensation semantics; retain atomic wording only for explicitly scoped single-file rename/replacement primitives and qualify team locking as cooperative advisory serialization.
  3. Add red-first controls for complete journal writes under one-byte progress, rejection of zero/invalid progress, Tea generation equivalence under recursive key reorder, and durable indeterminate classification when team-lock release cannot be verified.
  4. Implement bounded journal write-all, recursive canonical generation serialization, and release-before-seal team-lock cleanup classification; then run focused and baseline gates plus code/security advisories.
  5. Commit with explicit be-coder-07 identity, rebase rather than merge onto current origin/main, prove stable patch identity, run the required queue/direct-CI guards, and make one force-with-lease push pinned to the measured starting head.

Budget: hard context ceiling is 60%. Reuse predecessor evidence and avoid re-deriving unrelated 41-file history. Non-blocking secret zeroization is included only after all blockers are green. Stop and write a seam/report before the ceiling.

Objective

Deliver the governed mosaic cred identity boundary for issue, scope, validation, rotation, and revocation across explicitly declared estates. The trunk-only ruling superseded the original next checkpoint: the branch is rebased onto origin/main and its PR target is main. Linked issues remain believed-fixed, pending jarvis validation after merge.

Requirements sources

  • Charter: /home/hermes/agent-work/tl-mosaic/CHARTER-MC-CRED-01-be-coder-06.md
  • Stack issues: #1045, #1043, #1044, #1047, #1049, #1013, #1007; promotion #1037; consumer #1051
  • Remote spec: jason.woltje/jarvis-brain origin/main b7687d51f4efe52e43dbcd6dc95b5554b3332957
  • Greenfield PRD v3 addenda: INV-B durable journal, INV-C visible failure diagnostics, INV-D supported fixture
  • Binding doctrine: /src/jarvis-brain/infra/fleet/FLEET-DOCTRINE.md

Plan

  1. Publish grant/validate v1 caller contract for MB-BRAIN-01.
  2. Add repo PRD requirements and preregister acceptance tests.
  3. Implement explicit estate registry, secure current file-store adapter, durable operation journal/audit, provider transport, and terminal result types.
  4. Implement grant and side-effect-free validate; then provision/wire/get/whoami/list/rotate/revoke/audit.
  5. Make git and API resolver refusals identical and fail closed under fleet context.
  6. Reconcile live HOMELAB seats through each subject credential's own /user; #1044 hold is lifted, and its fail-closed change carries the pre-registered mechanism evidence (resolver refusal marker, same-run marker positive control, confirmed-lane negative arm).
  7. Run baseline/situational tests, independent code review and mandatory independent security review, CI on the exact head, then open the PR directly against main without closing issues or claiming Jarvis validation.
  8. C1 merges first. After any base/head move, re-derive merge-base, commit set, diff, CI, reviews, and provider measurements from the replacement SHA.

Budget

No explicit token cap supplied. Working cap: keep implementation in one package plus shipped framework resolver changes and required docs/tests; avoid unrelated wrapper defect fixes and VaultWarden redesign. Escalate only if a charter requirement is technically unsatisfiable.

Decisions

  • VaultWarden is out for the agent tier per the charter verdict; phase 1 governs the existing per-identity file store.
  • Estate is explicit input and must match a configured host mapping; target host is never inferred from machine location.
  • Grant authority and basic-auth provisioning material are delegated control-plane credentials, never caller bearer material and never CLI argument/output.
  • ok, refused, error, and indeterminate are distinct machine outcomes. Security callers fail closed on all but ok, while retaining the semantic distinction.
  • Gitea write-differential resolves the subject once and binds provider identity, repository permission, and receive-pack to the same in-memory credential handle. It adds a distinct provider-confirmed read-only-principal control plus the unauthenticated control, with no ref update. The live HOMELAB negative-control subject is tl-mosaic, verified read-only on mosaicstack/stack; code and contract remain principal-agnostic.

Progress

  • Mode/intake/core guides/skills/doctrine loaded.
  • Spec repository READ confirmed under be-coder-06 from provider object.
  • Target-branch conflict resolved by the trunk-only ruling; the lane was rebased from next onto origin/main.
  • Canonical remote PRD v3 addenda re-read at new head.
  • Required issues read via Mosaic wrapper.
  • Early grant/validate contract v1 published at docs/credentials/GRANT-VALIDATE-CONTRACT.md.
  • Contract v1.1 binds transport to the same resolved principal and adds a provider-confirmed read-only-principal control.
  • Contract v1.2 distinguishes provider outage, absent identity, and rejected credential.
  • Contract v1.3 positive-controlled anonymous visibility; subsequently withdrawn as unsound for private identities.
  • Contract v1.4 implements ruling (b): subject credential's own /user, no admin/inventory authority, no implemented identity-not-found path.
  • PRD update.
  • Red-first principal-bound validate, estate-registry, file-store, provider-transport, and journal tests.
  • Implementation: validate, direct/team grant, protected delegated authority, provision/wire/get/whoami/list/rotate/revoke/audit, reverse registry, and fleet fail-closed resolver paths.
  • Review hardening: rotation returns visible open journals; team evidence records absent objects accurately; team scope is checked before/after under a host-qualified OS advisory lock with verified compensation; wire authenticates the exact seat/path/roster binding and preserves post-rename mutation semantics.
  • Author advisory remediation: provisioning rollback verifies provider/token-store/Tea state and cannot suppress Tea cleanup failure; Tea put/remove always unlink secret-bearing temporary files; unrelated hosts exit before Mosaic identity grammar; cred get persists issuance start before disclosure, writes through a short-write-safe loop, and preserves partial/applied indeterminate semantics under write/append/seal faults; provision/rotate/revoke share a fixed cross-state-root lifecycle lock for cooperating processes only (provider authority is the authorization boundary; generation preconditions are optimistic for cooperating mutators; hostile same-UID filesystem mutation is explicitly deferred); Tea pre-state is snapshotted/restored independently; final journal seal faults revert to open classification.
  • Legacy-token estate binding is explicitly deferred: the legacy format contains no estate and the installed shell path has no distributed strict registry. Enabling refusal before registry distribution plus token-envelope migration would strand active legacy-only seats; governed envelopes already bind estate exactly.
  • Hostile same-UID direct filesystem mutation is explicitly deferred to #1065. The finding is copied verbatim there; PR #1059 links it. Phase 1 claims only optimistic generation preconditions and advisory locking for cooperating mutators, with provider authority as the authorization boundary.
  • Independent code/security approvals on the final exact head (Codex advisory iterations are not independent approval).
  • Final exact-head CI and provider evidence.

Tests and evidence

Baseline after workspace build: package typecheck passed; Vitest 81/81 files and 1,514/1,514 tests passed. The package shell suite reached a pre-existing tracked #973 Bash 5.2 BASH_LINENO incompatibility and exited 97 before wake tests; this is baseline, not introduced by MC-CRED.

Red-first evidence:

  • principal-bound validate module absent → focused suite red;
  • incremental v1.1 run: write-capable, identity-mismatched, and receive-pack-admitted read-only controls each returned ok, causing 3/13 tests to fail for the exact control defect; after the control checks, 13/13 passed;
  • read validation absent → 2 tests failed evaluateGiteaReadValidation is not a function; after implementation, 15/15 validate tests passed;
  • estate registry, secure file resolver, Gitea transport, and audit journal each failed first because the module did not exist, then passed focused behavior suites.

Pre-remediation focused evidence: 80/80 across 11 credential/command suites; package lint, typecheck, formatting, and build were green. The advisory remediation adds thirty-five focused regression cases for rollback cleanup, Tea temporary-file cleanup, unsupported-host passthrough, and credential issuance partial-write/post-write-audit truthfulness; focused reruns are green (latest credential/command set: 109/109). Final uncommitted author advisories report code approve with no findings and security none with no findings; they remain advisory rather than independent approval. Full package Vitest reached 1,614 passing tests and three unrelated CLI-smoke failures caused solely by the installed-version update banner writing to stderr. Provider bodies are stream-bounded and requests deadline-bounded; delegated fd input is ownership/mode/size/time bounded; token and Tea stores are private and use atomic rename only for each explicitly scoped single-file replacement primitive; cross-system lifecycle completion uses verified compensation rather than an atomic-commit claim; grant mutation/read-back state is journaled.

Fail-closed resolver evidence: synthetic missing-token API and git paths each emitted stable MOSAIC_CREDENTIAL_REFUSAL with reason=no-token-for-identity and shared_path_entered=false; all 13 live token-bearing identities bypassed the shared path without over-fire in the same run. Evidence: /home/hermes/agent-work/be-coder-06/review-evidence/failclosed-postcondition.jsonl; independent verification remains tl-mosaic's obligation.

Live validation v1.4 (subject credential's own /user, no admin): population 13; CONFIRMED 8; CREDENTIAL-REJECTED 4 (coder-mos1, coder-mos2, f10-coder, merge-gate); MISMATCH 1 (mos-admin token authenticates as Mos); NOT-MEASURED 0. The four false v1.2 identity-not-found sealed journals remain immutable and are explicitly superseded by four sealed correction journals. Evidence: /home/hermes/agent-work/be-coder-06/live-validation-v1.4/.

Write differential for be-coder-06 passed with the configured read-only control and unauthenticated arm. Unit evidence proves the control arm invalidates validation when write-capable, identity-mismatched, or receive-pack-admitted.

Successor review-remediation evidence

  • Canonical-image CI portability: /usr/bin/true was changed only to /bin/true; the second-process flock acquisition assertion remains status === 0 and passes in the focused lifecycle suite.
  • Required red phase: five exact finding controls failed before implementation (journal one-byte/zero/oversized progress, recursively reordered Tea metadata, and lock-release failure). Review remediation added a sixth red control proving final-seal failure could compensate a later cooperating team mutation after lock release; a prototype-named Tea metadata control also failed before canonical object construction was hardened.
  • Focused final: 120/120 passed across all 11 credential and credential-command files.
  • Package lint and typecheck passed; dependency-aware workspace build passed 13/13 packages; repository format check and git diff --check passed; both git credential resolver shell regressions passed.
  • Full local package Vitest: 1,624 passed / 3 failed. The failures are the same installed-version update banner emitted to stderr by three cli-smoke.spec.ts cases; prior canonical pipeline #2223 ran all 22 CLI-smoke cases green. Exact-head canonical CI remains required after push.
  • First uncommitted advisories found a real post-release compensation race. Its red control observed one removal after lock release; the fix forbids compensation after successful release, and the control then passed without weakening an assertion.
  • Final uncommitted advisories: code approve with no findings; security risk none with no findings. Codex could not execute tests in its read-only sandbox (EROFS), so these verdicts rely on review only; the writable author runs above are the test evidence and independent reviewers remain required.

Risks/blockers

  • Hostile same-UID direct filesystem mutation is outside phase-1 and requires a transactional service, broker/distinct identity, or equivalent non-bypassable primitive; lifecycle flock and generation preconditions cover cooperating mosaic cred mutators only. Track the explicit security deferral linked from PR #1059.
  • The full CLI surface is broad; protect scope by sharing one provider/registry/journal core rather than per-command scripts.
  • Gitea exact token-scope read-back may require delegated Basic Auth. If a bearer-only validation path cannot obtain an exact provider token object, return indeterminate rather than claim a scope.
  • #1044 hold is LIFTED. The four least-privilege credentials are capability-confirmed and identity-not-measured, not dead. Fleet fail-closed paths now refuse with stable reason markers and never enter shared fallback under MOSAIC_AGENT_NAME; interactive callers retain explicit shared behavior. Runtime mismatch coverage remains limited to tokens holding read:user; future mints close identity binding at creation without widening seat scopes.
  • C1 PR #1054 remains sequencing-prior and requires its own exact-head gates. MC-CRED PR #1059 must freeze only after a new advisory review, independent review, and exact-head CI.