Project Glossary#

This glossary is the project-wide vocabulary for wastech-orchestrator. It is organized by the parts of the system that an operator or task author can touch. Terms keep the same names used in code and docs; legacy or removed names are marked explicitly.

Use this file as the canonical reading aid for commands, task files, config keys, flow and provider concepts, checks, Git behavior, runtime artifacts, notifications, and recovered state.

Contents#

Entry points#

  • wastech-orchestrator / worc - The CLI entry point. Both names expose the same commands, so the short alias is just a convenience, not a different interface.
  • install - Binds the current repository into <repo>/.worc/, writes or refreshes config.yaml, seeds the packaged guide, flow, and tool-executable copies, and can run preflight after setup. --reconfigure snapshots what it replaces and keeps only the newest three of each config.yaml.bak-* / flows.bak-* / tools.bak-* (never your state.db*.bak*).
  • run - Processes one task file end to end through the orchestrator. Takes the path to the task file (e.g. tasks/pending/my-task.md), not a task id — it starts a new task from the file. (Lifecycle commands like rerun/status/finalize take the task id instead.) It refuses (exit 1) a file that is a terminal task's own leftover, pointing at rerun / finalize, and claims its orchestrator.run marker exclusively, so a second run racing it refuses rather than overwriting the marker.
  • promote - Moves a staged task file from tasks/preparing/ into tasks/pending/ (atomic rename). Takes a task id or file name, or --all; a decomposition root pulls its subtask specs along with it. The watcher never scans tasks/preparing/, so a draft composed there is never picked up mid-write.
  • watch - Watches the task queue, resumes in-flight work first, then picks pending tasks one at a time. --queue NAME serves only that queue.
  • stop - Stops a running watch daemon via the stop ladder: idle stops with no prompt; a busy daemon is refused unless confirmed (YES) or forced — --force (soft: finish the current flow node, park at the next checkpoint, then exit) or --force-full (hard: kill the daemon and agent now; POSIX groups / Windows tree). A soft stop never hard-kills: on timeout it stays a pending graceful stop (every handle retained, the daemon exits at its next node boundary), and --force-full is the only hard rung. --non-interactive skips the YES prompt and refuses a busy daemon unless a force flag is given.
  • restart - Stops the running watcher (same stop ladder, same --force/--force-full/--non-interactive flags) and starts a fresh one with new flags.
  • status - Shows the active or latest persisted task state without starting work — status=, node=, fix_iterations=, elapsed_since_update_seconds=, last_error=, a cost= line with the task's recorded spend (every node attempt plus the supervisor layer, in the same words as the PR body's ## Run cost — cost=$114.11 over 19 provider calls (Claude's reported cost includes its subagents)), and a cost_not_accounted= line when some provider attempt of the task carries no recorded cost.
  • top - Live, read-only monitor (a client over the daemon, not an engine host): the active task + flow node, a parked/gate-pending marker, the queue-filtered priority-sorted pending queue, recent terminal tasks, and a tail of the daemon --log-file; polls state.db read-only and quits on q. Stdlib-only — no extra needed.
  • shell - Interactive operator console (the [shell] extra): a prompt_toolkit REPL. Entry is passive — it attaches to a live watch daemon or opens idle (the queue is not served on entry; it never auto-spawns or auto-claims). up/watch starts serving by spawning a daemon and verifying it came up (surfacing the captured startup error on failure); enqueue/promote/ps (jobs)/status/tasks/list/logs/prs/merge-task/finalize/rerun/down/restart/cancel/clear dispatch onto the existing commands (clear wipes the console screen), and help (?) prints the verb list. quit (exit) detaches (the daemon and any in-flight task keep running; reopen to reattach) — warning and asking for confirmation first when the daemon is still serving the queue. It never hosts the engine itself.
  • clear - Clears the terminal screen and its scrollback (the ANSI screen-wipe Ctrl+L/Unix clear emits). A visual wipe only — no logs or files are deleted (that is logs clean). Available both as a standalone command and as a worc shell verb.
  • list - Read-only enumeration of the active task, the tasks/pending queue, and recent terminal tasks. --all is the uncapped view of every tasks row plus a fourth section, rejected, derived read-only from the ledger: the ids whose only trace is a validation reject and that have no row, each with its validation_reason and rejected_at (the table view prints them under a rejected: heading with the reason). --format json is the scripting contract — every entry carries task_id, status, title, branch, and pr_url (the URL of the PR the task opened, or null; always null for a still-queued file); status is a display label (running (paused), parked (no daemon), done (recovered: <loop>)), so match its leading token. The table view (only) ends with a note: <Provider> cost not accounted (…) footer when a listed task has unpriced attempts. --format ids (filtered by --scope) is the machine-readable source that backs completion; rejected ids never appear there or in the default view.
  • completion - Prints a bash/zsh completion script (sourced once) that completes subcommands and flags statically and task ids dynamically via worc list --format ids.
  • preflight - Runs readiness checks for the resolved env file, every allowed provider (version, auth probe, a <provider>-binary: resolution line, and a live no-model isolation capability smoke), the isolation policy and its host floor (isolation-floor:), the environment expansion and assigned paths (allowed-environment:, extra-environment:, assigned-paths:), the gh repository pin (gh-repo-pin:), gh, Telegram, and the configured check sets, announcing each active relaxation (read-isolation: OFF, git-evidence: ON, the advanced-mode line). Read-only in intent but not filesystem-read-only: assigned-paths: resolves real paths and may repair the clone-local .git/info/exclude. It does not validate flows — that is validate-flow.
  • preflight --paid-isolation-probe - The one probe that cannot be free. Claude offers no way to run a command under its sandbox without the model, so this spends one real (billed) model call per supporting provider, letting an agent try to write into the two Git directories, the control home, and one allowed workspace path; the verdict is read from the filesystem, never from what the model said. Never implied — no run and no plain preflight spends it. Evidence lands at .worc/preflight/claude-paid-isolation-probe.json.
  • telegram-test - Sends one correlated Telegram prompt and waits for a reply as a smoke test.
  • upgrade-config - Updates an older config.yaml to the current schema shape without changing user values. It confirms before writing (-y / --yes skips; --dry-run never asks), because its add-missing-only merge writes back every key a deliberately small generated config left at its default, and re-emitting via YAML drops inline comments. Two removals it deliberately does not strip: agents.providers.<id>.sandbox and the whole skills block.
  • upgrade-docs - Refreshes the installed packaged guide copy under .worc/guide/. Generated content with no operator edits to preserve, so it is a straight overwrite (no backup): differing files are rewritten and files no longer in the package are removed; --dry-run previews.
  • rerun - Re-attempts a terminal task, either from scratch or by resuming from the saved checkpoint. While it runs it holds the orchestrator.run marker exactly as run does, so status / list / top report its task as running rather than parked (no daemon), and a second run/rerun refuses. --continue --reset-fix-budget grants a fresh fix budget: the consecutive fix-loop counters and every non-blocking evaluator's max_rework_per_stage count start afresh (the latter through an appended rework_budget_reset marker), while the global max_total_fix_iterations backstop is kept. Without the flag, the plan (--dry-run and the confirmation) names each non-blocking evaluator on the resume path whose max_rework_per_stage is already spent, because it would accept on its next pass without another fix round.
  • finalize - Records a task that was completed or abandoned out of band, without running the pipeline.
  • prs - Read-only list of orchestrator PRs that are open and awaiting merge; --check adds live GitHub state, --sync reconciles PRs merged externally (dry-run unless --yes).
  • merge-task - Operator go-ahead to merge a reviewed PR: pulls base_branch into the task branch, resolves any conflicts via the merge flow, then merges. The human-in-the-loop counterpart to git.auto_merge. A conflicted path the flow left without a visible decision aborts the merge (nothing committed, PR left open) and exits 2 with merge-task: manual action required — ….
  • tasks - Read-only list of every known task with its status and branch; --status filters.
  • validate-flow - Runs the full fatal flow validator (graph, ceiling, and the config-aware layer including the .worc/tools/ tool check) on demand over the operator's own flows in .worc/flows/, read-only and without claiming a task, plus three non-fatal lints, each WARN carrying its own consequence: an unknown {name} in a role prompt (it would render verbatim to the agent), a tool node whose rework/fail edge declares a fix budget (that number holds as written only while the tool emits top-level findings), and a non-blocking evaluator whose rework loop allows fewer fix rounds than its max_rework_per_stage (it accepts with ⚠️ after the smaller number; the loop is clamped to agents.max_fix_cycles when a config is loaded). Takes a flow NAME or --all (a bare invocation is a usage error). Exit 0 valid / 1 invalid / 2 not found or no config. preflight no longer validates flows — this is where flow correctness is checked before you queue work, and the engine enforces the same validator fatally at dispatch regardless.
  • logs clean - Sweeps the whole .worc/logs/ root: per-task artifact dirs and the daemon logs (daemon.log + backups, daemon-startup.log), keeping the ledger unless --all. --keep N --all honors both. It refuses while a task is active, and holds the daemon logs back while a watch daemon is live (two distinct messages).
  • runs clean - Removes per-task frozen bundles and sealed exchanges under .worc/runs/; --include-quarantine also drops tainted exchange evidence. Refuses while a task is active. The manual counterpart to logging.clean_runs_on_success.
  • memory - Inspects and curates the persistent store under .worc/memory/: show / validate (read-only) and compact / restore / clear (mutating, refused while a task is active).
  • worc-night-run (packaged skill, not a command) - The copy-ready agent skill install delivers to .worc/guide/skills/worc-night-run/ (copy it into .claude/skills/ to use it): an agent that drives the pending queue unattended with worc run / rerun --continue, one task at a time, climbs a bounded four-start escalation ladder per task, abandons a task on a security refusal, never publishes or merges, and leaves a write-up per task under .worc/night-runs/<stamp>/.
  • --config - Explicit path to config.yaml; it overrides automatic discovery.
  • --env-file - Explicit path to an environment file; if omitted, the orchestrator auto-loads <repo>/.worc/.env when present.
  • --log-level / --log-format / --log-file / --heartbeat-seconds - The global operator-output flags: verbosity (overriding logging.level), logfmt or json, an additional rotating log file (10 MB, 5 backups — a watch daemon's copy of it is what top and shell tail), and the long-operation heartbeat interval (default 30, 0 disables).
  • --version - Prints the CLI version and exits.
  • operator - Typically the person who runs and manages the orchestrator.

Task language#

  • Task file - The input contract for a task. Markdown is the normal format, and JSON is also accepted.
  • Front matter - The YAML block at the top of a Markdown task file. It carries the task metadata that the validation gate allows: a closed key set (ALLOWED_TASK_KEYS), with an unrecognized key rejected unconditionally and id plus a non-blank title and a non-empty ## Description required. None of that is operator-configurable — the keys that once pretended it was are gone (config v35).
  • id - Stable normalized task identifier. It is used in task storage, branch naming, artifacts, and reports.
  • title - Human-readable task name. It is used in branch slugs, PR titles, and summaries.
  • task_type - Dispatch key that selects the flow. Built-ins are implementation, deep_research, security_audit, merge, and the content-authoring flows content_chapter / content_translate / blog_article / blog_article_revise; operator flows can add more.
  • branch_name - Full task-branch override (only in new branch mode). When omitted, the orchestrator derives {repo.branch_prefix}/{epoch}-{id}-{slug} — the Unix-epoch stamp is what makes a fresh attempt's branch unique, so a rerun never collides with the previous one.
  • branch_mode (task field) - Where the task's git operations point: new (fork a fresh branch, the owned default), existing (work in branch_ref), or current (work in the working tree's current branch as-is). Wins over repo.branch_mode. A branch is orchestrator-owned only in new.
  • branch_ref - The existing branch a task works in; required iff branch_mode is existing (a validation error otherwise) and must already exist locally or on the remote.
  • publish (task field) - Downgrade-only cap on the publish node: commit (stop after commits), push (stop before the PR), or pull_request (full). Effective scope is min(flow_policy, publish); a no-op on a flow with no PR-publishing node.
  • commit_type - The Conventional-Commits type for every commit the task lands — the code commit on the task branch, each subtask commit, and the squash commit on the base branch. One of feat fix docs style refactor perf test build ci chore revert; omitted ⇒ feat. The scope is always the task id and is never the author's to choose. Fail-closed on an unknown type: the value reaches permanent history on the base branch. It is the only part of a commit message a task supplies — no node can write one.
  • trust_level (task field) - Per-task override of security.trust_level, the approval threshold for the dangerous-diff gate: strict gates every deletion/dependency-manifest edit, auto gates only a protected_paths match. Task value wins; never lowers the hard ceiling and cannot touch protected_paths.
  • slug - Lowercase branch fragment derived from the task title, truncated to whatever the 50-character readability budget leaves after the prefix, epoch, and id (and dropped entirely when nothing is left). It is part of the default branch name, not a separate task field.
  • auto_merge - Per-task publish override. true requests auto-merge, false opts out, and omission falls back to the config default.
  • prompt_audit - Per-task prompt logging override. It wins over the global config value in both directions.
  • decomposition (task field) - Per-task gate override for whether decomposition is permitted. It wins over agents.decomposition.enabled in both directions; it only flips the gate, never forces a split.
  • contacts - Plain-text mentions that appear in Telegram notifications and HITL prompts. They are not access control.
  • depends_on - List of other task ids that must be merged before this task can start. Non-blocking: the scheduler skips a dependent while a dependency is unmerged and runs another eligible task instead. Eligibility is computed live from PR/merge state — nothing is persisted for it.
  • priority - Scheduling hint for the eligibility queue: high / mid (default) / low, ties broken by filename. Fail-open — an unrecognized value folds to mid, so a typo never blocks a task. It re-orders eligible tasks only; depends_on is always stronger, and the single slot is unchanged.
  • queue (task field) - Queue tag that partitions one git-distributed task pool across several worc instances: an instance picks the task only when its orchestrator.queue equals this value (plain string equality, no balancing). Defaults to default, and unlike priority it is fail-closed — a non-string or blank value rejects the task. Decomposition subtasks inherit it implicitly.
  • subtasks - Operator-authored decomposition list. It names ordered subtask spec files that the orchestrator will run as one branch and one PR.
  • nodes - Per-node overrides keyed by flow node id: enabled: false skips that node for the task, and model / reasoning / provider overlay that node's executor for this run (best-effort — an invalid value is warned and skipped at run time, never fatal).
  • references - Opaque single-line strings (1 to 16, each non-blank and at most 200 characters) appended verbatim to the pull-request body under a ## References heading when the run opens a PR — on the new-PR and the reused-PR path alike. The gate checks the shape fail-closed (invalid_references) before the injection scan, so an argv-shaped entry still reports injection_suspected. worc never interprets the lines (it knows no tracker's syntax); the field exists for a tool that files tasks on the operator's behalf (Fixes #142) and is a no-op wherever no PR is opened. The committed <id>.summary.md is not rewritten — the annotated body is a separate pr-body.md artifact.
  • ## Description - The body section used to describe the requested work. A Markdown task is expected to have a non-empty description body.
  • Acceptance criteria - Testable statements that define what done looks like. They help a vague task become complete enough to skip refinement.
  • refinement - The automatic enrichment pass for vague tasks. It adds missing context instead of asking the user to infer it later.
  • decomposition (concept) - A sequential split of one task into multiple subtasks. It is flow- and planning-controlled; the per-task decomposition field only flips whether a split is permitted (default agents.decomposition.enabled), never forces one.
  • Task statuses - new means the task has been parsed but not yet validated; validated means it passed the gate; preparing means the orchestrator owns the slot and is setting up execution; running means the flow engine is active; done, failed, and manual_action_required are terminal; pending is the queue waiting state before the slot is acquired.
  • State machine - The finite set of task statuses and allowed transitions between them: new → validated → preparing → running → (done | failed | manual_action_required), with pending → validated | preparing ahead of the slot and a → failed / → manual_action_required bailout from every non-terminal status. Terminal statuses have no outgoing edge.
  • Park - A resumable pause, not a status: the row stays running while tasks.blocked_since records the first park instant (the clock agents.retry.max_blocked_s measures) and tasks.blocked_until records when the provider says its window reopens. A running row with no live executor reads as parked (no daemon), and a soft stop --force parks at the next node boundary. "Executor" is both the watch daemon (.worc/orchestrator.pid) and a worc run or worc rerun (.worc/orchestrator.run) — each records itself for its whole duration precisely so its task is never mislabelled parked and never invites a second engine.
  • Single processing slot - The invariant that only one task can be active at a time.
  • Task lifecycle folders - tasks/preparing is the staging folder the watcher never scans (compose a task there, then promote), tasks/pending holds queued tasks, tasks/done and tasks/failed hold terminal tasks, and .worc/tasks/rejected is the quarantine folder for invalid tasks. A running task keeps its file in tasks/pending — "currently active" is tracked by its state.db status, not a folder. The tasks root is the default; it is configurable via paths.tasks_dir (the subfolder names are fixed).
  • summary.md - The plain-language handoff written at task close. In the default publish path it becomes the PR body. When no provider-authored synthesis reaches disk — the supervisor layer is off, the terminal has no prose by design, the synthesis could not run, or the prose came back collapsed below a short floor — no summary.md is written and the deterministic report becomes the PR body instead (the run is flagged degraded).
  • Deterministic report - The single renderer for a PR body with no provider-authored prose. Sections: Changes / Steps / Checks / Gates / Technical debt / follow-ups / Pipeline nodes skipped. A pure function of state.db plus the task's artifacts (two renders are byte-identical), it never inlines the diff — it names the changed paths and points at logs/<task-id>/current.diff. It replaced the four-field What / How / Integration / Why stub, so a failed or manual_action_required run now gets a real report.
  • Fact sections (## Provider fallbacks, ## Run cost) - The two deterministic blocks that close every PR body, whoever wrote the prose: one line per node that ran on a provider other than the one it was routed to (saying when the flow pinned it, and why the routed one failed), present only when one did, and the task's recorded spend with whatever was not priced named beside it. Rewritten in place under their headings, never duplicated, when a body written at an earlier stop is reused after rerun --continue, so they describe the whole run.
  • degraded - The additive summary.json flag marking a run whose synthesis was expected but did not reach disk (absent, unusable, or collapsed).
  • validation_report.json - The structured report written by the validation gate. Rejected tasks use it to explain the failure, and accepted tasks may also persist it for resume/audit.
  • task.normalized.json - The normalized resume-safe copy of the parsed task metadata written under logs/<task-id>/ and loaded back on recovery.
  • rejected - The quarantine outcome for a structurally invalid task. Rejected tasks do not create a branch.

Configuration#

  • config.yaml - The operator config file for repository binding, provider selection, security policy, check sets, Git publishing, and notifications.
  • schema_version - The config format version (currently 41), bumped only when the format changes. The loader refuses a newer schema than it understands; an older or absent one loads, and upgrade-config brings it forward.
  • orchestrator - The outer queue behavior block. It controls automatic continuation, the watch poll interval, and this instance's queue selector.
  • orchestrator.auto_mode.enabled - When true, watch may pick the next pending task after terminal cleanup succeeds.
  • orchestrator.auto_mode.confirm_next_task - Fail-closed Telegram approve/deny prompt before watch claims each pending task (default false; requires telegram.enabled). It gates new claims only — resuming an in-flight task after a daemon restart is never gated.
  • orchestrator.auto_mode.confirm_timeout_s - How long that claim gate waits for the answer (default 900, must be > 0). Its own key rather than telegram.ask_timeout_s, because the gate holds an idle slot and is re-asked next tick where the HITL ceiling bounds a node parking a half-finished task. A refusal — deny, silence, or no transport alike — is remembered for an hour instead of re-prompting every tick; the memory lives in the watch loop and is not persisted. worc stop cancels a wait in flight.
  • orchestrator.poll_interval_seconds - Watch loop interval; each tick fetch/pulls base_branch before re-scanning. 0 makes watch a single pass.
  • orchestrator.queue - This instance's queue selector (default default), matched by string equality against a task's queue. worc watch --queue NAME overrides it per launch.
  • repo - The target repository block. It names the remote URL, local clone path, base branch, branch prefix, branch mode, cleanup checkout, and extra governance paths.
  • repo.url - Remote repository URL for the target clone.
  • repo.local_path - Dedicated clone or workspace path used for agent runs.
  • repo.base_branch - The branch checked out before task work and, by default, restored after terminal cleanup (see repo.checkout_base_on_cleanup).
  • repo.branch_prefix - Prefix for the default task branch name.
  • repo.branch_mode - Instance default for where task git operations point (new/existing/current, default new); a per-task branch_mode overrides it.
  • repo.checkout_base_on_cleanup - Tri-state (true/false/unset) gating whether terminal cleanup returns to base_branch; unset defers to the branch mode (new returns; existing/current stay). Instance-only.
  • repo.governance_paths - Repo-relative globs (default [], config v41) naming where this repository keeps its rules, added to the built-in governance set (.agents/rules/** plus root AGENTS.md / AGENTS.override.md / CLAUDE.md) whose edits are reported as a notice — log, PR summary, ledger, Telegram — never a block. Additive only: no exclusion syntax exists, and a leading !, an absolute path, a ~ or a .. is refused at load, so no configuration can narrow or silence the notice.
  • paths - Optional block locating the task lifecycle on disk.
  • paths.tasks_dir - Repo-relative directory holding the preparing/pending/done/failed lifecycle subfolders (default tasks). Validated repo-relative (no ../absolute) and rejected if it lives under the gitignored .worc/ home; a subpath such as config/tasks is allowed.
  • agents - Provider availability, retry budgets, decomposition, and provider-specific settings.
  • agents.allowed - The provider ids the router may use.
  • agents.max_stage_attempts - Maximum attempts for one stage, including fallback.
  • agents.max_fix_cycles - Maximum fix rounds of one named fix loop (default 15): with 15, fifteen rounds run and the sixteenth fail/rework parks the task. A flow's own budgets entry is clamped to it.
  • agents.max_total_fix_iterations - Global cap on fix rounds across the whole task, including subtasks (default 30, must be >= max_fix_cycles); a budget of N is N rounds here too.
  • agents.retry - The bounded same-provider transient-retry policy plus the park ceiling: max_attempts (retries after the first failure, default 2, counted per provider in the route and separately from max_stage_attempts), deterministic exponential backoff between base_delay_s (2.0) and max_delay_s (30.0), and max_blocked_s (21600.0 — 6h) as the total parked wall-clock after which a parked task fails. Only the transient classes (provider_unavailable, network_unavailable) are retried.
  • agents.decomposition.enabled - Enables or disables decomposition as a planning option.
  • agents.decomposition.max_subtasks - Maximum accepted split size for decomposition.
  • agents.providers.<id> - Provider-specific config for codex or claude. It holds the executable command, model, reasoning level, timeout, permission profile, extra args, and the primary marker; Claude also uses max_turns, max_turns_gate, and background_tasks.
  • agents.providers.claude.max_turns_gate - Claude-only: a run that exhausts max_turns pauses for a durable Telegram continue/stop prompt instead of failing (default false; requires telegram.enabled). Continue resumes the same agent session with a fresh turn grant, which is what makes a low max_turns safe.
  • agents.providers.claude.background_tasks - Claude-only (a load error on codex): whether the agent may start background tasks — run_in_background subagents and shells. false (the default) launches the CLI with CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1, so subagents run in the foreground (several launched in one message still run in parallel), because headless -p mode stops every background task when the agent ends its turn and the run would end with a promise instead of the work. true also removes that variable when the operator's own environment exports it. The backstop either way is the background_work_lost error class.
  • security - Isolation, environment allowlist, denied paths, denied commands, and the fail-closed security ceiling.
  • security.strict_isolation - Controls whether full-access provider modes are rejected at preflight. The master switch: it always wins toward relaxation.
  • security.disable_read_isolation - Operator escape hatch (default true, i.e. read-isolation off out of the box) that relaxes only the read side of the envelope: native provider instruction/config discovery is restored and the private read-deny projection is lifted. The write side stays — including the write-deny on Claude's own config home, which only agents.providers.claude.allow_native_memory lifts. Effective off = disable_read_isolation OR NOT strict_isolation.
  • agents.providers.claude.allow_native_memory - The only switch governing the write side of the native-memory deny. Off (default) keeps Claude Code's own auto-memory store Write/Edit-denied, so .worc remains the complete input set; on lets it persist across tasks outside the orchestrator's redaction net and audit, and announces itself per run.
  • security.allowed_environment - Environment variable names that are allowed to reach child processes.
  • security.denied_read_paths - Paths that the orchestrator will not read as secrets or task context.
  • security.denied_commands - Commands that are refused even if they are otherwise present in config or flow arguments.
  • security.allow_git_evidence - The operator grant (default false) that makes a flow node's git_evidence declaration effective. config.yaml-only, never a task / extra_args / flow key.
  • security.trust_level - Approval policy for the mid-task dangerous-diff gate: strict gates every deletion/dependency-manifest edit, auto (fresh-install default) gates only a protected_paths match. A per-task trust_level overrides it; it never lowers the hard security ceiling. Replaced the removed deletion_approval_exempt_paths (config v25).
  • security.protected_paths - Repo-relative globs (same dialect as checks.command_sets[].paths) whose files always require approval on any change regardless of trust_level — the always-ask floor no level can lower. config.yaml-only; default [].
  • validation - The task input hardening block. It rejects malformed or suspicious task files before branch creation.
  • validation.max_task_bytes, validation.max_task_lines, validation.max_line_bytes, validation.max_control_ratio - Size and content ceilings for task input (defaults 262144, 5000, 8192, 0.01). These four plus quarantine_folder are the whole block — which fields are required and whether an unknown key is refused are hard-coded in the gate, not configurable (config v35).
  • validation.quarantine_folder - Where invalid tasks are moved (default ./.worc/tasks/rejected).
  • checks - The operator-authored quality gate block.
  • checks.command_sets - Named groups of checks selected by diff paths. An empty mapping means no quality gate.
  • checks.timeout_seconds - Default per-command timeout for the check runner (default 7200); a set's own timeout_seconds overrides it.
  • CheckCommandSpec - One structured check command: a logical name, an explicit argv list, and an optional repo-relative cwd.
  • CommandSet - A named bundle under checks.command_sets: a diff-selected group of CheckCommandSpecs with optional paths, timeout_seconds, and skip_if_unavailable.
  • paths - Diff selectors inside a check set. They decide when that set runs.
  • skip_if_unavailable - A check-set flag that allows a missing toolchain to be skipped loudly instead of failing the task.
  • git - Publish and PR behavior.
  • git.create_pull_request - Controls whether the orchestrator opens a PR after push.
  • git.pr_base - Target base branch for the PR.
  • git.auto_merge - Instance-level auto-merge default.
  • git.auto_merge_strategy - Merge strategy used when auto-merge runs, merge/squash/rebase (default squash), and the default for merge-task --strategy.
  • git.auto_merge_wait_for_checks - Whether GitHub-native auto-merge waits for required checks (and the default for merge-task --wait-for-checks).
  • git.merge_flow - Name of the flow merge-task runs to resolve a conflicting base-merge (default merge). A clean base-merge is mechanical (no flow); only a conflict launches it.
  • git.footprint.audit_commit_message - Commit message template for the audit trail commit.
  • git.footprint.audit_on_branch - Chooses whether the audit trail is committed on the task branch or on a sibling branch.
  • telegram - Optional Telegram human-in-the-loop and notification config.
  • telegram.enabled - Enables or disables the Telegram transport.
  • telegram.bot_token_env - Environment variable name that holds the bot token.
  • telegram.chat_id_env - Environment variable name that holds the chat id.
  • telegram.ask_timeout_s - Timeout for blocking HITL waits.
  • telegram.trace - One-way, best-effort live progress feed (default false): one message per finished flow node, node id and outcome only. A no-op when Telegram is disabled.
  • supervisor - The advisory oversight layer above any flow; on by default.
  • supervisor.enabled - Whole-layer switch (default true). false means the layer object is never built: no per-step observation, no finalize turn, no subtask handoff brief — the layer's three phases, all gone at once. The rest of the block becomes inert and unvalidated (one warning), and memory.enabled is forced to false for the run (a second warning names both keys). The PR body is then the deterministic report. It is its own key rather than a global observe.mode: none because the cadence-narrowing rule does not apply when there is no cadence.
  • supervisor.role_file - The observe-lens prompt file. Never loaded when the cadence resolves to none.
  • supervisor.provider - Provider all three phases run on (codex/claude); absent → the global primary. Validated ∈ agents.allowed, symmetric with flow nodes.
  • supervisor.observe - The observation cadence block: mode (all/selected/events/none, default events), triggers (rework/failure/fallback), include_nodes (for selected), plus this phase's model/reasoning. tool, checks, and the terminal publish node are never observed under any mode. A flow may narrow the mode but never widen it.
  • supervisor.finalize / supervisor.handoff - The other two phases' model/reasoning: the turn that writes summary.md (the PR body), and the subtask brief between decompose regions. Model and effort are per phase — there is no flat supervisor.model/supervisor.reasoning any more.
  • supervisor.emit_follow_ups (flow field, not config) - Opts a flow's finalize turn into emitting the evidence-gated follow_ups array. Off by default; code-oriented flows only. Independent of the evaluator-findings half, which is merged in regardless.
  • supervisor_usage - The measured per-run cost block in summary.json: calls, input, cache reads and writes, output, cost, and provider wall time — as a total and a by_function split over the jobs that ran (observe/finalize/handoff), in run order. Absent entirely when the layer made no calls, because a report of zeros would read as "it ran and cost nothing".
  • logging.level - Persisted operator trace verbosity (debug/info/warning/error, default warning); the --log-level flag overrides it for one invocation.
  • logging.artifacts - Which per-attempt provider files survive under logs/<task-id>/stages/…/<attempt>-<provider>/: minimal (result.json + request.json), standard (default; adds stdout.log/stderr.log), full (everything, adding events.jsonl and provider extras). request.json — the only record of an attempt's full argv and permission profile — survives at every level. Prompt-audit is independent.
  • logging.clean_runs_on_success - Whether a successful task evicts its own per-task state under .worc/runs/ (default true). Failed/parked tasks and quarantined evidence are never cleaned automatically; worc runs clean is the manual half.
  • memory - The repo-scoped persistent memory block: enabled (dataclass default false, but a fresh install writes true) plus bounded, runtime-clamped knobs — short-term TTL, per-node retrieval packet caps, promotion thresholds, and the background-cleanup budget. No knob is a fatal config error. supervisor.enabled: false forces memory.enabled to false for the run.
  • Memory tiers - The storage families the store keeps and worc memory clear --kind targets: short (recent episodic), long (the promoted long-term lessons), entity (repo entities), and quarantine (the mixed-kind holding area).
  • prompt_audit - Global default for prompt recording. A per-task value can override it.
  • tools.default_timeout_seconds - Flow-wide default wall-clock timeout for a tool node whose own timeout_seconds is unset (default 3600). Optional block; absent → the same default.

Flow vocabulary#

  • Flow - A validated YAML graph of typed nodes selected by task_type. The pipeline is data, not a hardcoded stage loop.
  • Packaged flow - A built-in flow shipped with the package under packaged/flows/. Delivery-only: install copies it into .worc/flows/, and the orchestrator resolves flows only from there — never from the packaged tree at run time.
  • Operator flow - A repository-local override under .worc/flows/<task_type>.yaml.
  • implementation - The default coding flow that produces a reviewed Pull Request.
  • deep_research - The research flow that produces a documentation-oriented output.
  • security_audit - The audit flow that produces a private control-workspace report.
  • merge - The conflict-resolution flow worc merge-task runs (only) when pulling base_branch into a task branch conflicts: conflict_resolution (agent) → testing (checks) with a bounded fixing loop, terminating at a no-op publish node (done, policy: none). Its nodes read the conflict inventory as {conflicts_path} (every conflicted path, its kind, the sides present, what the tree holds — markers are only one shape of conflict). It performs no git itself — the orchestrator commits the merge and merges the PR after the flow returns a clean, green tree in which every conflicted path shows a decision. Not dispatched for incoming tasks; selected by git.merge_flow.
  • content_chapter - A long-form book chapter editor: a read-only scout → editor → the deterministic check_chapter prose gate (structure only) → a blocking story critic → a style pass → publish, all rework routed through fixing.
  • content_translate - Adapts an approved source-language chapter into an English production file, gated by check_chapter (structure plus per-page length limits set in the flow's args) and an adaptation critic.
  • blog_article - Writes one new authorial blog article from scratch: a read-only scout → a networked researcher → the writer → the deterministic check_length minimum-size floor → a blocking tone/style critic → a polish pass → publish, all rework routed through fixing.
  • blog_article_revise - Sibling of blog_article that revises an existing article in place instead of writing a new one, with the same shape and gates.
  • Flow node kinds - agent runs an editing or authoring step, evaluator reads an artifact and returns a verdict, checks runs the quality gate, tool runs an operator executable from .worc/tools/ out-of-process (exit-code / optional-JSON gate), hitl asks the human in the loop, and publish performs the orchestrator-owned publish step.
  • Tool registry - The .worc/tools/ directory that turns a tool node's free-string tool: name into an executable, owning the path containment (a name resolves to a file inside that directory, never a path). install seeds the two shipped tools, check_chapter and check_length (each with a .cmd wrapper for Windows); a node's flat scalar args reach the tool on stdin.
  • Run vocabulary - RunKind is the top-level run discriminator (stage or evaluator); EvaluatorRole names the shipped evaluator roles (review, critic, verifier, test_quality).
  • Typed node output - OutputContract selects the strict structured-output parser for agent nodes (none, human_input, planning); HumanInputSignal is the validated question/approval payload; TypedStageOutput is the parsed structured result.
  • Route result - RouteSource says whether a node's provider came from config or an explicit flow-node override; ResolvedRoute, ProviderAttempt, and StageOutcome are the router's resolved pair, per-attempt record, and final result bundle.
  • NodeInfraError - The node-run exception used when a provider could not complete a node because of infrastructure trouble; it may lead to fallback or a terminal stop.
  • NodeManualRequired - The node-run exception that forces the task into manual_action_required.
  • Execution identity - ExecutionUnit is the (task_id, subtask_order) identity for a root task or one decomposed subtask; flow_fingerprint is the hash of the resolved flow snapshot used on resume.
  • Node bookkeeping - current_node is the in-flight node inside running, active_subtask is the 1-based subtask counter on the task row, and best_effort lets an agent node continue when no provider can complete it.
  • output_artifact - A named slot that stores an agent node's result and threads it downstream. The slot table is core-fixed and closed: enriched_spec (task.enriched.md, audit-only), plan (plan.md, the one slot that reaches a downstream provider, as a redacted exchange copy), summary (summary.md, an orchestrator publish input), and report (report.md, written privately into the flow's report directory).
  • Implementation flow nodes - refinement enriches a vague task, planning builds a plan and may propose decomposition, implementation edits files, testing runs checks, review performs read-only evaluation, fixing loops on quality findings, documentation writes the handoff material, and publish finalizes Git publication.
  • Deep-research flow nodes - refinement scopes the question into anchored sub-questions (it runs on every task; it is no longer gated on derived.needs_refinement), analysis_core / analysis_surfaces / analysis_docs_tests are three sequential passes over disjoint surfaces each with a narrow mandatory remit, coverage_gate measures those passes (rework re-enters at analysis_core), external_research fetches outside sources, architecture_design organizes the evidence and writes no file, synthesis writes the deliverable (output_file: report.md), citation_check validates sources.json, document_checks runs the operator's command_profile over the Markdown about to be committed, fact_verification and critical_review rework or accept, and publish creates the documentation PR.
  • Security-audit flow nodes - scope frames the audit, repository_analysis inspects the repo, dependency_scan runs evidence scanners, threat_analysis and finding_verification refine findings, report writes the private report, and private_storage records it without git.
  • resume_role_file - A node's optional second, short role prompt, used only on a turn that continues a session this node has already spoken on. Allowed only where a session survives — session_scope: editing_lineage on an agent, resume_own_lineage on an evaluator — and never in a flow's defaults: block. The choice is the orchestrator's, made per attempt at the same seam that decides the resume argv, so a dropped session gets the full text back automatically. Recorded per attempt as resumed in the prompt audit.
  • skills / allow_skills - Node-declared access to the target repository's own Claude Code skills (<repo>/.claude/skills/<name>/SKILL.md). Agent nodes only; skills are off unless a node asks, carried by a real per-attempt CLI switch (Claude --disable-slash-commands, Codex --disable skill_search) rather than by prompt text. Naming a skill is itself the request; allow_skills is tri-state (null → on iff skills names one). Requiring is advanced mode only — skills: or an explicit allow_skills: true under security.strict_isolation: true is a validation error, never an inert field. false narrows and is always legal. The declared names and the resolved switch are persisted on the node run (skills_required / skills_allowed).
  • when - A deterministic skip predicate on a node. It enables or disables execution based on a resolved fact.
  • permission_ceiling - The highest permission profile allowed by a flow.
  • output_policy - The write-containment policy for a flow: a closed set of three — code_change (the diff anywhere in the repo is the deliverable), repository_document (a <report_dir>/<task_id>/ report bundle, docs/research/<task_id>/ by default, that must produce report.md + sources.json), and private_control_workspace_report (a <report_dir>/<task_id>/ report, .worc/security-reports/<task_id>/ by default, that never enters git). The name is a contract, not a description; see flow-authoring.md → Output policy.
  • report_dir (flow field) - Optional repo-relative POSIX base for the deliverable of either report output_policy; the engine still appends /<task_id>, so a flow selects a home, never a template. Validated at flow load: no absolute path, drive letter, .. or backslash, every segment portable and not a Windows device name, and never overlapping .worc/, .worc-io/, .git/ or the configured paths.tasks_dir tree; on a code_change flow the key is a load error, because that policy resolves no report directory. The resolved directory reaches prompts as the {report_dir} variable (agent, evaluator, and a tool node's stdin paths) — the packaged deep_research synthesis prompt names it instead of a literal path — and a role prompt naming {report_dir} on a code_change flow is a fatal flow-load error rather than an empty render. Absent, every resolved directory is what it always was.
  • publishing - The terminal publication policy for a flow — a closed set of five: pull_request, documentation_pull_request, local_artifact, private_control_workspace_report, and none.
  • network_policy - The flow-wide network grant, advisories (vulnerability/package metadata, used by security_audit) or research (broader external fetches, used by deep_research). Absence means no network by default.
  • network_access (flow node field) - Per-node override of that flow-wide default: true grants network to this node even in a flow with no network_policy, false forces it offline even when the flow grants one, and absence inherits. It moves only the network dimension — never the filesystem ceiling.
  • session_scope - The provider session intent for a node, such as fresh disposable, editing lineage, or resumable own lineage.
  • lineage_affinity - An editing_lineage node's declaration that it joins another node's editing session instead of owning its own. The lineage key is lineage_affinity or <node id>, so an affinity-less node owns a lineage named after itself and a node with lineage_affinity: X shares lineage X. Chains are forbidden — the target must be a lineage owner.
  • FlowEngine - The execution spine that traverses the graph, routes outcomes, owns budgets, and updates checkpoints.
  • budget and loop - The repeat counters on rework edges. They bound fix cycles and other repeated regions. A budget of N is N fix rounds, read the same way for a named loop (budgets: {review_fix: 2}), an inline budget: 2 and the global max_total_fix_iterations backstop: the limit is checked before a round is charged, and the next fail/rework after the Nth is refused. (Named loops and the backstop used to allow one round fewer than their number.)
  • No-progress guards - The two checks that end a named fix loop before its budget, recorded as the failure report's limit_exhausted: no_file_change (the tree is unchanged across consecutive rework charges — the agent emits output without editing; in-memory, reset by a restart) and repeated_findings (the same node returned an identical non-empty finding set three times in a row — derived from the current attempt's recorded verdicts, so it survives a restart). Neither applies to a non-blocking evaluator's rework edge, since that node never parks. A tool node has its own bound: a byte-identical fail without top-level findings parks on the second repeat, or at the loop's declared budget when it carries data.
  • Non-blocking evaluator (blocking: false) and max_rework_per_stage - An advisory gate that never parks the task. It takes at most max_rework_per_stage rework rounds (counted from its recorded verdicts, per subtask) — or fewer, when the budget of the loop its rework edge charges or the global backstop runs out first — then accepts with its finding still open, with a console warning naming the limit reached first and the ⚠️ TRACE_REWORK_EXHAUSTED trace. The count survives rerun --continue; only --reset-fix-budget starts it afresh.
  • {change_overview_path} / {diff_base} - The prompt variables (agent, evaluator, and a tool node's stdin paths) for the change overview — written beside {diff_path} from the same snapshot, at most 200 paths per section, one line per changed path with its kind (A/M/D/R old → new) and line counts, a security.denied_read_paths match listed by name only and marked [denied] — and for the full SHA of the commit the change is measured from. Both are empty until the first workspace-write edit. Every node after that edit already finds the overview, the diff and Change base: <sha> in its context footer, so a prompt names them only to say something specific. change_overview is therefore a reserved node-id name.
  • Where-to-start sentence - The one sentence the orchestrator appends to the context footer of every node after the first edit (a prompt cannot branch on capability, so it is not a role-prompt concern). A node whose route grants a shell on every provider it may land on — unknown counts as no — is told to start from the overview, read an added file directly, inspect any other path with git diff <base> -- <path>, read the full diff only if it needs all of it, and leave [denied] paths alone; any other node is told to read the full diff with the overview as its map. In a decomposed run it also names the overview's "Change since the orchestrator's last commit" section as the subtask's own change. A fallback attempt handed only a partial diff gets neither the overview, the base, nor the sentence.
  • {conflicts_path} - The prompt variable naming the merge flow's conflict inventory; empty everywhere except a worc merge-task run whose base merge conflicted. conflicts is therefore a reserved node-id name.
  • sub_flow - The decomposition region that is repeated for each accepted subtask.
  • decomposition - The flow feature that fans one task into sequential subtasks when planning accepts a split.
  • supervisor - The advisory layer above every flow (on by default, removable with supervisor.enabled: false). It observes completed steps read-only at its configured cadence and writes the final summary, but it is not a node and not a status.
  • output_file (flow node field) - Declares that the file an agent node writes is its output: {<node_id>_path} then resolves to a redacted copy of that file rather than the node's closing message. For a node whose deliverable is a document, the closing paragraph is the smaller half of what downstream nodes should grade.
  • Node-output channel - {<node_id>_path}: every agent node's output (as <node_id>.out.md) and every tool node's redacted stdout, exposed to later nodes as a path, derived from the node id with no declaration. Both agent and evaluator prompts resolve these names, so an evaluator can grade an upstream node's own work and not only the file a later node wrote from it.
  • defaults.evaluator (flow block) - Per-flow defaults every evaluator node inherits (session_scope, permission_profile, max_rework_per_stage, gate_severity), so a flow whose evaluators all judge "good enough" rather than "correct" can lower gate_severity once instead of per node.
  • gate_severity - The minimum finding severity that drives rework on an evaluator (blocking/critical/high/medium/low; built-in default high). Less-severe findings are recorded as advisory and reach the PR follow-ups instead. Orthogonal to blocking.
  • gating (persisted finding key) - Whether a finding met its node's gate_severity. It is what makes the follow-ups composition gate-aware: only findings a gate let past become PR follow-ups, plus a gating finding still open because a non-blocking evaluator spent its rework budget. The persisted shape is {severity, reason, paths, gating, fix}.
  • task_type dispatch - The mapping from task type to flow. It is the entry point for choosing which graph runs.

Providers#

  • codex and claude - The only supported provider ids.
  • ProviderId - The canonical enum for supported providers.
  • global primary - The single configured provider with primary: true. It runs any node without an explicit provider and is the only fallback target.
  • ResolvedRoute - The chosen primary and fallback provider pair for one node.
  • fallback - A second provider run used only for infrastructure errors and only when policy allows it.
  • ProviderHealth - The preflight result for one provider: executable availability, version, secret-free diagnostics, the advisory degraded_reasons (fatal only when that provider has no fallback), and the auth probe — None there means not probed, never "authenticated".
  • AgentProvider - The provider adapter contract. It exposes preflight and one stage run, and it does not own fallback or state changes.
  • AgentRunRequest - The request object sent to a provider. It carries the task id, node id, working directory, prompt, permission profile, timeout, attempt and node-run id, model, reasoning, session id, extra args, the optional output schema, and artifact paths (the change overview among them, plus the change's base SHA and the where-to-start sentence the context footer closes with) — task content reaches a provider as a path, never as argv.
  • AgentRunResult - The normalized provider result, including status, timestamps, optional structured output, and artifact paths.
  • ProviderError - The normalized provider exception. It carries an error class that the router uses for fallback decisions.
  • RouteSource - Where a node's provider came from: config default or an explicit flow-node override.
  • ResolvedRoute - The chosen primary and fallback provider pair for one node.
  • ProviderAttempt - One provider invocation within a node run.
  • StageOutcome - The router result bundle for one node run, including attempts, result, terminal error, and partial change metadata.
  • ErrorClass - The provider failure taxonomy: binary_not_found, unsupported_version, invalid_invocation (the CLI rejected our argv with an argparse/usage error — a bad-argv bug on our side, not fallback-eligible, so it surfaces instead of masquerading as an unsupported version), model_request_invalid (the provider rejected our model request with a model/schema HTTP 400 — bad request / unsupported schema; not fallback-eligible, so it surfaces loudly instead of being misread as a generic process_crashed and silently burning the fallback provider), authentication_failed, authorization_failed, rate_limited, network_unavailable, provider_unavailable, timeout, process_crashed, invalid_output, permission_denied, configuration_error, task_failure, agent_no_progress (a parseable terminal event that carried no work at all — zero output tokens, no structured output, not a turn-cap stop; raised so the router falls over rather than letting a dead run pass as a quality task_failure, and fallback-eligible but never park-eligible), session_unavailable, cancelled (an operator stop killed the agent mid-run — produced only by the router when a cancellation was requested, which is what keeps a stop-kill distinguishable from a genuine process_crashed; not fallback-eligible, and the core parks the task), background_work_lost (Claude: the agent ended its turn while backgrounded subagents it started were still running, and the CLI stopped them at exit — read from the CLI's own stream-json, a subagent the agent stopped itself not counting; raised so a promise is never accepted as done, not fallback-eligible and not park-eligible, so the stage stops with the stopped tasks named and the attempt's cost still recorded), capability_unavailable (WRI-002/003 — a required host isolation capability is missing pre-model: no supported Claude Bash sandbox on native Windows for a workspace-write node, missing Linux/WSL2 bubblewrap+socat, or a Codex codex sandbox that cannot run / cannot demonstrate the generated profile on this host; a deterministic pre-model infrastructure result that may fall over only to a same-or-stricter, self-isolating provider, else manual_action_required — never a silent downgrade), and containment_unverified (WRI-012 — the provider process tree could not be proven quiescent after the attempt, so an unknown background/reparented descendant may still be writing; a security / manual-action condition, deliberately not fallback-eligible and not park-eligible, routed to manual_action_required).
  • Idle-tail settling - Claude's guard against a CLI that wrote its final result and then neither wrote nor exited: once the stream's last event is a result with no background task still out and 120 seconds pass in silence, the adapter stops the process and uses that result, with a warning saying so. A healthy run exits within a second of its result.
  • Provider fallback note - What an infrastructure fallback leaves behind once the node completes on the other provider: a console warning (node ran on a fallback provider — routed to <a>, ran on <b> after <a> failed (<class>), plus "the flow pinned this node's provider" when it did), the ⚠️ TRACE_PROVIDER_FALLBACK trace beside the node's ordinary one under telegram.trace, and a line in the PR body's ## Provider fallbacks section. The result stands and nothing is rerouted — the note exists because a critic pinned to a second model that silently ran on the first one passed, but not as the check the flow planned.
  • Infrastructure error - A provider failure that can be retried or fallen back from, such as a missing binary, auth failure, timeout, or crash.
  • Quality failure - A successful provider run that produced a failing result. It goes to fixing, not fallback.
  • session_unavailable - The provider could not resume the requested session. The router retries the same provider once with a fresh session.
  • permission_profile - The orchestrator permission profile passed to the provider adapter.
  • read-only - A permission profile that forbids writes. It does not imply "no shell": a flow node declaring git_evidence: true, with security.allow_git_evidence on, may run the read-only git verbs while staying read-only on disk. Read the profile as a mutation guarantee, not a capability list.
  • git_evidence (flow node field) - A node's declaration that its job needs read-only delivery history. Inert on its own — the capability arrives only when the operator sets security.allow_git_evidence, and it reaches only the nodes that asked.
  • security.allow_git_evidence - The grant switch for that capability, not a kill switch: off means "no node gains a capability it did not already have", and a Codex read-only node reads git history regardless (its sandbox permits commands). So off leaves the same flow with different reach per provider; on is what makes them match. Announced per run as git-evidence: ON.
  • Control-state drift (WRI-009) - Git control state (index, HEAD, task ref, repo-local config, hooks, merge markers) changing across a provider attempt that gets a shell. It is reported and never parks the task, on any node class — a WARNING carrying the redacted aspect summary plus the ⚠️ trace label TRACE_GIT_CONTROL_DRIFT, and the run continues. The fingerprint reads "the state moved", never whose hand moved it, so parking cost a finished node's work over what is usually the operator's own neighbouring commit. Read the warning as a stop-the-run signal; what actually holds a commit made inside a run is the pre-publish dangerous-diff gate.
  • Shell reach - The provider-neutral question "does this attempt get a shell?", which is what every drift/write bracket keys on rather than a profile name: Codex's read-only sandbox permits commands, while Claude's depends on whether the resolved tool set keeps Bash. The seam dispatches by provider id and the adapters answer; it is fail-closed toward bracketing (an unknown provider yields True), because a wrong True costs one fingerprint and a wrong False leaves an attempt unwatched.
  • ⚠️ synthetic trace labels - The Telegram/console trace outcomes that are not a plain node verdict. Five take the node's single trace slot: TRACE_REWORK_EXHAUSTED (a non-blocking evaluator accepted after its rework rounds ran out — its own max_rework_per_stage, or the loop budget / global backstop when that was reached first), TRACE_UNEXPECTED_WRITE — done (node wrote to the workspace unexpectedly) — for any node with a shell but no write access that changed the tree, TRACE_GIT_CONTROL_DRIFT — done (node changed git control state) — the sharper half of the same event, TRACE_ADOPTED_COMMITS — done (publish adopted commits it did not make), and TRACE_FINDINGS_WITHOUT_A_PATH — rework (no gating finding names a path). A sixth, TRACE_PROVIDER_FALLBACK — ran on a fallback provider: <which and why> — is sent as its own message beside the node's ordinary trace, because it qualifies the result rather than replacing it. The middle two were renamed from TRACE_READ_ONLY_WRITE / TRACE_READ_ONLY_GIT_DRIFT when the park went away, because they no longer describe a read-only-only phenomenon.
  • workspace-write - A permission profile that allows editing inside the workspace.
  • sandbox - The Codex isolation mode field.
  • danger-full-access - Codex full-access mode. It is operator-selectable but rejected when strict_isolation is enforced.
  • bypassPermissions - The Claude full-access mode. It is operator-selectable but rejected when strict_isolation is enforced.
  • model - The provider model name or account default selector.
  • reasoning - The provider reasoning-effort setting.
  • timeout_seconds - The provider run timeout.
  • max_turns - The Claude turn cap.
  • extra_args - Additional provider CLI arguments, appended after the orchestrator's own safety checks.

Checks and security#

  • checks.command_sets - The operator-authored quality gate. The orchestrator does not auto-discover commands.
  • command_profile - The current checks-node mode that diff-selects operator-authored checks.command_sets, runs them all through the Check Runner, and maps the aggregate to pass/fail/incomplete.
  • citation - The deterministic citation-manifest checker used by deep_research; it fails when a cited source is broken. Its citation.json report records the manifest_path it validated, so a downstream verifier opens the same manifest rather than guessing at it.
  • dependency_scan - The core-owned argv scanner used by security_audit; it always reports pass and lets the flow decide what that means.
  • Command set - A named group of check commands selected by diff paths and run together.
  • ResolvedCheck - The normalized internal form of one check command. It is always an argv list, never a shell string.
  • ResolvedCheckSet - The normalized internal form of one command set.
  • cwd - The repo-relative working directory for one check command.
  • skip_if_unavailable - A check-set setting that allows a missing binary to be skipped loudly. Not an escape hatch: it converts a launch failure into a loud skip, so a set that was the only one the diff selected and is then skipped leaves the gate with nothing run — and parks the task exactly where the launch failure would have. Disabling the checks node per task is the escape.
  • Quality gate - The check-run phase that can pass, fail, or be incomplete.
  • Incomplete gate - The gate state where a required toolchain is missing or every selected check was skipped. It sends the task to manual_action_required.
  • Check Runner - The component that launches configured checks and aggregates their outcome.
  • Green-but-dirtying guard - The core-owned property of a command_profile node: the working tree is snapshotted before and after the run, and a passing check that rewrote commit-candidate files (an auto-formatter, say) fails closed to manual_action_required with the node run recorded as dirtied_working_tree. A flow cannot declare it away or disable it; the read-only citation / dependency_scan checkers are out of its scope.
  • task validation gate - The pre-branch input validator that rejects malformed or unsafe tasks.
  • validation_report.json - The validation-gate report written under logs/<task-id>/; rejected tasks use it to explain the failure, and accepted tasks may also persist it.
  • quarantine_folder - The folder where invalid tasks are isolated.
  • strict_isolation - The master posture switch, and the only one. The dataclass/loader default is true (the fail-closed sandbox, and what an omitted key means); install writes false, which is the advanced mode. It is not a full-access gate — both provider full-access selectors are refused at every value of it. What it checks at either value is whether a provider's configured isolation is legal.
  • Advanced mode - strict_isolation: false. One door, not a matrix: "full freedom for the agent under your responsibility, except the floor". It forwards the parent environment whole to every process run on the agent's behalf, hands every node an unscoped shell and the full tool surface, widens writes to wherever the operator's own account can write rather than the clone, raises no OS sandbox for Claude on any host (Codex keeps its generated profile at either value), and puts every node online whatever its flow granted. allow_git_evidence, permission_profile and network_policy become inert in it; it is also the only mode in which a flow node may declare skills. Recorded in the frozen control bundle's manifest.json (the mode the task started in) and the completed ledger record's advanced_mode (a task that finished) — deliberately never in the pull request.
  • Isolation floor - The four levels that remain under advanced mode: (1) .git/.worc unwritable — re-proved by Codex before every attempt under its generated profile, but on Claude held only by the tool-level write denies plus the prompt contract and after-the-fact detection, since the mode raises no OS sandbox there on any host; (2) publication to your origin neither held nor detected — recovered from instead; (3) publication anywhere else held by nothing, asked for only in the prompt every node receives; (4) publication as the orchestrator reported by detection, never held. Level 1's absence is the advisory isolation-floor: NONE (<provider>: <cause>) status line — the cause only, the cost being stated once in .worc/guide/config/security.md — printed both on a host that cannot sandbox (either value of the key) and on every host under strict_isolation: false.
  • allowed_environment - The name gate for environment variables reaching child processes. Replaces its OS-aware default (9 names on Linux/macOS, 19 on Windows) rather than extending it. An entry is an exact name or a prefix pattern — a name plus one trailing *; * anywhere else is a load error, as is a secret-bearing prefix. PATH coverage is mandatory (a load error otherwise); on Windows a missing SystemRoot is a launch-critical FAIL at preflight and at run/watch/rerun start. Under advanced mode it gates only orchestrator-owned git/gh.
  • extra_environment - Variables the orchestrator assigns (rather than forwards) to agent/check/tool children and to orchestrator-owned git/gh. Strings only; PATH, secret-looking names, non-identifier names and case-duplicates are rejected. For toolchain roots and caches, never credentials — values are plaintext in config.yaml. A value whose path overlaps .git, .worc, .worc-io, the tasks dir, the env-file or a denied_read_paths match is rejected lexically at load and canonically in preflight. For git/gh it passes one more gate: a whitelist over the GIT_*/GH_*/GITHUB_* namespace admitting only GIT_CONFIG_GLOBAL, GH_TOKEN, GITHUB_TOKEN.
  • Pinned launchers - The executables the orchestrator launches as itself — git, gh, ps, bwrap, the agent CLIs, and the worc console script the watch daemon re-invokes — resolved once at startup and used as those absolute paths for the rest of the process. It removes the substitution window inside a run; it does not cover a stand-in already in place before the run, nor an edit to the installed package's own code.
  • Dangerous-diff gate - The mid-task approval, shared by the agent node (which can send itself back with the denial) and the publish node (where the agent is gone, so a denial is a manual stop). It measures from the last commit the orchestrator itself made for the task, or the task's base_ref until there is one — never HEAD. It asks in three places: after a writing node's edit, at that node's hitl round-trip, and immediately before the publishing commit. The same approved change is never asked about twice in one task.
  • denied_read_paths - A denylist of secret or sensitive paths that cannot be read by the orchestrator in agent context.
  • denied_commands - A denylist of commands that cannot be launched, even if they appear in args or flow config.
  • Forbidden args - Flags that disable approvals, sandboxing, or hook trust wholesale. They are rejected unconditionally.
  • Dangerous diff - A tracked-file deletion or dependency manifest or lock change that requires explicit approval before tests continue. security.trust_level sets which of those changes actually ask: strict gates all of them, auto (default) gates none of them (only a protected_paths match asks). security.protected_paths is the inverse always-ask floor — repo-relative globs whose files require approval on any change at any level.
  • approval - The HITL decision shape used for dangerous-diff gating.
  • network_policy - The security ceiling that decides whether a flow may reach the network.
  • output_policy - The containment policy that keeps writing nodes inside the expected report or workspace area.

Git, artifacts, and recovery#

  • Git Manager - The only component that commits, pushes, or opens a PR. Every push and PR call returns a structured outcome (PushOutcome, plus a RemoteState capture around the attempt) rather than a boolean, because "the branch already exists on origin" has four different right answers — see Publishing recovers.
  • Publishing recovers - The rule that an existing branch, a moved branch, and an open pull request on the task head are ordinary working state, never evidence of foreign ownership (inferring that does not hold: a recreated state.db has no records at all while the branch and its PR are still yours). So provenance is deliberately not inferred and recovery is the mechanism: a remote that matches sends nothing, one behind takes an ordinary push, one that diverged into exactly the commit we recorded pushing takes a lease-guarded force-push, and one that diverged from something we never pushed has those commits merged in locally, the quality gate re-run over the combination, and only then is anything sent. An open PR on that head is adopted, retitled, and appended to.
  • Adopted commits - Commits publishing had to merge in because they were on the remote and the orchestrator never put them there. The run records the adopted commit rather than reporting one it never performed, and says so in the pull-request body — or, with publish: push/commit where there is no body, in the run log and the ⚠️ TRACE_ADOPTED_COMMITS trace.
  • publish_operations.pushed_sha - The commit a push actually left on the remote, so a branch someone else moved is distinguishable from the one we put there. Nullable, and NULL is its real meaning ("not pushed by us"), not a placeholder.
  • base_branch - The branch that the orchestrator returns to after a task is finished (by default in new mode; repo.checkout_base_on_cleanup and the branch mode decide whether it returns at all).
  • branch_prefix - The prefix used for the default task branch name.
  • branch_name - A full branch override supplied by the task author.
  • scoped staging - Explicit pathspec staging that excludes orchestrator runtime artifacts and task lifecycle folders.
  • footprint - The audit trail policy for how task files and summaries are committed.
  • audit commit - The separate orchestrator-made commit that captures the task file and summary trail.
  • audit_on_branch - Whether the audit commit is attached to the task branch or a sibling branch.
  • Pull Request / PR - The publish artifact created by the Git Manager.
  • publish - The terminal Git step that turns the reviewed result into a PR, and optionally auto-merges it when configured.
  • publish idempotency - The guarantee that a rerun does not create duplicate commits, pushes, or PRs.
  • terminal cleanup - Freeing the single processing slot after a task reaches a terminal status: it returns the working tree to base_branch (safely, or fails closed) when the branch mode / repo.checkout_base_on_cleanup calls for it, otherwise it leaves HEAD on the working branch.
  • workspace/repo - The dedicated clone or workspace used for agent edits.
  • <repo>/.worc/ - The orchestrator runtime home. It holds config, the seeded editable flows/ (and their roles/), the installed guide/, logs (check logs included, under logs/<task-id>/checks/), workspace state, and other generated files. The typed layout (WRI-004) names three surfaces under it: control_home (the operator-editable control plane — config.yaml, flows/, tools/, guide/), private_home (private runtime state the agent must never read — state.db, logs/, memory, secrets, process-control files), and exchange_root (<repo>/.worc-io, the redacted agent-facing exchange). All three resolve under .worc/.worc-io today. A night-runs/ directory under it exists only if you run the worc-night-run skill — written by that agent, never by the orchestrator, and pruned by no command.
  • <private_home>/runs/ - The one parent of every per-task runtime root: control-bundles/, instruction-bundles/, exchange-seals/, and exchange-quarantine/. They share one defining property — private state keyed by task id, written by one run, never agent-readable — so they are grouped rather than scattered beside the operator's own config.yaml / flows/ / guide/. runs/ (not the individual roots) is the named entry in the internal read-deny set and the single root retention reasons about. No migration code exists: in a workspace installed before the rename the four pre-rename directories are orphaned at the .worc/ root.
  • Frozen instruction bundle (WRI-011) - A per-task, immutable snapshot of the agent inputs whose identity must stay stable — the validated task packet and the root repository instruction files (AGENTS.md / AGENTS.override.md / CLAUDE.md) — under one instruction_manifest_digest, at <private_home>/runs/instruction-bundles/<task-id>/. The agent only ever reads redacted exchange copies of these.
  • Exchange seal (WRI-007) - The checksum-verified terminal snapshot of a task's .worc-io/ exchange, at <private_home>/runs/exchange-seals/<task-id>/seal-<NNNNNN>/. Written at every terminal, success included — it is the archive of what the agent last saw, not a record of trouble. rerun --continue restores the latest verified one.
  • Exchange quarantine - Where a mutation-flagged exchange tree is kept as tainted evidence (<private_home>/runs/exchange-quarantine/<task-id>/<NNNNNN>/, with the expected and observed manifests plus created_at, the mutating node_id and the task attempt in evidence.json; a bundle with nothing to record is not written). Each bundle is also named on the task row in tasks.quarantine_refs. Never sealed, never restore-eligible, and never removed automatically — only worc runs clean --include-quarantine deletes it.
  • Frozen control bundle (WRI-010) - A per-task, immutable snapshot of the exact control inputs a task's flow references (the flow YAML, every node role_file, the supervisor prompts, and each tool node's resolved executable), written to <private_home>/runs/control-bundles/<task-id>/ at task start. The orchestrator binds the flow runners, supervisor, and tool-node registry to it so no later node reopens live .worc, preventing an agent from rewriting a later prompt or tool mid-run. A live control edit during any attempt is detected (after the WRI-012 quiescence barrier) and routed to manual_action_required — never provider fallback. continue/resume reuses the original bundle (verified against tasks.control_bundle_digest); a fresh rerun/restart re-freezes from the operator's current control plane.
  • State Store - The SQLite-backed persistence layer around state.db that stores task state and run records.
  • Ledger - The append-only completed-task record in completed.jsonl.
  • state.db - The SQLite state store that keeps task progress and run bookkeeping. Its schema version is stamped in PRAGMA user_version (currently 28): a newer database is refused, and so is an older versioned one (1 ≤ v < 28) — past bumps dropped and renamed tables, so an old shape cannot be reshaped in place; delete the local state.db and start fresh (greenfield). Only a 0 (brand-new or pre-versioning) database is adopted, migrated with the additive columns, and stamped.
  • tasks - The one row per task: status, branch and slug, the fix-cycle and subtask counters, current_node, flow_fingerprint, the park timestamps, the cleanup bookkeeping, the frozen-bundle digests, recovered_loop, quarantine_refs, and four nullable reference points below. The PR is not here — it lives in publish_operations.
  • tasks.base_ref - The commit the working branch sat at when the task started. NULL means the config base branch is the start. It must survive the process: re-derived from HEAD after the run has committed it would walk forward, and the task's reported change would shrink to whatever is still uncommitted.
  • tasks.gate_reference_sha - The commit the dangerous-diff gate measures the task's change from — the last commit the orchestrator itself made. NULL means the task's diff base. It advances per subtask commit in a decomposed run, which is why an approval given on one subtask is not requested again on the next.
  • tasks.source_sha256 - The content digest of the task file the attempt read. It is what tells a settled task's own file — resurfacing in tasks/pending/ after a checkout — apart from a different file reusing its id: the former is left in place, neither re-run nor quarantined, while only the latter is quarantined; neither appends a second ledger record or sends a notification. Identity comes from content because the terminal move rewrites source_path, so a path comparison could never match. NULL means no digest was recorded and the file's identity cannot be established, so it is left in place and reported.
  • tasks.recovered_loop - The fix loop a no-progress guard or budget stopped on a task that nevertheless reached done (continued by an operator, or past an evaluator that does not gate publication). NULL on a clean run; set, with failure_report_path cleared, at the transition to done, and cleared again by a fresh rerun. worc list shows such a task as done (recovered: <loop>).
  • tasks.quarantine_refs - Every exchange-quarantine bundle the task produced, as a JSON list of POSIX paths — append-only and never cleared, so a task still names its incident after an operator rerun --continue clears exchange_contaminated.
  • tasks.push_url_digest - The sha256 of where a push would go, read once at branch prep before any provider ran, so the unconditional pre-push re-read has a baseline. A digest rather than the URL because it can carry a token. NULL means no baseline was taken and is never read as a rewrite.
  • artifacts - The per-task registry of produced files (the diff, reports, node outputs) as kind + path + checksum, so a resume or a report finds them without re-deriving paths. path is POSIX and relative to the worc home (the lifecycle summary reads ../tasks/done/<id>.summary.md), so the database names no home directory.
  • subtasks - The persisted decomposition units of a split task in linear order, each with its own status, depends_on, commit sha, and spec path.
  • logs/<task-id>/ - The per-task artifact root.
  • summary.md - The human-readable handoff artifact written at task close; it doubles as the PR body in the default publish flow.
  • summary.json - The local-only machine-readable companion to summary.md. One key set on every terminal and from both writers: {what, summary, [follow_ups], [supervisor_usage], [task_usage], [cost_not_accounted], [degraded]} — task_usage is the whole task's spend (every node attempt plus the supervisor layer, as a total and by_provider; a Claude figure covers the subagents its attempt ran), and cost_not_accounted lists, per provider, the attempts with no recorded cost and their input tokens (Codex reports no USD), stated rather than estimated.
  • failure_report.json - The structured report written when a task ends in failure or becomes stuck: the loop, limit_exhausted, counters, the failing node's provider attempts, the last check log (or last_check_log_note for a tool node), findings, and the final diff. On a task that still reaches done it and stuck.md are renamed recovered-failure_report.json / recovered-stuck.md and the ledger says recovered_from_stuck with the recovered_loop.
  • stuck.md - The human-readable stuck-state note for exhausted fix budgets.
  • completed.jsonl - The append-only ledger: one record per terminal transition (not per run, not per provider attempt). attempt is the record's ordinal among the id's terminals, gate refusals excluded, counted when it is appended. A record of a run that did not finish done also says where it stopped — stop_node, stuck_loop (the fix loop, null for an infrastructure or operator stop) and stuck_limit (the limit reached, such as max_fix_cycles or repeated_findings, or the first line of the stop reason) — so a rework verdict followed by the same evaluator again after an operator's rerun --continue does not read as a missing fix step.
  • node_runs - The persisted per-node execution records. The row's lifetime belongs to the node layer: a node that raises before recording a verdict closes it aborted, and so does terminal reconciliation of a hard-killed run — both with the reason in abort_reason; skip_reason is set only on skipped = 1 rows.
  • provider_attempts - The persisted per-attempt records for provider routing and fallback, each carrying the effective model / reasoning that attempt ran on (NULL when neither the node nor the provider config named one), so per-model spend needs no prompt_audit.
  • check_runs - The persisted records for quality-gate execution.
  • evaluations - The immutable advisory verdict table written by evaluators and the supervisor. A non-blocking evaluator's max_rework_per_stage is counted from its in_flow_verdict rework rows — only those whose node run still exists (a fresh rerun deletes them) and that come after the task's latest rework_budget_reset marker, the row an operator's rerun --continue --reset-fix-budget appends.
  • publish_operations - The idempotency ledger for commit / push / PR operations, so reruns do not duplicate them.
  • editing_lineage - The durable session table for workspace-writing agent nodes, keyed (task_id, subtask_order, lineage_key) so one execution unit can hold more than one editing session (one per lineage).
  • node_lineage - The durable own-session table for evaluators and the supervisor.
  • flow_fingerprint - The hash of the resolved flow snapshot used to detect resume drift.
  • ExecutionUnit - The (task_id, subtask_order) identity for a root task or decomposed subtask.
  • active_subtask - The current 1-based subtask number on the task row when a task is decomposed, paired with subtask_count as the total number of accepted subtasks.
  • rerun - The command or workflow that re-attempts a terminal task.
  • resume - The crash-recovery path that continues an in-flight task from persisted state.
  • finalize - The workflow that records a manually handled terminal outcome.
  • current.diff - The redacted diff artifact used during fallback and review.
  • change-overview.txt - The bounded map of current.diff, written beside it under logs/<task-id>/ from the same snapshot every time the diff is, and published to .worc-io/<task-id>/ as {change_overview_path}: the task base it is measured from, one line per changed path (kind and line counts, [denied] for a denied_read_paths match), the totals and the full diff's size — paths and counts only, never hunk content. Once the orchestrator has committed inside the task (each subtask of a decomposed run) a second section, "Change since the orchestrator's last commit", follows. Sealed with the rest of the exchange at the terminal; a resumed task (crash recovery or rerun --continue) re-publishes it and reads the base back from it, rather than resolving it again from a repository that may have moved.

Notifications and observability#

  • Notifier - The narrow interface for terminal notifications, the one-way node trace, and two-phase HITL interactions (start_ask then wait_for_answer, so a wait survives a restart).
  • Trace feed - The one-way, best-effort per-node progress channel (send_trace, enabled by telegram.trace): one message per finished flow node carrying the node id and outcome only, never content.
  • Telegram - The optional transport implementation used for human-in-the-loop prompts and notifications.
  • HITL - Human in the loop. It means the orchestrator asks a real person for a question or approval before continuing.
  • AskHandle - The durable, secret-free handle stored before waiting for a human response.
  • AskResult - The structured result returned when a human interaction resolves. Its failure vocabulary is timeout, transport_error, invalid_response, and cancelled — the last for a wait an operator stop ended, distinct from a timeout because the operator was never late. Every notifier call except the HITL long poll carries a deadline, so a stalled send can no longer wedge a watch tick past its stop channel.
  • question - A free-form human prompt that expects text input.
  • approval - A yes/no human prompt that expects a decision.
  • OutputContract - The per-node typed-output selector for agent nodes: none, human_input, or planning. Derived from the node's declared structure, never from its name — the flow's decomposition proposer gets planning, any other HITL-capable node gets human_input, a plain author node gets none.
  • HumanInputSignal - The typed question/approval payload parsed out of structured output.
  • TypedStageOutput - The validated structured result for an agent node, including content and optional human_input.
  • contacts - Plain-text mentions appended to messages sent through the notifier.
  • prompt_audit - The per-step record of what prompt went to which actor. Two halves in one directory: a readable <NNNNNN>-<node>[-subNN].md step file (a fenced-json metadata header — route, provider, effective and configured model/reasoning, the declared skill posture, one row per attempt with its resumed flag — then the prompt verbatim as the body, plus a ## Continuation prompt section for a node with a resume_role_file), and timeline.jsonl, the machine-readable half carrying each record whole.
  • heartbeat - A progress pulse emitted during long provider, check, or Git operations.
  • Structured logging - Secret-free operator logs that include task, stage, attempt, and provider context.
  • Secret redaction - The scrub layer that removes secrets before logs, artifacts, or summaries are written.
  • Environment-derived secret - A secret loaded from the orchestrator's own environment or from <repo>/.worc/.env, not from task files or config values.
  • human_input_path - The artifact path that carries a human answer or approval back into the flow.
  • manual_action_required - The terminal state used when the orchestrator must stop and ask the operator to intervene.

Legacy and renamed terms#

  • Stage enum - A legacy vocabulary for task lifecycle identity. The current execution identity is the flow node id, not the old stage enum.
  • agents.routing - A removed stage-keyed provider-routing block. Routing is now node-based.
  • agents.skip_stages - A removed global skip list.
  • agents.allow_review_skip - A removed review-specific skip gate.
  • prompts block - A removed config block for prompt overrides.
  • decompose - A removed task flag for decomposition.
  • footprint.location, footprint.tracking, footprint.external_root - Removed footprint keys from older config shapes.
  • min_size_signal and commit_per_subtask - Removed decorative decomposition keys that are no longer read.
  • security.deletion_approval_exempt_paths - Removed skip-list (config v25). Replaced by the inverse model — security.trust_level (which deletions ask at all) plus security.protected_paths (the always-ask floor). upgrade-config strips the old key; there is no automatic conversion.
  • validation.required_fields and validation.reject_unknown_fields - Removed (config v35). Both were parsed and even written by install, but read by nothing: the task gate hard-codes the requirement (id, a non-blank title, a non-empty ## Description) and rejects an unrecognized front-matter key unconditionally. Neither was the operator's to set — a config able to drop id or open the fail-closed unknown-key gate would weaken invariants that branch names, run directories, and the state store depend on. Tolerated on load (every installed config carries them); upgrade-config strips them.
  • checks.discovery / checks.commands (v15), git.auto_merge_allow_per_task (v11), agents.providers.<id>.max_budget_usd (v14) - Other removed keys upgrade-config strips. They are tolerated on load, never read.
  • summary stage - The old name for the idea that is now handled by the supervisor layer and the final summary.md artifact.
  • write_minimal_summary - The removed four-field What / How / Integration / Why PR-body stub, and with it the summary.json triad how / integration / why. One deterministic report now writes the body on every terminal that has no provider prose.
  • GitManager.diff_stat - Deleted along with that stub; the stat comes from the durable current.diff.
  • supervisor.model / supervisor.reasoning - The former flat, one-per-layer model and effort keys. Both are now per phase under supervisor.observe / .finalize / .handoff.
  • agents.providers.codex.sandbox - The key no longer exists at all (removed in config v38). Its one remaining value selected a provider full-access mode, and that mode is now refused at every value of security.strict_isolation, so there is nothing left for it to take. It is not tolerated on load and not stripped by upgrade-config: a config carrying it is a load error with a named message telling you to delete the line. The access level is permission_profile plus security.strict_isolation.
  • skills block (skills.dynamic, skills.strict) and skill_map.json - Repo-skill selection was removed outright: whole-repo SKILL.md discovery, operator pins on a flow node's skills: list, the once-per-task supervisor proposal, the {skills_path} prompt variable, the persisted per-node map, and the skill packages in the frozen instruction bundle are all gone. The block is deliberately absent from the strip list for the same reason as sandbox — a config still carrying it is a load error the operator resolves by deleting it, because stripping it would read as "the block still works, it just does nothing". supervisor_usage.by_function lost its skill job with it, leaving three.
  • agents.providers.claude.allow_native_memory - Removed. It governed the write side of a deny on Claude's own config home; that deny no longer exists, because the agent CLIs' config homes (~/.claude / $CLAUDE_CONFIG_DIR, $CODEX_HOME) are outside every deny projection at any value of any key. Not tolerated on load.
  • find_full_access_args / "gated full access" - The former model in which a provider's full-access selector was operator-selectable under strict_isolation: false. Both selectors are now absolutely forbidden at every value of that key, in both argv spellings, enforced by the config validator, the flow validator's config-independent ceiling, and each adapter's argv builder.
  • TRACE_READ_ONLY_WRITE / TRACE_READ_ONLY_GIT_DRIFT - Renamed to TRACE_UNEXPECTED_WRITE / TRACE_GIT_CONTROL_DRIFT when git-control drift stopped parking a task. The old names described a read-only-only phenomenon; both events now apply to every node class that gets a shell.