Commit Graph
9 Commits
Author SHA1 Message Date
jason.woltje 88d9cf750f feat(sessions): sessionForkFrom - branch conversations from a common ancestor (#33)
- task schema: optional sessionForkFrom (source session name); requires
  session target; self-fork rejected
- runner: resolves source newest .jsonl (fail 4 if none/outside dataRoot);
  passes MOSAIC_SESSION_FORK + MOSAIC_SESSION_DIR; result records lineage
- pi adapter: --fork <source> --session-dir <target> when forking;
  ephemeral default unchanged; plain session resume unchanged
- compose passthrough; RELEASE -> 0.0.7 (adapter changed)
- suite +9 cases (58 total): plumbing via mock stderr, validation
  negatives, live fork - child recalls ancestor code word, ancestor
  session file untouched

Closes #33
2026-09-03 06:43:02 -05:00
jason.woltje 88eef507b0 feat(retention): run-record pruning - keep newest N, dry-run default (#32)
- mosaic-task.mjs prune [--keep=N] [--yes]: default keep 50; without
  --yes lists candidates without deleting
- only r-* directories under the runs root; symlinks skipped;
  sessions/workspaces/state/config untouched (asserted by suite sentinels)
- append-only receipt runs/.pruned.log records every pruned id
- test-task.sh: +8 retention cases (dry-run no-delete, keep-N, newest
  kept, receipt, isolation, invalid keep, empty no-op)

Also: suite hardening - prune section scopes its config per-command
(no export/unset leaking into later sections); duplicated check()
removed; latest_reason hoisted to helpers; status colors now green OK /
red FAIL (terminal-only, NO_COLOR-aware) per owner UX feedback.

Closes #32
2026-09-03 06:33:27 -05:00
jason.woltje 439bea6915 ui(test): green OK/PASS, red FAIL - terminal-only, NO_COLOR-aware
Owner feedback: grep match-highlighting made the word 'policy' red while
status words were plain - counter-indicative. Suites + verify now emit
ANSI colors (green success, red failure) when stdout is a terminal;
piped/machine-parsed output stays plain, honoring NO_COLOR. Word 'ok'
promoted to 'OK' for scannability.

Verified byte-level via forced-pty run; piped output unchanged; suites
41/24/14 + verify green.
2026-09-03 06:23:47 -05:00
jason.woltje 2ff49adff4 feat(policy): mission-level capability policy - least-privilege intersection (#30)
- mission schema: optional capabilities.tools (same validation as task)
- merge semantics in runTask: neither -> none; mission only -> mission;
  task only -> task; both -> intersection (task narrows, never widens);
  empty intersection -> tool-free run with an explicit stderr note
- result.json records EFFECTIVE tools; task/mission snapshots remain the
  immutable declaration of intent
- adapters unchanged; host-side only (no image change, 0.0.6 still active)
- task suite +5 cases (41 total): all four merge cases asserted from run
  evidence + invalid mission capabilities rejected

Policy decision recorded: missions govern; tasks cannot escalate.

Closes #30
2026-09-03 06:16:01 -05:00
jason.woltje afd5827db8 fix(retry): lineage tracking + relative mission path resolution (#28)
- retryRun rewrites a snapshot's relative mission path to the run's own
  recorded mission.json (absolute) before execution — retries stay
  faithful to what originally ran
- runTask accepts options.retriedFrom; retry records lineage in
  result.json (additive optional field, no schema break)
- task suite +4 cases: retry succeeds, lineage recorded, mission section
  present after retry (36 total), missing-run retry exits 4

Closes #28
2026-09-03 05:30:57 -05:00
jason.woltje b017e66e17 test(capabilities): workspace/tooling selftests + live demo fixture (#21)
- mock plumbing cases: workspace path + tools delivered (asserted from
  run-record stderr), host workspace created, absent fields = empty vars
- validation negatives: unknown tool, workspace traversal
- tasks/workspace-demo.json: pi uses bash inside the persistent demo
  workspace; host-visible proof.txt verified live

Closes #21
2026-09-02 22:06:43 -05:00
jason.woltje 3c1ffd2c2d test(adapters): seam selftests — deterministic mock cases + mission injection (#18)
- test-config: absent adapter defaults to pi; mock validates; unknown
  adapter exits 2; env exports MOSAIC_ADAPTER (24 cases total)
- test-task: mock adapter gate pass/mismatch (no provider needed),
  mismatch reason asserted, unknown adapter fails closed, mission section
  injected into generated prompt asserted by content (24 cases total)
- harness fixes: helpers defined before use; per-case config files (no
  cross-case leakage); newest-run selection for the live case; deduped
  accidentally duplicated live block

Closes #18
2026-09-02 21:28:57 -05:00
jason.woltje 88f55d9135 test(task): live failures self-report evidence; wrong-exit no longer masks (#15)
- live hello failure dumps latest run result.json + stderr tail before
  sandbox cleanup destroys them
- wrong-expectExact case asserts reason == expect-mismatch (was: any
  exit 1, which masked compose-level failures)
- repair dangling if/else from the docker-guard refactor

Closes #15
2026-09-02 20:56:58 -05:00
jason.woltje cfd2a19bd7 test(task): mission/task selftests — schema negatives + live runs (#8)
18 cases: validation negatives (unknown keys, versions, ids, prompt,
expectExact NUL, timeout range, missing/invalid mission, writes-nothing)
plus live cases: exact-marker success, wrong expectExact fails, distinct
run dirs, result.json contents, list output.

Closes #8
2026-09-02 19:57:34 -05:00