--body-file <path> and --body-file - (stdin) load the body/comment from
a file, killing the fragile shell-quoting class for long Markdown
(Jason remediation R3). Contract: mutually exclusive with --body
(rc 2), unreadable file rc 2 naming the path, resolution runs AFTER
parsing and BEFORE the required-value checks. Full arm set on the
issue-comment suite (file, stdin, exclusive, missing); all nine
carrier suites and the readback suite green. Mirrored to brain.
Codex review of a27b7dc9 (blocker): check-test-enumeration.sh rejects
unenumerated test files.
- test-issue-comment-usage-contract.sh enrolled in test:framework-shell
(hermetic by construction: PATH stubs, sandboxed runner, no network).
- test-issue-comment-readback.sh enrolled and its stale exclusion removed.
The exclusion's own note anticipated this: 'joins CI after the
wrapper-half hermeticity fix' - that fix (neutralizing seat-exported
MOSAIC_GIT_IDENTITY / MOSAIC_BRAIN_HOME that escape the sandboxed HOME)
landed in a27b7dc9. Suite green in brain and worktree trees tonight.
Enumeration guard: OK (population 73, enumerated 60, excluded 14).
Upstream of brain commits 08a00149 + 971586ef + the arm-6 sandbox fix
(brain 5th commit of 2026-08-28 series):
- R1: -b/--body is the canonical comment flag (matches issue-create,
issue-edit, pr-create, pr-edit); -c/--comment stays a compatible alias.
- R4: usage errors print to stderr and exit 2, distinct from provider,
credential, and verification failures (exit 1). Value-less flags fail
loudly (previously -c with no value died silently at rc=1 via set -e on
the failed shift 2). gh failures on the GitHub path normalize to exit 1
(gh's own usage errors exit 2 and would collide with the reserved code).
- Tests: new usage-contract suite (help rc, unknown/missing/value-less rc=2
on stderr, alias parse acceptance under a sandboxed runner, GitHub-path
exit normalization with a stubbed gh, zero provider contact on parser
failure); readback suite gains case 11 (full verified write via -b) and
neutralizes seat-exported MOSAIC_GIT_IDENTITY / MOSAIC_BRAIN_HOME that
escape the sandboxed HOME (documented HTTP 401 / fail-loud shapes).
Driver: a fleet seat full-stopped on an issue-comment usage error because
usage failures were indistinguishable from provider failures and the stop
gate treated every wrapper failure as blocking.
Per ops-ci-01's procedure (comments 23386/23394, brain D27): pipeline config
travels with the commit under test, so the controlled rerun requires the pinned
anchor in the PR head itself. This merge absorbs everything next took since the
original merge parent (1bdeed62): the ci-base pin (cb9a0d1, lock-9cb7ffcd8828),
the legacy-credential removal (#1325), and the ci-queue-wait statuses:null fix
(#1129 — the branch from the divergence analysis, now landed).
One conflict, same file as round 1: test:framework-shell union — our 54-entry
chain plus next's new test-ci-queue-wait-no-status.sh entry at its position
(55 entries, every target existence-verified). Enumeration guard green:
population 61, enumerated 46, excluded (signed) 16.
Review stack#1324 id 201 (rev-code-01): the union resolution chained main's #1073
fleet test while keeping next's signed exclusion of it (#1271 burn-down: the test
asserts missing-binary behavior but CI provides pi on PATH — fails by design).
check-test-enumeration CONTRADICTORY EXCLUSION, CI pipeline 2532 terminal failure.
Fix per verified review recommendation: remove the chain entry (55 -> 54 parts),
keeping next's exclusion and #1271 state. Guard now passes:
population 60, enumerated 45, excluded (signed) 16.
The repo format:check glob covers ts/js alongside md; four non-markdown
scripts inside the folded tree were flagged after the md pass. Same pinned
prettier 3.8.1, same markup-only class (verified: node --check still passes
on the js files).
Phase D3 of plan 2026-08-19 (decision S21): skills-local is the local test
bed; promote individually as each proves out. ms-unslop is the only one of
the seven local skills with working enforcement evidence — a checker
(tools/unslop-hook/unslop-check.js), a machine-source list (lists.json), a
19-test suite, a measured corpus, and a regression fixture.
The checker itself stays fleet-local for now (it binds to a specific
harness extension surface); this promotes the skill document only.
Gates verified on the moved file: sanitization denylist clean, prettier
3.8.1 clean (6730 chars was fred's measure at assignment; 7249 as shipped
today — both pass).
Phase D2 of plan 2026-08-19: single package, single install, single command.
The framework installer already treats skills/** as a shipped, manifest-owned
framework subtree, so the folded skills now install into
$MOSAIC_HOME/skills with the rest of the framework — no second repository,
no separate sync step:
- mosaic-sync-skills (bash + powershell): the fetch machinery is gone (clone,
pull, dirty-state migration, rsync from sources/agent-skills). The script
now only links installed skills into runtime homes. --link-only is a compat
no-op; --no-link exits having nothing to do.
- catalog.ts: the sources/agent-skills fallback is dead and removed.
- install.sh, launch.ts, defaults/README.md, README.md, skills/README.md:
references to the second repo rewritten to describe the shipped path.
Verified: clean install into a fresh MOSAIC_HOME produces 102 skills with no
sources/ directory; the linker then links the selected skills into the four
runtime homes with no git involvement.
963 markdown files reformatted with the repository's pinned prettier so
pnpm format:check covers the folded tree like every other repo file.
The formatter's embedded-language pass also normalized code fences
(TS semicolons, closed HTML tags in examples, lowercased CSS hex colors,
one renumbered list that skipped an index). Alphanumeric token deltas vs
the fold commit were audited file-by-file; all are formatter-equivalent
markup normalizations plus the four sanitized skills.
Four folded skills carried operator identity tokens that the sanitization
gate (verify-sanitized.sh) forbids in the public framework package:
- kickstart: template path pointed at a private brain checkout; now uses the
framework-shipped $MOSAIC_HOME/templates/docs/TASKS.md.template
- mosaic-deploy: dropped one estate-specific stack-name row from the example
table
- mosaic-portainer, mosaic-woodpecker: credentials now name the framework
credentials store (load_credentials <service>) instead of a private
checkout path
Estate-specific values can live in a skills-local override, which the linker
applies with precedence over canonical skills.
Fold the agent-skills repository into the monorepo as the shipped canonical
skills package (plan 2026-08-19 phase D1, decision S19: single package, single
install, single command).
History is preserved by rewriting each commit's paths from skills/ to
packages/mosaic/framework/skills/ (git fast-export/import) and merging the
rewritten history with --allow-unrelated-histories, so the original commits
with their authors, dates, and messages remain reachable. Blob content is
untouched by the rewrite; tree fidelity was verified blob-sha-for-blob-sha.
This change must be merged with a real merge commit (not squash) or the
history link is destroyed.