Files
stack/docs/TOOLS.md
T
jason.woltje bf56583a49 docs(skills): owner loop-doctrine + collaborator delivery discipline, remediated (#44)
ms-communications: integrated as-authored - owner preamble restructure +
collaborator delivery-discipline hunks from the #43 calibration (own
session output is not a send path; the tool performs the preamble flip;
receiving rule 3 requires actually running agent-send.sh).

ms-conductor: collaborator redraft integrated (canon-aligned tracking
surfaces, one-action cadence, fail-closed core) with one conductor
remediation - step 3 now distinguishes refusal (fail closed, never
bypass) from runner outage (direct dispatch to a qualified live seat via
ms-communications permitted, recorded loudly as degraded: no sandbox, no
run record; suites still gate integration). Preserves the owner's
outage-dispatch intent inside invariant 6.

docs/TOOLS.md: release.sh ensure row added (M16 subcommand existed in
code but not in the doc - flagged by the collaborator, verified in
release.sh usage).

Authorship: owner (ms-conductor doctrine, preamble restructure) +
ms-test collaborator (delivery hunks, redraft); remediation + integration
by conductor (dragon-lin:darkwing). Suites 24/74/14/17 + verify green;
unslop clean.
2026-09-03 17:17:29 -05:00

133 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TOOLS.md — command and tool reference
On-demand reference for agent sessions (conductors, bootstrapping agents,
reviewers). `AGENTS.md` routes here; this file carries the depth: usage,
inputs/outputs, exit codes, and safety notes for every entry point.
Reading guide: system entry points are `scripts/*.sh` (bash) or invoked via
`node scripts/mosaic-task.mjs` (node). Host-side helpers under `tools/`
(tmux messaging, watchers, prose checker) are covered under Tools
(host-side) below. Every script fails closed — missing
or invalid configuration/policy refuses the operation with a nonzero exit
and changes nothing.
## Lifecycle
| Command | Purpose | Notes |
|---|---|---|
| `scripts/bootstrap.sh` | Create `~/.config/mosaic-dev/config.json` if absent | Idempotent; existing config validated, never rewritten |
| `scripts/build.sh` | Build the release image | Tag derived from `RELEASE` + pinned pi version |
| `scripts/hello.sh` | One-shot startup request | Prints model response on stdout |
| `scripts/verify.sh` | Full gated test | Exit 0 only on exact `MOSAIC_HELLO_OK`; `EXPECTED_MARKER` overrides for negative drills |
## Tasks (missions, runs, evidence)
| Command | Purpose | Notes |
|---|---|---|
| `scripts/run-task.sh run <task.json>` | Execute a task | Immutable run record under `<dataRoot>/runs/` |
| `scripts/run-task.sh validate <task.json>` | Strict validation | Writes nothing |
| `node scripts/mosaic-task.mjs show <runId>` | Inspect a run | Full record + snapshots + artifacts |
| `node scripts/mosaic-task.mjs list` | List runs | task/workspace/session columns |
| `node scripts/mosaic-task.mjs retry <runId>` | Re-execute a run's snapshot | New run dir; `retriedFrom` lineage recorded |
| `node scripts/mosaic-task.mjs prune [--keep=N] [--yes]` | Retention | Dry-run default; receipt in `runs/.pruned.log` |
Task fields: `prompt` (required), `mission` (path), `expectExact`,
`timeoutSeconds` (5600), `workspace` (`:run` or named), `capabilities.tools`
(allowlist: read write edit bash grep find ls), `session`,
`sessionForkFrom` (requires `session`). Mission fields: `objective`,
`directives[]`, optional governing `capabilities.tools`. Policy: a task may
narrow a mission's tools, never widen; empty intersection = tool-free run.
## Agent (interactive TUI)
```bash
scripts/agent.sh <name> [--mission <file>] [--workspace <ws>] [--session <s>] [--tools <list>]
```
Launches an interactive pi TUI inside the container with the four immutable
contracts + optional mission + agent identity as its system prompt,
persistent named session, optional workspace. Exit with `/quit`.
## Release
| Command | Purpose | Notes |
|---|---|---|
| `scripts/release.sh package` | Build + tag the release image | Tag: `mosaic-poc-agent:<pi>-r<release>` |
| `scripts/release.sh activate` | Health gate → atomic pointer swap | `--fault-injection` proves the refusal path |
| `scripts/release.sh rollback` | Health-gated return to previous | Refuses if image missing |
| `scripts/release.sh status` | Release, tag, active pointer, log | Safe on empty state |
| `scripts/release.sh ensure` | Self-determination: align active pointer to `RELEASE` | Fast path restores a missing/mismatched pointer without a gate; slow path packages + health-gates first. Invoked automatically at launch |
## Conductor (worker patches)
```bash
scripts/conductor-apply.sh <runId> [--dry-run]
```
Auto-applies a worker's patch under `roles/conductor-policy.json`:
succeeded run → clean target tree → path allowlist → syntax gates →
apply → policy suites → attribution commit. Any failure reverts.
Push is never automatic.
## Maintenance
| Command | Purpose | Notes |
|---|---|---|
| `scripts/reset.sh` | Delete the data root | Triple-safety-checked (path, symlink, ownership marker) |
| `scripts/test-config.sh` | Config selftests (no Docker) | 24 cases |
| `scripts/test-task.sh` | Task selftests + live cases | 74 cases |
| `scripts/test-release.sh` | Release selftests | 14 cases |
| `scripts/test-conductor.sh` | Auto-apply selftests (sandboxed) | 17 cases |
| `scripts/gitea-api.sh <METHOD> <path> [body]` | Gitea API helper | Token never on argv/stdout |
## Tools (host-side)
Host-side helpers under `tools/`, outside the `scripts/` command surface.
Per-tool READMEs: `tools/tmux/README.md` and `tools/unslop-hook/README.md`.
| Command | Purpose | Notes |
|---|---|---|
| `tools/tmux/agent-send.sh` | Inter-agent tmux message with addressing preamble | Reliable submit (bracketed paste, Enter flush, draft detection); ships `send-message.sh` over ssh for remote panes (remote needs only bash + tmux + base64) |
| `tools/agent-watch/agent-watch.sh` | Condition watcher per agent seat | One transient systemd `--user` timer + service per watch; fires `agent-send.sh` when the condition command exits 0 |
| `node tools/unslop-hook/unslop-check.js <file>` | Mechanical AI-tell prose check | Dependency-free node CLI + module driven by `lists.json`; `extension.ts` is the pi extension wrapper |
`agent-send.sh` prepends the preamble
`[<src_host>:<src_session> -> <dst_host>:<dst_session>]`; `-C`/`--class` adds
a ` class=<CLASS>` token (`terminal-log`, `actionable`, `human`, `reaction`,
`digest`; consumers treat an absent class as `actionable`). Flags: `-s` dst
session (required) · `-H` ssh target for a remote pane · `-L` named tmux
socket · `-n` dst hostname for the preamble · `-m`/`-f`/stdin message body ·
`-S` source-label override · `-r N` Enter-flush attempts (default 2) · `-v`
verbose · `-h` help. Exit codes: `0` delivered/queued · `1` target not found ·
`2` still draft · `3` usage error · `4` ambiguous socket (the session exists
on more than one tmux server; disambiguate with `-L` or `MOSAIC_TMUX_SOCKET`).
`agent-watch.sh` subcommands: `start --name <id> --session <session> --when
'<shell command; exit 0 = met>' --message <text>` with `--class`,
`--interval` (default 30), `--timeout` (default 3600), `--repeat`,
`--quiet-timeout`, `--socket` · `list` · `status [--json]` · `stop <name>` ·
`log <name>` · `meta-install [--interval 300] [--unit-name <unit>]` ·
`meta-remove [--unit-name <unit>]`. Interval floor is 10s (a watcher is a
fallback cadence, never a tight poll); hidden `_tick`/`_scan` subcommands run
inside the systemd services. `status` exit codes: `0` clean · `3` any stale
watch or dead meta-watch · `6` systemd user bus unreachable. Delivery goes
through `agent-send.sh`; rc `2` means the text reached the pane as an
unsubmitted draft, which counts as delivered and is not retried (other
failures retry twice, then the watch gives up). Watches are one-shot by
default; `--repeat` re-arms. Notices carry a `[watch:<name>]` prefix.
`unslop-check.js` checks a file (or stdin) against the word, phrase,
punctuation-density, and pattern lists in `lists.json`, stripping fenced and
inline code first so a quoted mention never flags. Invocation:
`node tools/unslop-hook/unslop-check.js <file>`; `UNSLOP_LISTS=<path>`
overrides the lists location. Exit codes: `0` clean · `1` violations (findings
printed as JSON on stdout) · `2` gate broken (invalid lists or unreadable
input; error on stderr, never a clean verdict).
## Exit-code convention
`0` success · `1` operation failed · `2` invalid data/configuration ·
`3` configuration missing for a read operation · `4` usage/file/environment
problem. Scripts print diagnostics on stderr; model responses (and only
model responses) on stdout.