Files
stack/docs/scratchpads/1043-pane-git-identity.md
T

9.8 KiB

#1043 — Fleet pane git-identity propagation

Objective

Ensure a fleet seat's launched runtime process receives its roster-derived MOSAIC_GIT_IDENTITY, and lock the complete generated-environment propagation boundary with an enumerated set comparison.

Tracking

  • External issue: mosaicstack/stack#1043
  • Branch: fix/1043-pane-git-identity
  • Coordinator: tl-mosaic
  • docs/TASKS.md: read-only by project worker contract; not modified.

Constraints

  • RED-first bug reproducer is mandatory.
  • R7 delete-the-subject mutation must turn the behavioral test red.
  • Assert launched-process environment, not source text.
  • One push only; do not poll CI after push.
  • Run the CI queue guard immediately before push and report its state= line as state, not evidence.
  • Do not modify a live host launcher or obtain/copy another credential.
  • Self-post the PR, verify provider attribution, then stop.
  • Final status wording: believed-fixed, pending jarvis validation.

Scope inventory

Re-derived against origin/main at 85d2108e:

  • Launch consumer: packages/mosaic/framework/tools/fleet/start-agent-session.sh
  • Behavioral launch test: packages/mosaic/framework/tools/fleet/test-start-agent-session.sh
  • Generated-environment contract/parser: packages/mosaic/src/fleet/generated-env-boundary.ts
  • Roster projection producers:
    • packages/mosaic/src/commands/fleet.ts
    • packages/mosaic/src/fleet/fleet-reconciler.ts
    • packages/mosaic/src/fleet/fleet-agent-crud.ts
    • packages/mosaic/src/fleet/v1-v2-migration.ts
  • Contract and producer tests discovered by repository search.
  • Generated-environment operator/developer docs and their executable documentation contract test.

Discrepancy sent to tl-mosaic: current main no longer contains the charter's PANE_SHELL_SNIPPET; #772 replaced it with an /usr/bin/env -i argv launch boundary, and current generated projections do not declare git identity. Code-read inventory is NOT MEASURED behavior.

Plan

  1. Add the process-environment set-comparison regression first and record RED.
  2. Add roster-derived MOSAIC_GIT_IDENTITY=<agent name> to the complete generated projection contract.
  3. Validate identity syntax and equality with MOSAIC_AGENT_NAME; pass it through the clean pane environment.
  4. Update affected projection tests and generated-environment docs.
  5. Run focused and baseline gates.
  6. Perform R7 by deleting the pane propagation entry, prove RED, restore, and prove GREEN.
  7. Run independent review, remediate, commit, queue guard, one push, self-post PR, verify provider attribution, and stop without CI polling.

Budget

No explicit token cap was provided. Working cap: one narrow logical unit, no dependency installation unless existing tooling requires it, no unrelated refactor.

Evidence log

TDD and mutation evidence

  • RED-first, repository launcher: bash packages/mosaic/framework/tools/fleet/test-start-agent-session.sh exited 64 on pre-fix source with code=unknown-key key=MOSAIC_GIT_IDENTITY. The generated seat could not launch with the required declared identity.
  • GREEN: the same repository launcher test emitted ok - start-agent-session generated environment boundary.
  • R7 delete-the-subject: removed only "MOSAIC_GIT_IDENTITY=$MOSAIC_GIT_IDENTITY" from the repository launch array; the same test exited 1 with FAIL: runtime pane omitted or changed generated environment keys: MOSAIC_GIT_IDENTITY.
  • R7 restoration: restored that launch entry; the same test returned green.
  • Launcher under test is explicitly packages/mosaic/framework/tools/fleet/start-agent-session.sh through the test's $START, not the stale installed host copy.

Situational and focused tests

  • Repository launcher boundary: green, including set comparison of all nine generated projection entries and fail-before-tmux cases for missing, unsafe, mismatched, and local-shadow Git identity.
  • Fleet systemd launcher integration: bash packages/mosaic/framework/systemd/user/test-fleet-units.sh — green.
  • Focused Mosaic Vitest set: 6 files, 311 tests — green.
  • bash -n on changed shell files — green.
  • git diff --check — green.

Baseline gates

  • pnpm typecheck — 45/45 tasks green.
  • pnpm lint — 25/25 tasks green.
  • pnpm format:check — green.
  • pnpm test:checkout — green.
  • Repository-wide Vitest under a hermetic current-version npm prefix: Mosaic 81/81 files and 1510/1510 tests green; other workspace test tasks shown green before the framework-shell phase.
  • Canonical pnpm test is not fully green on this host for unrelated environment-sensitive gates:
    1. the first two runs exposed the globally installed Mosaic 0.0.48 update banner in three CLI smoke tests expecting empty stderr;
    2. after isolating that global-version input, the framework wake assertion aborted at the known #973 Bash BASH_LINENO convention check (exit 97; observed [3 5], expected [3 4]). No tests were weakened or bypassed; focused changed-surface tests are green. CI remains the canonical clean-environment result and is intentionally not polled after push per charter.

