mosaic comms: socket resolution is tool-owned (B2)
ci/woodpecker/pr/ci Pipeline failed
ci/woodpecker/manual/ci Pipeline is running

--socket forwards -L verbatim when given; when OMITTED the CLI sends
no -L at all and agent-send.sh's own resolution governs (explicit -L >
MOSAIC_TMUX_SOCKET > unique hit > ambiguity refusal, B1/PR #1466).
Measured design note: comms.ts was already correct by construction
after B1 — this change pins it with a spec arm (no -L forwarded when
--socket omitted) and makes the contract explicit in the option help,
so a future default-guess here cannot silently reintroduce the
stale-twin defect. Specs 7/7.
This commit is contained in:
2026-08-29 11:27:37 -05:00
parent 5125fe21b0
commit 6ad1f30d42
2 changed files with 15 additions and 1 deletions
@@ -15,6 +15,17 @@ import { afterEach, describe, expect, it } from 'vitest';
import { fleetCommsSendArgs, registerCommsCommand, tmuxSendArgs } from './comms.js'; import { fleetCommsSendArgs, registerCommsCommand, tmuxSendArgs } from './comms.js';
describe('arg translation', () => { describe('arg translation', () => {
// B2 (2026-08-29): when --socket is omitted, the CLI forwards NO -L and
// agent-send.sh's own resolution governs (explicit -L > MOSAIC_TMUX_SOCKET
// > unique hit > ambiguity refusal). Forwarding a guessed default here
// would defeat that resolution and reintroduce the stale-twin defect.
it('omits -L entirely when --socket is not given (tool-owned resolution)', () => {
const args = tmuxSendArgs('orch-01', 'hello', {});
expect(args).toEqual(['-s', 'orch-01', '-m', 'hello']);
expect(args).not.toContain('-L');
expect(args.join(' ')).not.toContain('-L');
});
it('tmux path: -s/-C/-L/-f/-m per agent-send.sh getopts', () => { it('tmux path: -s/-C/-L/-f/-m per agent-send.sh getopts', () => {
expect(tmuxSendArgs('orch-01', 'hello', {})).toEqual(['-s', 'orch-01', '-m', 'hello']); expect(tmuxSendArgs('orch-01', 'hello', {})).toEqual(['-s', 'orch-01', '-m', 'hello']);
expect( expect(
+4 -1
View File
@@ -62,7 +62,10 @@ export function registerCommsCommand(program: Command): void {
.description('send <target> [message...] — same-host tmux unless --site is given') .description('send <target> [message...] — same-host tmux unless --site is given')
.option('--class <class>', 'terminal-log | actionable | human | reaction | digest') .option('--class <class>', 'terminal-log | actionable | human | reaction | digest')
.option('--file <path>', 'message body from file (same-host path only)') .option('--file <path>', 'message body from file (same-host path only)')
.option('--socket <name>', 'tmux socket for the same-host send (e.g. mosaic-fleet)') .option(
'--socket <name>',
'tmux socket for the same-host send (e.g. mosaic-fleet). OMIT it to let agent-send.sh resolve the socket (explicit -L > MOSAIC_TMUX_SOCKET > unique hit; ambiguity refuses with its exit 4).',
)
.option('--site <site>', 'route via fleet-comms to <site>/<target>') .option('--site <site>', 'route via fleet-comms to <site>/<target>')
.option('--comms-repo <path>', 'fleet-comms checkout', defaultCommsRepo()) .option('--comms-repo <path>', 'fleet-comms checkout', defaultCommsRepo())
.argument('<target>', 'destination seat (session name)') .argument('<target>', 'destination seat (session name)')