OK valid task validates (exit 0) OK unknown task key exits 2 (exit 2) OK unsupported taskVersion exits 2 (exit 2) OK invalid task id exits 2 (exit 2) OK empty prompt exits 2 (exit 2) OK NUL in expectExact exits 2 (exit 2) OK out-of-range timeout exits 2 (exit 2) OK missing mission file exits 4 (exit 4) OK task with valid mission validates (exit 0) OK invalid mission exits 2 (exit 2) OK validate missing task exits 4 (exit 4) OK validation does not modify the task file OK prune dry-run exits 0 (exit 0) OK dry-run deleted nothing OK prune --keep=2 --yes removes oldest (exit 0) OK kept exactly 2 newest runs OK newest run kept, oldest pruned OK append-only receipt written (3 entries) OK sessions/workspaces untouched by prune OK prune with invalid keep exits 4 (exit 4) OK mock adapter: gate passes on matching mock response (exit 0) OK mock adapter: expect-mismatch recorded (exit 1) OK mismatch reason recorded OK unknown adapter fails closed (exit 1) OK mission task runs via mock adapter (exit 0) OK mission section injected into generated prompt OK retry of mission run succeeds (exit 0) OK retriedFrom lineage recorded OK mission section present after retry (relative path resolved) OK retry of missing run exits 4 (exit 4) OK skill install bundled ms-tools (exit 0) OK installed to skills-available OK double install refuses (exit 1) OK activate enables skill (exit 0) OK enabled dir populated OK uninstall while enabled refuses (exit 1) OK deactivate moves back to available (exit 0) OK uninstall removes from available (exit 0) OK seat with enabled skill launches OK skill path delivered to adapter OK shipped researcher contract resolves (ceiling + network) OK resolve-role refuses a non-role document (conductor policy) (exit 2) OK resolve-role refuses name/filename mismatch (exit 2) OK resolve-role refuses unknown network declaration (exit 2) OK resolve-role refuses duplicate role tool (exit 2) OK resolve-role refuses unsupported tool (exit 2) OK resolve-role refuses missing contract file (exit 4) OK version 1 role prints no contract line OK shipped version 2 roles resolve with their contracts (pm, cto, coder, reviewer) OK resolve-role accepts a minimal version 2 role (exit 0) OK resolve-role refuses an action outside the vocabulary (exit 2) OK resolve-role refuses a gated-only action in a role file (exit 2) OK resolve-role refuses a Vikunja verb no role may hold (exit 2) OK resolve-role refuses a version 2 role whose contract is missing (exit 2) OK resolve-role refuses a contract that is a symbolic link (exit 2) OK seat launches under role ceiling OK role ceiling narrows seat tools (read,write,bash -> read,bash) OK narrowing recorded loudly OK missing role contract refuses launch (exit 2) OK missing-contract refusal names the role OK empty ceiling intersection -> tool-free seat OK tool-free outcome recorded loudly OK overridden agents dir without seat definition refuses (exit 4) OK seat-resolution refusal names the seat OK policy: mission only -> mission tools OK policy: task only -> task tools OK policy: both -> intersection (task narrowed) OK policy: empty intersection -> tool-free OK invalid mission capabilities rejected (exit 2) mosaic-task: unsupported mission tool: "sudo" (supported: read, write, edit, bash, grep, find, ls) OK task run with user layer present (exit 0) OK user context dispatched into generated prompt OK workspace+tools task runs via mock (exit 0) OK workspace path + tools delivered to adapter OK persistent workspace created on host OK plain task still runs (no workspace/tools) (exit 0) OK workspace var present but empty when absent OK tools empty when absent OK unknown tool exits 2 (exit 2) OK workspace traversal exits 2 (exit 2) OK live hello task succeeds with exact marker OK result.json written in run dir OK result.json contents are correct OK wrong expectExact fails with exit 1 (reason: expect-mismatch) OK each run gets a distinct run dir (no clobber) OK list shows both runs OK fork base: teach succeeds (exit 0) OK fork child recalls ancestor context (exit 0) OK forked child recalled ancestor code word OK ancestor session untouched by fork OK child session dir has its own branch file OK onboard without name exits 4 (non-interactive) (exit 4) OK onboard --name renders profile (exit 0) OK profile written OK canon structure: required filled, optional placeholdered OK canon sections present OK user recall run succeeds OK recalled user name (response: Jason) OK no agent identity on headless run selftest: 98 passed, 0 failed rc=0