- MOSAIC_TMUX_SOCKET no longer leaks into remote sends (-L on a remote
host would target the wrong server; codex blocker).
- Socket-test outputs moved from fixed /tmp paths to mktemp artifacts
cleaned by the trap (parallel-safe; codex should-fix).
- MOSAIC_TMUX_SOCKET now disambiguates BEFORE the ambiguity refusal
(the old order told users to set the env var while never consulting
it on multi-hit; codex blocker).
- Socket discovery scans ${TMUX_TMPDIR:-/tmp}/tmux-UID, tmux's own
socket dir — TMPDIR was wrong wherever they diverge (codex blocker).
- Arm A2: env var beats ambiguity (twin delivers on the named socket,
no cross-delivery); arms A/B run hermetic (env unset).
- Same precedence + dir fix applied to brain agent-watch.
Measured defect (2026-08-28/29): tasking sends without -L landed in a
stale default-socket TWIN of the target seat; rc 0 reported honest
delivery to the wrong pane. Resolution order now: explicit -L >
MOSAIC_TMUX_SOCKET (launcher-exported) > unique socket hit; multiple
hits refuse with rc 4 naming the sockets. Local targets only; remote
pass-through unchanged.
Socket test gains arms A (twin session on two sockets -> rc 4 with the
socket list) and B (unique session auto-resolves and delivers on the
right socket, no cross-delivery). Test remains CI-excluded per its
signed exclusion (no tmux in the CI image, #1017).
gh stub exiting 2 on the close/api path -> wrapper exit 1 with the
normalized stderr message; mirrors the issue-assign 6b arm. All
touched suites green; brain mirror updated.
- issue-assign + milestone-create: set -o pipefail; the remove-assignee
lookup pipeline now fails loud on provider failure instead of reading
an empty result as a silent no-assignees skip (codex blocker). A
successful lookup with zero assignees still skips the edit.
- test-issue-assign-usage-contract: 6b arm proves provider-exit
normalization end to end (gh stub exiting 2 on issue edit -> wrapper
exit 1 with the normalized stderr message; codex should-fix).
- Battery: 23/23 suites green.
- Option-like value = any token starting with '-' followed by an
alphanumeric (-h, -ab, --help); multi-character short clusters were
still accepted (codex blocker). Bare '-' is reserved (future stdin).
- usage_error now prints the usage text to stderr as well (codex
should-fix): usage output belonged to stdout only on the help path.
- 16/16 usage-contract suites green.
- Value guards now reject option-like values: --anything always, and
single-dash flag shapes (-h, -i). Previously -b --help consumed
--help as the body and performed the write (codex example:
issue-close -i --help proceeding to 'Closed GitHub issue #--help').
Multi-char dash-leading text (-start of a list) stays a legal value.
- Every remaining direct provider exec (gh/tea/CMD arrays across
issue-create/edit/assign/list/view, milestone-*, pr-create/edit,
pr-close, issue-close/reopen) wrapped with rc capture and normalized
to exit 1 with a stderr message — provider exit 2 no longer collides
with the reserved usage-error status.
- All 16 usage-contract suites gained option-like and short-flag arms
(16/16 green). Existing suites re-verified; test-pr-edit and
test-issue-create-interactive-auth fail identically with these
changes stashed (environment-coupled, not regressions; documented).
request-changes and comment both validate their required body
immediately after argument parsing (rc 2, stderr, zero provider
contact). The repo-host-override suite's action-message expectation
updated to the new wording; suite green.
An unsupported --action previously reached platform detection (and
could touch the provider) before failing with a provider-class status;
comment-without-body exited 1 mid-switch. Both now fail fast with
usage_error (rc 2, stderr) immediately after argument parsing. Test
arms added including the zero-provider-contact assertion for
invalid-action runs.
- issue-list + milestone-create: usage() default exit 2, value guards,
missing-title via usage_error.
- lane-brief: getopts replaced with a while/case parser carrying R2
long-flag aliases (--repo --milestone --label/--labels --login
--limit) beside the short forms; login-resolution failure reclassified
from exit 2 to exit 1 (credential class, not an invocation defect).
- Three suites enrolled (population 88); lane-brief pr-linkage suite
still ALL PASS; green in both trees; mirrored to the brain tree.
With this, every agent-facing wrapper in tools/git carries the R1/R4
usage-error contract (22/22 non-guard wrappers; guards keep their own
contracts).
usage_error contract (stderr + exit 2) with value guards on every
value-taking option and the missing-required checks (milestone-close
-t, issue-view -i). Three suites enrolled (population 85); green in
both trees; mirrored to the brain tree.
usage() default exit 2 (usage-error contract); value guards on all
seven value-taking options; -d/--draft stays boolean. Existing
fallback-default-base suite green (29/29). Usage-contract suite
enrolled (population 81); mirrored to the brain tree.
usage() default exit 2; semantic invocation checks (mutual exclusion,
integer/format validation, missing edit option, --login-only-for-Gitea)
exit 2; value guards on all value-taking options; existing pr-edit
suite still green; usage-contract suite enrolled (population 80);
mirrored to the brain tree.
- issue-create: usage() default exit is now 2 (usage-error contract);
unknown option, missing title, and value-less -t/-b/-l/-m land there
with stderr messages; exit-code line added to help. Interactive
-i/--interactive unchanged (boolean, no value arm). Existing
body-safety and interactive-auth suites still green.
- Template bug fixed across ALL seven usage-contract suites:
expect_stderr referenced an unbound $desc (should be $2); latent
until issue-create's capitalized 'Unknown option' missed the
case-sensitive grep and fired it. All seven re-verified green.
- Suite enrolled (population 79); mirrored to the brain tree.
issue-edit already used long-flag-first parsing; this adds the rc=2
usage-error contract (unknown option, missing -i, value-less flags
across all five options), the exit-code line in help, and the enrolled
usage-contract suite (population 78). Mirrored to the brain tree.
-b/--body canonical review comment flag with -c/--comment alias; usage
errors stderr + exit 2 (unknown option, missing -n/-a, value-less
flags including -a/-l/-r/-H, and the semantic check: request-changes
without a comment). Existing pr-review suites still green.
Suite enrolled in framework-shell CI (enumeration guard OK); mirrored
to the brain tree.
Same contract as issue-close (7a38eed1): -b/--body canonical comment
flag with -c/--comment alias; usage errors stderr + exit 2 (unknown
option, missing required, value-less flags); GitHub-path provider
failures normalized to exit 1.
Both new suites enrolled in framework-shell CI (enumeration guard OK,
population 76). pr-close's suite uses FAILING provider stubs (exit 99):
its API fallback treats a successful curl as a closed PR, so exit-0
stubs let sandbox arms succeed (measured); post-sandbox contact
assertions are correspondingly scoped, parser arms remain zero-contact.
Mirrored to the brain tree; all usage-contract suites green in both.
Same contract as issue-comment (PR #1462): -b/--body canonical comment
flag with -c/--comment alias; usage errors stderr + exit 2 (unknown
option, missing -i, value-less flags); provider failures normalized to
exit 1 on the GitHub path (gh's own usage errors exit 2 and would
collide with the reserved status).
New suite test-issue-close-usage-contract.sh, enrolled in
framework-shell CI (enumeration guard OK, population 74). Probe
assertions split: parser arms must contact zero providers; sandbox arms
may issue detection reads only (tea login list), never gh/curl.
Existing fail-closed suite still green. Mirrored to the brain tree.
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.
- docs/PRD.md: Part I product north star authored from ratified decisions
D1-D14; Part II preserves all active workstream contracts verbatim
(KBN-101, FCM #758, FCOM #766, TESS, #756, MOS-PORT, #1150, #1174, #1194,
RI #1275, M1). Referenced anchors unchanged.
- docs/archive/PRD-v0.1.md: v0.1.0 beta PRD body archived verbatim with
supersession header.
- docs/ROADMAP.md: all phases P0-P5 present from day one per D11
(P2-P5 as explicit placeholders).
- docs/requirements/native-kanban-sot.md: Amendment A1 (D13) - hierarchy
parentage + RBAC chain above workspaces; sections 1-7 untouched.