E2E coverage matrix
The single feature×coverage inventory for iterion. One row per operator-observable promise, at the granularity a regression report would name it. Every row is terminal (covered-deterministic / covered-live / unit-only / excluded) or an honest uncovered gap with the plan.
A citation must be the test that would FAIL if the promise broke. The deterministic gate greps every reference, so it catches a citation that does not exist — it cannot catch one that exists but tests something else. Two adversarial audits sampled 70 rows and found 11 such mis-citations (mostly: a row citing the mechanics of a helper while the WIRING that invokes it went untested). When you touch a row, re-read the cited test and ask what its failure would actually mean.
This file supersedes the three partial coverage docs it reconciles:
- docs/e2e_coverage.md — the iterion×claw-code-go live matrix + the deliberate claw-side gaps (folded into the
backends,tools-mcpandobservabilityfamilies below). - docs/live-e2e-coverage.md — the opt-in real-LLM layer (how it works, the quality-judge panel, the per-bot targets). Still the reference for running the live layer; its bot/feature tables are mirrored here as
covered-liverows. - e2e/SCENARIOS.md — the flagship-workflow stub-executor scenarios (folded into
runtimeanddsl).
Legend
| Status | Meaning |
|---|---|
covered-deterministic | A CI-runnable, credential-free test drives the real seams and asserts observable outcomes |
covered-live | Only exercised in the opt-in live-tagged layer (needs a real model/credential) |
unit-only | Deliberately terminal at unit level — an e2e would only re-test the harness |
excluded | Not exercisable in this repo's harness (needs a third-party tenant / cloud control plane) |
uncovered | Real gap — backlog |
What "the front door" means per family
- dsl — the front door is
.botsource text: parse → compile → the diagnostic or IR an operator sees fromiterion validate. Rows whose behaviour only shows at execution time cite a runtime/e2e test instead. - runtime — the public engine API (
runtime.Engine.Run/Resume) against a realstore.RunStore, asserting persisted status, checkpoint, artifacts and the event stream.e2e/additionally enters through.botfixtures. - cli —
cli.Run*entry points with a real store and (where an LLM would be involved) a stubruntime.NodeExecutorinjected at the documented seam. - server-api / cloud —
httptestagainst the real wired handler. - studio-ui — Playwright (
studio/e2e/,task test:e2e:ui) drives a real Chromium against the REAL server: the builtiterionbinary serving the embedded SPA over a throwaway store thatstudio/e2e/serve.mjsseeds with genuine artifacts — runs the engine actually executed (tool + compute fixtures, no LLM credential) and a board card created through the CLI. The suite asserts rendered content and interactions, never HTTP status codes. It is deliberately NOT wired into the blocking CI job yet (the browser download is opt-in;task test:e2e:uiskips cleanly without it).
Scope of the current campaign
Pass 1 built this inventory and closed the highest-value CLI quick wins (run --preset, run --max-*, secret, runs questions|answer, report). Pass 2 closed the remaining CLI quick wins: issue, diagram, skill, memory, run --recipe. Pass 3 closed the four CLI rows earlier passes had written off as needing a seam or a live model — the cli family is now terminal end to end. Each turned out to have a deterministic front door:
run --model/--backend— drive the REAL executor at fixtures whose backend/model cannot resolve; the failure text quotes whichever value won the resolution chain, offline.run --auto-resume— the loop's only wait is the reset-aware USAGE_LIMIT_BLOCKED delay, and the run's own retry policy clamps it, so a 1ms horizon removes the sleep without a clock seam.bench asymptote— the command re-runs nothing; stub-driven runs of a judge-in-a-loop fixture supply the exact events it parses.dispatch— boot the daemon in-process on a loopback port, assert the served surface, stop it with SIGTERM.
Everything still uncovered is deliberate backlog for later scoped runs, family by family. What is left, and why it is not a quick win:
Pass 5 introduced the browser harness the studio-ui family was waiting on and closed its rows (see the family note above).
Pass 4 closed the three remaining cloud rows — dlq, migrate-blobs, valkey-state — which earlier passes had written off as needing a live Mongo/S3/Valkey. Each had a deterministic front door after all:
valkey-state— two servers built through the realNew()wiring over one miniredis; each flow starts on replica A and finishes on replica B.migrate-blobs— the walker between two real stores, plus the real AWS SDK against an in-process path-style S3 gateway.dlq— the admin REST surface behind a narrowQueueBackendseam; the JetStream-side semantics split out ascloud.dlq-jetstream(excluded, no vendored broker).
| ID | Feature | Family | Status | Tests | Notes |
|---|---|---|---|---|---|
| dsl.node-agent | agent node: LLM node with structured I/O executes and publishes | dsl | covered-deterministic | TestSingleModel_HappyPath (e2e/e2e_test.go) | |
| dsl.node-judge | judge node: verdict-producing LLM node | dsl | covered-deterministic | TestSingleModel_HappyPath (e2e/e2e_test.go) | |
| dsl.node-tool | tool node: direct shell command, no LLM | dsl | covered-deterministic | TestExecutorToolNodeShellCommand (pkg/backend/model/executor_test.go), TestToolNodeShellMaterializesSecret (pkg/backend/model/secrets_materialize_test.go) | the shell path needs the REAL executor: the e2e scenario stub replaces every node — agent and tool alike — so a tool node rerouted through the LLM path would still pass there |
| dsl.node-compute | compute node: deterministic expression output | dsl | covered-deterministic | TestToolAndComputePublishArtifact (pkg/runtime/engine_test.go) | |
| dsl.node-human | human node: pause/resume with interaction record | dsl | covered-deterministic | TestCompliance_HumanGate (e2e/e2e_test.go) | |
| dsl.node-subbot | subbot node: nested child run, outputs read back | dsl | covered-deterministic | TestRunSubbotsPersistNestedLineage (pkg/cli/run_subbot_test.go) | |
| dsl.node-emit-wait | emit/wait: in-bot event pair with mandatory timeout | dsl | covered-deterministic | TestEventsEmitWait (e2e/events_emit_wait_test.go) | |
| dsl.node-await-answers | await_answers node parks its branch until answers land | dsl | covered-deterministic | TestAwaitAnswersReleasedByAnswer (e2e/async_interaction_test.go) | |
| dsl.node-done | done terminal node ends the run finished | dsl | covered-deterministic | TestSingleModel_HappyPath (e2e/e2e_test.go) | |
| dsl.node-fail | fail terminal node ends the run non-resumable failed | dsl | covered-deterministic | TestFailNode (pkg/runtime/engine_test.go) | |
| dsl.router-fan-out-all | router fan_out_all spawns parallel branches | dsl | covered-deterministic | TestDualParallel_HappyPath (e2e/e2e_test.go) | |
| dsl.router-fan-out-each | router fan_out_each: per-item branches with a dep DAG | dsl | covered-deterministic | TestFanOutEach_DAG_DiamondOrderingAndParallelism (pkg/runtime/fan_out_each_test.go) | |
| dsl.router-condition | router condition mode picks the matching edge | dsl | covered-deterministic | pkg/dsl/ir/validate_test.go, TestElseEdge_Routing (pkg/runtime/else_edge_test.go) | |
| dsl.router-round-robin | router round_robin alternates targets across iterations | dsl | covered-deterministic | pkg/runtime/round_robin_test.go | |
| dsl.router-llm | router llm mode: model picks the route | dsl | covered-deterministic | TestLLMRouterSelectsOtherRoute (pkg/runtime/llm_router_test.go) | |
| dsl.edges-conditional | edge when / when not conditions on a boolean output field | dsl | covered-deterministic | TestSingleModel_RefineLoop (e2e/e2e_test.go) | |
| dsl.edges-else | edge else fires only when no sibling when matched | dsl | covered-deterministic | TestElseEdge_PreferredOverStrayUnconditional (pkg/runtime/else_edge_test.go) | |
| dsl.edges-loop | bounded loop edge as name(n) | dsl | covered-deterministic | TestBoundedLoop (pkg/runtime/engine_test.go) | |
| dsl.edges-loop-templated-cap | loop cap templated from an upstream output | dsl | covered-deterministic | TestLoopTemplatedCap_FromOutput (pkg/runtime/engine_test.go) | |
| dsl.edges-data-mapping | edge with {…} data mapping and reference interpolation | dsl | covered-deterministic | TestResolveMapping_InterpolatesSurroundingLiterals (pkg/runtime/engine_resolve_mapping_test.go) | |
| dsl.refs | reference syntax: input/vars/outputs/artifacts substitution | dsl | covered-deterministic | pkg/dsl/ir/ref_test.go | |
| dsl.vars-defaults | vars: defaults applied when no override is supplied | dsl | covered-deterministic | pkg/dsl/ir/validate_var_default_test.go | |
| dsl.vars-enum | vars: enum constraint rejects an out-of-set value at launch | dsl | covered-deterministic | TestRunRejectsInvalidEnumVar (pkg/runtime/engine_var_enum_test.go) | |
| dsl.presets | in-source presets: block resolves named value sets | dsl | covered-deterministic | pkg/dsl/ir/presets_test.go | CLI wiring covered by cli.run-preset |
| dsl.prompts | prompt <name>: blocks and prompt includes | dsl | covered-deterministic | pkg/dsl/ir/prompt_include_test.go | |
| dsl.schemas | schema <name>: typed node output contracts | dsl | covered-deterministic | pkg/backend/model/schema_test.go | |
| dsl.cursors | cursor <name>: calibration fragments reach the system prompt | dsl | covered-deterministic | TestBuildSystemPromptCursorsOnly (pkg/backend/delegate/cursors_test.go), pkg/backend/model/cursors_test.go, pkg/dsl/ir/cursor_resolve_test.go | |
| dsl.attachments | attachments: block: files resolved and passed to nodes | dsl | covered-deterministic | pkg/dsl/ir/attachments_test.go, pkg/runtime/attachment_path_test.go | |
| dsl.skills-field | skills: field pulls library skills into the run mirror | dsl | covered-deterministic | pkg/dsl/ir/validate_skills_test.go, pkg/runtime/library_skills_test.go | |
| dsl.mcp-server-block | mcp_server: block declares stdio/http/sse MCP servers | dsl | covered-deterministic | TestMCPServer_SSETransport (pkg/dsl/parser/parser_mcp_test.go) | |
| dsl.capabilities | capabilities: list opens the board tool surface | dsl | covered-deterministic | pkg/dsl/ir/validate_capabilities_test.go, TestBoardDispatcher_E2E_CapabilityGate (e2e/board_dispatcher_test.go) | |
| dsl.supervisor-block | supervisor <name>: declaration compiles and spawns a coordinator | dsl | covered-deterministic | pkg/dsl/ir/compile_supervisors_test.go, pkg/supervise/coordinator_test.go | |
| dsl.compress-field | compress: precedence (CLI → node → workflow → env → default) | dsl | covered-deterministic | TestResolveWithDefault (pkg/backend/rewrite/rewrite_test.go), TestResolveWithDefaultSourced (pkg/backend/rewrite/rewrite_test.go), pkg/dsl/ir/compress_test.go | |
| dsl.auto-memory-field | auto_memory: per-node MEMORY.md switch, off by default | dsl | covered-deterministic | pkg/dsl/ir/auto_memory_test.go, pkg/backend/model/executor_auto_memory_test.go | |
| dsl.permission-field | permission: mode + allow/ask/deny rule lists | dsl | covered-deterministic | pkg/dsl/ir/permission_test.go, pkg/backend/permission/permission_test.go | |
| dsl.budget-block | budget: block fields compile onto the workflow | dsl | covered-deterministic | pkg/dsl/ir/budget_ceiling_test.go | |
| dsl.sandbox-block | sandbox: block (image/build/network/host_state) compiles | dsl | covered-deterministic | pkg/dsl/ir/sandbox_test.go, pkg/dsl/parser/parser_sandbox_test.go | |
| dsl.worktree-field | worktree: mode default resolution | dsl | covered-deterministic | pkg/dsl/ir/worktree_default_test.go | |
| dsl.session-modes | session modes (fresh / inherit / artifacts_only) | dsl | covered-deterministic | TestSessionInherit (pkg/runtime/session_test.go), TestSessionFork (pkg/runtime/session_test.go), TestSessionInheritIfAvailable_FallsBackToFreshWhenNoSession (pkg/runtime/session_test.go) | the modes are a RUNTIME behaviour; pkg/backend/model/session_test.go is the session store (persistence + compaction), a different contract |
| dsl.secrets-block | secrets: declarations + optional-secret semantics | dsl | covered-deterministic | pkg/dsl/ir/secrets_test.go, pkg/dsl/ir/optional_secret_test.go | |
| dsl.memory-block | memory: block scopes/visibility validation | dsl | covered-deterministic | pkg/dsl/ir/memory_visibility_test.go | |
| dsl.verified-action | Verified Action quad (goal/postcondition/policy/recovery) | dsl | covered-deterministic | TestVerifiedActionEngineEmitsAndStrips (e2e/verified_action_test.go) | |
| dsl.groups-iteration | group: expansion / iteration sugar | dsl | covered-deterministic | pkg/dsl/ir/expand_groups_test.go, pkg/dsl/ir/foreach_test.go | |
| dsl.diagnostics | compile diagnostics C001–C2xx codes and severities | dsl | covered-deterministic | pkg/dsl/ir/diag_codes_test.go, TestValidate_Invalid (pkg/cli/cli_test.go) | |
| dsl.unparse-roundtrip | IR → .bot serialization round-trips | dsl | covered-deterministic | pkg/dsl/unparse/roundtrip_test.go | |
| dsl.ast-json | AST JSON encode/decode (MarshalFile/UnmarshalFile) | dsl | covered-deterministic | pkg/dsl/ast/jsonenc_test.go | |
| dsl.expr | expression evaluator for compute nodes and when conditions | dsl | unit-only | pkg/dsl/expr/expr_test.go, pkg/dsl/expr/overflow_test.go | pure evaluator, exhaustively asserted at unit level; its e2e effect is already covered by dsl.node-compute — an extra pipeline test would re-assert a pure function |
| dsl.parser-fuzz | lexer/parser robustness on malformed input | dsl | unit-only | pkg/dsl/parser/fuzz_test.go | fuzzing is by nature a unit-level property test; the operator-visible surface (a diagnostic, not a panic) is dsl.diagnostics |
| runtime.linear-execution | sequential node execution to a terminal node | runtime | covered-deterministic | TestLinearPath (pkg/runtime/engine_test.go) | |
| runtime.await-wait-all | convergence await: wait_all waits for every branch | runtime | covered-deterministic | TestDualParallel_HappyPath (e2e/e2e_test.go) | |
| runtime.await-best-effort | convergence await: best_effort proceeds on partial branches | runtime | covered-deterministic | TestChaos_FailMidFanOut_BestEffort (pkg/runtime/chaos_test.go) | |
| runtime.local-loop | local loop re-executes and versions artifacts | runtime | covered-deterministic | TestSingleModel_RefineLoop (e2e/e2e_test.go) | |
| runtime.global-reloop | global reloop restarts the recipe from an upstream node | runtime | covered-deterministic | TestSingleModel_GlobalReloop (e2e/e2e_test.go) | |
| runtime.loop-exhaustion | loop cap exhaustion fails the run with LOOP_EXHAUSTED | runtime | covered-deterministic | TestCIFix_LoopExhaustion (e2e/e2e_test.go), TestLoopExhaustionRuntimeError (pkg/runtime/hardening_test.go) | |
| runtime.budget-cost | max_cost_usd exceeded stops the run and emits budget_exceeded | runtime | covered-deterministic | TestBudgetCostExceeded (pkg/runtime/budget_test.go) | |
| runtime.budget-tokens | max_tokens exceeded stops the run | runtime | covered-deterministic | TestBudgetTokensExceeded (pkg/runtime/budget_test.go) | |
| runtime.budget-duration | max_duration exceeded stops the run | runtime | covered-deterministic | TestBudgetDurationExceeded (pkg/runtime/budget_test.go) | |
| runtime.budget-warning | budget warning event at the soft threshold, advisory only | runtime | covered-deterministic | TestBudgetWarningEmitted (pkg/runtime/budget_test.go), TestWarnTokensAdvisoryNeverBlocks (pkg/runtime/budget_test.go) | |
| runtime.budget-shared | budget accounting shared across parallel branches | runtime | covered-deterministic | TestBudgetSharedFirstComeFirstServed (pkg/runtime/budget_test.go) | |
| runtime.max-parallel-branches | max_parallel_branches semaphore bounds concurrency | runtime | covered-deterministic | TestFanOutEach_DAG_BoundedParallelism (pkg/runtime/fan_out_each_test.go) | |
| runtime.workspace-safety | only one mutating branch may run concurrently | runtime | covered-deterministic | TestWorkspaceSafetyRejectsDualMutation (pkg/runtime/budget_test.go) | |
| runtime.checkpoint | a checkpoint is saved after every successful node | runtime | covered-deterministic | TestCheckpointPreservesUpstreamOutputs (pkg/runtime/engine_test.go) | |
| runtime.resume-failed | resume from failed_resumable restarts at the failing node | runtime | covered-deterministic | TestResumeFromFailed (pkg/runtime/engine_test.go), TestResumeDoesNotReplayUpstream (pkg/runtime/engine_test.go) | |
| runtime.resume-hash-guard | resume refuses a changed .bot unless --force | runtime | covered-deterministic | TestForceResumeBypassesHashCheck (pkg/runtime/engine_test.go), pkg/runview/service_resume_hash_test.go | |
| runtime.resume-human | resume a paused_waiting_human run with answers | runtime | covered-deterministic | TestHumanPauseAndResume (pkg/runtime/engine_test.go), TestResume_Success (pkg/cli/cli_test.go) | |
| runtime.cancel | cancellation produces a cancelled status with a checkpoint | runtime | covered-deterministic | TestCancelProducesCancelledStatus (pkg/runtime/hardening_test.go) | |
| runtime.timeout | outer deadline produces a TIMEOUT failure | runtime | covered-deterministic | TestTimeoutProducesFailedStatus (pkg/runtime/hardening_test.go) | |
| runtime.interaction-modes | human interaction: llm / llm_or_human / async escalation | runtime | covered-deterministic | TestInteractionLLMOrHumanEscalation (pkg/runtime/engine_test.go), TestInteractionLLMAutoRespond (pkg/runtime/engine_test.go) | |
| runtime.ask-user-conversation | ask_user relays prior Q/A and persists the conversation | runtime | covered-deterministic | TestInteractionAskUserPersistsConversation (pkg/runtime/engine_test.go) | |
| runtime.worktree-finalize | worktree: auto creates a branch and fast-forwards the checkout | runtime | covered-deterministic | pkg/runtime/worktree_test.go | |
| runtime.rewind | iterion rewind re-anchors a run and invalidates downstream state | runtime | covered-deterministic | TestRewindThenResume_SkipsUpstreamNodes (e2e/rewind_resume_test.go) | |
| runtime.rewind-workspace | rewind restores workspace files for non-worktree runs, scoped to what the run recorded changing (issue #380) | runtime | covered-deterministic | TestRewindRestoresWorkspaceEndToEnd (e2e/rewind_workspace_test.go) | |
| runtime.rewind-workspace-failed-node | a node that dies mid-execution still has its debris undone, via the fail: boundary | runtime | covered-deterministic | TestRewindScopeCoversAFailedNodesDebris (e2e/rewind_workspace_test.go) | |
| runtime.rewind-workspace-stop-window | edits made while a run is stopped (fail → triage → resume, a human gate, a delegate ask_user pause) are not attributed to the run | runtime | covered-deterministic | TestRewindAfterResumeKeepsTriageEdits, TestRewindScopeAfterHumanGatePause, TestRewindScopeAfterDelegatePause (e2e/rewind_workspace_test.go) | |
| runtime.fork | fork a run at a prior LLM turn into a resumable child run | runtime | covered-deterministic | pkg/runview/fork_test.go | |
| runtime.event-stream | event sequence coherence (ordering, pairing, monotonic seq) | runtime | covered-deterministic | TestEventSequenceCoherence (e2e/e2e_test.go) | |
| runtime.artifact-versioning | repeated node executions version their artifacts | runtime | covered-deterministic | TestSingleModel_GlobalReloop (e2e/e2e_test.go) | |
| runtime.publish-gate | only a publish:-declared node leaves an artifact | runtime | covered-deterministic | TestOnlyAPublishedNodeLeavesAnArtifact (e2e/handoff_publish_test.go) | |
| runtime.skills-mirror | bundle/plugin/library skills mirrored into .claude/skills/ | runtime | covered-deterministic | TestMirrorBundleSkills_CopiesIntoClaudeSkills (pkg/runtime/bundle_test.go) | |
| runtime.devbox-provision | a bot's/target's devbox.json is installed and put on PATH | runtime | covered-deterministic | TestEngineRun_HostDevbox_RepoProjectInstallsInPlace (pkg/runtime/devbox_host_test.go) | |
| runtime.subbot-depth-guard | nested subbot recursion depth guard | runtime | covered-deterministic | TestSubbotRunnerForCLI_RecursionDepthGuard (pkg/cli/subbot_nested_test.go) | |
| runtime.supervisor | supervisor steers a watched node via the message inbox | runtime | covered-live | TestLive_Feat_Supervisor (e2e/live_feat_supervisor_test.go) | the composed steer decision is LLM-driven (Coordinator → GenerateObjectDirect), so only the live layer exercises the full watch→decide→inject path; the bricks are unit-tested (pkg/supervise/coordinator_test.go, pkg/backend/model/inbox_test.go) |
| runtime.recovery-dispatch | adaptive recovery ladder for verified action nodes | runtime | covered-deterministic | TestVerifiedActionEngineEmitsAndStrips (e2e/verified_action_test.go), pkg/backend/model/executor_verified_action_test.go | |
| runtime.privacy-redaction | secret/PII redaction across the run pipeline | runtime | covered-deterministic | TestE2E_PrivacyPipeline (e2e/privacy_test.go) | |
| persistence.run-json | run.json metadata, status transitions, format version | persistence | covered-deterministic | TestFormatVersionPersisted (pkg/runtime/hardening_test.go), pkg/store/store_test.go | |
| persistence.events-jsonl | events.jsonl append + monotonic seq + replay | persistence | covered-deterministic | pkg/store/store_test.go | |
| persistence.artifacts | versioned per-node artifacts under artifacts/ | persistence | covered-deterministic | pkg/store/store_test.go | |
| persistence.interactions | interaction records (questions/answers) persisted per run | persistence | covered-deterministic | TestAwaitAnswersAlreadyAnswered (e2e/async_interaction_test.go), pkg/store/store_test.go | |
| persistence.child-runs | parent/child run lineage for subbots | persistence | covered-deterministic | TestRunSubbotsPersistNestedLineage (pkg/cli/run_subbot_test.go) | |
| persistence.workspace-versioning | content-addressed workspace snapshots + restore | persistence | covered-deterministic | pkg/workspacetrack/native_test.go | |
| persistence.store-anchoring | store dir resolution (project .iterion vs $ITERION_HOME/projects) | persistence | covered-deterministic | TestStoreAnchorDir_BotInsideProjectResolvesProjectStore (pkg/cli/storeanchor_test.go) | |
| persistence.mongo-store | cloud Mongo-backed run store conformance | persistence | covered-deterministic | TestConformance_Mongo (pkg/store/mongo/conformance_test.go) | CI job mongo-conformance; skips without a Mongo endpoint. The board (kanban) Mongo store is a different contract — see dispatcher.native-tracker |
| cli.validate | iterion validate parses, compiles and reports diagnostics | cli | covered-deterministic | TestValidate_Valid (pkg/cli/cli_test.go), TestValidate_Invalid (pkg/cli/cli_test.go) | |
| cli.validate-bundle | iterion validate cross-checks a bundle manifest (C2xx) | cli | covered-deterministic | TestRunValidate_BundleVarTypoWarns (pkg/cli/validate_bundle_test.go) | |
| cli.run | iterion run executes a .bot and persists the run | cli | covered-deterministic | TestRun_Success (pkg/cli/cli_test.go) | |
| cli.run-vars | iterion run --var key=value overrides workflow vars | cli | covered-deterministic | TestRun_WithVars (pkg/cli/cli_test.go) | |
| cli.run-preset | iterion run --preset applies an in-source preset, --var wins over it | cli | covered-deterministic | TestRunPresetAppliesValuesAndVarWins (e2e/cli_launch_overrides_test.go) | |
| cli.run-budget-override | iterion run --max-* re-budgets the workflow for this run | cli | covered-deterministic | TestRunBudgetOverrideCapsTheRun (e2e/cli_budget_override_test.go) | |
| cli.run-model-backend-override | iterion run --model/--backend selector=… re-target nodes | cli | covered-deterministic | TestRunBackendOverrideRetargetsNodes (e2e/cli_model_backend_override_test.go), TestRunModelOverrideRetargetsNodes (e2e/cli_model_backend_override_test.go) | drives the REAL ClawExecutor (no stub) against fixtures whose backend/model cannot resolve, so the resolved value is readable from the failure text — credential-free and offline (unknown backend dies at registry lookup, unknown provider inside claw's spec parse) |
| cli.run-human-pause | iterion run returns at a human pause (--no-interactive) | cli | covered-deterministic | TestRun_HumanPause (pkg/cli/cli_test.go) | |
| cli.run-json | --json machine output mode for run | cli | covered-deterministic | TestRun_SuccessJSON (pkg/cli/cli_test.go) | |
| cli.run-recipe | iterion run --recipe <file> applies a recipe overlay | cli | covered-deterministic | TestRunRecipeAppliesPresetVarsAndVarStillWins (e2e/cli_recipe_test.go), TestRunRecipeBudgetOverridesTheWorkflowBudget (e2e/cli_recipe_test.go), TestRunRecipeRefusesAMismatchedWorkflow (e2e/cli_recipe_test.go), TestRunRecipeRefusesAnUnloadableFile (e2e/cli_recipe_test.go) | preset vars reaching the run, --var precedence over the recipe, workflow_ref.path resolving the .bot, the recipe budget changing the run outcome, and the mismatch/unloadable refusals |
| cli.run-auto-resume | --auto-resume N re-drives a retryable failed_resumable run | cli | covered-deterministic | TestRunAutoResumeRecoversRetryableFailure (e2e/cli_auto_resume_test.go), TestRunAutoResumeStaysOffByDefault (e2e/cli_auto_resume_test.go), TestRunAutoResumeRefusesNonRetryableCause (e2e/cli_auto_resume_test.go), TestRunAutoResumeStopsAtTheAttemptBudget (e2e/cli_auto_resume_test.go) | no clock seam needed: a USAGE_LIMIT_BLOCKED cause takes the reset-aware wait, which the run's own Retry policy (the field iterion schedule sets) clamps — a 1ms horizon collapses it, so the whole suite runs in <0.5s |
| cli.resume | iterion resume continues a paused/failed/cancelled run | cli | covered-deterministic | TestResume_Success (pkg/cli/cli_test.go) | |
| cli.resume-answers-file | iterion resume --answers-file / --answer @file | cli | covered-deterministic | TestResolveFileAnswerFlags_AttachesLocalFile (pkg/cli/resume_file_answers_test.go), TestParseAnswersFile (pkg/cli/cli_test.go) | |
| cli.resume-subbot | resume a run that owns subbot children | cli | covered-deterministic | TestResume_RunWithSubbot (pkg/cli/resume_subbot_test.go) | |
| cli.inspect | iterion inspect lists runs and shows a run's state | cli | covered-deterministic | TestInspect_ListRuns (pkg/cli/cli_test.go), TestInspect_SingleRun (pkg/cli/cli_test.go) | |
| cli.inspect-events | iterion inspect --events renders the stored event stream | cli | covered-deterministic | TestInspect_WithEvents (pkg/cli/cli_test.go) | |
| cli.inspect-node | iterion inspect --node per-node trace/artifacts/log sections | cli | covered-deterministic | TestInspect_SectionTrace (pkg/cli/cli_test.go), TestInspect_SectionArtifactsIncludesBody (pkg/cli/cli_test.go) | |
| cli.report | iterion report renders a run's chronological markdown report | cli | covered-deterministic | TestReportRendersChronologicalRunReport (e2e/cli_report_test.go), TestReportHonoursOutputPathAndJSON (e2e/cli_report_test.go) | |
| cli.diagram | iterion diagram emits a Mermaid graph for a .bot | cli | covered-deterministic | TestDiagramRendersEveryNodeAndEdgeOfTheWorkflow (e2e/cli_diagram_test.go), TestDiagramViewsDifferAndUnknownViewIsRefused (e2e/cli_diagram_test.go), TestDiagramJSONCarriesTheRenderedGraph (e2e/cli_diagram_test.go) | every node + edge of e2e/testdata/diagram_mini.bot, the condition/loop/mapping labels, the compact↔detailed↔full deltas, and the typo'd --view refusal |
| cli.runs-prune | iterion runs prune age/status/keep-last retention + dry-run | cli | covered-deterministic | TestRunPrune_AgeFiltering (pkg/cli/runs_prune_test.go), TestRunPrune_DryRunDeletesNothing (pkg/cli/runs_prune_test.go) | |
| cli.runs-async-questions | iterion runs questions / runs answer drive an async question to delivery | cli | covered-deterministic | TestRunsQuestionsThenAnswerReleasesAwaitGate (e2e/cli_async_questions_test.go), TestRunsAnswerRejectsBadInput (e2e/cli_async_questions_test.go) | |
| cli.fork | iterion fork creates a resumable fork at a prior turn | cli | covered-deterministic | pkg/runview/fork_test.go | CLI layer is a thin wrapper over runview.Service.Fork |
| cli.rewind | iterion rewind (incl. --auto bot-diff targeting) | cli | covered-deterministic | TestRewind_RefusesRunningRun_E2E (e2e/rewind_resume_test.go) | |
| cli.import | iterion import lowers a Claude-Code workflow script to a draft .bot | cli | covered-deterministic | TestRunImport_WritesDraft (pkg/cli/import_test.go) | |
| cli.bots-list | iterion bots list discovers .bot/.botz bundles | cli | covered-deterministic | TestBotsList_Bundle (pkg/cli/bots_test.go) | |
| cli.bots-create | iterion bots create scaffolds a discoverable bundle | cli | covered-deterministic | TestBotsCreate_ProducesDiscoverableBundle (pkg/cli/bots_create_test.go) | |
| cli.bots-regen-catalog | iterion bots regen-catalog regenerates Nexie's catalog skill | cli | covered-deterministic | bots/catalog_freshness_test.go | |
| cli.bundle-pack | iterion bundle pack produces a loadable .botz | cli | covered-deterministic | TestBundle_SecAuditSource_PackOpenCompile (e2e/bundle_sec_audit_source_test.go) | |
| cli.marketplace | iterion marketplace submit/install/uninstall (bot + plugin kinds) | cli | covered-deterministic | TestMarketplaceCLI_SubmitInstallUninstall_KindAware (pkg/cli/marketplace_test.go) | |
| cli.plugin | iterion plugin list/enable/disable/install/uninstall/config | cli | covered-deterministic | pkg/plugin/install_test.go, pkg/plugin/config_test.go | |
| cli.skill-library | iterion skill list/show/add/rm/export (layered global/project) | cli | covered-deterministic | TestSkillLibraryAddListShowExportRemove (e2e/cli_skill_test.go), TestSkillLibraryProjectScopeShadowsGlobal (e2e/cli_skill_test.go) | round-trip against an isolated ITERION_HOME, cross-checked through the same skilllib.LocalStoreForProject().Resolve the runtime mirror calls. skill import (git URL) is covered as plugins.install |
| cli.secret | iterion secret set/list/rm local sealed-secret lifecycle | cli | covered-deterministic | TestSecretSetListRemoveRoundTrip (e2e/cli_secret_test.go), TestSecretProjectScopeOverridesGlobal (e2e/cli_secret_test.go) | |
| cli.memory | iterion memory export/import/du | cli | covered-deterministic | TestMemoryExportImportRoundTripsASpace (cmd/iterion/memory_test.go), TestMemoryImportStrategyDecidesWhoWinsOnConflict (cmd/iterion/memory_test.go), TestMemoryDuReportsTheSpaceUsageAndQuota (cmd/iterion/memory_test.go), TestMemoryRefusesAnUnaddressableSpace (cmd/iterion/memory_test.go) | archive round-trip into a different space, the skip/overwrite conflict strategies, usage/quota reporting, and the unaddressable-space refusal — all through the real rootCmd against an isolated ITERION_HOME |
| cli.models | iterion models resolves capabilities and their source | cli | covered-deterministic | TestRunModels_JSONSingleModel (pkg/cli/models_test.go) | |
| cli.openapi | iterion openapi emits this build's OpenAPI 3.1 spec offline | cli | covered-deterministic | pkg/server/openapi_test.go | |
| cli.schedule | iterion schedule add/list/remove/install/uninstall crontab manifest | cli | covered-deterministic | TestRunScheduleAddListRemove (pkg/cli/schedule_test.go), TestRunScheduleInstallUninstall_SeamRoundTrip (pkg/cli/schedule_test.go) | |
| cli.schedule-gate | schedule overlap policy + pre-launch guard + tick audit | cli | covered-deterministic | TestScheduleRun_OverlapSkipsAndAuditsBlockingRun (pkg/cli/schedule_gate_test.go), TestScheduleRun_GuardNonZeroBlocks (pkg/cli/schedule_gate_test.go) | |
| cli.issue | iterion issue create/list/show/move/update/close/board | cli | covered-deterministic | TestIssueCLILifecycleCreateMoveUpdateClose (e2e/cli_issue_test.go), TestIssueCloseRefusesABoardWithNoTerminalState (e2e/cli_issue_test.go) | create → list/show → move → update → close read back through a fresh native.Store, plus the events.jsonl audit trail |
| cli.issue-import | iterion issue import pulls forge issues onto the board | cli | covered-deterministic | TestRunIssueImport_CreatesCardsAndIsIdempotent (e2e/cli_issue_import_test.go), TestRunIssueImport_RejectsUnsupportedForge (e2e/cli_issue_import_test.go) | drives the real CLI against a fake forge, then re-opens the board through a FRESH store: the cards that landed are the oracle, and a re-import proves idempotence |
| security.disable-auth-switch | ITERION_DISABLE_AUTH bypasses authentication on every /api/* endpoint | server-api | covered-deterministic | TestDisableAuthSwitchGovernsEveryProtectedRoute (pkg/server/disable_auth_switch_test.go) | both positions asserted as one contract — only the PAIR is meaningful, since pinning one alone passes for a switch welded shut |
| cli.sandbox-doctor | iterion sandbox doctor [--strict] host/run pre-flight diagnosis | cli | covered-deterministic | TestRunSandboxDoctorStrictNoSandbox (pkg/cli/sandbox_strict_test.go), TestRunNetworkStrictChecks (pkg/cli/sandbox_strict_test.go) | |
| cli.studio | iterion studio boots the server and reports its port | cli | covered-deterministic | TestRunStudio_OnReady_RandomPort (pkg/cli/studio_test.go), TestIsLoopbackBindHost (pkg/cli/studio_bind_test.go) | |
| cli.server | iterion server boots the HTTP server without the studio launcher | cli | covered-deterministic | TestServerCommandBootsLocalModeAndShutsDownOnSignal (e2e/cli_server_boot_test.go), TestServerCommandFailsLoudlyOnBusyPort (e2e/cli_server_boot_test.go) | spawns the built binary as a subprocess and signals THAT child (not the test binary), so the daemon-SIGTERM aliasing of cli.dispatch is not reproduced |
| cli.runner | iterion runner boots a cloud runner pod from its config | cli | covered-deterministic | TestRunnerCommandRefusesLocalMode (e2e/cli_server_boot_test.go), TestRunnerCommandRefusesBrokenConfig (e2e/cli_server_boot_test.go) | the entry-point posture (mode gate + config loader) is what is deterministic; the claim/execute loop IS a NATS/Mongo/S3 consumer and is covered by cloud.runner-pod |
| cli.bots-templates | iterion bots templates lists the templates bots create accepts | cli | covered-deterministic | TestBotsTemplates_MatchesStudioGallery (pkg/cli/bots_create_test.go) | pins the CLI list against botscaffold.Templates(), the same source the studio gallery renders |
| bots.install | bot bundle install from a git URL or local path (layout validation, name override, existing-needs-force) | bots | covered-deterministic | TestInstall_SingleBundleRoot (pkg/botinstall/install_test.go), TestInstall_MalformedRejected (pkg/botinstall/install_test.go), TestInstall_ExistingNeedsForce (pkg/botinstall/install_test.go) | iterion bots install and the studio install endpoint are both thin wrappers over this core |
| plugins.lifecycle-run | iterion plugin run <name> <phase> executes a plugin's lifecycle command | plugins | covered-deterministic | TestRunLifecycle (pkg/plugin/lifecycle_test.go), pkg/server/plugins_routes_test.go | |
| cli.dispatch | iterion dispatch daemon boots from a config with the bot catalogue | cli | covered-deterministic | TestDispatchDaemonBootsServesAndStopsOnSignal (e2e/cli_dispatch_daemon_test.go), TestDispatchDaemonFailsLoudlyOnABusyPort (e2e/cli_dispatch_daemon_test.go), TestDispatchDaemonRejectsAnInvalidConfig (e2e/cli_dispatch_daemon_test.go) | in-process boot on a temp store + loopback port: asserts /healthz, the server-info advertisement, the started actor's state and the YAML it runs, the mounted native-board routes, then the SIGTERM clean exit and the non-zero exit on a bind failure |
| cli.migrate-to-cloud | iterion migrate to-cloud local store → Mongo/S3 | cli | covered-deterministic | TestMigrateToCloud_TransfersEveryVersionAndIsIdempotent (cmd/iterion/migrate_to_cloud_test.go), TestMigrateToCloud_DryRunWritesNothing (cmd/iterion/migrate_to_cloud_test.go), TestMigrateToCloud_MissingRunIsAnError (cmd/iterion/migrate_to_cloud_test.go), pkg/cli/migrate_orgs_test.go, pkg/cli/migrate_run_paths_test.go | the command's own walker between two real stores (every artifact version, --dry-run writes nothing, re-runs don't duplicate, an unknown run is an error), plus the sibling migrate orgs backfill and run-path rewrite. The S3 upload half is cloud.migrate-blobs |
| cli.mcp-server | iterion mcp operator MCP server (local_/remote_ tools) | cli | covered-deterministic | TestMCPServer_DetachedRunSurvivesServerExit (e2e/mcp_server_test.go), pkg/operatormcp/tools_local_test.go | |
| cli.supervise | iterion supervise attaches to a managed run or a raw claude session | cli | covered-deterministic | pkg/supervise/coordinator_test.go, pkg/supervise/transcript_test.go | |
| cli.remote | iterion remote typed subcommands against a cloud instance | cli | covered-deterministic | TestRemoteRunsLaunch_SendsSourceAndVars (pkg/cli/remote_test.go), TestRemoteRunsFollow_CursorAndTerminal (pkg/cli/remote_test.go) | |
| cli.remote-login | browser loopback CLI-auth token mint + persistence | cli | covered-deterministic | TestResolveRemoteConfig_EnvMode (pkg/cli/remote_test.go), pkg/server/auth_routes_test.go | |
| cli.version | iterion version [--commit] | cli | covered-deterministic | cmd/iterion/version_test.go | |
| cli.bench-asymptote | iterion bench asymptote convergence benchmark | cli | covered-deterministic | TestBenchAsymptoteMeasuresTheConvergenceCurve (e2e/cli_bench_asymptote_test.go), TestBenchAsymptoteComparesTwoGroups (e2e/cli_bench_asymptote_test.go), TestBenchAsymptoteWritesTheMarkdownReport (e2e/cli_bench_asymptote_test.go), TestBenchAsymptoteRefusesAnIncompleteRequest (e2e/cli_bench_asymptote_test.go) | the command re-runs nothing — it derives the curve from what past runs persisted — so real stub-driven runs of a judge-in-a-loop fixture supply the same events an operator's runs would |
| backends.selection-explicit | node backend: / workflow default_backend: selects the delegate | backends | covered-deterministic | pkg/backend/model/resolve_backend_test.go | |
| backends.autodetect | credential probing picks a backend when none is declared | backends | covered-deterministic | pkg/backend/detect/detect_test.go, pkg/backend/model/resolve_backend_test.go | live variant: TestLive_Feat_BackendAutodetect |
| backends.claw | claw in-process client: generation, retry, cache observability | backends | covered-deterministic | pkg/backend/model/claw_backend_test.go, pkg/backend/model/generation_test.go | real-provider behaviour: covered-live by TestLive_Lite_ClawComprehensive |
| backends.claude-code | claude_code CLI delegate: append-system-prompt, setting sources | backends | covered-deterministic | pkg/backend/delegate/claude_code_cred_test.go | |
| backends.pi | pi delegate incl. the RPC session + embedded extension | backends | covered-deterministic | pkg/backend/delegate/pi_rpc_test.go, pkg/backend/delegate/pi_mcp_test.go | |
| backends.kimi | kimi CLI delegate through the generic CLI-agent seam | backends | covered-deterministic | pkg/backend/delegate/cliagent_test.go | |
| backends.grok | grok CLI delegate through the generic CLI-agent seam | backends | covered-deterministic | pkg/backend/delegate/grok_test.go | |
| backends.codex-legacy | legacy codex delegate (frozen, C030 diagnostic) | backends | covered-deterministic | pkg/dsl/ir/compile_test.go | deprecated surface: kept compiling + diagnosed, not extended |
| backends.system-prompt-composition | per-backend SystemPromptMode (Standalone/Append/AuthoredBase) | backends | covered-deterministic | pkg/backend/delegate/delegate_test.go | |
| backends.reasoning-effort | reasoning_effort propagation and wire remapping | backends | covered-deterministic | pkg/backend/model/effort_test.go | |
| backends.ultracode | ultracode mode: xhigh + orchestration prerogative + C089 | backends | covered-deterministic | pkg/dsl/ir/ultracode_test.go, pkg/backend/model/effort_test.go | live behaviour on 4.8: TestLive_Feat_Ultracode |
| backends.retry-classification | transient vs fatal backend errors, retry + feedback | backends | covered-deterministic | pkg/backend/model/executor_retry_classification_test.go, pkg/backend/model/network_retry_test.go | |
| backends.cost-accounting | per-call cost/token accounting reaching the run totals | backends | covered-deterministic | TestMetricsEmitter_delegateFinished_costReachesRunTotals (pkg/runner/metrics_test.go), TestMetricsEmitter_clawCostIsNotCountedTwice (pkg/runner/metrics_test.go), TestRunBudgetOverrideCapsTheRun (e2e/cli_budget_override_test.go), pkg/backend/cost/cost_test.go, pkg/backend/model/executor_hooks_cost_test.go | the whole money path: the delegate prices a call, the executor carries it on the event, the emitter accumulates it into RunTotals (and does NOT double-charge claw, which emits both a step and a delegation total), and the accumulated cost is what trips the run's own budget cap |
| backends.oauth-forfait | subscription OAuth paths (Anthropic auth token, ChatGPT codex) | backends | covered-deterministic | pkg/backend/model/openai_forfait_ctx_test.go, pkg/secrets/subscription_oauth_test.go | credential resolution is deterministic; a real forfait call is excluded (needs a live subscription) |
| backends.bedrock-vertex-foundry | AWS Bedrock / GCP Vertex / Azure Foundry providers | backends | excluded | needs real cloud credentials for AWS/GCP/Azure; claw's SDK paths are unit-tested with mocked clients and iterion adds no logic of its own | |
| backends.model-quality | real model output quality / value-for-money grading | backends | covered-live | e2e/live_quality_test.go | the essence of the feature IS the live model; the judge panel is report-only by default |
| tools-mcp.tool-registry | tool registry + per-node allow lists (claw-native names) | tools-mcp | covered-deterministic | pkg/backend/tool/registry_test.go | |
| tools-mcp.claw-builtins | claw built-in tools (read/write/bash/glob/grep/edit/web_fetch) | tools-mcp | covered-deterministic | pkg/backend/tool/claw_builtins_test.go | live variant: TestLive_Lite_ClawBuiltinTools |
| tools-mcp.mcp-lifecycle | MCP server startup, health check and --skip-mcp-health | tools-mcp | covered-deterministic | pkg/backend/mcp/config_test.go, TestSkipMCPHealthFromEnv (pkg/cli/run_skipmcp_test.go) | |
| tools-mcp.mcp-transports | MCP stdio / streamable-http / legacy-sse transports | tools-mcp | covered-deterministic | pkg/backend/mcp/config_test.go, pkg/backend/delegate/pi_mcp_test.go | |
| tools-mcp.mcp-oauth | MCP OAuth broker / PKCE wiring | tools-mcp | covered-deterministic | pkg/backend/mcp/oauth_test.go | a real third-party OAuth consent flow is excluded (see integrations.third-party-oauth) |
| tools-mcp.board-tools | board capability tools over stdio, HTTP and in-process claw | tools-mcp | covered-deterministic | TestBoardDispatcher_E2E_BotCreatesAndDispatches (e2e/board_dispatcher_test.go), pkg/backend/tool/claw_board_tools_test.go | |
| tools-mcp.ask-user | ask_user / ask_user_async / await_answers MCP surface | tools-mcp | covered-deterministic | pkg/askusermcp/http_test.go, TestAwaitAnswersReleasedByAnswer (e2e/async_interaction_test.go) | |
| tools-mcp.permission-gate | permission gate blocks/asks on a non-allow-listed tool call | tools-mcp | covered-deterministic | pkg/backend/model/permission_gate_test.go, pkg/backend/permission/permission_test.go | live variants: TestLive_Feat_Permission_Deny / _Ask |
| tools-mcp.secret-guard | secret placeholders never leak into tool input/output | tools-mcp | covered-deterministic | pkg/backend/model/hooks_secretguard_test.go, pkg/backend/model/secretguard_binding_hosts_test.go | |
| tools-mcp.computer-use | read_image / screenshot / computer_use dispatch | tools-mcp | covered-deterministic | pkg/backend/tool/claw_builtins_test.go | headless-unavailable propagation is the deterministic half; live use is TestLive_Lite_ClawReadImage |
| tools-mcp.tool-display | human-readable rendering of tool calls in console/report | tools-mcp | unit-only | pkg/backend/tooldisplay/display_test.go | pure formatter over an event payload; an e2e would assert string shape through the whole stack without adding risk coverage |
| observability.report-generation | report.md chronological rendering from events + artifacts | observability | covered-deterministic | TestReportRendersChronologicalRunReport (e2e/cli_report_test.go) | the artifact table lifts each artifact's conventional summary: field; node outputs without one are intentionally not inlined |
| observability.metrics | benchmark.CollectMetrics over a finished run | observability | covered-deterministic | TestCIFix_HappyPath (e2e/e2e_test.go), pkg/benchmark/benchmark_test.go | |
| observability.alerts | stall/budget/failure alerting + liveness heartbeat | observability | covered-deterministic | pkg/alert/manager_test.go | |
| observability.completion-webhooks | run-completion webhooks behind the SSRF guard | observability | covered-deterministic | pkg/notify/completion_test.go, pkg/secure/httpdial/httpdial_test.go | |
| observability.user-notifications | run-outcome web-push notifications with per-episode dedup | observability | covered-deterministic | pkg/usernotify/dispatcher_test.go | |
| observability.otlp-tracing | OTLP exporter wiring for runs/server | observability | covered-deterministic | pkg/cloud/tracing/tracing_test.go, pkg/benchmark/otlp_test.go | an end-to-end span assertion needs a real collector; setup/shutdown/no-endpoint paths are asserted here |
| sandbox.docker-driver | docker driver: container lifecycle, workspace bind-mount | sandbox | covered-live | e2e/live_feat_sandbox_net_test.go | needs a container runtime; the deterministic half is spec construction (pkg/sandbox/spec_test.go) |
| sandbox.spec-resolution | sandbox spec resolution (auto / devcontainer / image / none) | sandbox | covered-deterministic | pkg/sandbox/spec_test.go, pkg/sandbox/factory_test.go | |
| sandbox.network-policy | network: allowlist/denylist CONNECT proxy enforcement | sandbox | covered-deterministic | TestSandboxNetworkAllowlist_DeclarationStartsAnEnforcingProxy (pkg/runtime/sandbox_network_policy_test.go), TestSandboxNetworkDenylist_BlocksOnlyTheListedHosts (pkg/runtime/sandbox_network_policy_test.go), TestSandboxNetworkOpen_StartsNoProxy (pkg/runtime/sandbox_network_policy_test.go), pkg/sandbox/netproxy/proxy_test.go, e2e/live_feat_sandbox_net_test.go | the proxy runs on the HOST, so the whole wire is deterministic after all: the declaration compiled from real .bot source starts an enforcing proxy, an allowed host tunnels to a loopback echo server, a host outside the policy is refused AND emits the network_blocked event the operator sees, an un-tokened client is refused (not an open relay), and network: open / no block at all start no proxy. Forcing ResolveNetworkPolicy to open turns both policy tests red. Only the container-side half — the sandboxed process actually routing its egress through the injected HTTPS_PROXY — still needs the live layer |
| sandbox.host-state | host_state: auto / none mounts of ~/.iterion and ~/.claude | sandbox | covered-deterministic | TestApplyHostStateMounts_ClaudeConfigFile (pkg/runtime/sandbox_mounts_test.go), TestApplyHostStateMounts_HomeNestedBindParentsWritable (pkg/runtime/sandbox_mounts_test.go) | pkg/sandbox/spec_test.go only validates the enum string; the mounts themselves are asserted in the runtime tests cited here |
| sandbox.kubernetes-driver | kubernetes driver: capabilities, pod/network manifests, mounts, GC, orphan sweep | sandbox | covered-deterministic | TestPodManifestStructure (pkg/sandbox/kubernetes/driver_test.go), TestBuildNetworkPolicyShape (pkg/sandbox/kubernetes/driver_test.go), TestValidateSpecMatchesPrepare (pkg/sandbox/kubernetes/validate_test.go), pkg/sandbox/kubernetes/gc_test.go, pkg/sandbox/kubernetes/mounts_test.go | the manifest/spec/GC half is deterministic (57 unit tests, same shape as the docker driver); only the real pod lifecycle needs a cluster — see sandbox.kubernetes-pod-lifecycle |
| sandbox.kubernetes-pod-lifecycle | a k8s sandbox pod is actually created, executed against and torn down | sandbox | excluded | needs a live cluster + registry; no fake apiserver harness exists in this repo. The manifest/spec/GC half is covered — see sandbox.kubernetes-driver | |
| sandbox.buildkit | sandbox.build: via docker buildx on the local driver | sandbox | excluded | needs a Docker daemon with BuildKit; rejected by design on the k8s driver | |
| plugins.registry | plugin discovery, enable state, builtin embedding | plugins | covered-deterministic | pkg/plugin/plugin_test.go, pkg/plugin/inspect_test.go | |
| plugins.install | plugin install from a git URL or path (incl. bare skills repos) | plugins | covered-deterministic | pkg/plugin/install_test.go, pkg/plugin/skilllib_test.go | |
| plugins.rewriters | rewriter chain rewrites shell commands (rtk compression) | plugins | covered-deterministic | pkg/plugin/plugin_test.go, pkg/dsl/ir/compress_test.go | live end-to-end with the rtk binary: TestLive_Feat_Compress |
| plugins.contributed-skills | plugin skills/commands/agents mirrored into the workspace | plugins | covered-deterministic | TestMirrorInjectedPluginFiles_WritesEachKind (pkg/runtime/contributions_test.go) | |
| plugins.hooks-merge | plugin hook fragments idempotently merged into settings.json | plugins | covered-deterministic | TestMergePluginHooks_InjectIdempotentRemove (pkg/runtime/plugin_hooks_test.go), pkg/backend/model/settings_hooks_test.go | |
| plugins.private-source | team-scoped private plugin source binding (git + secret ref) | plugins | covered-deterministic | pkg/pluginsource/pluginsource_test.go | |
| server-api.run-console | run console REST: run detail, events, log, node sections | server-api | covered-deterministic | pkg/server/runs_test.go, pkg/runview/service_test.go | |
| server-api.run-launch | launch a run over HTTP with vars/overrides | server-api | covered-deterministic | pkg/runview/service_launch_budget_test.go, pkg/runview/service_launch_dispatch_fields_test.go, pkg/runview/service_launch_pause_test.go, pkg/runview/service_launch_operator_resume_test.go, pkg/server/runs_test.go | budget overrides (local + forwarded on the cloud path) and invalid durations, dispatch fields, the paused-launch and operator-resume shapes, and the HTTP surface itself |
| server-api.run-control | pause / cancel / resume / rewind / bump-loop / raise-budget | server-api | covered-deterministic | pkg/runview/service_commands_test.go | |
| server-api.run-ws | live run WebSocket stream | server-api | covered-deterministic | pkg/server/runs_ws_test.go | |
| server-api.review-scope | review scope + diff since the previous human gate | server-api | covered-deterministic | pkg/server/runs_review_scope_test.go | |
| server-api.run-files | run workspace file browse/read/write with path containment | server-api | covered-deterministic | pkg/server/runs_files_test.go | |
| server-api.run-commits | per-run commit list + commit detail | server-api | covered-deterministic | pkg/server/runs_commits_test.go | |
| server-api.preview-proxy | run preview proxy behind the SSRF guard | server-api | covered-deterministic | pkg/server/runs_preview_test.go | |
| server-api.answer-human | answer a human gate / async question over HTTP | server-api | covered-deterministic | pkg/server/runs_answer_uploads_test.go | |
| server-api.queued-messages | operator chat messages queued into a running node's inbox | server-api | covered-deterministic | pkg/backend/model/inbox_test.go, pkg/server/runs_steer_test.go | |
| server-api.bots | bot catalog listing + per-bot metadata over HTTP | server-api | covered-deterministic | pkg/server/bots_routes_test.go, pkg/botregistry/registry_test.go | |
| server-api.board | native kanban REST (CRUD, transitions, labels, views) | server-api | covered-deterministic | pkg/dispatcher/native/http_test.go, pkg/dispatcher/native/store_test.go | |
| server-api.dispatcher-dashboard | dispatcher state/refresh/cancel HTTP surface | server-api | covered-deterministic | TestDispatcherE2E_HTTPSurface (e2e/dispatcher_test.go), pkg/dispatcher/http_test.go | |
| server-api.server-info | /api/server/info capability flags gate the SPA features | server-api | covered-deterministic | TestServerInfo (pkg/server/runs_uploads_test.go), TestServerInfo_SkillsEnabledLocal (pkg/server/local_skills_routes_test.go), TestMarketplace_ServerInfoFlag (pkg/server/marketplace_routes_test.go), TestMarketplace_ServerInfoFlagFalseWhenNil (pkg/server/marketplace_routes_test.go), pkg/server/backends_routes_test.go | each flag is asserted against the wiring that decides it — present when the store/feature is wired, false when it is nil |
| server-api.openapi | generated OpenAPI 3.1 spec matches the wired routes | server-api | covered-deterministic | pkg/server/openapi_test.go | |
| server-api.pipeline-board | /api/v1/pipeline-board/* control centre (columns, folding, actions, bulk ops) | server-api | covered-deterministic | TestPipelineBoardColumnBucketing (pkg/server/pipeline_boards_test.go), TestPipelineBoardFoldsDescendantsAndCollectsReviews (pkg/server/pipeline_boards_test.go), pkg/server/pipeline_board_actions_test.go | the REST layer behind studio-ui.pipelines |
| server-api.limits-cost | /api/v1/limits/cost + /override admin cost-cap surface | server-api | covered-deterministic | TestCostCapStatusDisabledByDefault (pkg/server/limits_test.go), TestCostCapStatusAndOverride (pkg/server/limits_test.go) | |
| server-api.backends-detect | /api/backends/detect credential auto-detection the toolbar reads | server-api | covered-deterministic | TestBackendsDetectRouteShape (pkg/server/backends_routes_test.go), TestBackendsDetect_NoSensitiveLeak (pkg/server/backends_routes_test.go) | the no-leak assertion is the one that matters: the endpoint reports availability, never a credential |
| server-api.effort-capabilities | /api/effort-capabilities per-backend/model effort lookup | server-api | covered-deterministic | TestEffortCapabilities_ClawOpus48 (pkg/server/effort_test.go), TestEffortCapabilities_UltracodeOnlyOnOpus48 (pkg/server/effort_test.go), TestEffortCapabilities_UnknownModel (pkg/server/effort_test.go) | also covers the sibling /api/resolve-effort. The ultracode-only-on-4.8 case is the one that would catch a capability table drifting |
| server-api.editor-endpoints | /api/parse, /api/unparse, /api/validate DSL round-trip surface | server-api | covered-deterministic | TestUnparse_RoundTripIsSemanticallyStable (pkg/server/server_dsl_test.go), TestValidate_UnknownNodeReferenceIsC001 (pkg/server/server_dsl_test.go), TestParse_UnparseableSource (pkg/server/server_dsl_test.go) | round-trip fidelity (parse -> unparse -> parse is byte-identical) and the diagnostic CODE, not the message text |
| server-api.local-secrets | /api/local/secrets desktop/CLI secret surface | server-api | covered-deterministic | TestLocalSecrets_CreateListDeleteSealsAndNeverEchoesTheValue (pkg/server/local_secrets_routes_test.go), TestLocalSecrets_RenameOntoAnExistingNameIsRefused (pkg/server/local_secrets_routes_test.go) | the real routes on a New()-built local-mode server with the sealed store FILE as the oracle: create → the plaintext is absent from disk and from every response (only name/last4/fingerprint), list, re-post rotates in place without duplicating or widening the egress lock, delete removes it from both API and file; rename collision 409 leaves both records intact, unknown id 404. The previous citation (local_skills_routes_test.go) was a mis-citation — it holds no secrets coverage |
| server-api.run-shell | /api/ws/runs/{id}/shell post-mortem PTY shell in a preserved worktree | server-api | covered-deterministic | TestRunShell_Gates (pkg/server/runs_shell_test.go), TestShellEligible (pkg/server/runs_shell_test.go) | the gate (which runs may be shelled into) is the part that matters; the PTY itself is Unix-only with a Windows stub |
| cloud.oauth-connections | /api/me/oauth/* connect / authorize / refresh a subscription credential for cloud runs | cloud | covered-deterministic | TestOAuthConnections_SealsAndNeverEchoesTheCredential (pkg/server/oauth_routes_test.go) | the store is the oracle: the persisted payload must not contain the plaintext token, no response may echo it, and a second account is isolated from the first one's credential |
| server-api.static-spa | embedded studio SPA served from the binary | server-api | covered-deterministic | pkg/server/spa_test.go | |
| dispatcher.poll-dispatch | poll a tracker and dispatch one run per eligible issue | dispatcher | covered-deterministic | TestDispatcherE2E_DispatchAndRelease (e2e/dispatcher_test.go) | |
| dispatcher.retry | retry with backoff after a failed run, give up at max attempts | dispatcher | covered-deterministic | TestDispatcherE2E_RetryAfterFailure (e2e/dispatcher_test.go), TestDispatcherGivesUpAfterMaxAttempts (pkg/dispatcher/dispatcher_test.go) | |
| dispatcher.cancel | cancel an in-flight dispatched run | dispatcher | covered-deterministic | TestDispatcherE2E_CancelInFlight (e2e/dispatcher_test.go) | |
| dispatcher.state-transitions | issue state transitions around dispatch + revert on failure | dispatcher | covered-deterministic | TestDispatch_TransitionsToInProgress (pkg/dispatcher/loop_state_test.go), TestDispatcherE2E_RespectsTerminalStateChange (e2e/dispatcher_test.go) | |
| dispatcher.hooks | hook mechanics (script, env, timeout, failure, validation) + the before_remove hook FIRES | dispatcher | covered-deterministic | pkg/dispatcher/hooks_test.go, TestCleanupWorkspace_RunsBeforeRemoveBeforeDeletingDir (pkg/dispatcher/cleanup_workspace_test.go) | |
| dispatcher.hooks-lifecycle-firing | the after_create / before_run / after_run hooks actually FIRE at their lifecycle point | dispatcher | covered-deterministic | TestRunWorker_FiresLifecycleHooksInOrder (pkg/dispatcher/hooks_lifecycle_test.go), TestRunWorker_AfterRunFiresEvenWhenRunnerFails (pkg/dispatcher/hooks_lifecycle_test.go) | every phase appends to one shared order log, so the assertion is the ORDER of what actually fired — deleting any of the three Run() calls turns it red |
| dispatcher.per-ticket-bot | per-ticket bot override + assignee routing | dispatcher | covered-deterministic | TestBuildSpec_PerTicketBotSetsRouteKey (pkg/dispatcher/loop_bot_override_test.go) | |
| dispatcher.concurrency | per-state concurrency caps + claim conflict handling | dispatcher | covered-deterministic | TestDispatcherRespectsClaimConflict (pkg/dispatcher/dispatcher_test.go), TestDispatch_SlotCountedFromClaimTime (pkg/dispatcher/loop_setup_offload_test.go) | |
| dispatcher.cost-cap | daily cost cap gate blocks further dispatch | dispatcher | covered-deterministic | TestRefreshCostCapGatesWhenExceeded (pkg/dispatcher/cost_cap_test.go) | |
| dispatcher.workspace-cleanup | per-run workspace/worktree teardown policies | dispatcher | covered-deterministic | TestCleanupWorkspace_RemovesLinkedWorktreeRegistration (pkg/dispatcher/cleanup_workspace_test.go) | |
| dispatcher.native-tracker | native filesystem kanban tracker (board.json/issues/events) | dispatcher | covered-deterministic | pkg/dispatcher/native/store_test.go, TestNativeStore_Conformance (pkg/dispatcher/boardmongo/conformance_test.go) | |
| dispatcher.github-tracker | GitHub Issues tracker adapter | dispatcher | covered-deterministic | pkg/dispatcher/tracker/github_test.go | real GitHub API is stubbed at the HTTP boundary |
| dispatcher.forgejo-tracker | Forgejo/Gitea tracker adapter | dispatcher | covered-deterministic | pkg/dispatcher/tracker/forgejo_test.go | real Forgejo API is stubbed at the HTTP boundary |
| triggers.subscription-registry | subscription CRUD through the REST surface | triggers | covered-deterministic | pkg/server/triggers_routes_test.go | matching/mode semantics: pkg/trigger/subscription_test.go |
| triggers.subscription-query | subscription query by repo / by bot (tenant-scoped; by-repo also returns the workspace-wide ones) | triggers | covered-deterministic | TestSubscriptionStoreQueries (pkg/trigger/store_query_test.go) | |
| triggers.evaluator | evaluator matches an event to subscriptions and launches | triggers | covered-deterministic | pkg/trigger/evaluator_test.go | |
| triggers.board-source | board transition promotes a card / direct-launches a bot | triggers | covered-deterministic | pkg/trigger/board_integration_test.go, TestIssueTriageTrigger_E2E_ConsumeAndLaunch (e2e/issue_triage_trigger_test.go) | |
| triggers.consume-labels | consume_labels strips the matcher labels atomically pre-launch | triggers | covered-deterministic | pkg/trigger/consume_labels_test.go, TestIssueTriageTrigger_E2E_ConsumeAndLaunch (e2e/issue_triage_trigger_test.go) | |
| triggers.run-outcome | run completion events chain the next bot | triggers | covered-deterministic | TestEvaluatorRunCompletionChaining (pkg/trigger/evaluator_test.go), pkg/runview/trigger_emit_test.go, pkg/trigger/runoutcome_test.go | the chaining itself (a finished run's event matches a direct-mode subscription and launches the next bot), the emitter that publishes it from runview, and the envelope/episode-id builder shared with the runner |
| triggers.scheduler | schedule-kind subscriptions tick on their cron | triggers | covered-deterministic | pkg/trigger/scheduler_test.go, pkg/trigger/scheduler_gate_test.go | |
| triggers.eventbus-inproc | in-process event bus delivery | triggers | covered-deterministic | pkg/eventbus/inproc_test.go | |
| triggers.eventbus-nats | NATS event bus on the separate ITERION_EVENTS stream | triggers | covered-deterministic | pkg/eventbus/nats_test.go | needs a NATS endpoint; skips cleanly without one |
| triggers.cloudsched | cloud recurring-bot scheduler with a multi-replica CAS ticker | triggers | covered-deterministic | pkg/cloudsched/cloudsched_test.go | |
| triggers.retry-policy | usage_window retry policy resolution across all layers | triggers | covered-deterministic | pkg/retrypolicy/policy_test.go | |
| webhooks.gitlab | GitLab MR open/reopen + /revi note re-review launches | webhooks | covered-deterministic | pkg/server/webhooks_gitlab_test.go, pkg/webhooks/webhooks_test.go | |
| webhooks.github | GitHub PR events launch the configured bot | webhooks | covered-deterministic | pkg/server/webhooks_github_test.go | |
| webhooks.forgejo | Forgejo/Gitea PR events launch the configured bot | webhooks | covered-deterministic | pkg/server/webhooks_forgejo_test.go | |
| webhooks.generic | generic JSON inbound trigger | webhooks | covered-deterministic | TestGenericWebhook_HappyPath_VarsPrecedence (pkg/server/webhooks_generic_test.go), TestGenericWebhook_MissingBotIs400 (pkg/server/webhooks_generic_test.go), TestGenericWebhook_BodyHashIdempotency (pkg/server/webhooks_generic_test.go), pkg/webhooks/generic/generic_test.go, pkg/webhooks/router_test.go | the endpoint itself: var precedence on launch, 400 without a bot, body-hash idempotency, oversized-var refusal; the parser in pkg/webhooks/generic and the command routing in router_test.go |
| webhooks.auth | iwh_ token / HMAC admission, rate limits, idempotent delivery | webhooks | covered-deterministic | pkg/webhooks/match_test.go, pkg/server/webhooks_routes_test.go | |
| webhooks.handoff | produces/consumes hand-off stamps the next run's launch vars | webhooks | covered-deterministic | pkg/server/webhooks_handoff_test.go, bots/handoff_declarations_test.go | |
| webhooks.merge-gate | Revi posts a deterministic revi/review commit status | webhooks | covered-deterministic | TestForgePublishReview_GatePostedEvenWhenTheReviewFails (pkg/server/forge_publish_test.go), pkg/server/forge_gate_relaunch_test.go, pkg/server/forge_gate_autofix_test.go | pkg/forge/reviews_test.go is a PR-URL parser + markdown folder — orthogonal to the gate |
| forge.connections | forge connection / repo-integration / OAuth-app stores | forge | covered-deterministic | pkg/forge/oauth_app_store_test.go | |
| forge.admin-clients | per-provider admin clients (repos, hooks, permissions) | forge | covered-deterministic | pkg/forge/forgelive_test.go, pkg/forge/command_map_test.go | provider APIs stubbed at the HTTP boundary |
| forge.github-app | GitHub App manifest flow + installation-token minting | forge | covered-deterministic | pkg/server/forge_app_resolution_test.go | the interactive App-creation consent screen is excluded (needs a real GitHub org) |
| forge.orchestrator | provision/deprovision: webhook + secret + bindings + schedules | forge | covered-deterministic | pkg/forge/orchestrator_test.go | |
| forge.token-refresh | background token refresh worker | forge | covered-deterministic | pkg/forge/refresh_test.go | |
| forge.config-share | shared-config read/write under a synthetic share grant | forge | covered-deterministic | pkg/configshare/configshare_test.go | |
| cloud.auth-session | login / logout / refresh / session cookies + JWT claims | cloud | covered-deterministic | pkg/auth/service_test.go, pkg/server/auth_routes_test.go | |
| cloud.sso-oidc | OIDC SSO providers + domain verification | cloud | covered-deterministic | pkg/auth/oidc/generic_test.go, pkg/server/org_sso_routes_test.go | a real IdP consent round-trip is excluded (see integrations.third-party-oauth) |
| cloud.password-reset | password reset request/confirm + mail delivery fallback | cloud | covered-deterministic | pkg/auth/password_reset_test.go, pkg/mail/mail_test.go | |
| cloud.orgs-teams | two-level tenancy: org membership, team scoping, context switch | cloud | covered-deterministic | pkg/identity/team_test.go, pkg/server/auth_teams_test.go | |
| cloud.invitations | team/org invitations: create, lookup, accept | cloud | covered-deterministic | TestInvitations_AdminIssuesAnonymousLookupAcceptGrantsMembership (pkg/server/invitations_e2e_test.go), TestInvitations_DeletingAPendingInviteKillsItsToken (pkg/server/invitations_e2e_test.go), TestInvitationFlow (pkg/auth/service_test.go) | the whole grant path over real HTTP: a plain member is refused (403, nothing created), an admin's token is looked up ANONYMOUSLY (the invitee has no session yet), accepting creates the membership — proven by the outsider's 403 on the team turning into a 200 that lists them at the invited role — and the token is single-use, login-gated, and dead once the admin deletes the invitation. The previous citation (auth_views_test.go) holds only an org-tree test |
| cloud.pat | personal access tokens (iap_ bearers) | cloud | covered-deterministic | TestPATBearer_AuthenticatesProgrammaticClientsThroughTheRealServer (pkg/server/pat_bearer_e2e_test.go), TestPATBearer_DiesWithTheMembershipItResolvesThrough (pkg/server/pat_bearer_e2e_test.go), pkg/server/pat_routes_test.go, pkg/pat/pat_test.go | the promise is programmatic access, and it lives in the auth MIDDLEWARE: the token is minted over real HTTP and then presented as a bearer to a server built by the real New() wiring — identity + pinned team served back, a protected endpoint reachable, cross-team read 403, unknown iap_ failing closed (never falling through to JWT parsing), revoke and membership removal each turning the next call into a 401 while the JWT session survives. Deleting the iap_ branch from requireAuth leaves the store and handler tests green and turns these red |
| cloud.audit-log | tenant + platform audit log of control-plane mutations | cloud | covered-deterministic | TestAuditEndToEnd (pkg/server/audit_routes_test.go), pkg/audit/audit_test.go | a control-plane mutation through the routes leaves the row an operator reads back on /api/teams/{id}/audit; the store half (TTL, filters) in pkg/audit |
| cloud.quotas | per-org monthly run/cost counters gate the launch | cloud | covered-deterministic | pkg/orgusage/orgusage_test.go, pkg/server/launch_gate_test.go | |
| cloud.queue-dispatch | NATS work queue: enqueue, claim, schema-version handling | cloud | covered-deterministic | pkg/queue/types_test.go, TestSchemaVersionMismatchIsATypedTransientError (pkg/queue/schema_version_transient_test.go) | |
| cloud.runner-pod | runner claims a queued run, executes, reports status back | cloud | covered-deterministic | pkg/runner/loop_test.go | |
| cloud.runner-credentials | credential injection + sealing into a runner pod | cloud | covered-deterministic | pkg/runner/git_credentials_test.go, pkg/secrets/run_secrets_test.go | |
| cloud.credential-pool | pledge/lease broker as the fourth credential tier | cloud | covered-deterministic | pkg/credpool/broker_test.go, pkg/server/cloudpublisher/credpool_tier_test.go, pkg/server/credpool_routes_test.go | |
| cloud.secrets-sealing | AES-256-GCM sealing + BYOK/generic/bot-binding domains | cloud | covered-deterministic | pkg/secrets/sealer_test.go, pkg/secrets/run_secrets_test.go | |
| cloud.bot-sources | team-authored bot bundles (fork a catalog bot, author a new one) | cloud | covered-deterministic | pkg/botsource/botsource_test.go, pkg/server/bot_sources_routes_test.go | |
| cloud.marketplace | hosted registry entries (bot + plugin), moderation, visibility | cloud | covered-deterministic | TestMarketplace_SubmitListGetInstall (pkg/server/marketplace_routes_test.go), TestMarketplace_InstallThenUninstall (pkg/server/marketplace_routes_test.go), pkg/marketplace/moderation_test.go, pkg/marketplace/visibility_test.go, pkg/marketplace/jsonstore_test.go, pkg/cli/marketplace_test.go | submit → list → get → install/uninstall over the REST surface (plus the disabled/404/malformed-bundle refusals), with moderation status and visibility scope asserted at store level and the CLI half in pkg/cli |
| cloud.memory-store | cloud MemoryStore adapter + quota | cloud | covered-deterministic | pkg/knowledge/scope_test.go, pkg/memory/space_test.go, pkg/server/memory_routes_test.go | |
| cloud.dlq | dead-letter queue show/replay/delete (admin REST surface) | cloud | covered-deterministic | TestDLQAdmin_ListPeekReplayLeavesAuditTrail (pkg/server/dlq_admin_routes_test.go), TestDLQAdmin_NonSuperAdminCannotReplayOrDiscard (pkg/server/dlq_admin_routes_test.go) | the endpoints behind iterion remote admin dlq: super-admin gate (an unprivileged caller never reaches the queue), list/peek/replay/discard state transitions, the platform audit row naming the replayed run, and 400/404/502 mapping. Driven through the real New()/routes()/auth middleware with an in-process QueueBackend double (the seam added for it); the broker-side half is cloud.dlq-jetstream |
| cloud.dlq-jetstream | DLQ transport semantics: park with headers, paged list over deleted holes, replay with a salted Nats-Msg-Id | cloud | excluded | lives entirely inside JetStream (pkg/queue/nats/dlq.go): every operation is a stream Get/Publish/DeleteMsg. Needs a live broker — nats-server/v2 is not vendored and vendoring an embedded broker is a heavy test dependency this repo has deliberately not taken (see the coverage note at the top of pkg/queue/nats/nats_test.go) | |
| cloud.migrate-blobs | migrate to-cloud artifact/blob upload to S3 | cloud | covered-deterministic | TestMigrateToCloud_TransfersEveryVersionAndIsIdempotent (cmd/iterion/migrate_to_cloud_test.go), TestMigrateToCloud_DryRunWritesNothing (cmd/iterion/migrate_to_cloud_test.go), TestS3Client_ArtifactUploadRoundTripAndLayout (pkg/store/blob/s3_roundtrip_test.go), TestS3Client_DeleteRunSweepsOnlyThatRunsPrefix (pkg/store/blob/s3_roundtrip_test.go) | both halves of the one-way door: the walker (migrateRun between two real stores — every artifact VERSION, events, interactions, --dry-run writes nothing, re-runs don't duplicate) and the S3 upload driven by the REAL AWS SDK against an in-process path-style gateway (canonical key layout on the wire, byte round-trip, ErrArtifactNotFound mapping, prefix-scoped DeleteRun). Not covered: the Mongo store's own WriteArtifact→blob glue, which needs a live Mongo (mongo-conformance CI job) |
| cloud.desktop-exchange | desktop auth token exchange endpoint | cloud | covered-deterministic | pkg/server/desktop_sso_test.go | |
| cloud.valkey-state | ephemeral cross-replica state (OAuth/CSRF, board tokens, rate buckets) | cloud | covered-deterministic | TestValkeyCrossReplica_ForgeOAuthStartedOnACompletesOnB (pkg/server/valkey_cross_replica_test.go), TestValkeyCrossReplica_BoardTokenMintedOnAAuthorizesWriteOnB (pkg/server/valkey_cross_replica_test.go), TestValkeyCrossReplica_LoginRateBudgetIsSharedNotPerPod (pkg/server/valkey_cross_replica_test.go), pkg/server/valkey_stores_test.go | two servers built through the real New() wiring over ONE miniredis: each flow starts on replica A and finishes on replica B (OAuth connect → callback creates the connection, board token → board write, login burst → 429). Give each replica its own Valkey and all three fail. store-level TTL/GETDEL/write-failure surfacing in valkey_stores_test.go. Not covered: valkey.New's Sentinel-HA topology (needs a real Sentinel quorum; the single-node client is what miniredis speaks) |
| bots.catalog-universality | catalog bots stay repo- and stack-agnostic | bots | covered-deterministic | bots/catalog_universality_test.go | |
| bots.catalog-compiles | every catalog bot parses + compiles clean | bots | covered-deterministic | bots/catalog_parse_compile_test.go, bots/catalog_typing_test.go | |
| bots.catalog-freshness | the generated bot-catalog skill matches the manifests | bots | covered-deterministic | bots/catalog_freshness_test.go | |
| bots.golden-replay | bot golden replay revalidates frozen LLM outputs | bots | covered-deterministic | TestGoldens (pkg/botreplay/goldens_test.go) | |
| bots.feature-dev | feature-dev (Featurly): campaign + gate convergence | bots | covered-deterministic | TestVibeFeatureDev_ConvergesFirstPass (e2e/feature_dev_test.go), TestVibeFeatureDev_RedVerifyRoutesBackToCampaign (e2e/feature_dev_test.go) | |
| bots.whole-improve-loop | whole-improve-loop (Willy) | bots | covered-deterministic | TestWholeImproveLoop_ContinuesUntilComplete (e2e/whole_improve_loop_test.go) | |
| bots.branch-improve-loop | branch-improve-loop (Billy) | bots | covered-deterministic | TestBranchImproveLoop_ContinuesUntilClean (e2e/branch_improve_loop_test.go) | |
| bots.docs-refresh | docs-refresh (Doki) | bots | covered-deterministic | TestDocsRefresh_ConvergesFirstPass (e2e/docs_refresh_test.go) | |
| bots.whats-next | whats-next (Nexie) chat loop + dispatch | bots | covered-deterministic | TestWhatsNextV2_ChatLoop_PauseResumeClose (e2e/whats_next_loop_test.go) | |
| bots.secured-renovacy | secured-renovacy (Renovacy) patch/minor/fix-loop paths | bots | covered-deterministic | TestSecuredRenovacy_PatchFastTrack (e2e/secured_renovacy_test.go) | |
| bots.sec-audit-source | sec-audit-source (Seki): cap_findings + scan_health gates | bots | covered-deterministic | TestSecAuditSource_ScanHealth_GuardsAgainstFacade (e2e/sec_audit_scan_health_test.go), TestSecAuditSource_CapFindings_BoundsScannerOutput (e2e/sec_audit_cap_findings_test.go) | |
| bots.sec-audit-deps | sec-audit-deps (Depsy): per-ecosystem + generic CVE heuristics | bots | covered-deterministic | TestSecAuditDeps_GenericHeuristic_DetectsMalwareSignals (e2e/sec_audit_deps_heuristics_test.go) | |
| bots.e2e-coverage | e2e-coverage (Endy): matrix gate + continuation loop | bots | covered-deterministic | TestE2ECoverage_ContinuesUntilComplete (e2e/e2e_coverage_bot_test.go), bots/e2e_coverage_matrix_gate_test.go | |
| bots.review-pr | review-pr (Revi): finding ids, stale anchors, gate status | bots | covered-deterministic | bots/review_pr_finding_id_test.go, bots/review_pr_stale_anchor_test.go | |
| bots.dep-update-guard | dep-update-guard (Vetty): prepare/gate/automerge routing | bots | covered-deterministic | bots/dep_update_guard_gate_test.go, bots/dep_update_guard_automerge_test.go | |
| bots.feed-watch | feed-watch: state machine, routing, SSRF-safe fetch | bots | covered-deterministic | TestFeedWatch_ScriptsStateMachine (e2e/feed_watch_test.go), TestFeedWatch_FetchRejectsSSRF (e2e/feed_watch_test.go) | |
| bots.issue-triage | issue-triage (Triagy): author trust gate + label consumption | bots | covered-deterministic | TestIssueTriageTrigger_E2E_ConsumeAndLaunch (e2e/issue_triage_trigger_test.go) | |
| bots.golden-master-sync | the golden-master bot and its oracle harness stay in sync (same functions, same report fields) | bots | covered-deterministic | bots/golden_master_harness_sync_test.go | |
| bots.review-topology | mono/dual review topology injected only into opting-in bots | bots | covered-deterministic | TestReviewTopology_MonoClaudeSingleFamily (e2e/review_topology_test.go) | |
| bots.verify-gate | the deterministic verify_build/verify_run gate resists drift | bots | covered-deterministic | bots/verify_run_drift_test.go, bots/verify_probe_wiring_test.go | |
| bots.live-covered-catalog | the catalog bots that HAVE a live test (evolve, adr-cartograph, adr-rechallenge, rgaa-audit, bmady, devbox-setup, revi-converse, feature-gap-fill, test-coverage) | bots | covered-live | e2e/live_bot_adr_cartograph_test.go, e2e/live_bot_adr_rechallenge_test.go, e2e/live_bot_evolve_test.go, e2e/live_bot_rgaa_audit_test.go, e2e/live_bot_bmady_test.go, e2e/live_bot_devbox_setup_test.go, e2e/live_bot_revi_converse_test.go, e2e/live_bot_feature_gap_fill_test.go, e2e/live_bot_test_coverage_test.go | these bots' value IS the LLM work product (a review, an ADR map, an accessibility audit); they have no deterministic graph gate to assert against, so the live layer + quality panel is the honest coverage. Their graphs are compile-checked by bots.catalog-compiles |
| bots.uncovered-catalog | the catalog bots with NO test beyond parse+compile (modernize, wiki-gen, app-dev, supply-shield, supply-shield-cve, smoke) | bots | uncovered | plan: one e2e/live_bot_<name>_test.go each, on the runBotLive harness, with the quality panel — same shape as the live-covered row. Compile-only coverage (bots.catalog-compiles) is NOT coverage of what these bots produce | |
| studio-ui.run-console | run console view: timeline, node detail, diffs, chat | studio-ui | covered-deterministic | studio/e2e/specs/run-console.spec.ts | Playwright against the real server: the seeded run's IR graph (node ids, kinds, per-node status incl. the never-reached fail), its declared budget, its replayed edge-selection log lines and a published artifact's real payload all render. Chat needs a live agent — out of this row's deterministic reach |
| studio-ui.launch-modal | Launch modal: bot picker, vars, overrides, target repo | studio-ui | covered-deterministic | studio/e2e/specs/launch.spec.ts | Playwright: ?bot= resolves through the catalog to the workflow, the vars: block splits into required primaries vs defaulted Bot options, missing-required validation blocks the launch, and Engine options offers the workflow's own agent node for model retargeting. The "target repo" attach needs a forge connection (covered at REST level by the forge rows). The same spec found a REAL BUG — preview-cost answers nodes: null for a workflow with NO agent/judge node and CostPreviewChip dereferenced it, dropping the whole view into its error boundary — fixed in 457374dd; the test now asserts the positive contract (such a workflow still renders a launchable view) |
| studio-ui.board | /board kanban with drag-and-drop | studio-ui | covered-deterministic | studio/e2e/specs/board.spec.ts | Playwright: the native board's real columns + the CLI-seeded card render, and moving the card through the UI is asserted against the native store's REST read AND a reload (an optimistic-only client update fails). The move uses the selection toolbar rather than an HTML5 drag gesture — same mutation, same endpoint, no synthetic-DnD flake |
| studio-ui.pipelines | /pipelines control-center board + concurrency cap | studio-ui | covered-deterministic | studio/e2e/specs/pipelines.spec.ts | Playwright: the banner renders the cap the server actually booted with (--max-concurrent-pipelines, read back from /api/server/info — changing one side alone turns it red), and the seeded finished runs land as Closed cards linking to their own run console |
| studio-ui.dispatcher | /dispatcher live dashboard | studio-ui | covered-deterministic | studio/e2e/specs/dispatcher.spec.ts | Playwright drives the whole lifecycle: Start refused without a config, settings saved, dispatcher started, then the dashboard asserted against THAT instance's real settings (name, tracker, poll interval, slots) and lane counters, then stopped through its confirm dialog. A second test asserts the server's own config-validation error reaches the dialog. Poll pinned to 1h so the actor never claims the seeded card mid-test |
| studio-ui.bots-gallery | /bots gallery, per-bot home, guided builder /bots/new | studio-ui | covered-deterministic | studio/e2e/specs/bots-gallery.spec.ts | Playwright: the gallery lists what botregistry discovered on disk (and its search filters that set), the per-bot home renders the manifest fields + "declares no vars", and the guided builder is driven end to end — the assertion is the bundle it WRITES (main.bot + manifest.yaml under bots/scaffold-probe/) and the registry picking it up, not a toast |
| studio-ui.editor | workflow editor + /api/parse round-trip | studio-ui | covered-deterministic | studio/e2e/specs/editor.spec.ts | Playwright: the canvas + inspector are asserted against what the Go parser produced (node kinds, the tool node's command, entry node, budget) plus the real compiler diagnostic (C128), and an inspector edit is followed through save into the REWRITTEN .bot source on disk and back out through a fresh parse |
| studio-ui.secrets-view | Secrets view gated on server_info.secrets_enabled | studio-ui | covered-deterministic | studio/e2e/specs/secrets.spec.ts | Playwright: the gate flag is asserted, then add → list → delete is driven through the UI with the SEALED store file on disk as the oracle (name + last4 present, plaintext absent). ITERION_HOME/HOME/ITERION_SECRETS_KEY are redirected into the throwaway workspace so the operator's own store and keychain are never touched |
| studio-ui.browser-pane | Browser pane / preview attach | studio-ui | covered-deterministic | studio/e2e/specs/browser-pane.spec.ts | Playwright: a fixture tool node prints [iterion] preview_url=…, the runtime turns it into a preview_url_available event, and the pane auto-reveals carrying exactly that URL (bar + open link). The negative case — a run that published none has no Browser tab — pins the trigger. The URL is the suite's own loopback origin, so the iframe never leaves the test server. Live CDP attach needs a real Chromium session and stays out of the deterministic layer |
| desktop.wails-app | Wails desktop wrapper (window, runtime bridge, packaging) | desktop | unit-only | studio/src/tests/desktopBridge.test.ts | the Go half is cgo + build-tagged (desktop,webkit2_41) and excluded from lint/CI; an e2e needs a GUI session — the bridge contract is the testable seam |
| integrations.third-party-oauth | real third-party OAuth consent flows (GitHub App, IdP, MCP OAuth) | integrations | excluded | needs a real provider tenant and a human consent screen; iterion's side (state/PKCE, callback handling, token storage) is covered by cloud.sso-oidc, forge.github-app and tools-mcp.mcp-oauth | |
| integrations.claude-md-autoload | claw TUI CLAUDE.md auto-load | integrations | excluded | a claw-code-go TUI-boot behaviour with no iterion workflow surface; iterion uses its own command registry (carried over from docs/e2e_coverage.md) | |
| integrations.claw-lifecycle-hooks | claw lifecycle hooks / ctx propagation into hook handlers | integrations | excluded | iterion installs no lifehooks.Runner on its claw client, so there is no iterion-level behaviour to exercise; wiring one is a separate feature (carried over from docs/e2e_coverage.md) | |
| integrations.permission-modes-auto | claw permission modes auto / dontAsk | integrations | excluded | iterion runs headless (workflow mode) and never surfaces these modes; the two it does use are covered by tools-mcp.permission-gate |