Independent review

  • Codex code review first pass: request changes for missing shell rejection-path coverage.
  • Remediation: added table-driven missing/unsafe/mismatch/local-shadow launcher cases, each asserting no tmux call.
  • Codex code re-review: approve, no findings, confidence 0.88.
  • Codex security review: risk none, no findings, confidence 0.97.

Acceptance criteria mapping

Acceptance criterion Evidence
AC-FGI-01: launched process receives every generated key/value Repository launcher process-environment comm -23 set comparison; GREEN and R7 RED evidence above
AC-FGI-02: missing, unsafe, or split identity fails before tmux Table-driven shell cases plus TypeScript generated-boundary tests
AC-FGI-03: focused/baseline/review evidence recorded Commands and review outcomes above; host-sensitive full-suite limitations stated explicitly

Documentation checklist

  • PRD updated with #1043 requirements and acceptance criteria.
  • Fleet launch runbook, generated-env concept, and generated-env reference updated.
  • No API/OpenAPI, sitemap, user publishing target, deployment, or external docs publication change applies.
  • docs/TASKS.md remains unmodified per its single-writer project contract.

Round 2 — PR #1073 review 97 remediation

Review blocker

The launched-process suite was signed-excluded from CI enumeration. Manual GREEN/R7 evidence therefore did not prove a PR workflow could detect regression.

RED-first and canonical wiring

  1. Removed the suite's signed exclusion before adding a CI execution path.
  2. check-test-enumeration.sh went RED with exact UNENUMERATED output for test-start-agent-session.sh: population 49, enumerated 30, excluded 18.
  3. Added both framework/tools/fleet/test-start-agent-session.sh and framework/systemd/user/test-fleet-units.sh to @mosaicstack/mosaic's canonical test:framework-shell chain.
  4. The guard returned GREEN: population 49, enumerated 32, excluded 18, surfaces 45. The systemd suite is outside the guard's tools-only population but now has the same explicit canonical execution disposition.

Workflow-level R7

  • Deleted only the pane launch entry "MOSAIC_GIT_IDENTITY=$MOSAIC_GIT_IDENTITY".
  • Ran the exact .woodpecker/ci.yml test-step command, pnpm test, with only a temporary PATH-scoped npm shim reporting the checkout's current 0.0.49 version so the unrelated global 0.0.48 banner could not preempt the shell chain.
  • Result: exit 1 at @mosaicstack/mosaic#test, with the enumeration guard GREEN followed by FAIL: runtime pane omitted or changed generated environment keys: MOSAIC_GIT_IDENTITY.
  • Restored the launch entry. The canonical test:framework-shell chain then reached both newly wired suites and printed both GREEN markers before the known unrelated #973 host-only BASH_LINENO abort.
  • An actual provider PR workflow on the intentionally broken mutant is NOT MEASURED: the one-push constraint forbids pushing a red mutant and then a repaired head. Local execution proves the exact PR workflow command and dependency chain go RED on the subject deletion; CI on the repaired pushed head remains canonical.

Workflow population

  • DEFINED: 3 workflows (ci.yml, ci-image.yml, publish.yml).
  • ELIGIBLE for pull_request: 1/3 (ci.yml), based on top-level when: clauses.
  • REPORTED: Round-1 exact-head provider read reported 1/1 eligible context (ci/woodpecker/pr/ci). Post-remediation-head reported count is NOT MEASURED by this seat because CI polling is prohibited; workflow definitions and eligibility did not change.

Independent remediation review

  • First Round-2 review identified a CI-image blocker: the newly wired launcher suite used Perl, which the Alpine CI base does not install.
  • Replaced the suite's three Perl-only fixture mutations with POSIX/BusyBox-compatible sed -i substitutions; production behavior and assertions are unchanged.
  • Codex re-review: APPROVE, confidence 0.93, no findings.

Vitest denominator reconciliation

The PR's 311/311 is correct for its explicitly named six-file command at both the original and remediation worktrees:

  • generated environment boundary: 24
  • fleet documentation: 23
  • Tess service profile: 6
  • fleet regen command: 27
  • fleet agent CRUD command: 22
  • fleet command: 209
  • total: 311

Review 97 reported 312/312 without naming its six files. That is a different or miscounted population and cannot replace the command-scoped 311 denominator; the PR follow-up will name the exact files and arithmetic.

Residual risk

  • Landing on main does not update the currently installed host launcher. Host framework installation/reseed and Jarvis live-seat validation are separate downstream events.
  • Canonical CI result is pending and will not be polled by this seat.