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
- Task language
- Configuration
- Flow vocabulary
- Providers
- Checks and security
- Git, artifacts, and recovery
- Notifications and observability
- Legacy and renamed terms
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 refreshesconfig.yaml, seeds the packaged guide, flow, andtool-executable copies, and can run preflight after setup.--reconfiguresnapshots what it replaces and keeps only the newest three of eachconfig.yaml.bak-*/flows.bak-*/tools.bak-*(never yourstate.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 likererun/status/finalizetake the task id instead.) It refuses (exit1) a file that is a terminal task's own leftover, pointing atrerun/finalize, and claims itsorchestrator.runmarker exclusively, so a secondrunracing it refuses rather than overwriting the marker.promote- Moves a staged task file fromtasks/preparing/intotasks/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 scanstasks/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 NAMEserves only that queue.stop- Stops a runningwatchdaemon 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-fullis the only hard rung.--non-interactiveskips theYESprompt and refuses a busy daemon unless a force flag is given.restart- Stops the running watcher (same stop ladder, same--force/--force-full/--non-interactiveflags) 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=, acost=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 acost_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; pollsstate.dbread-only and quits onq. Stdlib-only — no extra needed.shell- Interactive operator console (the[shell]extra): a prompt_toolkit REPL. Entry is passive — it attaches to a livewatchdaemon or opens idle (the queue is not served on entry; it never auto-spawns or auto-claims).up/watchstarts 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/cleardispatch onto the existing commands (clearwipes the console screen), andhelp(?) 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-wipeCtrl+L/Unixclearemits). A visual wipe only — no logs or files are deleted (that islogs clean). Available both as a standalone command and as aworc shellverb.list- Read-only enumeration of the active task, thetasks/pendingqueue, and recent terminal tasks.--allis the uncapped view of everytasksrow 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 itsvalidation_reasonandrejected_at(the table view prints them under arejected:heading with the reason).--format jsonis the scripting contract — every entry carriestask_id,status,title,branch, andpr_url(the URL of the PR the task opened, ornull; alwaysnullfor a still-queued file);statusis a display label (running (paused),parked (no daemon),done (recovered: <loop>)), so match its leading token. The table view (only) ends with anote: <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 abash/zshcompletion script (sourced once) that completes subcommands and flags statically and task ids dynamically viaworc 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:), theghrepository 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 isvalidate-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 plainpreflightspends 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 olderconfig.yamlto the current schema shape without changing user values. It confirms before writing (-y/--yesskips;--dry-runnever 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>.sandboxand the wholeskillsblock.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-runpreviews.rerun- Re-attempts a terminal task, either from scratch or by resuming from the saved checkpoint. While it runs it holds theorchestrator.runmarker exactly asrundoes, sostatus/list/topreport its task as running rather thanparked (no daemon), and a secondrun/rerunrefuses.--continue --reset-fix-budgetgrants a fresh fix budget: the consecutive fix-loop counters and every non-blocking evaluator'smax_rework_per_stagecount start afresh (the latter through an appendedrework_budget_resetmarker), while the globalmax_total_fix_iterationsbackstop is kept. Without the flag, the plan (--dry-runand the confirmation) names each non-blocking evaluator on the resume path whosemax_rework_per_stageis 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;--checkadds live GitHub state,--syncreconciles PRs merged externally (dry-run unless--yes).merge-task- Operator go-ahead to merge a reviewed PR: pullsbase_branchinto the task branch, resolves any conflicts via the merge flow, then merges. The human-in-the-loop counterpart togit.auto_merge. A conflicted path the flow left without a visible decision aborts the merge (nothing committed, PR left open) and exits2withmerge-task: manual action required — ….tasks- Read-only list of every known task with its status and branch;--statusfilters.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, eachWARNcarrying its own consequence: an unknown{name}in a role prompt (it would render verbatim to the agent), atoolnode whose rework/fail edge declares a fix budget (that number holds as written only while the tool emits top-levelfindings), and a non-blocking evaluator whose rework loop allows fewer fix rounds than itsmax_rework_per_stage(it accepts with ⚠️ after the smaller number; the loop is clamped toagents.max_fix_cycleswhen a config is loaded). Takes a flow NAME or--all(a bare invocation is a usage error). Exit0valid /1invalid /2not found or no config.preflightno 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 --allhonors 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-quarantinealso drops tainted exchange evidence. Refuses while a task is active. The manual counterpart tologging.clean_runs_on_success.memory- Inspects and curates the persistent store under.worc/memory/:show/validate(read-only) andcompact/restore/clear(mutating, refused while a task is active).worc-night-run(packaged skill, not a command) - The copy-ready agent skillinstalldelivers to.worc/guide/skills/worc-night-run/(copy it into.claude/skills/to use it): an agent that drives the pending queue unattended withworc 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 toconfig.yaml; it overrides automatic discovery.--env-file- Explicit path to an environment file; if omitted, the orchestrator auto-loads<repo>/.worc/.envwhen present.--log-level/--log-format/--log-file/--heartbeat-seconds- The global operator-output flags: verbosity (overridinglogging.level),logfmtorjson, an additional rotating log file (10 MB, 5 backups — awatchdaemon's copy of it is whattopandshelltail), and the long-operation heartbeat interval (default30,0disables).--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 andidplus a non-blanktitleand a non-empty## Descriptionrequired. 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 areimplementation,deep_research,security_audit,merge, and the content-authoring flowscontent_chapter/content_translate/blog_article/blog_article_revise; operator flows can add more.branch_name- Full task-branch override (only innewbranch 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 inbranch_ref), orcurrent(work in the working tree's current branch as-is). Wins overrepo.branch_mode. A branch is orchestrator-owned only innew.branch_ref- The existing branch a task works in; required iffbranch_modeisexisting(a validation error otherwise) and must already exist locally or on the remote.publish(task field) - Downgrade-only cap on thepublishnode:commit(stop after commits),push(stop before the PR), orpull_request(full). Effective scope ismin(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 offeatfixdocsstylerefactorperftestbuildcichorerevert; 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 ofsecurity.trust_level, the approval threshold for the dangerous-diff gate:strictgates every deletion/dependency-manifest edit,autogates only aprotected_pathsmatch. Task value wins; never lowers the hard ceiling and cannot touchprotected_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.truerequests auto-merge,falseopts 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 overagents.decomposition.enabledin 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 tomid, so a typo never blocks a task. It re-orders eligible tasks only;depends_onis 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 itsorchestrator.queueequals this value (plain string equality, no balancing). Defaults todefault, and unlikepriorityit 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: falseskips that node for the task, andmodel/reasoning/provideroverlay 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## Referencesheading 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 reportsinjection_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.mdis not rewritten — the annotated body is a separatepr-body.mdartifact.## 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-taskdecompositionfield only flips whether a split is permitted (defaultagents.decomposition.enabled), never forces one.- Task statuses -
newmeans the task has been parsed but not yet validated;validatedmeans it passed the gate;preparingmeans the orchestrator owns the slot and is setting up execution;runningmeans the flow engine is active;done,failed, andmanual_action_requiredare terminal;pendingis 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), withpending → validated | preparingahead of the slot and a→ failed/→ manual_action_requiredbailout from every non-terminal status. Terminal statuses have no outgoing edge. - Park - A resumable pause, not a status: the row stays
runningwhiletasks.blocked_sincerecords the first park instant (the clockagents.retry.max_blocked_smeasures) andtasks.blocked_untilrecords when the provider says its window reopens. Arunningrow with no live executor reads asparked (no daemon), and a softstop --forceparks at the next node boundary. "Executor" is both the watch daemon (.worc/orchestrator.pid) and aworc runorworc 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/preparingis the staging folder the watcher never scans (compose a task there, thenpromote),tasks/pendingholds queued tasks,tasks/doneandtasks/failedhold terminal tasks, and.worc/tasks/rejectedis the quarantine folder for invalid tasks. A running task keeps its file intasks/pending— "currently active" is tracked by itsstate.dbstatus, not a folder. Thetasksroot is the default; it is configurable viapaths.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 — nosummary.mdis written and the deterministic report becomes the PR body instead (the run is flaggeddegraded).- 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 ofstate.dbplus the task's artifacts (two renders are byte-identical), it never inlines the diff — it names the changed paths and points atlogs/<task-id>/current.diff. It replaced the four-fieldWhat / How / Integration / Whystub, so afailedormanual_action_requiredrun 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 afterrerun --continue, so they describe the whole run. degraded- The additivesummary.jsonflag 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 underlogs/<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 (currently41), bumped only when the format changes. The loader refuses a newer schema than it understands; an older or absent one loads, andupgrade-configbrings 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- Whentrue,watchmay pick the next pending task after terminal cleanup succeeds.orchestrator.auto_mode.confirm_next_task- Fail-closed Telegram approve/deny prompt beforewatchclaims each pending task (defaultfalse; requirestelegram.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 (default900, must be> 0). Its own key rather thantelegram.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 thewatchloop and is not persisted.worc stopcancels a wait in flight.orchestrator.poll_interval_seconds- Watch loop interval; each tick fetch/pullsbase_branchbefore re-scanning.0makeswatcha single pass.orchestrator.queue- This instance's queue selector (defaultdefault), matched by string equality against a task'squeue.worc watch --queue NAMEoverrides 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 (seerepo.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, defaultnew); a per-taskbranch_modeoverrides it.repo.checkout_base_on_cleanup- Tri-state (true/false/unset) gating whether terminal cleanup returns tobase_branch; unset defers to the branch mode (newreturns;existing/currentstay). 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 rootAGENTS.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 thepreparing/pending/done/failedlifecycle subfolders (defaulttasks). Validated repo-relative (no../absolute) and rejected if it lives under the gitignored.worc/home; a subpath such asconfig/tasksis 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 (default15): with15, fifteen rounds run and the sixteenthfail/reworkparks the task. A flow's ownbudgetsentry is clamped to it.agents.max_total_fix_iterations- Global cap on fix rounds across the whole task, including subtasks (default30, 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, default2, counted per provider in the route and separately frommax_stage_attempts), deterministic exponential backoff betweenbase_delay_s(2.0) andmax_delay_s(30.0), andmax_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 forcodexorclaude. It holds the executable command, model, reasoning level, timeout, permission profile, extra args, and theprimarymarker; Claude also usesmax_turns,max_turns_gate, andbackground_tasks.agents.providers.claude.max_turns_gate- Claude-only: a run that exhaustsmax_turnspauses for a durable Telegram continue/stop prompt instead of failing (defaultfalse; requirestelegram.enabled). Continue resumes the same agent session with a fresh turn grant, which is what makes a lowmax_turnssafe.agents.providers.claude.background_tasks- Claude-only (a load error oncodex): whether the agent may start background tasks —run_in_backgroundsubagents and shells.false(the default) launches the CLI withCLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1, so subagents run in the foreground (several launched in one message still run in parallel), because headless-pmode stops every background task when the agent ends its turn and the run would end with a promise instead of the work.truealso removes that variable when the operator's own environment exports it. The backstop either way is thebackground_work_losterror 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 (defaulttrue, 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 onlyagents.providers.claude.allow_native_memorylifts. 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 storeWrite/Edit-denied, so.worcremains 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 (defaultfalse) that makes a flow node'sgit_evidencedeclaration effective.config.yaml-only, never a task /extra_args/ flow key.security.trust_level- Approval policy for the mid-task dangerous-diff gate:strictgates every deletion/dependency-manifest edit,auto(fresh-install default) gates only aprotected_pathsmatch. A per-tasktrust_leveloverrides it; it never lowers the hard security ceiling. Replaced the removeddeletion_approval_exempt_paths(config v25).security.protected_paths- Repo-relative globs (same dialect aschecks.command_sets[].paths) whose files always require approval on any change regardless oftrust_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 (defaults262144,5000,8192,0.01). These four plusquarantine_folderare 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 (default7200); a set's owntimeout_secondsoverrides it.CheckCommandSpec- One structured check command: a logical name, an explicit argv list, and an optional repo-relativecwd.CommandSet- A named bundle underchecks.command_sets: a diff-selected group ofCheckCommandSpecs with optionalpaths,timeout_seconds, andskip_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(defaultsquash), and the default formerge-task --strategy.git.auto_merge_wait_for_checks- Whether GitHub-native auto-merge waits for required checks (and the default formerge-task --wait-for-checks).git.merge_flow- Name of the flowmerge-taskruns to resolve a conflicting base-merge (defaultmerge). 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 (defaultfalse): 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 (defaulttrue).falsemeans 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), andmemory.enabledis forced tofalsefor the run (a second warning names both keys). The PR body is then the deterministic report. It is its own key rather than a globalobserve.mode: nonebecause 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 tonone.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, defaultevents),triggers(rework/failure/fallback),include_nodes(forselected), plus this phase'smodel/reasoning.tool,checks, and the terminalpublishnode 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 writessummary.md(the PR body), and the subtask brief between decompose regions. Model and effort are per phase — there is no flatsupervisor.model/supervisor.reasoningany more.supervisor.emit_follow_ups(flow field, not config) - Opts a flow's finalize turn into emitting the evidence-gatedfollow_upsarray. 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 insummary.json: calls, input, cache reads and writes, output, cost, and provider wall time — as atotaland aby_functionsplit 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, defaultwarning); the--log-levelflag overrides it for one invocation.logging.artifacts- Which per-attempt provider files survive underlogs/<task-id>/stages/…/<attempt>-<provider>/:minimal(result.json+request.json),standard(default; addsstdout.log/stderr.log),full(everything, addingevents.jsonland 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/(defaulttrue). Failed/parked tasks and quarantined evidence are never cleaned automatically;worc runs cleanis the manual half.memory- The repo-scoped persistent memory block:enabled(dataclass defaultfalse, but a freshinstallwritestrue) 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: falseforcesmemory.enabledtofalsefor the run.- Memory tiers - The storage families the store keeps and
worc memory clear --kindtargets:short(recent episodic),long(the promoted long-term lessons),entity(repo entities), andquarantine(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 atoolnode whose owntimeout_secondsis unset (default3600). 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:installcopies 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 flowworc merge-taskruns (only) when pullingbase_branchinto a task branch conflicts:conflict_resolution(agent) →testing(checks) with a boundedfixingloop, 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 bygit.merge_flow.content_chapter- A long-form book chapter editor: a read-only scout → editor → the deterministiccheck_chapterprose gate (structure only) → a blocking story critic → a style pass → publish, all rework routed throughfixing.content_translate- Adapts an approved source-language chapter into an English production file, gated bycheck_chapter(structure plus per-page length limits set in the flow'sargs) and an adaptation critic.blog_article- Writes one new authorial blog article from scratch: a read-only scout → a networked researcher → the writer → the deterministiccheck_lengthminimum-size floor → a blocking tone/style critic → a polish pass → publish, all rework routed throughfixing.blog_article_revise- Sibling ofblog_articlethat revises an existing article in place instead of writing a new one, with the same shape and gates.- Flow node kinds -
agentruns an editing or authoring step,evaluatorreads an artifact and returns a verdict,checksruns the quality gate,toolruns an operator executable from.worc/tools/out-of-process (exit-code / optional-JSON gate),hitlasks the human in the loop, andpublishperforms the orchestrator-owned publish step. - Tool registry - The
.worc/tools/directory that turns atoolnode's free-stringtool:name into an executable, owning the path containment (a name resolves to a file inside that directory, never a path).installseeds the two shipped tools,check_chapterandcheck_length(each with a.cmdwrapper for Windows); a node's flat scalarargsreach the tool on stdin. - Run vocabulary -
RunKindis the top-level run discriminator (stageorevaluator);EvaluatorRolenames the shipped evaluator roles (review,critic,verifier,test_quality). - Typed node output -
OutputContractselects the strict structured-output parser for agent nodes (none,human_input,planning);HumanInputSignalis the validated question/approval payload;TypedStageOutputis the parsed structured result. - Route result -
RouteSourcesays whether a node's provider came from config or an explicit flow-node override;ResolvedRoute,ProviderAttempt, andStageOutcomeare 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 intomanual_action_required.- Execution identity -
ExecutionUnitis the(task_id, subtask_order)identity for a root task or one decomposed subtask;flow_fingerprintis the hash of the resolved flow snapshot used on resume. - Node bookkeeping -
current_nodeis the in-flight node insiderunning,active_subtaskis the 1-based subtask counter on the task row, andbest_effortlets 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), andreport(report.md, written privately into the flow's report directory).- Implementation flow nodes -
refinementenriches a vague task,planningbuilds a plan and may propose decomposition,implementationedits files,testingruns checks,reviewperforms read-only evaluation,fixingloops on quality findings,documentationwrites the handoff material, andpublishfinalizes Git publication. - Deep-research flow nodes -
refinementscopes the question into anchored sub-questions (it runs on every task; it is no longer gated onderived.needs_refinement),analysis_core/analysis_surfaces/analysis_docs_testsare three sequential passes over disjoint surfaces each with a narrow mandatory remit,coverage_gatemeasures those passes (rework re-enters atanalysis_core),external_researchfetches outside sources,architecture_designorganizes the evidence and writes no file,synthesiswrites the deliverable (output_file: report.md),citation_checkvalidatessources.json,document_checksruns the operator'scommand_profileover the Markdown about to be committed,fact_verificationandcritical_reviewrework or accept, andpublishcreates the documentation PR. - Security-audit flow nodes -
scopeframes the audit,repository_analysisinspects the repo,dependency_scanruns evidence scanners,threat_analysisandfinding_verificationrefine findings,reportwrites the private report, andprivate_storagerecords 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_lineageon an agent,resume_own_lineageon an evaluator — and never in a flow'sdefaults: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 asresumedin 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_skillsis tri-state (null→ on iffskillsnames one). Requiring is advanced mode only —skills:or an explicitallow_skills: trueundersecurity.strict_isolation: trueis a validation error, never an inert field.falsenarrows 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 producereport.md+sources.json), andprivate_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 reportoutput_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 configuredpaths.tasks_dirtree; on acode_changeflow 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 atoolnode's stdinpaths) — the packageddeep_researchsynthesis prompt names it instead of a literal path — and a role prompt naming{report_dir}on acode_changeflow 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, andnone.network_policy- The flow-wide network grant,advisories(vulnerability/package metadata, used bysecurity_audit) orresearch(broader external fetches, used bydeep_research). Absence means no network by default.network_access(flow node field) - Per-node override of that flow-wide default:truegrants network to this node even in a flow with nonetwork_policy,falseforces 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- Anediting_lineagenode's declaration that it joins another node's editing session instead of owning its own. The lineage key islineage_affinity or <node id>, so an affinity-less node owns a lineage named after itself and a node withlineage_affinity: Xshares lineageX. 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.budgetandloop- 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 inlinebudget: 2and the globalmax_total_fix_iterationsbackstop: the limit is checked before a round is charged, and the nextfail/reworkafter 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) andrepeated_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'sreworkedge, since that node never parks. Atoolnode has its own bound: a byte-identicalfailwithout top-levelfindingsparks on the second repeat, or at the loop's declared budget when it carriesdata. - Non-blocking evaluator (
blocking: false) andmax_rework_per_stage- An advisory gate that never parks the task. It takes at mostmax_rework_per_stagerework rounds (counted from its recorded verdicts, per subtask) — or fewer, when the budget of the loop itsreworkedge 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_EXHAUSTEDtrace. The count survivesrerun --continue; only--reset-fix-budgetstarts it afresh. {change_overview_path}/{diff_base}- The prompt variables (agent, evaluator, and atoolnode's stdinpaths) 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, asecurity.denied_read_pathsmatch 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 firstworkspace-writeedit. Every node after that edit already finds the overview, the diff andChange base: <sha>in its context footer, so a prompt names them only to say something specific.change_overviewis 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 aworc merge-taskrun whose base merge conflicted.conflictsis 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 withsupervisor.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 anagentnode 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}: everyagentnode's output (as<node_id>.out.md) and everytoolnode's redacted stdout, exposed to later nodes as a path, derived from the node id with no declaration. Bothagentandevaluatorprompts 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 everyevaluatornode inherits (session_scope,permission_profile,max_rework_per_stage,gate_severity), so a flow whose evaluators all judge "good enough" rather than "correct" can lowergate_severityonce instead of per node.gate_severity- The minimum finding severity that drivesreworkon an evaluator (blocking/critical/high/medium/low; built-in defaulthigh). Less-severe findings are recorded as advisory and reach the PR follow-ups instead. Orthogonal toblocking.gating(persisted finding key) - Whether a finding met its node'sgate_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_typedispatch - The mapping from task type to flow. It is the entry point for choosing which graph runs.
Providers#
codexandclaude- The only supported provider ids.ProviderId- The canonical enum for supported providers.global primary- The single configured provider withprimary: 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 advisorydegraded_reasons(fatal only when that provider has no fallback), and theauthprobe —Nonethere 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 genericprocess_crashedand 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 qualitytask_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 genuineprocess_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 ownstream-json, a subagent the agent stopped itself not counting; raised so a promise is never accepted asdone, 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/WSL2bubblewrap+socat, or a Codexcodex sandboxthat 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, elsemanual_action_required— never a silent downgrade), andcontainment_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 tomanual_action_required).- Idle-tail settling - Claude's guard against a CLI that wrote its final
resultand then neither wrote nor exited: once the stream's last event is aresultwith 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_FALLBACKtrace beside the node's ordinary one undertelegram.trace, and a line in the PR body's## Provider fallbackssection. 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 declaringgit_evidence: true, withsecurity.allow_git_evidenceon, may run the read-only git verbs while stayingread-onlyon 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 setssecurity.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 Codexread-onlynode 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 asgit-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
WARNINGcarrying the redacted aspect summary plus the ⚠️ trace labelTRACE_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-onlysandbox permits commands, while Claude's depends on whether the resolved tool set keepsBash. The seam dispatches by provider id and the adapters answer; it is fail-closed toward bracketing (an unknown provider yieldsTrue), because a wrongTruecosts one fingerprint and a wrongFalseleaves 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 ownmax_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), andTRACE_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 fromTRACE_READ_ONLY_WRITE/TRACE_READ_ONLY_GIT_DRIFTwhen the park went away, because they no longer describe aread-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 whenstrict_isolationis enforced.bypassPermissions- The Claude full-access mode. It is operator-selectable but rejected whenstrict_isolationis 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 currentchecks-node mode that diff-selects operator-authoredchecks.command_sets, runs them all through the Check Runner, and maps the aggregate to pass/fail/incomplete.citation- The deterministic citation-manifest checker used bydeep_research; it fails when a cited source is broken. Itscitation.jsonreport records themanifest_pathit validated, so a downstream verifier opens the same manifest rather than guessing at it.dependency_scan- The core-owned argv scanner used bysecurity_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_profilenode: 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 tomanual_action_requiredwith the node run recorded asdirtied_working_tree. A flow cannot declare it away or disable it; the read-onlycitation/dependency_scancheckers 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 underlogs/<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 istrue(the fail-closed sandbox, and what an omitted key means);installwritesfalse, 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_profileandnetwork_policybecome inert in it; it is also the only mode in which a flow node may declareskills. Recorded in the frozen control bundle'smanifest.json(the mode the task started in) and the completed ledger record'sadvanced_mode(a task that finished) — deliberately never in the pull request. - Isolation floor - The four levels that remain under advanced mode: (1)
.git/.worcunwritable — 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 youroriginneither 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 advisoryisolation-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 understrict_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.PATHcoverage is mandatory (a load error otherwise); on Windows a missingSystemRootis a launch-critical FAIL at preflight and atrun/watch/rerunstart. Under advanced mode it gates only orchestrator-ownedgit/gh.extra_environment- Variables the orchestrator assigns (rather than forwards) to agent/check/tool children and to orchestrator-ownedgit/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 inconfig.yaml. A value whose path overlaps.git,.worc,.worc-io, the tasks dir, the env-file or adenied_read_pathsmatch is rejected lexically at load and canonically in preflight. Forgit/ghit passes one more gate: a whitelist over theGIT_*/GH_*/GITHUB_*namespace admitting onlyGIT_CONFIG_GLOBAL,GH_TOKEN,GITHUB_TOKEN.- Pinned launchers - The executables the orchestrator launches as itself —
git,gh,ps,bwrap, the agent CLIs, and theworcconsole script thewatchdaemon 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_refuntil there is one — neverHEAD. It asks in three places: after a writing node's edit, at that node'shitlround-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_levelsets which of those changes actually ask:strictgates all of them,auto(default) gates none of them (only aprotected_pathsmatch asks).security.protected_pathsis 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 aRemoteStatecapture around the attempt) rather than a boolean, because "the branch already exists onorigin" 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.dbhas 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/commitwhere there is no body, in the run log and the ⚠️TRACE_ADOPTED_COMMITStrace. 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 innewmode;repo.checkout_base_on_cleanupand 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 tobase_branch(safely, or fails closed) when the branch mode /repo.checkout_base_on_cleanupcalls 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 editableflows/(and theirroles/), the installedguide/, logs (check logs included, underlogs/<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), andexchange_root(<repo>/.worc-io, the redacted agent-facing exchange). All three resolve under.worc/.worc-iotoday. Anight-runs/directory under it exists only if you run theworc-night-runskill — 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/, andexchange-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 ownconfig.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 oneinstruction_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 --continuerestores 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 pluscreated_at, the mutatingnode_idand the taskattemptinevidence.json; a bundle with nothing to record is not written). Each bundle is also named on the task row intasks.quarantine_refs. Never sealed, never restore-eligible, and never removed automatically — onlyworc runs clean --include-quarantinedeletes 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 eachtoolnode'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 tomanual_action_required— never provider fallback.continue/resume reuses the original bundle (verified againsttasks.control_bundle_digest); a freshrerun/restart re-freezes from the operator's current control plane. - State Store - The SQLite-backed persistence layer around
state.dbthat 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 inPRAGMA user_version(currently28): 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 localstate.dband start fresh (greenfield). Only a0(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 inpublish_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 fromHEADafter 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 intasks/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 rewritessource_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 reacheddone(continued by an operator, or past an evaluator that does not gate publication). NULL on a clean run; set, withfailure_report_pathcleared, at the transition todone, and cleared again by a freshrerun.worc listshows such a task asdone (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 operatorrerun --continueclearsexchange_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) askind+path+ checksum, so a resume or a report finds them without re-deriving paths.pathis 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 linearorder, 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 tosummary.md. One key set on every terminal and from both writers:{what, summary, [follow_ups], [supervisor_usage], [task_usage], [cost_not_accounted], [degraded]}—task_usageis the whole task's spend (every node attempt plus the supervisor layer, as atotalandby_provider; a Claude figure covers the subagents its attempt ran), andcost_not_accountedlists, 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 (orlast_check_log_notefor atoolnode), findings, and the final diff. On a task that still reachesdoneit andstuck.mdare renamedrecovered-failure_report.json/recovered-stuck.mdand the ledger saysrecovered_from_stuckwith therecovered_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).attemptis 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 finishdonealso says where it stopped —stop_node,stuck_loop(the fix loop,nullfor an infrastructure or operator stop) andstuck_limit(the limit reached, such asmax_fix_cyclesorrepeated_findings, or the first line of the stop reason) — so a rework verdict followed by the same evaluator again after an operator'srerun --continuedoes 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 itaborted, and so does terminal reconciliation of a hard-killed run — both with the reason inabort_reason;skip_reasonis set only onskipped = 1rows.provider_attempts- The persisted per-attempt records for provider routing and fallback, each carrying the effectivemodel/reasoningthat attempt ran on (NULL when neither the node nor the provider config named one), so per-model spend needs noprompt_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'smax_rework_per_stageis counted from itsin_flow_verdictreworkrows — only those whose node run still exists (a freshrerundeletes them) and that come after the task's latestrework_budget_resetmarker, the row an operator'srerun --continue --reset-fix-budgetappends.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 withsubtask_countas 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 ofcurrent.diff, written beside it underlogs/<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 adenied_read_pathsmatch), 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 orrerun --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_askthenwait_for_answer, so a wait survives a restart).- Trace feed - The one-way, best-effort per-node progress channel (
send_trace, enabled bytelegram.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 istimeout,transport_error,invalid_response, andcancelled— the last for a wait an operatorstopended, 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 awatchtick 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, orplanning. Derived from the node's declared structure, never from its name — the flow's decomposition proposer getsplanning, any other HITL-capable node getshuman_input, a plain author node getsnone.HumanInputSignal- The typed question/approval payload parsed out of structured output.TypedStageOutput- The validated structured result for an agent node, includingcontentand optionalhuman_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].mdstep file (a fenced-jsonmetadata header — route, provider, effective and configured model/reasoning, the declared skill posture, one row per attempt with itsresumedflag — then the prompt verbatim as the body, plus a## Continuation promptsection for a node with aresume_role_file), andtimeline.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#
Stageenum - 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.promptsblock - 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_signalandcommit_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) plussecurity.protected_paths(the always-ask floor).upgrade-configstrips the old key; there is no automatic conversion.validation.required_fieldsandvalidation.reject_unknown_fields- Removed (config v35). Both were parsed and even written byinstall, but read by nothing: the task gate hard-codes the requirement (id, a non-blanktitle, a non-empty## Description) and rejects an unrecognized front-matter key unconditionally. Neither was the operator's to set — a config able to dropidor 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-configstrips them.checks.discovery/checks.commands(v15),git.auto_merge_allow_per_task(v11),agents.providers.<id>.max_budget_usd(v14) - Other removed keysupgrade-configstrips. 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 finalsummary.mdartifact.write_minimal_summary- The removed four-fieldWhat / How / Integration / WhyPR-body stub, and with it thesummary.jsontriadhow/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 durablecurrent.diff.supervisor.model/supervisor.reasoning- The former flat, one-per-layer model and effort keys. Both are now per phase undersupervisor.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 ofsecurity.strict_isolation, so there is nothing left for it to take. It is not tolerated on load and not stripped byupgrade-config: a config carrying it is a load error with a named message telling you to delete the line. The access level ispermission_profileplussecurity.strict_isolation.skillsblock (skills.dynamic,skills.strict) andskill_map.json- Repo-skill selection was removed outright: whole-repoSKILL.mddiscovery, operator pins on a flow node'sskills: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 assandbox— 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_functionlost itsskilljob 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 understrict_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 toTRACE_UNEXPECTED_WRITE/TRACE_GIT_CONTROL_DRIFTwhen git-control drift stopped parking a task. The old names described aread-only-only phenomenon; both events now apply to every node class that gets a shell.