199 lines
13 KiB
Markdown
199 lines
13 KiB
Markdown
# #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.
|
|
|
|
## Round 3 — Alpine stale-marker portability
|
|
|
|
### Objective and plan
|
|
|
|
- Replace the GNU-only relative-date fixture with a deterministic POSIX/BusyBox timestamp while preserving the required stale-marker assertion.
|
|
- Re-run the launcher suite in the canonical `ci-base:latest` Alpine image, then run applicable repository gates and independent review.
|
|
- Update the PR body to name the repeated GNU-host/Alpine-CI portability pattern, run the mandatory queue guard, push once, verify provider attribution, and stop without CI polling.
|
|
- Working budget: 8K tokens; scope is one fixture line plus delivery evidence. No production behavior changes.
|
|
|
|
### RED-first evidence
|
|
|
|
Before the fix, the canonical CI image command
|
|
`docker run --rm -v "$PWD:/work" -w /work git.mosaicstack.dev/mosaicstack/stack/ci-base:latest bash packages/mosaic/framework/tools/fleet/test-start-agent-session.sh`
|
|
exited 1 at the stale-marker setup with exact BusyBox output
|
|
`touch: invalid date '10 seconds ago'`. The prior fresh-marker assertions had already executed, matching pipeline 2233's failure location.
|
|
|
|
### Root cause and fix
|
|
|
|
The test used GNU `touch -d` relative-date parsing although the PR workflow runs on Alpine/BusyBox. The fixture now uses POSIX `touch -t 200001010000.00`, a fixed timestamp that is unconditionally stale; the stale assertion remains mandatory and was not made tolerant of missing timestamp metadata.
|
|
|
|
### Structural pattern
|
|
|
|
This is the third GNU-host/Alpine-CI portability defect in the lane: GNU `grep` multi-match counting, Perl-only fixture mutation, and GNU `touch -d` date parsing. The repeated cause is shell suites authored on a GNU host but executed in an Alpine CI image; durable prevention belongs in CI-image execution or portability lint, not assertion weakening.
|
|
|
|
### GREEN and quality evidence
|
|
|
|
- Focused launcher suite in `ci-base:latest`: exit 0, `ok - start-agent-session generated environment boundary`.
|
|
- Canonical test step in `ci-base:latest` with the pipeline's `pgvector/pgvector:pg17` service, readiness check, migration, and `pnpm test`: exit 0; 46/46 Turbo tasks; Mosaic 81/81 files and 1510/1510 tests; Gateway 57 passed/5 skipped files and 629 passed/11 skipped tests; enumeration 49 population / 32 enumerated / 18 signed exclusions / 45 named surfaces.
|
|
- The first image-only `pnpm test` attempt lacked the pipeline PostgreSQL service and failed only on connection refusal after the launcher suite was GREEN. The rerun supplied the canonical service precondition and passed.
|
|
- Canonical-image baseline: typecheck 45/45 tasks, lint 25/25 tasks, format check GREEN; `git diff --check` GREEN.
|
|
- Independent Codex code review: APPROVE, confidence 0.96, 2/2 Round-3 files, no findings.
|
|
- Independent Codex security review: risk none, confidence 0.99, 2/2 Round-3 files, no findings.
|
|
|
|
### Re-derived inventory and denominators
|
|
|
|
- Round-3 git delta: **2/2 files** — launcher suite and task scratchpad; 25 insertions / 1 deletion before evidence finalization.
|
|
- Full PR path inventory against `origin/main` at `85d2108e`: **19/19 changed paths**; Round 3 adds no new PR path.
|
|
- Workflow definition population: **1/3 pull-request-eligible** (`ci.yml` of `ci.yml`, `ci-image.yml`, `publish.yml`).
|
|
- Do not re-litigate the settled 311/312 populations; both are valid for their separately named Tess6 and CRUD-core7 sets.
|
|
|
|
## 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.
|