diff --git a/.llm/2026-08-11-rfc-runtime-versioned-automation.md b/.llm/2026-08-11-rfc-runtime-versioned-automation.md new file mode 100644 index 0000000000..22d552773b --- /dev/null +++ b/.llm/2026-08-11-rfc-runtime-versioned-automation.md @@ -0,0 +1,10 @@ +# 2026-08-11 — runtime-versioned automation RFC orchestrator run + +Fable 5 medium supervisor run (owner override). Deliverables: the RFC +(`rfcs/0000-runtime-versioned-automation.md`), legacy + current evidence reports with behavioral +probes, 1444-impact memo (PR #1444), draft PR #1446. Two Codex Sol research slices (one thread, +resumed) + a Sol·xhigh evaluator thread in a dedicated worktree. PLAN-EVAL: 2× FAIL_PLAN → +per-protocol owner escalation with all findings fixed and verified. Lessons: (1) run-codex-slice +forwards ONLY --launch-arg values; (2) one Codex sender per worktree — evaluator needs its own +worktree; (3) NEVER patch by remembered strings after deno fmt — verify every replacement (drift +D-7). diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/1444-impact.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/1444-impact.md new file mode 100644 index 0000000000..b8ae267734 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/1444-impact.md @@ -0,0 +1,91 @@ +# #1444 impact memo — control-plane / runtime split for plugin modules + +From: RFC orchestrator run `docs-rfc-runtime-versioned-automation--supervisor` (Fable 5, +2026-08-11). Audience: the #1443/#1444 orchestrator. Scope: the immediate normative answer plus the +compatibility constraints #1444 must honor so the runtime-versioned-automation RFC is not +foreclosed. This memo does not ask #1444 to build anything beyond its current slices. + +## 1. Normative answer — the split is correct; keep it exactly this shape + +The owner's D-10 decision in +`.llm/runs/orchestrator-1443-plugin-ai-next-canary--supervisor/drift.md` is **ratified from the RFC +side**: + +```text +workers/plugin.ts (configured module) -> manifest-only, import-safe CONTROL PLANE +workers/mod.ts, workers/runtime.ts -> application/runtime surface (unchanged) +workers/runtime/** -> versioned operator-managed definitions (unchanged) +``` + +Rationale the RFC will elaborate: a configured plugin manifest is _inventory metadata_ the control +plane (CLI, `generate runtime-schemas`, doctor, future cockpit/management API) must read **without a +running stack** — no DB, no Aspire env, no producers. Runtime initialization belongs to the barrel +the app imports. Every credible external analogue (K8s CRD vs controller, Terraform provider schema +vs apply, VS Code extension manifest vs activation) makes the same split: **declaration loads cold; +activation runs hot.** The legacy `netscript-start` design conflated the two, which is one of the +reasons its cockpit could not be made production-safe. + +## 2. Child-process loader — required, keep it + +Verdict: **the child-process loader remains required**, not a workaround. In-process `import()` from +the CLI cannot honor the _consumer's_ import map / compiler options; only a child +`deno run +--config /deno.json` resolves the module the way the consumer's own runtime will. +`clearEnv: +true` is load-bearing: it is the executable proof of the "loads under empty environment" +contract — do not weaken it. The stdout marker-line protocol + JSON-serialized manifests is fine. + +## 3. Compatibility constraints #1444 must honor now + +C1. **Import-safety is a contract, not a convention.** The shared all-first-party contract test +(D-10 "required proof") must pin: empty env, exactly one exported `PluginManifest`, no runtime +construction at module scope. Keep it parameterized so future plugins are covered by default. + +C2. **Manifests stay data.** The child protocol serializes manifests over JSON. Never add function +or class fields to `PluginManifest`; future capability declarations (e.g. "this plugin owns a +versioned runtime tree at `workers/runtime/**`") must be declarative fields. The RFC will likely add +such fields — see C3. + +C3. **Leave the manifest schema additively extensible.** `manifest.ts` is `.strict()`. Strict is +fine for now, but version the schema (or reserve an optional namespaced extension field) so an older +CLI meeting a newer plugin manifest fails with a _versioned_ error, not a generic Zod strip/throw. +The RFC will propose `runtime` capability metadata on the manifest; #1444 does not need to add it — +it only needs to not make adding it a breaking change. + +C4. **Do not couple identity to hardcoded names.** Installed-plugin identity must follow the +configured module's exported manifest (S5 direction is right). The accepted registered-spec set +(`plugins//plugin.ts`, `/plugin.ts`, plus legacy `mod.ts` forms) is the migration bridge +for existing consumers — keep accepting the legacy `mod.ts` registration until a deprecation cycle +is declared, and surface a doctor hint instead of a hard failure when the configured module is +`mod.ts`-shaped. + +C5. **`deno.jsonc` gap (flag, fix cheaply or record).** The loader branches on +`readOptionalTextFile(join(projectRoot, 'deno.json')) === null` → falls back to in-process +resolution. A consumer with `deno.jsonc` (valid for Deno) silently loses consumer-config resolution +and will get the old failure mode. Either probe both filenames or record it as a known limitation + +doctor check. (Scaffolded projects emit `deno.json`, so this is an edge, not a blocker.) + +C6. **`generate runtime-schemas` stays control-plane-only.** It must depend on manifests + schema +metadata only — never on importing `mod.ts`/`runtime.ts` or on live services. That is what un-breaks +#1445 for every plugin and is a boundary the RFC will build on (schema generation for +operator-managed versioned documents will extend this path). + +C7. **Do not touch `workers/runtime/**` / `triggers/runtime/**` semantics.** Preserved exactly as +scaffolded today, including the `current` pointer + versioned JSON documents consumed by +`@netscript/runtime-config`. The redesign (atomic promotion, DB/object-store sync, multi-instance +propagation, sandboxing, RBAC, cockpit) is this RFC's scope, not #1444's. + +C8. **Permission surface of the child loader.** `--allow-read --allow-net` with `clearEnv` is +acceptable today (net is needed for cold jsr resolution). Note in the PR body that the loader +executes consumer-controlled code with network access at _control-plane_ time; the RFC's threat +model will formalize this (lockfile-pinned resolution, `--cached-only` fast path, and a future +capability prompt are candidate hardenings). No action required in #1444 beyond the note. + +## 4. What #1444 must not absorb + +Per D-10's scope boundary: no versioned-tree redesign, no cockpit work, no DB synchronization, no +sandbox/RBAC design, no static-config collapse, no deletion/neutering of runtime surfaces to green a +gate. Anything in that list discovered mid-slice: record it and hand it to this RFC run. + +— End of memo. Full RFC (with evidence-backed legacy/current matrix) follows in +`rfcs/0000-runtime-versioned-automation.md` on branch `docs/rfc-runtime-versioned-automation`. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/current-state-brief.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/current-state-brief.md new file mode 100644 index 0000000000..f42870429f --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/current-state-brief.md @@ -0,0 +1,121 @@ +use harness + +# Slice brief — Current-state capability matrix: runtime-versioned workers/tasks/triggers + +## SKILL + +Load and honor: `netscript-harness`, `netscript-doctrine`, `netscript-tools`, +`netscript-deno-toolchain` (use `deno doc` / `deno doc --filter` before broad source reads), +`netscript-cli`. Research slice inside +`.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/`. + +## Identity and hard constraints + +- Codex GPT-5.6 Sol research sub-agent for a Claude Fable 5 RFC supervisor. +- Worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, branch + `docs/rfc-runtime-versioned-automation` (== origin/main @ 2256a67bf). **Do not commit, push, or + modify tracked files.** Writes allowed only under + `.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/`. +- Bounded disposable proofs ARE allowed and wanted: `deno check` probes, `deno doc`, targeted + `deno test` of existing suites, CLI invocations against throwaway scaffolds under + `.llm/tmp/rfc-probes/` (create, use, then note; do not leave services running). Do NOT run the + expensive `scaffold.runtime` E2E; do not start Aspire or containers. Do not run + `deno cache --reload` or touch lock files. +- Prefix read-heavy git/grep/ls with `rtk`. +- A prior report exists at `evidence/legacy-capability-map.md` (legacy `netscript-start` + archaeology). Read its executive summary first; your job is the CURRENT repo side of the same + story. + +## Mission + +Build the current-state half of a legacy → current → gap matrix for runtime-versioned +workers/tasks/triggers. **Do not infer support from exported types alone** — for each high-value +claim, either point at a test/E2E that proves it or run a bounded disposable proof yourself. +Tag every capability `PROVEN` (test/E2E/probe evidence), `IMPLEMENTED-UNPROVEN` (code path +complete, nothing exercises it), `PARTIAL`, or `ABSENT`. + +Context you must know: the owner has authorized a **complete redesign with no +backward-compatibility layer** — this matrix decides what ideas/seams are worth KEEPING and what +gets inventoried for REMOVAL, not how to migrate. So for every surface also record a +keep/extract-idea/delete disposition hint, and be precise about which types/commands/files are +exported-but-unused (they are removal candidates). + +## Parent hypotheses to verify or refute (each needs a verdict + evidence) + +H1. The versioned read model (`runtime-config` loader/watcher) and the CLI versioned store + (`runtime-config-store-port.ts`, `deno-runtime-config-store.ts` temp+rename activation, + `manage-runtime-overrides.ts`) both work, but **no production worker/trigger composition + consumes the snapshots** — `loadRuntimeConfig`/`watchRuntimeConfig`/`getRuntimeTask`/ + `getTriggerOverride` are used only by the package's own docs/tests. Build the real call graph + (exclude generated/embedded assets like `agent-docs.generated.ts`). +H2. Two drifting task schemas: permissive `RuntimeTask` (runtime-config domain, 7 runtimes) vs + rich `TaskDefinition` (plugin-workers-core domain). The executor executes `TaskDefinition`; + nothing feeds `RuntimeConfig.tasks` into it; `NETSCRIPT_TASKS_DIR` remaps entrypoint paths + rather than loading additive versioned definitions (`local-runtime-backend.ts::runTask`, + `plugins/workers/worker/job-execution.ts`). +H3. Triggers: `TriggerOverride {id, enabled?, paths?}` is override-only (no additive runtime + trigger definitions); the trigger runtime processor (KV idempotency, DLQ, deferred replay, + OTel) loads generated TS registries (`project-trigger-registry.ts`) and does NOT compose + versioned overrides from runtime-config. +H4. `generate runtime-schemas` plans/writes real JSON Schema objects and rejects duplicate topic + owners, but on this baseline `plugin-registry.ts::resolveRegisteredPluginSnapshot` collapses + declared `runtimeConfigTopics` to `runtimeConfig: { schemas: [] }` — so output is empty in + practice. (PR #1444 fixes configured-module loading; state what baseline behavior is, do not + re-derive #1444.) +H5. Competing/duplicate CLI surfaces: generic `netscript config override` (real versioned store) + vs workers-plugin `config-edit`/`config-publish` writing `.netscript/runtime/.json` + without versioning/activation — unfinished duplicate DX. +H6. The versioned store has: no optimistic concurrency/revision preconditions, no author/approval + metadata, no multi-instance propagation, local-fs atomicity only. Also check path-traversal + handling on topic/version inputs and partial multi-topic promotion consistency. + +## Behavioral proofs (bounded, disposable, highest value) + +Under `.llm/tmp/rfc-probes/` (throwaway scaffold or minimal fixture dirs; record commands + exit +codes; leave nothing running): + +P1. Publish → activate → rollback via the real store adapter; verify temp+rename atomicity and + what a concurrent second writer does (best-effort observation). +P2. Watcher reload: start a tiny consumer using `watchRuntimeConfig`, flip `current`, observe + callback; malformed version doc → observe silent-empty behavior. +P3. `generate runtime-schemas` on a minimal consumer fixture: capture real output (or its + absence/emptiness) on baseline. +P4. Additive task attempt: put a task into the versioned `tasks` topic and demonstrate whether ANY + existing execution path picks it up (expected: none — prove the disconnect). +P5. Executor polyglot smoke: run one trivial deno + one shell/cmd task through + `MultiRuntimeTaskExecutor` directly (unit-level, no services) to confirm the engine executes. + +### Required coverage + +1. `packages/runtime-config` — types, loaders, accessors, `current` pointer semantics, version + document format, the watcher (`src/application/watcher.ts`): what triggers reload, atomicity, + error handling on malformed documents, who actually calls `loadRuntimeConfig`/the watcher in + apps/plugins/scaffold output. +2. `netscript generate runtime-schemas` — implementation path, what it emits where, and its real + behavior on a clean consumer (note: PR #1444 is fixing the configured-module loader; document + the on-main behavior and mark the known #1445 breakage rather than re-deriving it). +3. Workers: the workers CLI surface, `MultiRuntimeTaskExecutor`, runtime adapters (which runtimes + actually execute: deno/node/python/shell/...?), permission model per task, polyglot execution + reality. Where do runtime task definitions come from at execution time (versioned tree? static + registry?). +4. Triggers: runtime processor, stores, streams integration, idempotency/dead-letter behavior, + how trigger definitions are loaded/reloaded. +5. Plugin scaffold output: what `plugin install workers|triggers` actually emits today — + `workers/runtime.ts`, `triggers/runtime.ts`, `workers/runtime/**` config trees (`current` + pointer, `schema.json`, versioned JSON docs), and whether anything consumes them at runtime. +6. Aspire wiring: how workers/triggers services are declared, env plumbing for runtime config dirs, + deployment/runtime reload behavior (does a deployed stack see pointer changes without restart?). +7. Telemetry/management: any OTel spans/events/metrics for task/trigger execution; any management + API or UI endpoints touching runtime config; execution-history persistence. +8. Test/docs/E2E truth: which of the above are covered by tests or `e2e:cli` suites (name them), + what the docs claim vs what is proven. List every claim that is documented but unproven. + +## Output contract + +- Full report → `evidence/current-state-matrix.md`. Start with a ≤25-line executive summary. +- Include a `## Legacy → current mapping` table: for each legacy capability in the legacy report's + summary, state current equivalent, status tag, and gap. +- Cite `path:line` for load-bearing claims; record every probe command + exit code in a + `## Probe log` section. +- Final section `## Claims the supervisor should re-verify` (5 weakest inferences). +- Reply exactly `DONE` on the final line, or `BLOCKED: `. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/legacy-archaeology-brief.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/legacy-archaeology-brief.md new file mode 100644 index 0000000000..5bcdfce153 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/legacy-archaeology-brief.md @@ -0,0 +1,77 @@ +use harness + +# Slice brief — Legacy capability archaeology: runtime-versioned workers/tasks/triggers + +## SKILL + +Load and honor: `netscript-harness` (run mechanics), `netscript-doctrine` (vocabulary only — the +legacy repo predates doctrine; do not grade it), `netscript-tools` (rtk usage, evidence rules). +This is a **research-only** slice inside the harness run +`.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/`. + +## Identity and hard constraints + +- You are a Codex GPT-5.6 Sol research sub-agent for a Claude Fable 5 RFC supervisor. +- Working directory / git worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation` + (branch `docs/rfc-runtime-versioned-automation`). **Do not commit, push, stage, or modify any + tracked file.** Your only writes are new files under + `.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/`. +- Evidence subject: the legacy product repo at `/home/codex/repos/netscript-start-ref` + (HEAD `6ba9ba0`, branch master). It is **strictly read-only**: never run git mutations, never + edit files, never push. Reading files and running read-only `git log`/`git show` there is fine. +- Do not start services, containers, or long-running processes. Static archaeology only. +- Prefix read-heavy git/grep/ls with `rtk` to save tokens. + +## Mission + +Reconstruct — from code evidence, not aspiration — what an **operator** could actually do with the +legacy runtime-versioned workers/tasks and triggers system in `netscript-start-ref`. This feeds a +production RFC; wrong claims poison the RFC, so every claim must carry a file path (and line refs +for load-bearing claims) and an explicit confidence tag: `IMPLEMENTED` (wired end-to-end), +`PARTIAL` (code exists but path incomplete), `ASPIRATIONAL` (UI/schema/docs only), or `DEAD` +(unreachable/unused). + +Known anchor points (verify and expand; do not assume this list is complete or correct): + +- `config/runtime/mod.ts` +- `workers/runtime/tasks/v1.0.0.json`, `workers/runtime/current`, `workers/runtime/schema.json` +- the corresponding `triggers/runtime/**` tree +- cockpit routes under `apps/playground/routes/(dashboard)/dashboard/plugin/workers/tasks` and the + triggers dashboard equivalents +- CLI: `netscript generate runtime-schemas` (find its implementation and what it emitted) + +## Required report sections (answer each concretely) + +1. **Version pointer + immutable version documents** — how `current` pointers and `vX.Y.Z.json` + documents worked: format, who read them, who wrote them, atomicity, validation on load. +2. **Schema generation/validation** — how `schema.json` was produced and enforced; drift between + schema and actual loader behavior. +3. **Hot add/update/rollback** — could an operator add or change a task/trigger on a *running* + stack without rebuild/restart? Trace the actual reload path (fs watch? poll? API mutation? + restart-required?). This is the single most load-bearing question — give the strongest evidence + either way. +4. **Worker tasks + scheduled/background jobs** — task definition shape, runtimes supported, + scheduling, execution loop. +5. **Triggers + event handling** — trigger definition shape, event sources, dispatch, coupling to + workers. +6. **Execution history / status / observability** — what was persisted (tables/collections), what + the cockpit displayed, gaps. +7. **Cockpit workflows** — enumerate the dashboard routes/components for workers tasks + triggers; + for each, which operations were wired to real APIs vs mock/dead UI. +8. **Permissions, runtime selection, polyglot/legacy-wrapper support** — evidence of running + non-TS scripts (shell/python/etc), permission model per task, sandboxing if any. +9. **Persistence/synchronization** — filesystem vs DB source of truth, sync between them, + multi-instance behavior, race/failure handling. +10. **Operational limitations + why it was not production-ready** — concrete defects, TODOs, + missing auth, race conditions you can point at. + +## Output contract + +- Write the full report to + `.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/legacy-capability-map.md`. +- Start the report with a ≤25-line executive summary of what an operator could genuinely do. +- Use the confidence tags everywhere. Cite `path:line` for every load-bearing claim. +- Include a final section `## Claims the supervisor should re-verify` listing your 5 weakest + inferences. +- When finished, reply with exactly `DONE` on the final line. If blocked, reply + `BLOCKED: `. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/plan-eval-brief.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/plan-eval-brief.md new file mode 100644 index 0000000000..39794c92a6 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/briefs/plan-eval-brief.md @@ -0,0 +1,65 @@ +use harness + +# PLAN-EVAL brief — runtime-versioned automation RFC (adversarial, Sol · xhigh) + +## SKILL + +Load: `netscript-harness` (evaluator separation), `.llm/harness/evaluator/plan-protocol.md`, +`.llm/harness/gates/plan-gate.md`, `netscript-doctrine` (archetype/thinness laws), `netscript-pr`. +You are the **formal PLAN-EVAL** for a Claude-authored RFC; owner override sets your route to +**Codex GPT-5.6 Sol · xhigh** (run drift D-2). You are a fresh evaluator session: you did NOT write +this RFC; attack it. + +## Session shape + +You run in the dedicated evaluator worktree `/home/codex/repos/ns-rfc-plan-eval` (branch +`eval/rfc-runtime-versioned-automation`, same commit as the RFC branch). You are NOT the research +thread and NOT the authoring session. Never write in +`/home/codex/repos/ns-rfc-runtime-versioned-automation` except the single verdict file named below; +never commit or push in either worktree. + +## Inputs (read all — paths relative to your worktree unless absolute) + +Run dir `.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/`: `supervisor.md`, `drift.md` +(owner directives D-1…D-6), `research.md`, `plan.md`, `evidence/legacy-capability-map.md`, +`evidence/current-state-matrix.md`, `1444-impact.md`. Deliverable under evaluation: +`rfcs/0000-runtime-versioned-automation.md` (moved 2026-08-11 from +`docs/architecture/rfc/rfc-0001-…` after cycle 9; number `0000` until acceptance) plus draft PR +#1446 body/comments. + +## Constraints the RFC must satisfy (evaluate against these, not your own preferences) + +1. Owner D-10: runtime-versioned tasks/triggers are a differentiating capability; no static-config + collapse. +2. D-4: complete redesign allowed; legacy bounded to outcomes/journeys. +3. D-5: NO backward-compat/migration layer; transition = replacement/cleanup inventory. +4. D-3: cockpit downstream of RFC #890/epic #922 with an explicit minimum dependency cut; no + parallel Fresh seam. +5. `1444-impact.md` C1–C8 constraints must be honored, not contradicted. +6. Doctrine: contract-first, wrap-don't-reinvent, plugin thinness, no hardcoded plugin names. + +## Adversarial focus (attack hardest here) + +- **Evidence integrity**: does any RFC claim contradict or overreach the two evidence reports? + Spot-check citations yourself (`rtk grep`, `deno doc`); the evidence lists its own weakest claims + — check whether the RFC leaned on any of them. +- **§9 ownership decision (O2+O4)**: is the connector plugin justified vs the recorded fallback? +- **§5.2/5.3 consistency model**: find the race/failure the snapshot+CAS design misses (partial + activation sets, feed outage + poll fallback, replica schema mismatch, dev-KV vs prod-Postgres + divergence). +- **§5.4 security honesty**: is any claim stronger than the cited technology supports? Is T1 + described anywhere as a tenancy boundary (it must not be)? +- **§10 cleanup inventory completeness**: anything in the current repo that would survive as a + competing surface but isn't listed? +- **§12 roadmap**: dependency edges correct (incl. #922 cut)? wave sizing landable? anything that + should be a prerequisite RFC but is presented as decided (or vice versa)? +- **Plan-gate checklist**: run it item by item. + +## Output contract + +- Write your verdict to the ABSOLUTE path + `/home/codex/repos/ns-rfc-runtime-versioned-automation/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/plan-eval.md` + using the template `.llm/harness/templates/plan-eval.md`, verdict `PASS` or `FAIL_PLAN` with + numbered, actionable findings (severity-tagged; cite file:line). +- Do not edit the RFC or any other file. Do not commit or push. +- Final line exactly: `PLAN-EVAL: PASS` or `PLAN-EVAL: FAIL_PLAN`. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/codex-slice-status.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/codex-slice-status.json new file mode 100644 index 0000000000..1e11618f55 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/codex-slice-status.json @@ -0,0 +1,7 @@ +{ + "threadId": "019fef2b-3b13-7bd2-a07e-24a4d9db03fc", + "turns": 8, + "lastState": "budget_exhausted", + "reason": "max turns reached", + "quotaEvents": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/codex-thread-ids.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/codex-thread-ids.md new file mode 100644 index 0000000000..bc06afb21b --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/codex-thread-ids.md @@ -0,0 +1,95 @@ +# rfc-plan-eval — Codex implementation thread + +- **Thread / session id:** `019fef2b-3b13-7bd2-a07e-24a4d9db03fc` +- **Rollout:** + `/home/codex/.codex/sessions/2026/08/11/rollout-2026-08-11T06-53-35-019fef2b-3b13-7bd2-a07e-24a4d9db03fc.jsonl` +- **Worktree:** `/home/codex/repos/ns-rfc-plan-eval` +- **Branch:** `eval/rfc-runtime-versioned-automation` (NO upstream by design). +- **Push rule:** explicit refspec only — + `git push origin HEAD:refs/heads/eval/rfc-runtime-versioned-automation`. +- **Requested route:** provider=openai · model=gpt-5.6-sol · effort=xhigh +- **Observed route:** provider=openai · model=gpt-5.6-sol · effort=xhigh +- **Route verdict:** matched +- **Runtime:** approval=never · sandbox=dangerFullAccess +- **Brief (staged):** `/home/codex/rfc-plan-eval-brief.md` + +## Steering (same thread — never a second send-message-v2 at this worktree) + +```bash +codex exec resume 019fef2b-3b13-7bd2-a07e-24a4d9db03fc -- "" +``` + +_Written by `.llm/tools/agentic/codex/launch-codex-slice.ts`._- 2026-08-11T05:07:49.687Z — thread +`019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running + +- 2026-08-11T05:09:12.137Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T05:09:54.039Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T05:10:20.660Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T05:10:30.493Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T05:10:37.190Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T05:10:43.930Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T05:10:50.975Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running +- 2026-08-11T05:26:06.319Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running +- 2026-08-11T05:26:35.895Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T05:27:01.066Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T05:27:25.143Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T05:27:46.459Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T05:28:04.652Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T05:28:21.886Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T05:28:36.819Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running +- 2026-08-11T05:51:22.250Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running +- 2026-08-11T05:52:19.434Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T05:52:30.137Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T05:52:38.715Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T05:52:46.048Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T05:52:55.561Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T05:53:03.471Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T05:53:15.098Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running +- 2026-08-11T06:58:35.718Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running +- 2026-08-11T06:59:01.334Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T06:59:12.243Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T06:59:21.665Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T06:59:34.650Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T06:59:45.500Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T06:59:57.510Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T07:00:10.595Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running +- 2026-08-11T07:07:29.176Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running +- 2026-08-11T07:07:39.190Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T07:07:49.575Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T07:08:00.810Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T07:08:10.301Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T07:08:23.421Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T07:08:33.631Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T07:08:43.610Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running +- 2026-08-11T07:18:39.782Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running +- 2026-08-11T07:19:01.332Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T07:19:17.510Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T07:19:33.553Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T07:19:42.228Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T07:19:49.666Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T07:20:01.502Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T07:20:10.107Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running +- 2026-08-11T07:24:45.582Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running +- 2026-08-11T07:24:54.619Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T07:25:03.746Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T07:25:13.951Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T07:25:23.221Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T07:25:31.144Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T07:25:40.743Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T07:25:49.147Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running +- 2026-08-11T07:29:04.167Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running +- 2026-08-11T07:29:15.056Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T07:29:23.448Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T07:29:34.346Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T07:29:43.434Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T07:29:53.425Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T07:30:04.406Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T07:30:13.774Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running +- 2026-08-11T07:32:55.945Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 1, state running +- 2026-08-11T07:33:07.279Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 2, state running +- 2026-08-11T07:33:18.624Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 3, state running +- 2026-08-11T07:33:29.103Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 4, state running +- 2026-08-11T07:33:38.244Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 5, state running +- 2026-08-11T07:33:50.263Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 6, state running +- 2026-08-11T07:34:03.482Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 7, state running +- 2026-08-11T07:34:13.324Z — thread `019fef2b-3b13-7bd2-a07e-24a4d9db03fc`, turn 8, state running diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/context-pack.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/context-pack.md new file mode 100644 index 0000000000..ab46af7bdb --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/context-pack.md @@ -0,0 +1,29 @@ +# Context Pack — docs-rfc-runtime-versioned-automation--supervisor + +Resume here. State as of 2026-08-11: **PLAN-EVAL PASS (cycle 9)**; D-8 + D-9 applied; RFC produced; +awaiting owner ratification (PR #1446 draft). + +- **What this run is**: research + architecture RFC for runtime-versioned workers/tasks/triggers + (operator capability on a running stack). No implementation. Draft PR #1446 vs main. +- **Identity/overrides**: Fable 5 medium supervisor (D-1); final PLAN-EVAL Codex Sol xhigh (D-2); + owner directives D-3 (cockpit downstream of #890/#922 cut), D-4 (complete redesign in scope), D-5 + (no compat/migration — clean break + cleanup inventory), D-6 (parent hypotheses). +- **Evidence**: `evidence/legacy-capability-map.md` (legacy trees were dead wiring; polyglot engine + real, no control plane) and `evidence/current-state-matrix.md` (H1–H6 confirmed; P1 pointer race + 20/20; P3 runtime-schemas writes 0; P4 RuntimeTask rejected by executor; P5 deno+shell execute). + Both supervisor-reviewed (A1) with verbatim spot-checks. +- **Deliverable**: `rfcs/0000-runtime-versioned-automation.md` — two-plane architecture; families + task@1/trigger@1 (no task schedule — scheduled trigger is the only operator cron); immutable + revisions + transactional activation-set epochs + fleet admission; three-package ownership + (automation-core contracts / automation-runtime behavior+adapters / thin connector plugin) — + LOCKED; T1 honesty contract; TM1–TM9; cleanup inventory; slices A0–A8 with files+gates; E2E model + incl. outage test 8; P-1..P-6 staged items (P-6 = DevTools RFC per D-9; §8.2 = two decided + operator surfaces). +- **Eval state**: seven Sol·xhigh cycles (same dedicated evaluator thread `019fef2b-…03fc`, worktree + ns-rfc-plan-eval). C1 9 findings → C3 6 → C4 5 → C5 2 → C6 "no unresolved runtime architecture + decision remains" (bookkeeping only) → C7 one Design-vocabulary line + progress narratives (this + fix). Every finding of every cycle is fixed in-tree; the final pass closes on the reconciled + record; on PASS the RFC is produced and the owner ratifies. + +- **Hard rules**: draft PR only; no issue filing; no ready-for-review until owner ratifies; never + write in ns-1443 worktree or netscript-start-ref. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/drift.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/drift.md new file mode 100644 index 0000000000..ea784b219e --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/drift.md @@ -0,0 +1,16 @@ +# Drift Log — docs-rfc-runtime-versioned-automation--supervisor + +Append-only. Severity: note | significant | architectural. + +| ID | Date | Severity | Drift | +| ---- | ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| D-1 | 2026-08-11 | note | Supervisor runs on Claude Fable 5 · medium (bypass permissions, Remote Control) instead of the canonical Opus 5 · high `planning_decisions` route — explicit owner override in the launch brief for this complex RFC. Recorded in `supervisor.md` § overrides. | +| D-2 | 2026-08-11 | note | Final PLAN-EVAL is ordered at Codex GPT-5.6 Sol · **xhigh** (canonical for Claude-authored plans is Sol · high) — explicit owner override; the RFC is Claude-authored and unusually complex. | +| D-3 | 2026-08-11 | significant | Owner sequencing correction (mid-run directive): the workers/tasks/triggers cockpit is a downstream consumer of the Frontend Contribution Layer — RFC PR #890 (MERGED 2026-08-03, design record `.llm/runs/plan-frontend-contrib--seed/rfc.md`) and implementation epic #922 (OPEN, milestone 0.0.9, children #923–#946). No cockpit frontend slice may land before the required #922 foundation lands; no parallel hardcoded Fresh/dashboard seam may be invented. RFC/matrix/roadmap must cite both links, model the cockpit dependency as a precise minimum cut (evaluate Wave-0 #923–#927, Wave-1 #928–#932, gateway #934, later DX/testing slices as actually needed), and mark frontend-independent backend/control-plane work as such. | +| D-4 | 2026-08-11 | architectural | Owner clarification (mid-run): **complete redesign is explicitly in scope.** Legacy repo = evidence of outcomes/journeys/constraints only, never an architectural template; current runtime-config/workers/triggers/CLI/store/watcher = evidence and candidate seams, not mandatory foundations. RFC must compare evolutionary repair vs clean-sheet vs hybrid. Legacy archaeology bounded to outcome-level evidence + three representative operator journeys. Design depth goes to contribution model (#890-pattern extraction, not copy), control/data-plane boundaries, ports/adapters + established sandbox tech survey, version/promotion consistency, multi-instance propagation, security, observability, package/plugin ownership (5 options to compare without pre-deciding). | +| D-5 | 2026-08-11 | architectural | Owner decision (mid-run): **no backward-compatibility or migration layer.** Feature is pre-production and unused; clean break authorized. No data import, dual-read/write, compat adapters, deprecation windows, or preservation of existing CLI/API/file shapes. Transition plan = codebase replacement/cleanup plan (explicit inventory of obsolete packages, commands, types, docs, generated files, tests to remove/rewrite). Compatibility required only with stable doctrine + active framework seams. | +| D-6 | 2026-08-11 | note | Parent-orchestrator supplied an initial current-shape analysis (hypothesis/routing aid, not accepted truth): versioned read model + fs write/rollback primitives + polyglot executor + durable trigger processor present; snapshot→live composition apparently DISCONNECTED; cockpit absent; runtime-schemas integration incomplete (snapshots yield empty schema sets on baseline); duplicate workers-plugin config CLI surface. G2 brief updated to verify/refute each claim with behavioral proofs. | +| D-7 | 2026-08-11 | significant | Fix-cycle process failure: three cycle-1 fixes (§9 ownership lock, TM9 row, T1 tier-row honesty companion text) silently no-opped — python `str.replace` patterns were composed against pre-`deno fmt` text and did not match the fmt-rewrapped file; the fix commit claimed them applied. Detected via PLAN-EVAL cycle 2's citations; all edits re-applied with per-edit match verification (assert-on-miss) and grep audit. Lesson: after `deno fmt`, never patch by remembered text — re-read the file and verify every replacement. | +| D-8 | 2026-08-11 | significant | Owner directive (pre-cycle-3): add a bounded, primary-source-backed competitive architecture study — Temporal, Restate, Inngest, Trigger.dev, Hatchet, Windmill, Azure Durable Functions, AWS Step Functions, plus operator/low-code representatives (Kestra/n8n) — across definition/versioning, activation/rollback, live mutation, scheduling ownership, consistency/multi-instance, idempotency/retries, history/audit/telemetry, isolation, control/data plane, extensibility, cockpit UX, self-hosting. Distinguish adopted patterns vs non-goals vs NetScript differentiators; NO empirical performance benchmark claims — define executable implementation-stage benchmark gates instead; correct overbroad wording (e.g. "market survey done" scoped to isolation). Then resume the retained Sol·xhigh evaluator for authorized PLAN-EVAL cycle 3 against the new head. | +| D-9 | 2026-08-11 | architectural | Owner clarification (pre-final-acceptance): #890 ratifies primarily the USERLAND app contribution family (routes/islands/zones/nav/theme + #934 gateway) and does NOT settle the complete frontend contribution problem. Five distinct contribution surfaces: (1) userland UI via the app family; (2) Fresh UI registry/component/style-dictionary extensions (potentially extending CLI fresh-ui commands); (3) deferred Vite plugin contribution; (4) a first-class DevTools contribution family/host; (5) SDK contribution (owned by its separate RFC). Dev Dashboard epic #400 + designs #685 / draft PR #780 / older #506 predate the modern RFC profile — evidence, not ratified DevTools architecture. This runtime RFC must NOT design those general mechanisms. §§8.2/12/A7 corrected: #890/#922 are sufficient only for the production/admin userland automation console; the DevTools surface (runtime diagnostics, live definitions/state, execution journeys, dev management affordances) goes behind a new dedicated DevTools RFC (staged P-6) that re-evaluates #400 and consumes this RFC's stable management/observability contracts. Decide + document: production operator management and developer diagnostics are TWO hosts/contribution surfaces, not one ambiguous cockpit. Backend slices stay frontend-independent. | +| D-10 | 2026-08-11 | note | Owner directive (post-PASS, pre-merge): normalize PR #1446 to the canonical in-repo RFC process. The RFC moved from `docs/architecture/rfc/rfc-0001-runtime-versioned-automation.md` (authored there when no RFC home existed — that S4 locked decision is superseded) to `rfcs/0000-runtime-versioned-automation.md` with the `0000-template.md` frontmatter (status `Draft`; number `0000` until a maintainer assigns one at acceptance). Living references updated (plan, context-pack, phase-registry G4, plan-eval brief, evidence identifiers RFC-0001→RFC-0000, 1444-impact tail, .llm run summary, PR #1446 body). Intentionally preserved verbatim: `plan-eval.md` (evaluator-authored, append-only; its citations anchor to historical revisions) and dated historical worklog entries and PR comments. No issues or milestones touched; tracking-issue filing remains owner-gated. | diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/competitive-architecture-study.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/competitive-architecture-study.md new file mode 100644 index 0000000000..7205f216a2 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/competitive-architecture-study.md @@ -0,0 +1,239 @@ +# Competitive architecture study — runtime/workflow systems vs RFC-0000 + +Owner-directed (drift D-8), retrieved 2026-08-11 via primary sources (vendor documentation; two +lighter-weight sources are used ONLY for color/representative-UX and never for a load-bearing matrix +cell: a Hatchet HN engineering post and n8n vendor-community guidance; every load-bearing cell cites +vendor documentation, or the cell is marked ◐/unknown). Scope: architecture comparison ONLY — **no +empirical performance claims are made anywhere in this study**; performance is handled exclusively +as executable implementation-stage benchmark gates (§Benchmark gates). Each claim carries its source +URL; quotes are from the retrieved pages. + +Systems: Temporal, Restate, Inngest, Trigger.dev, Hatchet, Windmill, Azure Durable Functions (DF), +AWS Step Functions (SFN), and the operator/low-code group Kestra + n8n. + +## Per-system profiles (dimensions relevant to RFC-0000) + +### Temporal — durable code workflows, worker-deployment versioning + +- Definition = code (workflows/activities) executed by app-hosted workers against a server; + event-history replay demands **deterministic** workflow code. +- Versioning: **Worker Deployment Versions**; a running workflow can be **pinned** "on the Worker + Deployment Version where it started", with rainbow deployments recommended for pinned workflows; + safe-deploy doctrine includes replay testing before switching pinned workflows to a new version. + Sources: https://docs.temporal.io/production-deployment/worker-deployments/worker-versioning · + https://docs.temporal.io/worker-versioning · https://docs.temporal.io/develop/safe-deployments +- Live mutation: none for definitions (deploy-driven); operators act on executions (signal/ + cancel/reset), not on definitions. +- Control/data plane: server (control + history) vs app-hosted workers on task queues; self-host + (OSS server) + cloud. + +### Restate — durable execution log, immutable service deployments + +- "When you deploy a version of your code, you give it an **immutable, unique endpoint** and + register it with Restate"; **"When a bug affects in-flight invocations, they remain pinned to the + original deployment"**, with explicit + `restate invocations resume --deployment + ` to move them. Deployments are + removed only when drained. Source: https://docs.restate.dev/services/versioning +- Observability: SQL introspection over invocations incl. `pinned_deployment_id`. Sources: + https://docs.restate.dev/references/sql-introspection · + https://docs.restate.dev/services/introspection +- Single-binary self-host; control plane = broker/log, data plane = service endpoints (any platform + incl. FaaS). + +### Inngest — event-driven durable functions, app sync model + +- Functions live in the **app**; the server discovers them by **syncing apps** ("resync your app + with Inngest whenever you deploy new function configurations"), optionally polling + (`--poll-interval`). Source: https://www.inngest.com/docs/apps/cloud · + https://www.inngest.com/docs/self-hosting +- Versioning doctrine: "deploy changes to functions without explicit version markers"; safe + evolution strategies documented rather than first-class immutable versions. Source: + https://www.inngest.com/docs/learn/versioning +- Self-host: single-node `inngest start`, Postgres for configuration/history persistence, Redis for + queue/run state. Source: https://www.inngest.com/docs/self-hosting +- Control/data plane: server orchestrates; steps execute in the app (HTTP) or connected workers. + +### Trigger.dev — task versioning with atomic promote + +- Every deploy creates a version (`20240313.1` style); **atomic deploys**: "deploying your tasks … + without promoting them to the default version" (`--skip-promotion`) then explicit `promote`; app + pins `TRIGGER_VERSION` so app and tasks move **atomically**; "Atomic versioning allows you to + deploy new versions … without affecting currently running tasks"; **replay** re-runs a task's + inputs on the latest version. Sources: https://trigger.dev/docs/versioning · + https://trigger.dev/docs/deployment/atomic-deployment · https://trigger.dev/product · + https://trigger.dev/docs/self-hosting/overview +- Isolation: managed/self-hosted worker infrastructure runs task code out-of-app. + +### Hatchet — Postgres-source-of-truth task orchestration + +- "PostgreSQL is the durable store for workflow definitions and execution state …; state transitions + are performed transactionally." Source: https://docs.hatchet.run/v1/architecture-and-guarantees +- Durable tasks = cached intermediate results + replay on retry (engineering post, color only: + https://news.ycombinator.com/item?id=43572733). +- Control/data plane: Hatchet engine over Postgres; app-hosted workers. Self-host first-class. + +### Windmill — operator-edited scripts/flows with deployment history + +- Closest operator model to NetScript's intent: scripts/flows/apps are **edited in the UI**, each + with versioned deployment history ("Flow versioning", "Deployment history" — + https://www.windmill.dev/changelog); staging→prod promotion via UI/git + (https://www.windmill.dev/docs/advanced/deploy_to_prod · + https://www.windmill.dev/docs/core_concepts/staging_prod); polyglot execution (Python/TS/Go/ + Bash/SQL) on worker fleets; Docker/K8s self-host + (https://www.windmill.dev/docs/advanced/self_host). + +### Azure Durable Functions — the cautionary versioning tale + +- Whole doc trees exist because orchestration replay makes code changes breaking: breaking- change + taxonomy, **orchestration versioning** (instances "permanently associated with a specific version + when created"), side-by-side deployments via separate **task hubs**/storage accounts, name-based + versioning, application routing. Deploying breaking changes unmitigated ⇒ "nondeterministic + orchestration errors" or stuck `Running`. Sources: + https://learn.microsoft.com/en-us/azure/durable-task/durable-functions/durable-functions-versioning + · + https://learn.microsoft.com/en-us/azure/durable-task/durable-functions/durable-functions-zero-downtime-deployment + · https://learn.microsoft.com/en-us/azure/durable-task/common/durable-orchestration-versioning + +### AWS Step Functions — declarative definitions, versions + weighted aliases + +- Definitions are data (ASL JSON). **Published versions are immutable; aliases route between ≤2 + versions with weights** — canary/rolling/gradual deployment and rollback are documented + first-class flows; executions are associated with the exact version/alias that started them. + Sources: https://docs.aws.amazon.com/step-functions/latest/dg/concepts-state-machine-alias.html · + https://docs.aws.amazon.com/step-functions/latest/dg/example-alias-version-deployment.html · + https://docs.aws.amazon.com/step-functions/latest/dg/version-rolling-deployment.html · + https://docs.aws.amazon.com/step-functions/latest/dg/execution-alias-version-associate.html +- Managed-only (non-goal for NetScript self-hosting, but the versioning model is the cleanest + published analogue to RFC-0000 epochs). + +### Kestra / n8n — operator/low-code group + +- Kestra: YAML flows edited in the UI editor (https://kestra.io/docs/ui/flows); "Whenever you make + any changes to your flows, a **new revision is created**" with rollback + (https://www.youtube.com/watch?v=Z3w1pZxNa9U — vendor material); **plugin versioning + hot + reload**: "run multiple versions of the same plugin simultaneously" + (https://kestra.io/blogs/plugin-versioning) — the closest published analogue to plugin-contributed + runtime families. +- n8n: workflow JSON with **Publish** semantics + Version History (draft vs published live version) + per vendor community guidance + (https://community.n8n.io/t/change-from-save-activate-to-publish-for-workflows/258417) — + representative of draft→publish operator UX; graph-style visual programming is its authoring + model. + +## Comparison matrix (the 12 owner-named dimensions rendered as 15 rows × 9 systems, condensed) + +(Versioning is split into four rows — definitions-as-data, immutable versions, activation pointer, +rollback — so the row count exceeds the dimension count by design.) + +Legend: ● first-class · ◐ partial/strategy-level **or not assessed from dedicated sources** · ○ +absent/out-of-model. "NS" = RFC-0000 position. Cells in the three later-added rows (isolation, +control/data plane, cockpit UX) are either tied to a citation, derived from the cited architecture +structure, or explicitly marked ◐ not assessed — no absolute claim rests on an uncited cell. + +| Dimension | Temporal | Restate | Inngest | Trigger.dev | Hatchet | Windmill | DF | SFN | Kestra/n8n | NS (RFC §) | +| ----------------------------------- | ------------------------------------------------------------------------------ | -------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| Definitions as data (vs code) | ○ code | ○ code | ○ code | ○ code | ○ code | ◐ code+meta, UI-owned | ○ code | ● ASL | ● YAML/JSON | ● schema-first families (5.1) | +| Immutable versions | ● deploy versions | ● immutable endpoints | ◐ implicit | ● dated versions | ◐ | ● per-item history | ◐ instance-bound | ● published versions | ● revisions | ● content-addressed revisions (5.2) | +| Explicit activation pointer/alias | ◐ current version | ◐ latest deployment | ○ | ● promote | ◐ | ● deploy-to-prod | ○ | ● alias (+weights) | ● publish | ● epoch manifest (5.2) | +| Rollback = re-point | ◐ | ◐ resume-on-deployment | ○ | ● promote old | ◐ | ● restore version | ○ | ● alias re-point | ● revision restore | ● activate older revision (5.2) | +| In-flight pinning | ● pinned workflows | ● pinned invocations | ◐ | ● running tasks unaffected | ◐ | ◐ | ● instance version | ● exec↔version assoc | ◐ | ● revision-pinned dispatch (5.3-6) | +| Operator live mutation (no rebuild) | ○ | ○ | ○ | ○ | ○ | ● UI edit+deploy | ○ | ◐ console edit+publish | ● UI edit=revision | ● core journey J1/J2 (1) | +| Scheduling ownership | server (schedules on defs) | server | server | server | server | server | server (timers) | server | server | trigger family only (5.1) | +| Multi-instance consistency | server-serialized | log-serialized | server-serialized | server-serialized | Postgres txn | Postgres | storage provider | managed | server DB | epoch admission + acks (5.3) | +| Idempotency/retries/DLQ | ● | ● | ● | ● | ● | ◐ | ● | ◐ | ◐ | ● engine-kept + queue-native (5.4) | +| History/audit/telemetry | ● event history | ● SQL introspection | ● | ● runs+replay | ● | ● runs/audit (EE) | ● | ● | ● | ● history+audit stores (5.2, 7) | +| Plugin/extension contribution | ○ | ○ | ○ | ○ | ○ | ◐ hub items | ○ | ○ | ● versioned plugins, hot reload | ● contribution families (5.1) | +| Self-host | ● OSS server | ● single binary | ● single node (PG/Redis) | ● (pinned version) | ● | ● Docker/K8s | ◐ Azure-bound | ○ managed only | ● / ● | ● in-stack, Aspire-composed (4) | +| Isolation of executed code | app-owned workers (execution stays in the app per the cited architecture docs) | app-owned endpoints (same basis) | app-owned (HTTP/workers, same basis) | platform/self-hosted worker infrastructure runs task code out-of-app (cited above) | app-owned workers (same basis) | worker fleet executes scripts with **configurable per-job isolation (PID namespaces / NSJAIL; defaults and host caveats apply)** — https://www.windmill.dev/docs/advanced/security_isolation | ◐ not assessed from dedicated security docs | ◐ not assessed from dedicated security docs | ◐ not assessed from dedicated security docs | tiered boundary port T0–T3, honesty per tier (5.4) | +| Control/data-plane split | ● server vs workers | ● broker/log vs endpoints | ● server vs app | ● platform vs workers | ● engine vs workers | ◐ server+workers one product | ● runtime vs app | ● managed plane | ◐ single server | ● management service vs engine replicas (4) | +| Cockpit / operator UX | exec ops (signal/cancel/reset; cited safe-deploy docs), no def editing | CLI/SQL introspection (cited) | ◐ runs UI (not re-verified from dedicated docs) | runs UI + replay + promote (cited) | ◐ runs UI (not re-verified) | ● full editor + deploy history (cited) | ◐ portal ops (not re-verified) | console editor + publish (cited alias/version docs) | ● editor + revisions (cited) / ● editor + publish (community-sourced, color-only) | list/detail/run/history + draft→activate flows, #922-gated (8.2) | + +## Synthesis + +### Established patterns RFC-0000 adopts (independent convergence, now cited) + +1. **Immutable version + explicit activation pointer + rollback-as-re-point** — SFN + versions/aliases, Trigger.dev deploy/promote, Restate immutable deployments, Kestra/n8n + revisions/publish. RFC: revisions + epoch manifests (§5.2). The `--skip-promotion` → verify → + `promote` shape maps 1:1 to draft → validate → activate. +2. **In-flight work pinned to the version that started it** — Temporal pinned workflows, Restate + pinned invocations, DF instance-version association, SFN execution↔version association, + Trigger.dev running tasks. RFC: revision-pinned dispatch (§5.3 step 6) is the same principle + applied at task granularity. +3. **Database as transactional system of record for definitions + execution state** — Hatchet + (explicitly), Inngest self-host (Postgres), Windmill. RFC §5.2. In none of the retrieved + documentation does a studied system consume watched files as its runtime definition source; where + file formats appear (Kestra YAML, SFN ASL, Windmill git sync) they are authoring/interchange + surfaces — consistent with RFC-0000's demotion of the filesystem. (Scoped to the retrieved docs, + not an exhaustive product-wide negative.) +4. **Server-owned scheduling attached to definitions; single-fire is the platform's job** — in every + studied system whose scheduling is documented in the retrieved sources, schedules attach to + definitions and fire server-side; no counterexample was found. RFC: trigger-family cron ownership + (§5.1) + P-1. +5. **App-hosted execution with server-side orchestration and explicit app/worker sync** — Inngest + app sync/poll, Temporal workers, Restate endpoints, Hatchet workers. RFC: snapshot client + + change feed + poll fallback (§5.3) is the same control/data split. +6. **Draft → publish operator UX with version history in the cockpit** — Windmill, Kestra, n8n. RFC: + J1–J3 + §8.2. +7. **Plugin-versioned extensibility** — Kestra plugin versioning/hot-reload is precedent that + contribution-style extensibility co-exists with a revisioned control plane. RFC §5.1. +8. **Staged/weighted activation (canary) as a proven pointer-model extension** — SFN weighted + aliases + rolling deployment. RFC adds this as staged item **P-5** (not v1 scope): the epoch + manifest can carry weighted entry pairs once convergence tracking (A2d) exists. + +### Deliberate non-goals (v1), with the evidence for declaring them + +- **Replay-determinism durable execution for tasks/triggers.** Temporal/DF/Restate/Inngest/ Hatchet + all pay a heavy versioning tax for replayable code workflows — DF maintains an entire + breaking-change taxonomy and four mitigation strategies. NetScript `task@1` is a single-shot, + engine-retried subprocess execution with no replay contract, so that tax is deliberately not + imported. Multi-step durable orchestration remains the saga plugin's domain; if a durable `saga@1` + family arrives (P-4), _these_ systems' versioning lessons apply there. +- **External/managed control plane.** SFN's model is the cleanest but is managed-only; the NetScript + control plane ships inside the consumer's stack (self-host by construction). +- **Visual graph programming as the authoring model** (n8n-style). The cockpit edits schema-derived + forms over declarative definitions; it does not introduce a node-graph DSL. +- **A generic compute marketplace.** Out of scope until P-2/P-3 (isolation + provenance land first) + — consistent with every studied system treating untrusted third-party code as a separate, harder + product. + +### NetScript differentiators (defensible after this study) + +1. **In-framework, not alongside it**: definitions live inside the consumer's full-stack app and + compose with the same auth, DB, streams, sagas, and Aspire topology — every studied system is an + adjacent server/SaaS the app integrates with. +2. **Operator wrapping of existing project-local polyglot scripts** with declared capability grants + and honest per-tier enforcement — Windmill is the nearest neighbor but owns the code in its own + workspace model; NetScript wraps what already lives in the repo/deployment. +3. **Contribution-family extensibility**: third-party plugins add new definition _families_ (not + just new tasks) through the same manifest/registry machinery as the rest of the framework — only + Kestra's plugin system is comparable, and it is not schema-first. +4. **One control plane across heterogeneous engines** (workers + triggers today, sagas/streams + later) rather than one product per engine. + +## Benchmark gates (executable, implementation-stage — replacing any performance claim) + +No throughput/latency numbers in this study or the RFC are empirical claims about NetScript or the +systems above. Instead, the following gates become part of the named slices; each pins a **reference +environment** (scaffolded stack, documented hardware class) in its slice PR, ships as an executable +measurement, and fails CI on regression. Initial budgets are owner-ratified at slice time; the +_gate_ is that the measurement exists, is reproducible, and is enforced: + +| Gate | Measures | Lands in | +| ---- | ------------------------------------------------------------------------------------- | ------------------------------- | +| BG-1 | activation → all-replica convergence latency (p50/p95, 3 replicas) with SLO assertion | A2d, exercised in A8 | +| BG-2 | per-dispatch overhead of revision-pinned lookup vs direct registry read (warm cache) | A3a micro-bench | +| BG-3 | epoch commit transaction latency (publish+activate+audit) on the reference Postgres | A1a conformance suite perf case | +| BG-4 | sustained execution-history write rate without queue growth on the reference stack | A8 | +| BG-5 | T1 boundary spawn overhead per runtime (deno/python/shell) vs bare subprocess | A5a | + +## Limitations + +- Retrieval is point-in-time (2026-08-11); vendor docs move. URLs + retrieval date are the + provenance; re-verify before implementation-stage reliance. +- Kestra revision behavior cites vendor material incl. a vendor video; n8n publish semantics cite + vendor community guidance — both are representative-group members, held to lighter weight than the + seven primary systems. +- No hands-on deployment of any studied system was performed in this run (bounded study); the matrix + reflects documented architecture, not operational experience. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-matrix.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-matrix.md new file mode 100644 index 0000000000..592bcfcdf0 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-matrix.md @@ -0,0 +1,255 @@ +# Current-state capability matrix: runtime-versioned workers, tasks, and triggers + +## Executive summary + +- **[PARTIAL]** The current repository still contains two functional halves of runtime versioning: a typed loader/watcher and a CLI filesystem publisher, but no production worker or trigger composition imports the snapshots. +- **[PROVEN]** The real filesystem store publishes immutable-looking topic documents, activates through temp-file + rename, and rolls back one topic while preserving the pointer fields it read. +- **[PROVEN]** That preservation is not concurrency-safe: a probe lost one of two simultaneous topic promotions in 20/20 trials; there is no revision, compare-and-swap, lock, author, or approval field. +- **[PROVEN]** The watcher reacts to filesystem changes and reloads, but malformed JSON is silently converted to an empty topic and callback failures are swallowed. +- **[PARTIAL]** `RuntimeTask` describes seven runtimes, while the worker executor consumes a different, richer `TaskDefinition`; no adapter maps or seeds versioned tasks into the KV task registry. +- **[PROVEN]** The execution engine itself ran trivial Deno and shell tasks successfully; built-in adapters also exist for Python, .NET, PowerShell, cmd, and native executables. +- **[PARTIAL]** Deno permissions are translated into flags, but an omitted permission object grants `--allow-all`; non-Deno subprocesses inherit the full host environment and have no task sandbox. +- **[PROVEN]** Worker APIs expose KV-backed task definitions and execution history, but those definitions originate in KV/project source—not the versioned runtime tree. +- **[PARTIAL]** Task `schedule` is data only; the delivered scheduler enumerates jobs, once at startup, not tasks. +- **[PROVEN]** Trigger definitions load from generated TypeScript registries at process startup; scheduled and file-watch definitions are wired to the processor, and webhook service composition uses the same loaded definition set. +- **[PROVEN]** Trigger processing has tested idempotency, retry, concurrency, DLQ behavior, KV-backed defer replay, enabled-state enforcement, and tracing seams. +- **[PARTIAL]** Trigger enable/disable is a real KV-backed API, but versioned `TriggerOverride` files are never composed into it and cannot add a trigger. +- **[PROVEN]** `netscript generate runtime-schemas` has a real planner/writer and duplicate-owner rejection, yet the baseline plugin snapshot deliberately replaces declared topic schemas with `schemas: []`; a clean CLI probe wrote zero files. +- **[PARTIAL]** Plugin installation emits executable `workers/runtime.ts` and `triggers/runtime.ts`; official samples additionally emit `current` and version documents. The runtime glue consumes generated code registries, not those JSON trees. +- **[ABSENT]** A pointer change cannot hot-add, update, or roll back a running task/trigger in the delivered composition. The watcher is a library primitive with no production subscriber. +- **[PARTIAL]** The present system is useful as a static worker/trigger runtime and as an experimental local filesystem control plane, but it is not a coherent production runtime-versioned automation capability. + +## Scope, baseline, and labels + +- **[PROVEN]** Research was performed in `/home/codex/repos/ns-rfc-runtime-versioned-automation` on branch `docs/rfc-runtime-versioned-automation` at `e7378bf7c15dcb5ef22e4904a99601cbd4b79ca9`. The brief names `origin/main` at `2256a67bf612907195ce5e51df1df7326c504f2b`; a path-scoped diff established that `packages/`, `plugins/`, `apps/`, `deno.json`, and `deno.lock` are unchanged between those commits. The later commit contains harness artifacts only. +- **[PROVEN]** `PROVEN` means an existing test/E2E definition or a bounded probe exercised the behavior; `IMPLEMENTED-UNPROVEN` means the executable call path appears complete but was not exercised here; `PARTIAL` means useful code exists with a material missing connection; `ABSENT` means no executable path was found. +- **[PROVEN]** This is current-state evidence, not a doctrine grade. Dispositions assume the authorized clean redesign: **keep** means retain the behavior/contract, **extract idea** means preserve the concept but not this surface, and **delete** means inventory the current surface for removal. + +## Hypotheses H1–H6 + +| Hypothesis | Verdict | Evidence and disposition | +|---|---|---| +| H1 — loader/watcher and CLI store work, but production does not consume snapshots | **[PROVEN] Confirmed** | The loader reads `current` and five topic files (`packages/runtime-config/src/application/loader.ts:94-118`); the watcher uses recursive `Deno.watchFs` and debounced reload (`packages/runtime-config/src/application/watcher.ts:23-57`). A production-source search excluding tests, docs, templates, and generated assets found no external import/call; only a Windows environment-builder comment claims future use (`packages/cli/src/kernel/adapters/windows/servy/servy-environment.ts:242-252`). **Disposition:** keep the snapshot concept and tested loader semantics; delete the disconnected package/composition surface unless it becomes the new control-plane port. | +| H2 — task schemas drift and snapshots do not feed execution | **[PROVEN] Confirmed** | `RuntimeTask` uses `runtime`, carries seven runtime labels, and permits arbitrary extra fields (`packages/runtime-config/src/domain/types.ts:26-39`, `packages/runtime-config/src/domain/types.ts:109-130`). The executor requires `type`, supports permissions/env/args/metadata, and dispatches on `task.type` (`packages/plugin-workers-core/src/executor/executor-types.ts:13-41`; `packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:71-83`, `:116-134`). The worker runtime gets a KV task registry and executor independently (`plugins/workers/services/src/service-runtime.ts:79-88`; `plugins/workers/bin/runtime.ts:89-103`). P4 loaded a versioned task but `executor.supports()` returned false. `NETSCRIPT_TASKS_DIR` only resolves entrypoint paths (`packages/plugin-workers-core/src/executor/adapters/path-resolution.ts:14-23`; `plugins/workers/worker/job-execution.ts:200-219`). **Disposition:** keep one rich execution contract; delete `RuntimeTask` or replace it with a validated canonical definition plus explicit promotion adapter. | +| H3 — trigger JSON is override-only; runtime uses generated registries | **[PROVEN] Confirmed** | `TriggerOverride` has only `id`, optional `enabled`, optional `paths`, and an escape hatch (`packages/runtime-config/src/domain/types.ts:81-93`). Service composition loads definitions through `loadProjectTriggerDefinitions()` (`plugins/triggers/services/src/main.ts:161-183`), whose default is `.netscript/generated/plugin-triggers/triggers.registry.ts` and whose validator requires `id`, `kind`, and `handler` (`plugins/triggers/src/runtime/project-trigger-registry.ts:6-25`, `:69-95`). Background startup schedules/watches this fixed definition array (`plugins/triggers/src/runtime/trigger-processor.ts:30-70`). No runtime-config import exists. **Disposition:** keep generated-registry boot support only as a static-authoring input; extract enabled-state and processor ports; delete duplicate JSON override shape. | +| H4 — schema generator is real but baseline contributions collapse to empty | **[PROVEN] Confirmed** | The use case plans per-topic writes, honors configured output paths, writes JSON, and rejects duplicate owners (`packages/cli/src/public/features/generate/runtime-schemas/generate-runtime-schemas.ts:99-175`). CLI dependencies source schemas from registered plugin snapshots (`packages/cli/src/public/features/root/public-command-dependencies.ts:329-341`), but snapshot normalization emits `{ schemas: [] }` for every manifest with runtime topics (`packages/cli/src/kernel/adapters/config/plugin-registry.ts:447-471`), and a test explicitly expects the placeholder (`packages/cli/src/kernel/adapters/config/plugin-registry.test.ts:25-33`). P3 exited 0 with `0 written`. This records baseline behavior only; it does not re-evaluate PR #1444 / issue #1445. **Disposition:** keep duplicate-owner detection and deterministic planning; delete the placeholder registry projection and redesign schema ownership/loading. | +| H5 — generic versioned CLI competes with workers `.netscript/runtime` commands | **[PROVEN] Confirmed** | `netscript config override` wires list/get/set/clear/enable/disable plus publish/rollback to `RuntimeConfigStorePort` (`packages/cli/src/public/features/config/override/override-group.ts:13-38`). Workers `config-edit` creates `.netscript/runtime/.json`; `config-publish` merely parses and echoes it without versioning or activation (`plugins/workers/src/cli/local-runtime-backend.ts:335-351`). **Disposition:** keep one control-plane CLI after its contract is redesigned; delete workers `config-edit`/`config-publish`. | +| H6 — no concurrency/control-plane metadata or multi-instance propagation | **[PROVEN] Confirmed** | The store port has only pointer read/replace, topic read/write, and version list—no revision/CAS or audit inputs (`packages/cli/src/kernel/ports/runtime-config-store-port.ts:13-34`). Activation writes a UUID temp then renames locally (`packages/cli/src/kernel/adapters/config/runtime-config/deno-runtime-config-store.ts:35-45`). Publish performs document write then read/merge/write of `current` (`packages/cli/src/public/features/config/override/manage-runtime-overrides.ts:14-38`), so concurrent topics race; P1 observed 20/20 lost updates. Topic names are CLI allow-listed (`packages/cli/src/public/features/config/override/runtime-lifecycle-command.ts:46-52`) and version input is reduced with `basename` (`packages/cli/src/kernel/adapters/config/runtime-config/deno-runtime-config-store.ts:74-76`), but the loader accepts arbitrary string pointer paths and joins them without confinement (`packages/runtime-config/src/application/loader.ts:80-87`, `:102-110`). There is no broadcast or shared revision protocol. **Disposition:** extract atomic immutable publication as an idea; delete this store as a production control plane. | + +## Legacy → current mapping + +| Legacy executive-summary capability | Current equivalent | Status | Current gap / disposition | +|---|---|---|---| +| Static compiled TypeScript jobs and webhook/file/scheduled triggers ran | Generated worker job registry and generated trigger registry are loaded at startup (`plugins/workers/bin/runtime.ts:36-58`; `plugins/triggers/src/runtime/project-trigger-registry.ts:6-25`) | **[PROVEN]** | Static runtime remains real. **Keep** as a bootstrap/source input, not as mutable runtime state. | +| Checked-in `current` pointers did not control running subsystems | Loader/store are better isolated and tested, but still have no production subscriber | **[PROVEN]** | Same operational gap. **Extract idea/delete surface.** | +| Pointer/version edits could not hot-add/update/rollback live tasks/triggers | Watcher probe reloads a consumer, but no delivered worker/trigger registers one (`packages/runtime-config/src/application/watcher.ts:9-62`) | **[ABSENT]** | No operator hot path. **Redesign.** | +| KV task registry and polyglot executor existed without a versioned seeder | Current service creates `KvTaskRegistry`; execution resolves it before queue work (`plugins/workers/services/src/service-runtime.ts:79-88`; `plugins/workers/worker/job-dispatcher.ts:191-229`) | **[PARTIAL]** | Still no filesystem snapshot → canonical registry promotion. **Keep registry/executor, add explicit control-plane adapter.** | +| Pre-registered tasks executed seven runtimes with persistence | Default adapter map has Deno, Python, .NET, shell, PowerShell, cmd, executable (`packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:184-204`); P5 proved Deno+shell | **[PROVEN]** | Other five rely on unit/path evidence here. **Keep engine behind canonical task contract.** | +| Task scheduling was declarative only | `RuntimeTask.schedule` remains, while scheduler loads only `registry.listScheduled()` jobs at startup (`packages/runtime-config/src/domain/types.ts:125-130`; `plugins/workers/worker/scheduler.ts:78-110`, `:147-167`) | **[PARTIAL]** | No task scheduler or reschedule subscription. **Delete misleading field until implemented.** | +| Worker job CRUD/manual trigger real; timers startup-only | Workers API/CLI and generated registry are richer, but scheduler still loads at `start()` only | **[PARTIAL]** | Static timer refresh problem remains. **Keep API contracts only where backed; redesign scheduler reconciliation.** | +| Trigger actions enqueue jobs or defer | Runtime dispatch uses worker queue and KV defer scheduler (`plugins/triggers/src/runtime/trigger-runtime-processor.ts:67-96`) | **[PROVEN]** | Strong reusable processor seam. **Keep.** | +| Webhooks persisted; scheduled/file events bypassed ingress history | Trigger service owns KV event store; scheduled/file processor startup invokes processor directly (`plugins/triggers/services/src/main.ts:168-199`; `plugins/triggers/src/runtime/trigger-processor.ts:46-62`) | **[PARTIAL]** | History remains source-dependent. **Keep event contract, unify ingestion.** | +| Worker cockpit task/execution pages called real APIs | Current worker routes list/get/trigger tasks and list/get task executions (`plugins/workers/services/src/routers/tasks.ts:16-43`, `:45-83`, `:86-118`) | **[PROVEN]** | API is real but task population is disconnected from versioned files. **Keep API concept.** | +| Cockpit could not create tasks; trigger UI contract was dead | Trigger v1 now backs reads, webhook ingress, enable/disable, but explicitly leaves other mutations/streaming pending (`plugins/triggers/services/src/routers/v1.ts:1-15`, `:220-248`) | **[PARTIAL]** | Improved connector, still not a runtime-config control plane. **Keep backed routes; delete/withhold unbacked ones.** | +| Deno permission omission meant allow-all; non-Deno unsandboxed | Same behavior (`packages/plugin-workers-core/src/executor/adapters/permission-flags.ts:3-18`; `packages/plugin-workers-core/src/executor/adapters/dax-process-runner.ts:89-97`) | **[PROVEN]** | Unsafe default and no OS isolation. **Keep explicit permission vocabulary; delete allow-all default.** | +| Schemas were editor artifacts, not load validators | Loader still uses unchecked casts and catches parse errors (`packages/runtime-config/src/application/loader.ts:36-42`, `:102-118`) | **[PROVEN]** | Generated schemas do not enforce load. **Keep JSON Schema as authoring artifact; require runtime validation separately.** | +| Schema CLI registered but plugin schemas collapsed to empty | Exactly persists on this baseline (`packages/cli/src/kernel/adapters/config/plugin-registry.ts:466-468`) | **[PROVEN]** | P3 wrote zero. **Delete placeholder path.** | +| Static-demo quality, not production runtime configuration | Static runtimes/API/history improved, but control-plane split, races, silent failure, and absent auth/revision remain | **[PARTIAL]** | Still not production-ready as runtime-versioned automation. **Complete redesign justified.** | + +## Current capability matrix + +### 1. Versioned read model and filesystem store + +| Surface | Actual behavior | Status | Disposition | +|---|---|---|---| +| Pointer format | `current` may be a JSON object with optional `version/jobs/sagas/tasks/triggers/features` string fields, or legacy plain semver expanded to conventional topic paths (`packages/runtime-config/src/application/loader.ts:45-77`; `packages/runtime-config/src/domain/types.ts:149-165`). | **[PROVEN]** by loader tests and P2 | **Extract idea.** Use a required schema/revision, not optional unvalidated strings. | +| Version documents | Loader concurrently reads `{overrides}` for jobs/sagas/triggers, `{flags}` for features, `{tasks}` for tasks (`packages/runtime-config/src/application/loader.ts:102-118`). | **[PROVEN]** | **Keep conceptual topic documents**, replace unchecked shapes. | +| Missing/malformed behavior | All read/parse exceptions become `null`, then empty arrays; malformed pointer returns all-empty (`packages/runtime-config/src/application/loader.ts:36-42`, `:94-118`). | **[PROVEN]** by tests and P2 | **Delete silent success**; fail closed and surface diagnostics. | +| Watch behavior | Recursive FS watch accepts create/modify/remove, debounces 300 ms, reloads whole snapshot, and swallows reload/callback errors (`packages/runtime-config/src/application/watcher.ts:23-61`, `:65-76`). | **[PROVEN]** by P2 | **Extract idea.** Consumer lifecycle, diagnostics, and last-known-good semantics must be explicit. | +| Publication | Topic document is written directly and the same version can be overwritten; only the pointer uses temp + rename (`packages/cli/src/kernel/adapters/config/runtime-config/deno-runtime-config-store.ts:35-56`). Thus filenames are versioned but documents are not immutable by enforcement. | **[PROVEN]** by P1/code | **Extract immutable publish/atomic activate**, add create-only/digest checks, fsync/durability, and transactional manifest semantics. | +| Rollback | Verifies target JSON parses, shallow-merges one topic into the previously read pointer, then activates (`packages/cli/src/public/features/config/override/manage-runtime-overrides.ts:25-38`). | **[PROVEN]** | **Keep operator intent**, redesign as revision-conditional transaction. | + +No load-time JSON Schema validation, referential check, duplicate-ID check, entrypoint check, runtime availability check, or schedule validation exists. **[ABSENT]** The loader's `JSON.parse(...) as T` is the entire validation boundary (`packages/runtime-config/src/application/loader.ts:36-42`). + +### 2. Tasks, execution, scheduling, and permissions + +- **[PROVEN]** The canonical worker service task source is KV: `createWorkersServiceRuntime()` constructs `KvTaskRegistry`, and task API handlers read it (`plugins/workers/services/src/service-runtime.ts:79-88`; `plugins/workers/services/src/routers/tasks.ts:16-43`). **Disposition: keep** a durable registry port. +- **[PROVEN]** The local workers CLI instead discovers project files under `workers/tasks` (plus marked external files), imports Deno definitions, and directly calls the executor (`plugins/workers/src/cli/local-runtime-backend.ts:276-318`, `:207-223`). It neither reads versioned runtime-config nor seeds KV. **Disposition: consolidate/delete duplicate source paths.** +- **[PROVEN]** Worker queue dispatch resolves `taskId` from `context.taskRegistry`, creates an execution record, and then executes (`plugins/workers/worker/job-dispatcher.ts:191-229`; `plugins/workers/worker/job-execution.ts:177-197`). **Disposition: keep** the dispatch seam. +- **[PROVEN]** Execution records persist concept, task/job ID, status, trigger, timestamps, result/error, retry, correlation, and trace context under KV prefix `['workers','executions']` (`packages/plugin-workers-core/src/state/execution-state.ts:8-12`, `:27-78`, `:132-178`). **Disposition: keep** the domain data, add config revision/digest linkage. +- **[PROVEN]** Deno task permissions map to Deno flags, but undefined permissions yield `--allow-all` (`packages/plugin-workers-core/src/executor/adapters/permission-flags.ts:3-18`). Other adapters run host processes with inherited environment (`packages/plugin-workers-core/src/executor/adapters/dax-process-runner.ts:51-65`, `:89-97`). **Disposition: keep explicit least-privilege policy; delete permissive default and require external sandbox policy for native runtimes.** +- **[PARTIAL]** The plugin resource authoring CLI exposes only Deno/Python/shell/PowerShell even though the executor supports seven types (`plugins/workers/src/adapter/resources/input.ts:8-12`, `:104-117`; `packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:194-204`). **Disposition: unify capability negotiation.** +- **[ABSENT]** No task scheduler consumes `RuntimeTask.schedule`; the current scheduler enumerates job registry schedules only once at startup (`plugins/workers/worker/scheduler.ts:78-110`, `:147-167`). + +### 3. Triggers, dispatch, persistence, and replay + +- **[PROVEN]** Trigger source of truth at process boot is a generated TypeScript registry or fallback `triggers/mod.ts`; there is no runtime reload watcher (`plugins/triggers/src/runtime/project-trigger-registry.ts:6-39`, `:69-95`). **Disposition: keep static boot discovery only as one publisher input.** +- **[PROVEN]** Background runtime registers scheduled and file-watch definitions with adapters and routes callbacks to the processor (`plugins/triggers/src/runtime/trigger-processor.ts:30-70`). Webhook service composition filters the same loaded definitions for ingress (`plugins/triggers/services/src/main.ts:168-199`). +- **[PROVEN]** Core processor applies idempotency, retries, per-trigger concurrency/circuit state, dispatch, completion marking, and DLQ; the targeted suite proved dispatch-once, duplicate rejection, exhausted-retry DLQ, jitter, and reserved-kind rejection (`packages/plugin-triggers-core/src/runtime/trigger-processor.ts:61-103`, `:117-174`; probe log test result). +- **[PROVEN]** Plugin composition supplies KV idempotency, KV DLQ, KV defer scheduler, worker-job queue dispatch, and tracing; deferred definitions are held in process memory for replay lookup (`plugins/triggers/src/runtime/trigger-runtime-processor.ts:67-96`, `:131-180`). **Disposition: keep ports and durable records; persist definition revision with deferred events.** +- **[PROVEN]** Trigger enable/disable API writes a KV enabled-state store and returns the updated definition response (`plugins/triggers/services/src/routers/v1.ts:220-243`; `plugins/triggers/services/src/main.ts:168-182`). **Disposition: keep behavior**, but fold it into the canonical revisioned control plane. +- **[PARTIAL]** Webhook ingress has a KV event store, while scheduled/file-watch callbacks call the processor directly, so history is not uniform (`plugins/triggers/services/src/main.ts:168-199`; `plugins/triggers/src/runtime/trigger-processor.ts:46-62`). +- **[ABSENT]** Versioned `TriggerOverride.paths` and `.enabled` are never applied. Trigger definitions cannot be additively created by a JSON snapshot. + +### 4. Schema generation and scaffold truth + +- **[PROVEN]** `generate runtime-schemas` is a registered public command with `--dry-run`, `--force`, and `--project-root`; it reports only write/unchanged counts (`packages/cli/src/public/features/generate/runtime-schemas/generate-runtime-schemas-command.ts:29-65`). +- **[PROVEN]** Given actual contributions, the use case emits one raw schema object per topic either to configured `schemaPath` or `/runtime/schema.json`, and rejects multiple owners (`packages/cli/src/public/features/generate/runtime-schemas/generate-runtime-schemas.ts:137-175`). +- **[PROVEN]** On this baseline, registered official plugins expose an empty schema list despite declaring runtime topics (`packages/cli/src/kernel/adapters/config/plugin-registry.ts:447-471`). P3's real CLI output was `Schema generation complete: 0 written.` **Disposition: preserve planner tests, replace discovery/projection.** +- **[PROVEN]** Normal plugin install emits `workers/runtime.ts` and `triggers/runtime.ts`; tests assert these glue files and their package-runtime imports (`packages/cli/src/public/features/plugins/install/install-plugin_test.ts:163-178`, `:527-552`, `:815-834`). The glue starts package runtimes and contains no runtime-config loading (`plugins/workers/src/adapter/resources/glue/runtime.stub.ts:11-25`; `plugins/triggers/src/adapter/resources/glue/runtime.stub.ts:11-21`). +- **[PROVEN]** Official sample copying additionally writes per-workspace `current` plus `v1.0.0.json` task/saga/trigger documents (`plugins/workers/src/cli/official-sample-configuration.ts:72-139`, `:142-180`); tests assert worker tasks and trigger overrides (`packages/cli/src/maintainer/features/sync/plugin/copy-official-plugin-samples_test.ts:61-76`). With `includeSamples: false`, those runtime docs are absent (`packages/cli/src/maintainer/features/sync/plugin/copy-official-plugin-samples_test.ts:79-101`). +- **[PARTIAL]** Sample config names `workers/runtime/schema.json`, `sagas/runtime/schema.json`, and `triggers/runtime/schema.json` (`plugins/workers/src/cli/official-sample-configuration.ts:241-256`), but the sample writer creates only pointer/topic documents and baseline schema generation writes none. Thus a version document can contain a `$schema` reference to a nonexistent file (`plugins/workers/src/cli/official-sample-configuration.ts:149-178`). **Disposition: delete generated dead artifacts until the pipeline is coherent.** + +### 5. Aspire/deployment and multi-instance behavior + +- **[PROVEN]** Windows/Servy environment generation sets `NETSCRIPT_RUNTIME_CONFIG_DIR` for all services and `NETSCRIPT_TASKS_DIR` for workers (`packages/cli/src/kernel/adapters/windows/servy/servy-environment.ts:239-253`). This is environment plumbing only; its adjacent comment claiming trigger loader/watcher use is contradicted by the production call graph. +- **[PROVEN]** Worker generated runtime glue calls `startCombinedProcess()`, which creates KV-backed runtime services, imports the generated job registry, starts worker/scheduler, and constructs the task executor (`plugins/workers/src/adapter/resources/glue/runtime.stub.ts:21-25`; `plugins/workers/bin/runtime.ts:89-128`). It does not load a snapshot. +- **[PROVEN]** Trigger glue calls `startCombinedProcess()`, whose definition array is loaded once and used to install scheduled/file watchers (`plugins/triggers/src/adapter/resources/glue/runtime.stub.ts:16-21`; `plugins/triggers/src/runtime/trigger-processor.ts:30-70`). It does not watch a config tree or registry module. +- **[ABSENT]** Therefore a deployed process does not observe pointer changes. Multiple instances have no shared filesystem notification/revision protocol; even on a shared filesystem each would require an explicitly registered watcher, which none has. + +### 6. Telemetry, management APIs, UI, and history + +- **[PROVEN]** `MultiRuntimeTaskExecutor` creates an internal span and records adapter, executor, runtime, task, correlation, duration, status, and error attributes (`packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:76-113`, `:159-180`). Targeted tests prove tracer export. +- **[PROVEN]** Worker history is durable KV state and task endpoints expose list/get execution records (`packages/plugin-workers-core/src/state/execution-state.ts:132-178`; `plugins/workers/services/src/routers/tasks.ts:86-118`). **Gap:** records do not identify the runtime-config version because execution never consumes one. +- **[PROVEN]** Trigger runtime wraps processor dispatch in shared tracing and uses KV stores for idempotency, DLQ, defer, enabled state, and webhook event history (`plugins/triggers/src/runtime/trigger-runtime-processor.ts:23-65`, `:67-96`; `plugins/triggers/services/src/main.ts:168-199`). +- **[PARTIAL]** Trigger v1 handlers explicitly say introspection, event reads, webhook ingress, and enable/disable are real while remaining mutations/streaming are pending (`plugins/triggers/services/src/routers/v1.ts:1-15`). There is no management endpoint for version documents, pointer activation, approvals, or diff/preview. +- **[ABSENT]** A focused search found no app route or management UI importing `@netscript/runtime-config`, calling the generic runtime store, or mutating `current`. Current UI/API operational surfaces sit over KV registries/state, not the versioned filesystem. + +## Persistence and synchronization model + +| Concern | Current reality | Status | +|---|---|---| +| Filesystem source | CLI version documents and `current`; local workers config uses a second `.netscript/runtime/.json` tree | **[PROVEN]** | +| Worker source | Generated TS job registry at boot; KV task/job registries and KV execution/idempotency state at runtime | **[PROVEN]** | +| Trigger source | Generated TS definitions at boot; KV enabled/idempotency/DLQ/defer/event state | **[PROVEN]** | +| Filesystem → KV sync | No mapper, seeder, reconciliation loop, or event consumer | **[ABSENT]** | +| Atomicity | Local pointer replacement only; topic write and multi-topic state are not one transaction | **[PROVEN]** | +| Multi-instance | KV state can be shared through its adapter, but filesystem activation has no subscriber/broadcast/version acknowledgment | **[PARTIAL]** | +| Race/failure handling | Temp pointer cleaned on activation error; malformed reads silently empty; concurrent read/merge/write loses updates; no last-known-good or quorum | **[PROVEN]** | +| Path confinement | CLI topic allow-list and version `basename` reduce direct CLI traversal; loader pointer paths are not confined to runtime root | **[PARTIAL]** | + +## Test, docs, and E2E truth + +### Tests and gates that prove something + +- **[PROVEN]** Targeted existing suites run in this slice: runtime-config loader/accessors/summary, override lifecycle, schema planning/writing/duplicate-owner rejection, worker executor dispatch/telemetry, and trigger processor behavior. Result: 22 passed, 0 failed. +- **[PROVEN]** The repository's `scaffold.runtime` gate catalog includes live workers health/jobs/tasks/seed/execution checks and trigger health/webhook/event checks (`packages/cli/e2e/src/application/gates/scaffold/runtime-gates.ts:373-410`, `:452-483`; identifiers at `packages/cli/e2e/src/domain/cli-surface.ts:125-142`). The expensive suite was not run in this research slice, per brief. +- **[PROVEN]** Install tests prove runtime glue and sample-copy tests prove sample pointer/doc emission, as cited above. +- **[ABSENT]** No located E2E gate flips `current`, observes a running task/trigger change, rolls a topic back across running instances, validates a runtime document, or promotes multiple topics atomically. + +### Documented but unproven or contradicted claims + +- **[PARTIAL]** Runtime-config README says operators can disable jobs/flags/triggers without deploy (`packages/runtime-config/README.md:10-16`). The library mechanics are proven; delivered composition is absent. +- **[PARTIAL]** README's consumer example invokes watcher and accessors (`packages/runtime-config/README.md:60-85`), but it is example code, not scaffold/runtime wiring. +- **[PARTIAL]** Workers README claims an end-to-end operations surface and durable multi-runtime tasks (`plugins/workers/README.md:21-37`). Direct execution and KV APIs are real, but versioned additive task publication is not. +- **[PARTIAL]** Triggers README says all three kinds drain through one processor and crash replay follows stored webhook ingress (`plugins/triggers/README.md:23-37`). Processor reuse is real; scheduled/file-watch history is not unified, and no boot-time scan proving webhook crash replay was found. +- **[IMPLEMENTED-UNPROVEN]** Built-in Python, .NET, PowerShell, cmd, and executable adapters are registered (`packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:194-204`), but this slice directly executed only Deno and shell. Existing executor tests use injected adapters rather than all host runtimes. + +## Operational limitations and production-readiness gaps + +- **[PROVEN]** Split-brain sources: versioned filesystem, `.netscript/runtime`, project source/generated registries, and KV registries have no declared precedence or synchronization. +- **[PROVEN]** Lost updates: activation is whole-pointer read/merge/write without a revision precondition; P1 reproduced the race every trial. +- **[PROVEN]** Partial promotion: each topic publish writes and activates independently, so a five-topic release has observable mixed versions and can fail mid-sequence (`packages/cli/src/public/features/config/override/manage-runtime-overrides.ts:14-38`). +- **[PROVEN]** False immutability: publishing an existing version overwrites its topic document in place before pointer activation; historical rollback targets can therefore change (`packages/cli/src/kernel/adapters/config/runtime-config/deno-runtime-config-store.ts:48-56`). +- **[PROVEN]** Silent corruption: malformed pointer/topic JSON becomes empty configuration, and watcher exceptions disappear (`packages/runtime-config/src/application/loader.ts:36-42`; `packages/runtime-config/src/application/watcher.ts:49-60`). +- **[PROVEN]** No runtime validation: generated JSON Schema is neither discovered reliably nor enforced by the loader. +- **[PROVEN]** No audit/control metadata: pointer and store contracts lack author, reason, approval, timestamps, digest, signatures, revision, or expected-current fields (`packages/cli/src/kernel/ports/runtime-config-store-port.ts:13-34`). +- **[PROVEN]** No rollout acknowledgment: there is no per-instance observed revision, health gate, automatic rollback, or convergence status. +- **[PROVEN]** Unsafe task defaults: missing Deno permission policy grants all permissions; native runtimes inherit host environment and process authority. +- **[PROVEN]** Startup-only code registries: trigger definitions and scheduled jobs are loaded at process start; generated modules are not safely hot re-imported. +- **[PARTIAL]** Authentication/authorization for runtime mutations is not part of the generic local CLI store, and no service control-plane endpoint exists. Filesystem access is the effective authority. +- **[PROVEN]** Loader pointer paths are not root-confined, so a hand-edited `current` can direct reads outside the runtime tree even though CLI-produced paths are safe-shaped. + +## Disposition inventory + +### Keep + +- **[PROVEN]** Worker execution result/history vocabulary, KV registry ports, queue dispatch, idempotency, correlation, and OTel attributes. +- **[PROVEN]** Trigger processor ports and tested idempotency/retry/DLQ/defer/enabled-state behaviors. +- **[PROVEN]** Immutable document plus atomic active-reference concept, duplicate schema-owner detection, and dry-run planning. +- **[PROVEN]** Static generated registries as one boot/publisher source, provided they compile into a canonical validated revision. + +### Extract ideas, replace implementation + +- **[PARTIAL]** Runtime-config snapshot/watch semantics; require validation, last-known-good behavior, explicit subscription lifecycle, revision acknowledgment, and multi-instance distribution. +- **[PARTIAL]** JSON Schema authoring pipeline; make schema ownership discoverable and enforce the same contract at publish and load. +- **[PARTIAL]** Task runtime/permission vocabulary; unify `RuntimeTask`, executor `TaskDefinition`, builder/domain definitions, and CLI supported-runtime lists. +- **[PARTIAL]** Enable/disable and rollback operator journeys; move them into one authenticated, audited, revision-conditional control plane. + +### Delete / removal candidates + +- **[PROVEN]** Disconnected `RuntimeTask` and `TriggerOverride` snapshot types if no canonical adapter is introduced. +- **[PROVEN]** Workers `.netscript/runtime` `config-edit`/`config-publish` duplicate surface. +- **[PROVEN]** Baseline `{ schemas: [] }` plugin snapshot placeholder and sample `$schema` references whose targets are not emitted. +- **[PROVEN]** Windows environment-builder comments that claim loader/watcher wiring not present in code. +- **[PROVEN]** README language implying deploy-free operator behavior before a production consumer exists. + +## Probe log + +All probe-created files are confined to `.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/`; no service, container, or long-running process was started. + +1. **P1, P2, P4, P5 combined bounded script** + + Command: + + ```text + rtk proxy deno run --frozen -A .llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/runtime-probes.ts + ``` + + Exit code: `0`. + + Output: + + ```text + P1 {"rollbackPointer":{"version":"1.0.0","jobs":"jobs/v1.0.0.json"},"temporaryAfterLifecycle":0,"lostUpdates":20,"races":20} + P2_P4 {"loadedTaskId":"runtime-only","directExecutorSupport":false,"watcherChanges":[{"tasks":2},{"tasks":0}]} + P5 {"deno":{"success":true,"exitCode":0,"stdout":"deno-ok","error":null},"shell":{"success":true,"exitCode":0,"stdout":"shell-ok","error":null}} + ``` + + Interpretation: **[PROVEN]** P1 publish/rollback worked, pointer activation left zero temp files, and concurrent topic rollback lost an update 20/20 times. **[PROVEN]** P2 first flipped to a valid two-task document and observed `{tasks:2}`, then flipped to malformed JSON and observed silent `{tasks:0}`. **[PROVEN]** P4 loader saw `runtime-only`, but the unadapted object was unsupported because executor dispatch expects `type`, not `runtime`. **[PROVEN]** P5 executed real Deno and shell subprocesses successfully. Probe source: `.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/runtime-probes.ts`. + +2. **P3 real CLI, first minimal-fixture attempt** + + Command: + + ```text + rtk proxy deno run --frozen -A packages/cli/bin/netscript.ts generate runtime-schemas --project-root .llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture --verbose + ``` + + Exit code: `1`; the isolated consumer lacked `@netscript/config` in its import map. The fixture was corrected inside the evidence directory. + +3. **P3 second attempt** + + Same command. Exit code: `1`; the isolated consumer lacked the `zod` catalog entry. The fixture was corrected inside evidence. + +4. **P3 third attempt** + + Same command. Exit code: `76`; workers declared a missing streams dependency. Streams was added to the fixture. + +5. **P3 final baseline result** + + Same command. Exit code: `0`. + + ```text + Schema generation complete: 0 written. + ``` + + **[PROVEN]** The CLI command is wired and successful, but actual official-plugin discovery produces no schema writes on this baseline. No `schema.json` appeared. + +6. **Targeted existing suites** + + Command: + + ```text + rtk proxy deno test --frozen -A packages/runtime-config/tests packages/cli/src/public/features/config/override/manage-runtime-overrides_test.ts packages/cli/src/public/features/generate/runtime-schemas/generate-runtime-schemas_test.ts packages/plugin-workers-core/tests/executor/multi-runtime-task-executor_test.ts packages/plugin-triggers-core/src/runtime/trigger-processor_test.ts + ``` + + Exit code: `0`; `22 passed`, `0 failed`. **[PROVEN]** This validates loader/accessors, abstract lifecycle behavior, schema planner/writer, executor adapter dispatch/telemetry, and core trigger processor behavior. It does not prove production snapshot consumption. + +## Claims the supervisor should re-verify + +1. **[IMPLEMENTED-UNPROVEN]** The five built-in task adapters not directly smoked here—Python, .NET, PowerShell, cmd, executable—appear complete, but host tool availability and platform-specific behavior were not exercised. +2. **[PARTIAL]** “No management UI touches runtime config” is based on repository-wide focused symbol/path searches; a dynamically generated or external cockpit consumer could exist outside the inspected source tree. +3. **[PARTIAL]** “No webhook crash replay” is an inference from the absence of a boot-time stored-event replay scan in focused trigger composition; the supervisor should re-check all event-store adapters and startup hooks before quoting it categorically. +4. **[PARTIAL]** Local `Deno.rename` gives the intended atomic pointer replacement on the tested filesystem, but this probe did not establish crash durability, fsync semantics, Windows replacement semantics, or network-filesystem atomicity. +5. **[PARTIAL]** The 20/20 lost-update result is a deterministic observation on this host, not a statistical guarantee of every scheduler/filesystem interleaving; the underlying read/merge/write race is nevertheless explicit in code. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-0/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-1/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/current new file mode 100644 index 0000000000..857658f426 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "features": "features/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-10/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/current new file mode 100644 index 0000000000..857658f426 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "features": "features/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-11/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-12/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/current new file mode 100644 index 0000000000..857658f426 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "features": "features/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-13/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-14/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-15/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/current new file mode 100644 index 0000000000..857658f426 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "features": "features/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-16/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-17/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-18/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-19/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-2/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-3/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-4/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/current new file mode 100644 index 0000000000..857658f426 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "features": "features/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-5/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-6/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/current new file mode 100644 index 0000000000..2c527b4bea --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "jobs": "jobs/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-7/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/current new file mode 100644 index 0000000000..857658f426 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "features": "features/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-8/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/current new file mode 100644 index 0000000000..857658f426 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/current @@ -0,0 +1,4 @@ +{ + "version": "1", + "features": "features/v1.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/features/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/features/v1.json new file mode 100644 index 0000000000..b033cd8736 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/features/v1.json @@ -0,0 +1,3 @@ +{ + "flags": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/jobs/v1.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/jobs/v1.json new file mode 100644 index 0000000000..84c85a3882 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1-race-9/jobs/v1.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/current new file mode 100644 index 0000000000..55f3a71a74 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/current @@ -0,0 +1,4 @@ +{ + "version": "1.0.0", + "jobs": "jobs/v1.0.0.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/jobs/v1.0.0.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/jobs/v1.0.0.json new file mode 100644 index 0000000000..c3dba8a8fa --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/jobs/v1.0.0.json @@ -0,0 +1,7 @@ +{ + "overrides": [ + { + "id": "job-a" + } + ] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/jobs/v2.0.0.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/jobs/v2.0.0.json new file mode 100644 index 0000000000..205d53a209 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p1/jobs/v2.0.0.json @@ -0,0 +1,7 @@ +{ + "overrides": [ + { + "id": "job-b" + } + ] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/current b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/current new file mode 100644 index 0000000000..8a7c8c5586 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/current @@ -0,0 +1,4 @@ +{ + "version": "3.0.0", + "tasks": "tasks/v3.0.0.json" +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v1.0.0.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v1.0.0.json new file mode 100644 index 0000000000..3b29b48744 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v1.0.0.json @@ -0,0 +1,10 @@ +{ + "tasks": [ + { + "id": "runtime-only", + "name": "Runtime only", + "runtime": "deno", + "entrypoint": "./runtime-only.ts" + } + ] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v2.0.0.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v2.0.0.json new file mode 100644 index 0000000000..b59eb65856 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v2.0.0.json @@ -0,0 +1,16 @@ +{ + "tasks": [ + { + "id": "runtime-two", + "name": "Runtime two", + "runtime": "deno", + "entrypoint": "./two.ts" + }, + { + "id": "runtime-three", + "name": "Runtime three", + "runtime": "shell", + "entrypoint": "./three.sh" + } + ] +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v3.0.0.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v3.0.0.json new file mode 100644 index 0000000000..2bb12baace --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p2-runtime/tasks/v3.0.0.json @@ -0,0 +1 @@ +{ malformed diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p5-scripts/hello.sh b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p5-scripts/hello.sh new file mode 100644 index 0000000000..3922301312 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p5-scripts/hello.sh @@ -0,0 +1 @@ +printf "shell-ok\n" diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p5-scripts/hello.ts b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p5-scripts/hello.ts new file mode 100644 index 0000000000..e72061ad1a --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/fixture/p5-scripts/hello.ts @@ -0,0 +1 @@ +console.log("deno-ok"); diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/runtime-probes.ts b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/runtime-probes.ts new file mode 100644 index 0000000000..10e4c02efb --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/runtime-probes.ts @@ -0,0 +1,90 @@ +import { dirname, fromFileUrl, join } from "@std/path"; +import { DenoRuntimeConfigStore } from "../../../../../packages/cli/src/kernel/adapters/config/runtime-config/deno-runtime-config-store.ts"; +import { + publishRuntimeOverride, + rollbackRuntimeOverride, +} from "../../../../../packages/cli/src/public/features/config/override/manage-runtime-overrides.ts"; +import { + loadRuntimeConfig, + watchRuntimeConfig, +} from "../../../../../packages/runtime-config/mod.ts"; +import { MultiRuntimeTaskExecutor } from "../../../../../packages/plugin-workers-core/src/executor/mod.ts"; + +const probeRoot = new URL("./fixture/", import.meta.url); +const root = fromFileUrl(probeRoot); +await Deno.remove(root, { recursive: true }).catch(() => undefined); +await Deno.mkdir(root, { recursive: true }); + +async function writeJson(path: string, value: unknown): Promise { + await Deno.mkdir(dirname(path), { recursive: true }); + await Deno.writeTextFile(path, `${JSON.stringify(value, null, 2)}\n`); +} + +// P1: real filesystem store lifecycle and best-effort lost-update observation. +const storeRoot = join(root, "p1"); +const store = new DenoRuntimeConfigStore(() => storeRoot); +await publishRuntimeOverride(store, "jobs", "1.0.0", { overrides: [{ id: "job-a" }] }); +await publishRuntimeOverride(store, "jobs", "2.0.0", { overrides: [{ id: "job-b" }] }); +await rollbackRuntimeOverride(store, "jobs", "1.0.0"); +const rollbackPointer = await store.readPointer(); +const temporaryAfterLifecycle = [...Deno.readDirSync(storeRoot)].filter((entry) => entry.name.endsWith(".tmp")); + +let lostUpdates = 0; +for (let index = 0; index < 20; index++) { + const raceRoot = join(root, `p1-race-${index}`); + const raceStore = new DenoRuntimeConfigStore(() => raceRoot); + await raceStore.write("jobs", "1", { overrides: [] }); + await raceStore.write("features", "1", { flags: [] }); + await Promise.all([ + rollbackRuntimeOverride(raceStore, "jobs", "1"), + rollbackRuntimeOverride(raceStore, "features", "1"), + ]); + const pointer = await raceStore.readPointer(); + if (!(pointer.jobs && pointer.features)) lostUpdates++; +} +console.log("P1", JSON.stringify({ rollbackPointer, temporaryAfterLifecycle: temporaryAfterLifecycle.length, lostUpdates, races: 20 })); + +// P2/P4: loader sees additive tasks, watcher follows current, malformed docs collapse to empty. +const runtimeRoot = join(root, "p2-runtime"); +await Deno.mkdir(join(runtimeRoot, "tasks"), { recursive: true }); +await writeJson(join(runtimeRoot, "tasks", "v1.0.0.json"), { + tasks: [{ id: "runtime-only", name: "Runtime only", runtime: "deno", entrypoint: "./runtime-only.ts" }], +}); +await writeJson(join(runtimeRoot, "current"), { version: "1.0.0", tasks: "tasks/v1.0.0.json" }); +Deno.env.set("NETSCRIPT_RUNTIME_CONFIG_DIR", runtimeRoot); +const initial = await loadRuntimeConfig(); +const runtimeTask = initial.tasks[0]; +const executor = new MultiRuntimeTaskExecutor(); +const directSupport = executor.supports(runtimeTask as never); + +const changes: Array<{ tasks: number }> = []; +const abort = new AbortController(); +watchRuntimeConfig(async (config) => { + changes.push({ tasks: config.tasks.length }); +}, { signal: abort.signal }); +await new Promise((resolve) => setTimeout(resolve, 100)); +await writeJson(join(runtimeRoot, "tasks", "v2.0.0.json"), { + tasks: [ + { id: "runtime-two", name: "Runtime two", runtime: "deno", entrypoint: "./two.ts" }, + { id: "runtime-three", name: "Runtime three", runtime: "shell", entrypoint: "./three.sh" }, + ], +}); +await writeJson(join(runtimeRoot, "current"), { version: "2.0.0", tasks: "tasks/v2.0.0.json" }); +await new Promise((resolve) => setTimeout(resolve, 700)); +await Deno.writeTextFile(join(runtimeRoot, "tasks", "v3.0.0.json"), "{ malformed\n"); +await writeJson(join(runtimeRoot, "current"), { version: "3.0.0", tasks: "tasks/v3.0.0.json" }); +await new Promise((resolve) => setTimeout(resolve, 700)); +abort.abort(); +console.log("P2_P4", JSON.stringify({ loadedTaskId: runtimeTask?.id, directExecutorSupport: directSupport, watcherChanges: changes })); + +// P5: direct engine smoke for Deno and POSIX shell. +const scripts = join(root, "p5-scripts"); +await Deno.mkdir(scripts, { recursive: true }); +await Deno.writeTextFile(join(scripts, "hello.ts"), 'console.log("deno-ok");\n'); +await Deno.writeTextFile(join(scripts, "hello.sh"), 'printf "shell-ok\\n"\n'); +const denoResult = await executor.execute({ id: "deno-smoke", type: "deno", entrypoint: join(scripts, "hello.ts") }); +const shellResult = await executor.execute({ id: "shell-smoke", type: "shell", entrypoint: join(scripts, "hello.sh") }); +console.log("P5", JSON.stringify({ + deno: { success: denoResult.success, exitCode: denoResult.exitCode, stdout: denoResult.stdout.trim(), error: denoResult.error }, + shell: { success: shellResult.success, exitCode: shellResult.exitCode, stdout: shellResult.stdout.trim(), error: shellResult.error }, +})); diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/deno.json b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/deno.json new file mode 100644 index 0000000000..8af8a87d44 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/deno.json @@ -0,0 +1,14 @@ +{ + "name": "runtime-schema-probe", + "version": "0.0.0", + "exports": "./netscript.config.ts", + "catalog": { + "zod": "^4.4.3" + }, + "imports": { + "@netscript/config": "file:///home/codex/repos/ns-rfc-runtime-versioned-automation/packages/config/mod.ts", + "@netscript/plugin-workers": "file:///home/codex/repos/ns-rfc-runtime-versioned-automation/plugins/workers/mod.ts", + "@netscript/plugin-triggers": "file:///home/codex/repos/ns-rfc-runtime-versioned-automation/plugins/triggers/mod.ts", + "@netscript/plugin-streams": "file:///home/codex/repos/ns-rfc-runtime-versioned-automation/plugins/streams/mod.ts" + } +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/deno.lock b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/deno.lock new file mode 100644 index 0000000000..d2cc4f84bc --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/deno.lock @@ -0,0 +1,396 @@ +{ + "version": "5", + "specifiers": { + "jsr:@std/fs@1": "1.0.24", + "jsr:@std/internal@^1.0.14": "1.0.14", + "jsr:@std/jsonc@1": "1.0.2", + "jsr:@std/path@1": "1.1.6", + "jsr:@std/path@^1.1.5": "1.1.6", + "npm:zod@^4.4.3": "4.4.3" + }, + "jsr": { + "@std/fs@1.0.24": { + "integrity": "f3061b45b81673a2bece689da041df32d174be064c89eb6397fb5718d3fb7877", + "dependencies": [ + "jsr:@std/internal", + "jsr:@std/path@^1.1.5" + ] + }, + "@std/internal@1.0.14": { + "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7" + }, + "@std/jsonc@1.0.2": { + "integrity": "909605dae3af22bd75b1cbda8d64a32cf1fd2cf6efa3f9e224aba6d22c0f44c7" + }, + "@std/path@1.1.6": { + "integrity": "c68485c2a4dfbb5ae3cc74fae4e8c4e5d874cf8a8ed12927917235c758b46cbe", + "dependencies": [ + "jsr:@std/internal" + ] + } + }, + "npm": { + "zod@4.4.3": { + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==" + } + }, + "workspace": { + "links": { + "jsr:@netscript/ai@0.0.5": { + "dependencies": [ + "jsr:@standard-schema/spec@1.1.0", + "jsr:@std/assert@1", + "npm:@tanstack/ai-anthropic@~0.15.13", + "npm:@tanstack/ai-mcp@0.2.1", + "npm:@tanstack/ai-openai@~0.15.10", + "npm:@tanstack/ai@0.39" + ] + }, + "jsr:@netscript/aspire@0.0.5": { + "dependencies": [ + "jsr:@std/assert@1", + "jsr:@std/fs@1", + "jsr:@std/path@1" + ] + }, + "jsr:@netscript/auth-better-auth@0.0.5": { + "dependencies": [ + "jsr:@std/assert@1" + ] + }, + "jsr:@netscript/auth-kv-oauth@0.0.5": { + "dependencies": [ + "jsr:@panva/oauth4webapi@^3.8.6", + "jsr:@std/assert@1" + ] + }, + "jsr:@netscript/auth-workos@0.0.5": { + "dependencies": [ + "jsr:@std/assert@1" + ] + }, + "jsr:@netscript/bench@0.0.5": { + "dependencies": [ + "jsr:@cliffy/command@^1.0.0-rc.7", + "jsr:@std/assert@1", + "jsr:@std/fs@1", + "jsr:@std/path@1", + "jsr:@std/streams@1", + "npm:@orpc/server@^1.14.6" + ] + }, + "jsr:@netscript/cli-e2e@0.0.5": { + "dependencies": [ + "jsr:@cliffy/command@^1.0.0-rc.7", + "jsr:@std/assert@1", + "jsr:@std/fs@1", + "jsr:@std/path@1", + "npm:@orpc/server@^1.14.6" + ] + }, + "jsr:@netscript/cli@0.0.5": { + "dependencies": [ + "jsr:@cliffy/command@^1.0.0-rc.7", + "jsr:@cliffy/prompt@1", + "jsr:@david/dax@0.48", + "jsr:@netscript/aspire@0.0.5", + "jsr:@netscript/config@0.0.5", + "jsr:@netscript/fresh-ui@0.0.5", + "jsr:@netscript/mcp@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@netscript/sdk@0.0.5", + "jsr:@std/async@1", + "jsr:@std/cli@1", + "jsr:@std/collections@1", + "jsr:@std/fmt@1", + "jsr:@std/fs@1", + "jsr:@std/json@1", + "jsr:@std/jsonc@1", + "jsr:@std/net@1", + "jsr:@std/path@1", + "jsr:@std/semver@1", + "jsr:@std/text@1" + ] + }, + "jsr:@netscript/config@0.0.5": { + "dependencies": [ + "jsr:@std/fs@1", + "jsr:@std/jsonc@1", + "jsr:@std/path@1" + ] + }, + "jsr:@netscript/contracts@0.0.5": { + "dependencies": [ + "npm:@orpc/contract@^1.14.6" + ] + }, + "jsr:@netscript/cron@0.0.5": { + "dependencies": [ + "jsr:@std/assert@1", + "jsr:@std/async@1" + ] + }, + "jsr:@netscript/database@0.0.5": {}, + "jsr:@netscript/fresh-ui@0.0.5": { + "dependencies": [ + "jsr:@netscript/sdk@0.0.5", + "jsr:@std/assert@1", + "npm:preact@^10.29.2" + ] + }, + "jsr:@netscript/fresh@0.0.5": { + "dependencies": [ + "jsr:@fresh/core@^2.3.3", + "jsr:@netscript/ai@0.0.5", + "jsr:@netscript/plugin-streams-core@0.0.5", + "jsr:@netscript/sdk@0.0.5", + "jsr:@netscript/telemetry@0.0.5", + "jsr:@std/assert@1", + "jsr:@std/http@1", + "jsr:@std/path@1", + "jsr:@std/text@1", + "npm:@durable-streams/state@~0.3.1", + "npm:@durable-streams/tanstack-ai-transport@^0.0.8", + "npm:@orpc/server@^1.14.6", + "npm:@preact/signals@2.9.2", + "npm:@tanstack/ai-preact@~0.10.1", + "npm:@tanstack/ai@0.39", + "npm:@tanstack/preact-query@^5.101.0", + "npm:@tanstack/query-core@^5.101.0", + "npm:@tanstack/react-db@~0.1.95", + "npm:preact-render-to-string@^6.7.0", + "npm:preact@^10.29.2", + "npm:vite@7.2.2" + ] + }, + "jsr:@netscript/kv@0.0.5": { + "dependencies": [ + "jsr:@olli/kvdex@^3.6.7", + "jsr:@std/assert@1", + "jsr:@std/async@1", + "jsr:@std/collections@1", + "jsr:@std/data-structures@1", + "jsr:@std/ulid@1" + ] + }, + "jsr:@netscript/logger@0.0.5": { + "dependencies": [ + "jsr:@hono/hono@4.12.24", + "jsr:@logtape/logtape@2", + "jsr:@std/assert@1", + "npm:@orpc/server@^1.14.6" + ] + }, + "jsr:@netscript/mcp@0.0.5": { + "dependencies": [ + "jsr:@netscript/aspire@0.0.5", + "jsr:@netscript/telemetry@0.0.5", + "jsr:@standard-schema/spec@1.1.0", + "jsr:@std/assert@1", + "jsr:@std/path@1" + ] + }, + "jsr:@netscript/plugin-ai-core@0.0.5": { + "dependencies": [ + "jsr:@netscript/ai@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@std/assert@1", + "npm:@orpc/contract@^1.14.6", + "npm:@orpc/server@^1.14.6" + ] + }, + "jsr:@netscript/plugin-ai@0.0.5": { + "dependencies": [ + "jsr:@netscript/plugin-ai-core@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@std/assert@1" + ] + }, + "jsr:@netscript/plugin-auth-core@0.0.5": { + "dependencies": [ + "jsr:@std/assert@1", + "npm:@orpc/contract@^1.14.6", + "npm:@orpc/server@^1.14.6" + ] + }, + "jsr:@netscript/plugin-auth@0.0.5": { + "dependencies": [ + "jsr:@netscript/auth-better-auth@0.0.5", + "jsr:@netscript/auth-kv-oauth@0.0.5", + "jsr:@netscript/auth-workos@0.0.5", + "jsr:@netscript/contracts@0.0.5", + "jsr:@netscript/kv@0.0.5", + "jsr:@netscript/plugin-auth-core@0.0.5", + "jsr:@netscript/plugin-streams-core@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@netscript/service@0.0.5", + "jsr:@netscript/telemetry@0.0.5" + ] + }, + "jsr:@netscript/plugin-sagas-core@0.0.5": { + "dependencies": [ + "jsr:@hono/hono@4.12.24", + "jsr:@netscript/kv@0.0.5", + "jsr:@netscript/telemetry@0.0.5", + "jsr:@std/assert@1" + ] + }, + "jsr:@netscript/plugin-sagas@0.0.5": { + "dependencies": [ + "jsr:@hono/hono@4.12.24", + "jsr:@netscript/contracts@0.0.5", + "jsr:@netscript/kv@0.0.5", + "jsr:@netscript/plugin-sagas-core@0.0.5", + "jsr:@netscript/plugin-streams-core@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@netscript/queue@0.0.5", + "jsr:@netscript/service@0.0.5", + "jsr:@netscript/telemetry@0.0.5", + "jsr:@std/async@1" + ] + }, + "jsr:@netscript/plugin-streams-core@0.0.5": { + "dependencies": [ + "jsr:@netscript/telemetry@0.0.5", + "jsr:@std/assert@1" + ] + }, + "jsr:@netscript/plugin-streams@0.0.5": { + "dependencies": [ + "jsr:@hono/hono@4.12.24", + "jsr:@netscript/aspire@0.0.5", + "jsr:@netscript/contracts@0.0.5", + "jsr:@netscript/plugin-streams-core@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@netscript/service@0.0.5", + "jsr:@standard-schema/spec@1.1.0", + "jsr:@std/net@1" + ] + }, + "jsr:@netscript/plugin-triggers-core@0.0.5": { + "dependencies": [ + "jsr:@netscript/cron@0.0.5", + "jsr:@netscript/kv@0.0.5", + "jsr:@netscript/watchers@0.0.5", + "jsr:@std/assert@1" + ] + }, + "jsr:@netscript/plugin-triggers@0.0.5": { + "dependencies": [ + "jsr:@hono/hono@4.12.24", + "jsr:@netscript/contracts@0.0.5", + "jsr:@netscript/kv@0.0.5", + "jsr:@netscript/plugin-triggers-core@0.0.5", + "jsr:@netscript/plugin-workers-core@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@netscript/queue@0.0.5", + "jsr:@netscript/service@0.0.5", + "jsr:@netscript/telemetry@0.0.5", + "jsr:@std/assert@1", + "jsr:@std/path@1" + ] + }, + "jsr:@netscript/plugin-workers-core@0.0.5": { + "dependencies": [ + "jsr:@david/dax@0.48", + "jsr:@netscript/kv@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@netscript/telemetry@0.0.5", + "jsr:@standard-schema/spec@1.1.0", + "jsr:@std/assert@1", + "jsr:@std/path@1", + "npm:@orpc/contract@^1.14.6", + "npm:@orpc/server@^1.14.6" + ] + }, + "jsr:@netscript/plugin-workers@0.0.5": { + "dependencies": [ + "jsr:@hono/hono@4.12.24", + "jsr:@netscript/contracts@0.0.5", + "jsr:@netscript/cron@0.0.5", + "jsr:@netscript/kv@0.0.5", + "jsr:@netscript/plugin-streams-core@0.0.5", + "jsr:@netscript/plugin-workers-core@0.0.5", + "jsr:@netscript/plugin@0.0.5", + "jsr:@netscript/queue@0.0.5", + "jsr:@netscript/service@0.0.5", + "jsr:@netscript/telemetry@0.0.5", + "jsr:@standard-schema/spec@1.1.0", + "jsr:@std/async@1", + "jsr:@std/path@1" + ] + }, + "jsr:@netscript/plugin@0.0.5": { + "dependencies": [ + "jsr:@netscript/contracts@0.0.5", + "jsr:@netscript/service@0.0.5", + "jsr:@standard-schema/spec@1.1.0", + "jsr:@std/assert@1", + "jsr:@std/path@1", + "npm:@orpc/contract@^1.14.6", + "npm:@orpc/server@^1.14.6" + ] + }, + "jsr:@netscript/prisma-adapter-mysql@0.0.5": {}, + "jsr:@netscript/queue@0.0.5": { + "dependencies": [ + "jsr:@fedify/amqp@^2.2.5", + "jsr:@fedify/denokv@^2.2.5", + "jsr:@fedify/fedify@^2.2.5", + "jsr:@fedify/redis@^2.2.5", + "jsr:@std/assert@1", + "jsr:@std/async@1" + ] + }, + "jsr:@netscript/runtime-config@0.0.5": { + "dependencies": [ + "jsr:@std/path@1" + ] + }, + "jsr:@netscript/sdk@0.0.5": { + "dependencies": [ + "jsr:@netscript/service@0.0.5", + "jsr:@standard-schema/spec@1.1.0", + "jsr:@std/assert@1", + "npm:@orpc/client@^1.14.6", + "npm:@orpc/contract@^1.14.6", + "npm:@orpc/openapi@^1.14.6", + "npm:@orpc/server@^1.14.6", + "npm:@orpc/tanstack-query@^1.14.6", + "npm:@orpc/zod@^1.14.6", + "npm:@tanstack/db@~0.6.8", + "npm:@tanstack/query-core@^5.101.0", + "npm:@tanstack/query-db-collection@^1.2.1" + ] + }, + "jsr:@netscript/service@0.0.5": { + "dependencies": [ + "jsr:@hono/hono@4.12.24", + "jsr:@std/assert@1", + "npm:@orpc/client@^1.14.6", + "npm:@orpc/openapi@^1.14.6", + "npm:@orpc/server@^1.14.6", + "npm:@orpc/zod@^1.14.6" + ] + }, + "jsr:@netscript/telemetry@0.0.5": { + "dependencies": [ + "jsr:@hono/otel@^1.1.2", + "jsr:@standard-schema/spec@1.1.0", + "jsr:@std/assert@1", + "npm:@opentelemetry/semantic-conventions@1.41.1" + ] + }, + "jsr:@netscript/watchers@0.0.5": { + "dependencies": [ + "jsr:@std/assert@1", + "jsr:@std/async@1", + "jsr:@std/fs@1", + "jsr:@std/path@1" + ] + }, + "npm:@netscript/plugin-ai-core@0.0.1-alpha.0": {}, + "npm:@netscript/plugin-auth-core@0.0.1-alpha.0": {} + } + } +} diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/netscript.config.ts b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/netscript.config.ts new file mode 100644 index 0000000000..ef6341cd31 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/current-state-probes/schema-fixture/netscript.config.ts @@ -0,0 +1,5 @@ +export default { + name: "runtime-schema-probe", + databases: { config: [] }, + plugins: ["@netscript/plugin-streams", "@netscript/plugin-workers", "@netscript/plugin-triggers"], +}; diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/legacy-capability-map.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/legacy-capability-map.md new file mode 100644 index 0000000000..1592c3f8e8 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/legacy-capability-map.md @@ -0,0 +1,241 @@ +# Legacy capability map: runtime-versioned workers, tasks, and triggers + +## Executive summary + +- **[IMPLEMENTED]** Operators could run statically compiled TypeScript worker jobs and statically compiled webhook, file-watch, and scheduled triggers. The worker binaries import a generated job registry; Aspire contributes both trigger API and processor resources, which import the generated trigger registry at startup (`workers/bin/combined.ts:13-30`; `plugins/triggers/src/aspire/triggers-contribution.ts:42-68`; `plugins/triggers/src/runtime/project-trigger-registry.ts:4-15`). +- **[DEAD]** The checked-in `workers/runtime/current` and `triggers/runtime/current` version pointers did not control either running subsystem. Their loader and watcher existed, but no executable service imported them (`packages/runtime-config/mod.ts:206-247`, `packages/runtime-config/mod.ts:299-383`). +- **[DEAD]** Consequently, changing a `current` pointer, adding a `vX.Y.Z.json`, or editing an override could not hot-add, update, or roll back a running worker task or trigger at this revision. +- **[PARTIAL]** A real KV-backed task registry and polyglot task executor existed, and queued task messages were resolved from KV at execution time (`packages/plugin-workers-core/src/registry/kv-task-registry.ts:11-93`; `plugins/workers/worker/job-dispatcher.ts:129-196`). No delivered API, startup seeder, or CLI command registered the versioned task documents into that KV registry. +- **[IMPLEMENTED]** Once a task definition was already present in KV, it could execute Deno, Python, .NET, shell, PowerShell, cmd, or a native executable, with timeout, captured output, and execution-state persistence (`packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:110-130`; `packages/plugin-workers-core/src/domain/constants.ts:13-22`). +- **[DEAD]** Runtime task scheduling was declarative only. `schedule` appeared in task data, but the scheduler enumerated jobs—not tasks—and loaded its timers only at process start (`packages/runtime-config/mod.ts:68-85`; `plugins/workers/worker/scheduler.ts:69-103`, `plugins/workers/worker/scheduler.ts:139-198`). +- **[PARTIAL]** Worker job CRUD and manual triggering were real KV-backed APIs, but scheduled timers were not refreshed by those mutations, and compiled workers normally required a statically registered handler (`plugins/workers/services/src/routers/jobs.ts:42-120`; `packages/plugin-workers-core/src/runtime/job-dispatcher.ts:25-68`). +- **[IMPLEMENTED]** Trigger handlers emitted only two action types—enqueue a worker job or defer—and the runtime dispatched enqueue actions to the workers queue with correlation and deduplication metadata (`packages/plugin-triggers-core/src/domain/trigger-action.ts:3-35`; `plugins/triggers/src/runtime/trigger-runtime-processor.ts:86-123`). +- **[PARTIAL]** Webhook events were stored in Deno KV and queryable through a small Hono API, but post-202 processing was scheduled only as an in-process microtask. Scheduled and file-watch events bypassed that event-store ingress, so their history was not persisted (`plugins/triggers/src/runtime/kv-trigger-runtime-stores.ts:25-95`; `packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:97-110`, `packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:156-164`; `plugins/triggers/src/runtime/trigger-processor.ts:40-57`). +- **[IMPLEMENTED]** The workers cockpit task list, detail, run, and execution-detail pages called real worker task endpoints (`apps/playground/routes/(dashboard)/dashboard/plugin/workers/tasks/(_shared)/query-loaders.ts:38-78`; `apps/playground/islands/TriggerButton.tsx:28-50`). +- **[DEAD]** Those pages could not create a task, and the trigger cockpit targeted an oRPC contract that had no matching server handlers; its list/detail/event views were effectively dead against the delivered trigger service (`packages/plugin-triggers-core/src/contracts/v1/triggers.contract.ts:197-261`; `plugins/triggers/services/src/router.ts:15-23`). +- **[PARTIAL]** Deno task permissions were translated to Deno flags, but omission meant `--allow-all`; all non-Deno adapters inherited the host environment and had no per-task OS sandbox (`packages/plugin-workers-core/src/executor/adapters/permission-flags.ts:3-19`; `packages/plugin-workers-core/src/executor/adapters/dax-process-runner.ts:27-91`). +- **[DEAD]** The runtime schemas were editor-oriented artifacts, not load-time validators. The checked-in worker schema even rejected `.NET`, which the checked-in task document and actual task model accepted (`workers/runtime/schema.json:106-115`; `workers/runtime/tasks/v1.0.0.json:107-115`; `packages/runtime-config/mod.ts:68-85`). +- **[PARTIAL]** `netscript generate runtime-schemas` was registered and could write plugin-contributed schemas, but the plugin registry snapshot discarded contributions into empty `schemas` arrays, and the workers/triggers manifests supplied paths rather than schema bodies (`packages/cli/src/public/features/generate/generate-group.ts:7-26`; `packages/cli/src/kernel/adapters/config/plugin-registry.ts:217-239`). A repository test explicitly expects the workers snapshot to preserve this empty-schema placeholder (`packages/cli/src/kernel/adapters/config/plugin-registry.test.ts:7-35`). +- **[PARTIAL]** The system was suitable for static demos and local development, not production runtime configuration: direct non-atomic writes, missing runtime validation, split filesystem/KV sources of truth, startup-only registry loading, incomplete APIs, permissive subprocesses, and no visible service authentication were all present in executable paths. + +## Evidence scope and interpretation + +- **[IMPLEMENTED]** This report describes repository `/home/codex/repos/netscript-start-ref` at commit `6ba9ba03b9107c895305d972b1abf0a5d93b78b9` on `master`. “Operator” means a user of the delivered CLI, service APIs, or cockpit—not a developer directly calling an internal class. +- **[IMPLEMENTED]** Confidence labels mean: `IMPLEMENTED` = connected executable path; `PARTIAL` = executable pieces with a missing or materially incomplete path; `ASPIRATIONAL` = schema, UI, contract, or documentation without the matching runtime path; `DEAD` = present but unreachable or unused at this revision. +- **[IMPLEMENTED]** Doctrine terminology is used only to describe boundaries and failure modes. The legacy repository is not graded against the later doctrine. +- **[IMPLEMENTED]** This is outcome and journey evidence, not an architectural recommendation. Nothing below implies that the legacy file shapes, APIs, packages, or migration paths should be retained. + +## Three representative operator journeys + +### Journey A — change or roll back live configuration + +- **[IMPLEMENTED]** The public CLI can dispatch framework-owned plugin verbs such as `enable` and `disable` to a published plugin’s `/cli` entrypoint (`packages/cli/src/public/features/plugins/dispatch/dispatch-plugin-verb.ts:6-17`, `packages/cli/src/public/features/plugins/dispatch/dispatch-plugin-verb.ts:35-62`). The workers and triggers packages both publish `./cli` composition entrypoints (`plugins/workers/deno.json:6-13`; `plugins/triggers/deno.json:6-14`). +- **[DEAD]** For workers, enable/disable writes `.netscript/runtime/workers.json`; for triggers it writes `.netscript/runtime/triggers.json` (`plugins/workers/src/cli/workers-cli-backend.ts:152-159`; `plugins/triggers/src/cli/triggers-cli-backend.ts:164-176`). Neither running subsystem reads those files. The similarly intended `current` pointer and version documents have an unconsumed loader/watcher (`packages/runtime-config/mod.ts:206-247`, `packages/runtime-config/mod.ts:299-383`). +- **[DEAD]** Genuine operator outcome: the command can report success and persist a local file, but it does not change a running worker or trigger. Editing `current` to an older version likewise does not roll back runtime behavior. A rebuild/restart alone still cannot apply these overrides unless the missing consumer wiring is supplied. + +### Journey B — add and run a Python/shell/.NET task + +- **[PARTIAL]** The main CLI’s `plugin add` verb can reach the workers `/cli` entrypoint, whose argument normalizer recognizes `add task`; the local backend generates only a runtime-specific script file (`packages/cli/src/public/features/plugins/dispatch/dispatch-plugin-verb.ts:41-62`; `plugins/workers/src/cli/composition/main.ts:38-61`; `plugins/workers/src/cli/workers-cli-backend.ts:79-85`). +- **[DEAD]** The generated file is not inserted into `KvTaskRegistry`, added to a version document, or registered through an API. Default worker startup registers jobs only (`plugins/workers/bin/runtime.ts:29-44`, `plugins/workers/bin/runtime.ts:91-110`), and the task API has no create/update route (`plugins/workers/services/src/routers/tasks.ts:9-100`). The task therefore does not appear in the cockpit and cannot be run through the delivered operator path. +- **[PARTIAL]** If an application developer or external integration directly seeds the KV task registry, the already-running worker resolves it on the next task message and can execute all seven supported runtimes (`packages/plugin-workers-core/src/registry/kv-task-registry.ts:33-45`; `plugins/workers/worker/job-dispatcher.ts:129-196`; `packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:110-130`). That proves the executor outcome, not an operator control plane. + +### Journey C — add a trigger, fire it, and inspect history + +- **[PARTIAL]** The main CLI’s `plugin add` verb can reach the triggers `/cli` entrypoint. The local backend writes a trigger source file and recompiles the static project registry (`packages/cli/src/public/features/plugins/dispatch/dispatch-plugin-verb.ts:41-62`; `plugins/triggers/src/cli/composition/main.ts:35-55`; `plugins/triggers/src/cli/triggers-cli-backend.ts:83-103`). A running process has already imported its registry and installed definitions, so rebuild/restart is required (`plugins/triggers/src/runtime/project-trigger-registry.ts:4-15`; `plugins/triggers/src/runtime/trigger-processor.ts:27-65`). +- **[DEAD]** The plugin CLI labels `fire` as firing through the runtime processor (`plugins/triggers/src/cli/commands.ts:152-164`), but the local backend only invokes the handler and returns its actions; it never dispatches them (`plugins/triggers/src/cli/triggers-cli-backend.ts:125-144`). Thus a successful CLI response does not enqueue the worker action. +- **[PARTIAL]** After restart, real webhook ingress can persist and process an event, and its event record is queryable (`plugins/triggers/services/src/main.ts:29-59`; `plugins/triggers/src/runtime/kv-trigger-runtime-stores.ts:25-95`; `plugins/triggers/services/src/routers/events.ts:14-58`). Scheduled and file-watch events bypass persistence, and the cockpit calls a contract surface the Hono server does not implement (`plugins/triggers/src/runtime/trigger-processor.ts:40-57`; `apps/playground/lib/api-clients.ts:35-52`; `plugins/triggers/services/src/router.ts:15-23`). Genuine observability is therefore webhook-only through the small service API, not the advertised unified cockpit journey. + +## 1. Version pointer + immutable version documents + +### Format + +- **[ASPIRATIONAL]** The workers pointer is one JSON object containing `version`, plus relative paths for `jobs`, `tasks`, and `features` (`workers/runtime/current:1`). The triggers pointer contains `version` and a relative `triggers` path (`triggers/runtime/current:1`). +- **[ASPIRATIONAL]** Versioned worker task documents use `{ "version": "1.0.0", "tasks": [...] }`; trigger override documents use `{ "version": "1.0.0", "overrides": [...] }` (`workers/runtime/tasks/v1.0.0.json:1-4`; `triggers/runtime/triggers/v1.0.0.json:1-40`). Worker job documents likewise use an `overrides` array whose records carry `id`, `enabled`, `schedule`, `timeout`, and `maxRetries` (`workers/runtime/jobs/v1.0.0.json:1-43`). +- **[PARTIAL]** The general loader also accepts a plain semver string in `current`; otherwise it parses JSON, accepts explicit topic paths, and derives `/v.json` when a topic path is absent (`packages/runtime-config/mod.ts:153-200`). The checked-in pointers use JSON. + +### Readers and writers + +- **[DEAD]** `loadRuntimeConfig()` reads `current`, then loads jobs/tasks/features or triggers topic documents and substitutes empty collections for missing documents (`packages/runtime-config/mod.ts:206-247`). `watchRuntimeConfig()` uses that loader from a recursive `Deno.watchFs` loop with 300 ms debounce (`packages/runtime-config/mod.ts:299-383`). Repository-wide import search found no executable consumer of `@netscript/runtime-config` or these symbols; therefore neither the loader nor watcher affected the running stack. +- **[ASPIRATIONAL]** The package header says workers and triggers consume this module (`packages/runtime-config/mod.ts:1-17`), and Windows service-environment code says `triggers-api` uses both loader and watcher while setting `NETSCRIPT_RUNTIME_CONFIG_DIR` for all services (`packages/cli/src/kernel/adapters/windows/servy/servy-environment.ts:234-247`). Those are comments/configuration intent, contradicted by the absent executable imports and the actual startup composition described below. +- **[DEAD]** A second CLI-side override loader parses the same pointer/topic layout (`packages/cli/src/kernel/adapters/config/runtime-override.ts:49-156`). Repository-wide reference search found only its declaration, not a caller. +- **[PARTIAL]** Windows deployment did write version documents and the pointer. It wrote schemas directly, skipped an existing version document unless forced, created an empty tasks document, and always replaced `current` (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:37-73`, `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:99-105`, `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:127-158`). The Windows build invokes that writer (`packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:82-90`). +- **[PARTIAL]** Development overrides could be copied into deployment version files, after which the pointer was read, modified, and rewritten (`packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:153-209`). This is a build/deploy operation, not a running-stack mutation endpoint. +- **[IMPLEMENTED]** Deploy output consolidated all built-in topics beneath one `/runtime/` directory and one JSON `current` pointer containing `jobs`, `sagas`, `tasks`, `triggers`, `features`, and `updatedAt` (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:45-49`, `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:75-125`, `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:143-158`). This is the concrete packaged layout, distinct from the repository’s separate workers/triggers development roots. +- **[DEAD]** The deploy writer also adds arbitrary plugin topic keys to `current` and claims binaries can discover them without core changes (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:22-27`, `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:132-154`). The runtime loader reads only five fixed built-in keys and returns a fixed `RuntimeConfig` shape (`packages/runtime-config/mod.ts:88-108`, `packages/runtime-config/mod.ts:220-247`). Custom plugin topic documents were therefore packaged but not discoverable through this loader. + +### Immutability, atomicity, and validation + +- **[PARTIAL]** “Immutable” was enforced only by the deployment writer’s “do not overwrite an existing version file unless `force`” branch (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:51-63`, `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:127-140`). Files remained ordinary writable files; no content-addressing, filesystem protection, or compare-and-swap existed. +- **[DEAD]** Pointer and document writes used direct `Deno.writeTextFile`/`Deno.copyFile`, not a temporary file plus atomic rename (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:65-73`, `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:143-158`; `packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:153-209`). A crash or concurrent writer could expose partial or lost updates. +- **[DEAD]** Dev-topic copy failures are downgraded to warnings, yet the later pointer merge is not conditioned on each topic’s copy/skip result and does not verify the referenced file exists (`packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:123-175`, `packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:178-210`). A build can therefore complete with `current` advertising a dev version that was skipped or failed to copy. +- **[DEAD]** The general loader calls `JSON.parse`, casts the result, and catches every failure as `null`; it does not apply `schema.json` or structural validation (`packages/runtime-config/mod.ts:144-151`, `packages/runtime-config/mod.ts:206-247`). The CLI-side loader also uses raw `JSON.parse`; it suppresses only not-found errors, so malformed JSON fails loudly but remains schema-unvalidated (`packages/cli/src/kernel/adapters/config/runtime-override.ts:34-47`). +- **[DEAD]** Rollback was only the latent ability to point `current` at an older version. No CLI/API rollback transaction was found, and—because running services did not read the pointer—changing it had no runtime effect at this revision. + +## 2. Schema generation and validation + +### How schemas were produced + +- **[IMPLEMENTED]** `netscript generate runtime-schemas` was mounted in the generate command group and exposed output/root/clean flags (`packages/cli/src/public/features/generate/generate-group.ts:7-26`; `packages/cli/src/public/features/generate/runtime-schemas/generate-runtime-schemas-command.ts:30-66`). +- **[PARTIAL]** Its planner iterated plugin runtime-schema contributions, selected an explicit `schemaPath` or `/runtime/schema.json`, and wrote changed JSON directly (`packages/cli/src/public/features/generate/runtime-schemas/generate-runtime-schemas.ts:105-173`). This was a real generator for non-empty contributions. +- **[DEAD]** For the legacy workers/triggers plugins, the registration snapshot converted every declared runtime topic to `{ schemas: [] }` (`packages/cli/src/kernel/adapters/config/plugin-registry.ts:217-239`). The command passes those arrays unchanged into its request (`packages/cli/src/public/features/root/public-command-dependencies.ts:256-268`), and the planner emits one file only for each actual schema entry (`packages/cli/src/public/features/generate/runtime-schemas/generate-runtime-schemas.ts:135-173`). The plugin manifests declared topic names and schema paths but no schema bodies (`plugins/workers/src/public/mod.ts:146-197`; `plugins/triggers/src/public/mod.ts:80-101`). A repository test deliberately asserts that workers has zero schemas (`packages/cli/src/kernel/adapters/config/plugin-registry.test.ts:7-35`), so the zero-output conclusion is directly supported for this registration path. +- **[PARTIAL]** Windows deployment used a separate built-in schema generator and writer. That generator describes the files as JSON editor autocomplete/validation schemas and emits task/job/trigger variants (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-schema.ts:10-27`, `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-schema.ts:227-267`). + +### Enforcement and drift + +- **[DEAD]** Neither runtime loader validates documents against `schema.json`; both parse and cast (`packages/runtime-config/mod.ts:144-151`; `packages/cli/src/kernel/adapters/config/runtime-override.ts:34-47`). The schemas were tooling artifacts, not an admission gate. +- **[DEAD]** The checked-in worker schema’s runtime enum contains only `deno`, `shell`, `python`, and `powershell` (`workers/runtime/schema.json:106-115`). The actual runtime task model accepts `deno`, `python`, `dotnet`, `cmd`, `powershell`, `shell`, and `executable` (`packages/runtime-config/mod.ts:68-85`), and the checked-in task document contains a `dotnet` task (`workers/runtime/tasks/v1.0.0.json:107-115`). A schema-validity check would therefore reject repository-owned data. +- **[PARTIAL]** The separate deployment generator does include all seven runtime types (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-schema.ts:97-123`), demonstrating two diverged schema authorities. +- **[DEAD]** The triggers schema validates only an `overrides` array whose records contain `id`, `enabled`, and `paths` (`triggers/runtime/schema.json:7-55`); it does not describe executable trigger definitions, handlers, webhook secrets, schedules, retry policy, or action shapes. + +## 3. Hot add, update, and rollback + +### Versioned filesystem configuration + +- **[DEAD]** An operator could not hot-add, update, or roll back tasks/triggers by editing the versioned runtime tree. The only filesystem reload mechanism is `watchRuntimeConfig()` (`packages/runtime-config/mod.ts:299-383`), and no worker or trigger executable imports it. The active worker starts from generated jobs plus KV runtime components (`plugins/workers/bin/runtime.ts:29-88`); the active trigger services import generated definitions once (`plugins/triggers/src/runtime/project-trigger-registry.ts:4-15`). +- **[DEAD]** No HTTP endpoint mutates `current` or version documents. Worker task routes expose list/get/trigger and execution reads only (`plugins/workers/services/src/routers/tasks.ts:9-100`). Trigger service routes expose health, event reads, and webhook ingress only (`plugins/triggers/services/src/router.ts:15-23`). + +### Worker jobs and tasks + +- **[PARTIAL]** Worker job create/update/delete operations write the KV job registry, and a worker resolves the job definition on each dequeued execution (`plugins/workers/services/src/routers/jobs.ts:42-83`; `plugins/workers/worker/job-dispatcher.ts:31-49`). Enabled/config changes can therefore affect later manual or event-driven dispatches without a process restart. +- **[PARTIAL]** That does not provide general hot code loading. The default dispatcher disables dynamic-import fallback and requires a handler in the static generated registry (`packages/plugin-workers-core/src/runtime/job-dispatcher.ts:25-68`); the combined runtime supplies that static registry (`plugins/workers/bin/runtime.ts:75-85`). A newly created KV job without compiled handler code can be registered but not normally executed. +- **[DEAD]** Scheduled job timers are loaded from KV only when the scheduler starts (`plugins/workers/worker/scheduler.ts:69-103`, `plugins/workers/worker/scheduler.ts:139-198`). Although methods for rescheduling and full reload exist (`plugins/workers/worker/scheduler.ts:227-244`, `plugins/workers/worker/scheduler.ts:449-467`), repository-wide call search found no external caller. API schedule changes therefore require scheduler restart to affect timers. +- **[PARTIAL]** Rebuild/restart is not a reliable static-definition update mechanism either. Startup registers a generated job definition only if its ID is absent from KV; an existing record is unconditionally retained (`plugins/workers/bin/runtime.ts:91-110`). Once seeded, generated-source changes to schedule, timeout, permissions, or entrypoint do not replace the KV definition through this startup path. +- **[PARTIAL]** Task execution resolves a KV task definition for every queued message (`plugins/workers/worker/job-dispatcher.ts:129-196`), so an internal caller that writes `KvTaskRegistry` could change the next execution live. However, no delivered task create/update/delete route, startup registration call, or version-file seeder was found (`plugins/workers/services/src/routers/tasks.ts:9-100`; `packages/plugin-workers-core/src/registry/kv-task-registry.ts:11-93`). This was not an operator workflow. + +### Triggers + +- **[DEAD]** Background trigger definitions are loaded once, installed into cron/file adapters, and then the processor waits for abort (`plugins/triggers/src/runtime/trigger-processor.ts:27-65`). Webhook definitions are likewise loaded once before router construction (`plugins/triggers/services/src/main.ts:29-69`). There is no definition watcher, polling loop, or mutation endpoint. +- **[PARTIAL]** The triggers CLI can add source files and regenerate the static registry (`plugins/triggers/src/cli/triggers-cli-backend.ts:83-103`), but a running process must be rebuilt/restarted or otherwise relaunched to import them. +- **[DEAD]** CLI enable/disable writes `.netscript/runtime/triggers.json` (`plugins/triggers/src/cli/triggers-cli-backend.ts:164-176`), while the running trigger processor never reads that file. The equivalent worker CLI writes `.netscript/runtime/workers.json` (`plugins/workers/src/cli/workers-cli-backend.ts:152-159`) with the same disconnect. + +## 4. Worker tasks and scheduled/background jobs + +### Task definitions and execution + +- **[ASPIRATIONAL]** Versioned task records contain ID, name, runtime, entrypoint, optional args/environment, timeout, retries, and sometimes schedule (`workers/runtime/tasks/v1.0.0.json:1-115`). The loader’s `RuntimeTask` type broadly mirrors that shape (`packages/runtime-config/mod.ts:68-85`). +- **[PARTIAL]** The executable task domain accepts runtime, entrypoint, args, environment, working directory, timeout, retry metadata, and Deno permission fields (`packages/plugin-workers-core/src/domain/task.ts:8-105`). `KvTaskRegistry` persists normalized definitions through a KV-compatible store and supports register/get/list/update/unregister (`packages/plugin-workers-core/src/registry/kv-task-registry.ts:11-111`). Retry metadata is declarative here; the dispatcher limitation is called out below. +- **[PARTIAL]** The task queue listener is active in worker startup (`plugins/workers/worker/queue-consumer.ts:49-73`). On a task message, the dispatcher loads the KV definition, creates execution state, invokes the task executor, and marks completion/failure (`plugins/workers/worker/job-dispatcher.ts:129-196`). The missing operator registration path prevents end-to-end use of versioned task records. +- **[DEAD]** Task definitions persist `maxRetries`, but the task dispatch path invokes the executor exactly once and records its result; it never reads `taskDef.maxRetries` (`packages/plugin-workers-core/src/domain/task.ts:90-105`; `plugins/workers/worker/job-dispatcher.ts:129-196`). Task retry configuration was therefore not enforced by this execution loop. + +### Supported runtimes + +- **[IMPLEMENTED]** The executable runtime set is Deno, Python, .NET, shell, PowerShell, cmd, and native executable (`packages/plugin-workers-core/src/domain/constants.ts:13-22`). The default executor maps each type to an adapter (`packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:110-130`). +- **[IMPLEMENTED]** Command construction calls `deno run`, `python`, `dotnet run`/`dotnet `, a platform shell, PowerShell with `-ExecutionPolicy Bypass`, `cmd /d /s /c`, or the executable directly (`packages/plugin-workers-core/src/executor/adapters/argv-builder.ts:7-125`). + +### Job scheduling and execution loop + +- **[IMPLEMENTED]** The scheduler enumerates enabled KV job definitions with schedules at startup and creates cron timers (`plugins/workers/worker/scheduler.ts:139-198`). On a tick it constructs and enqueues a job execution request (`plugins/workers/worker/scheduler.ts:267-326`). +- **[IMPLEMENTED]** Worker queue consumption separates job and task messages, respects configured concurrency, and dispatches through the shared dispatcher (`plugins/workers/worker/queue-consumer.ts:49-73`). Static job definitions are registered into KV during startup if absent (`plugins/workers/bin/runtime.ts:91-110`). +- **[DEAD]** No corresponding task scheduler enumerates `TaskDefinition.schedule`. The scheduler is constructed around a job registry, and its scheduled-load loop calls `listScheduled()` on jobs (`plugins/workers/worker/scheduler.ts:69-103`, `plugins/workers/worker/scheduler.ts:139-198`). Scheduled examples in `workers/runtime/tasks/v1.0.0.json:77-105` were therefore not executable scheduling configuration. + +## 5. Triggers and event handling + +### Definition shape and event sources + +- **[IMPLEMENTED]** The triggers Aspire contribution starts a `triggers-api` Deno service and a separate `trigger-processor` Deno background resource (`plugins/triggers/src/aspire/triggers-contribution.ts:42-68`). This closes the static launch path for webhook ingress plus scheduled/file processing; it does not add hot reload. +- **[IMPLEMENTED]** Executable trigger definitions support `webhook`, `file-watch`, and `scheduled`. Queue, stream, and manual kinds are explicitly reserved rather than implemented (`packages/plugin-triggers-core/src/domain/trigger-definition.ts:89-143`). +- **[IMPLEMENTED]** Repository definitions include CSV/product file watchers, scheduled worker-job triggers, and webhook triggers (`triggers/csv-import.ts:9-37`; `triggers/scheduled-worker-jobs.ts:10-80`; `triggers/generic-webhook.ts:9-26`). File paths are read from environment during module import (`triggers/csv-import.ts:14-23`). +- **[PARTIAL]** The generic webhook uses an in-memory verifier intended for development (`triggers/generic-webhook.ts:9-26`), so replay/nonce protection is process-local and unsuitable for a multi-instance production ingress. + +### Dispatch and worker coupling + +- **[IMPLEMENTED]** Trigger handlers can return only `enqueue-job` or `defer` actions (`packages/plugin-triggers-core/src/domain/trigger-action.ts:3-35`). The runtime processor translates enqueue actions to the worker queue and attaches source event, trigger, correlation, and deduplication data (`plugins/triggers/src/runtime/trigger-runtime-processor.ts:31-46`, `plugins/triggers/src/runtime/trigger-runtime-processor.ts:86-123`). +- **[IMPLEMENTED]** Core processing applies idempotency, bounded concurrency, retry delay, dead-lettering, and circuit-breaker behavior (`packages/plugin-triggers-core/src/runtime/trigger-processor.ts:59-99`, `packages/plugin-triggers-core/src/runtime/trigger-processor.ts:112-226`). +- **[PARTIAL]** The CLI `test` and `fire` operations dynamically import a trigger and invoke its handler, but merely return the resulting actions; they do not run those actions through `TriggerRuntimeProcessor` (`plugins/triggers/src/cli/triggers-cli-backend.ts:125-144`). “Fire” therefore did not actually enqueue its worker job in this backend. + +## 6. Execution history, status, and observability + +### Worker persistence + +- **[IMPLEMENTED]** Worker executions are records in a KV-compatible store under `['workers', 'executions']`. The store creates queued records, transitions status, and supports get/list/count/delete (`packages/plugin-workers-core/src/state/execution-state.ts:10-44`, `packages/plugin-workers-core/src/state/execution-state.ts:58-212`). +- **[PARTIAL]** Status transitions use read-modify-write rather than KV atomic compare-and-set (`packages/plugin-workers-core/src/state/execution-state.ts:183-197`). Concurrent updates can overwrite one another. +- **[DEAD]** Prisma declares Postgres job/task definitions and an execution-history archive (`plugins/workers/database/workers.prisma:10-177`, `plugins/workers/database/workers.prisma:212-272`), but the active service runtime constructs KV job/task/execution stores (`plugins/workers/services/src/service-runtime.ts:10-18`). Admin cleanup/archive routes explicitly report the persistence operation unavailable or simulate counts (`plugins/workers/services/src/routers/admin.ts:8-72`). +- **[PARTIAL]** The task executor captures stdout/stderr (`packages/plugin-workers-core/src/executor/adapters/dax-process-runner.ts:146-169`), but task completion stores only result/error/exit code in execution state (`plugins/workers/worker/job-dispatcher.ts:157-170`). The cockpit’s richer output presentation can therefore lack the captured process streams. + +### Trigger persistence + +- **[IMPLEMENTED]** Webhook ingress acknowledges/persists an event before scheduling processing, then updates outcome asynchronously (`packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:65-110`, `packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:113-201`). The legacy store persists events, indexes, idempotency claims, and dead letters in Deno KV (`plugins/triggers/src/runtime/kv-trigger-runtime-stores.ts:25-204`). +- **[PARTIAL]** Scheduled and file-watch adapters create process-local sequential IDs and in-memory adapter records (`plugins/triggers/src/runtime/cron-trigger-scheduler-adapter.ts:131-180`; `plugins/triggers/src/runtime/watchers-file-watcher-adapter.ts:36-189`). The background processor passes those events directly to processing rather than through the persistent ingress (`plugins/triggers/src/runtime/trigger-processor.ts:40-57`). Their event history/status is not queryable after the fact. +- **[DEAD]** The triggers Prisma schema describes trigger definitions and events in Postgres (`plugins/triggers/database/triggers.prisma:1-94`), but the running service uses the Deno-KV runtime store and contains no Prisma-backed definition registry. + +### Acceptance versus execution status + +- **[PARTIAL]** Worker task/job trigger endpoints await their queue adapter and then return only `{ taskId|jobId, triggered: true }`; they do not allocate or return an execution ID (`plugins/workers/services/src/routers/tasks.ts:39-65`; `plugins/workers/services/src/routers/jobs.ts:85-121`). The execution record is created later by the consumer (`plugins/workers/worker/job-dispatcher.ts:31-51`, `plugins/workers/worker/job-dispatcher.ts:140-155`). An operator can know that the API accepted a queue request, but cannot use the response to address the eventual execution directly. +- **[DEAD]** Task execution failures do not reach the queue as handler failures. `processWorkerTask()` catches and records/logs every error without rethrowing, and the task listener also catches unexpected errors and returns normally (`plugins/workers/worker/job-dispatcher.ts:129-196`; `plugins/workers/worker/queue-consumer.ts:49-69`). Provider-native negative acknowledgement/retry therefore cannot act on task failure, which independently confirms that task `maxRetries` is not operational. +- **[PARTIAL]** The native Deno-KV queue adapter calls its underlying `enqueue()` without `await`, then returns from its async wrapper (`packages/queue/adapters/deno-kv.adapter.ts:109-125`). Redis and AMQP adapters await the same underlying operation (`packages/queue/adapters/redis.adapter.ts:66-81`; `packages/queue/adapters/amqp.adapter.ts:59-76`). On the Deno-KV provider, the API-level `await queue.enqueue()` therefore does not prove that the underlying enqueue promise completed or that a later rejection was observed; this is a provider-specific durability/acknowledgement risk. +- **[IMPLEMENTED]** Webhook ingress has the stronger operator contract: it verifies the request, persists the event, starts processing later, and returns HTTP 202 with `eventId` and `acceptedAt` (`packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:80-110`; `plugins/triggers/services/src/routers/webhooks.ts:26-51`). Later processing writes completed/failed status against that durable event (`packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:162-200`). +- **[PARTIAL]** The persisted webhook event is not a durable work item. After saving it, ingress schedules processing with `queueMicrotask()` and a deliberately unawaited promise (`packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:97-110`, `packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:156-164`). No startup scan/requeue of pending events was found. A process crash after the 202 response can therefore leave an event permanently `pending`, and even a later status-write failure is only logged and swallowed (`packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:186-200`). + +## 7. Cockpit workflows + +### Workers tasks + +- **[IMPLEMENTED]** Routes exist for task list, task detail, and task execution detail: `apps/playground/routes/(dashboard)/dashboard/plugin/workers/tasks/index.tsx:13-44`, `apps/playground/routes/(dashboard)/dashboard/plugin/workers/tasks/[taskId]/index.tsx:16-48`, and `apps/playground/routes/(dashboard)/dashboard/plugin/workers/tasks/[taskId]/executions/[executionId]/index.tsx:9-31`. +- **[IMPLEMENTED]** Their loaders call the real worker service contract for list/get task and list/get execution (`apps/playground/routes/(dashboard)/dashboard/plugin/workers/tasks/(_shared)/query-loaders.ts:38-78`, `apps/playground/routes/(dashboard)/dashboard/plugin/workers/tasks/(_shared)/query-loaders.ts:84-205`). +- **[IMPLEMENTED]** Task cards expose a Run control wired to the `triggerTask` mutation (`apps/playground/routes/(dashboard)/dashboard/plugin/workers/(_components)/list.tsx:532-612`; `apps/playground/islands/TriggerButton.tsx:28-50`). +- **[DEAD]** There is no cockpit task create/edit/delete workflow, matching the service’s absence of task mutation endpoints (`plugins/workers/services/src/routers/tasks.ts:9-100`). The detail component is inspection/navigation only (`apps/playground/routes/(dashboard)/dashboard/plugin/workers/tasks/(_components)/detail.tsx:127-195`). +- **[PARTIAL]** The real pages can list/run only tasks already present in KV. Since no delivered path seeds versioned tasks into that registry, a normal stack can present an empty task list despite populated `workers/runtime/tasks/v1.0.0.json`. + +### Triggers + +- **[ASPIRATIONAL]** Routes exist for trigger list, trigger detail, and event detail: `apps/playground/routes/(dashboard)/dashboard/plugin/triggers/index.tsx:15-59`, `apps/playground/routes/(dashboard)/dashboard/plugin/triggers/[id]/index.tsx:13-43`, and `apps/playground/routes/(dashboard)/dashboard/plugin/triggers/[id]/events/[eventId]/index.tsx:9-32`. +- **[ASPIRATIONAL]** Their loaders call `listTriggers`, `getTrigger`, `listEvents`, and `getEvent` through the generated triggers client (`apps/playground/routes/(dashboard)/dashboard/plugin/triggers/(_shared)/query-loaders.ts:22-71`, `apps/playground/routes/(dashboard)/dashboard/plugin/triggers/(_shared)/query-loaders.ts:177-240`; `apps/playground/lib/api-clients.ts:35-39`). +- **[DEAD]** The contract advertises definition queries, fire/test/preview, enable/disable, event queries, and event streaming (`packages/plugin-triggers-core/src/contracts/v1/triggers.contract.ts:197-261`), but the delivered trigger router mounts only health, event-read, and webhook routes (`plugins/triggers/services/src/router.ts:15-23`; `plugins/triggers/services/src/routers/events.ts:14-58`; `plugins/triggers/services/src/routers/webhooks.ts:9-88`). No matching contract handlers were found, so the generated cockpit client could not drive those pages against this service. +- **[ASPIRATIONAL]** Trigger cards and detail/event components are navigation and inspection surfaces, not mutation workflows (`apps/playground/routes/(dashboard)/dashboard/plugin/triggers/(_components)/list.tsx:241-270`; `apps/playground/routes/(dashboard)/dashboard/plugin/triggers/(_components)/detail.tsx:100-407`). No cockpit call to fire/test/enable/disable was found. + +## 8. Permissions, runtime selection, and polyglot/legacy-wrapper support + +- **[IMPLEMENTED]** Runtime selection is per KV task definition and dispatched across seven adapters (`packages/plugin-workers-core/src/domain/task.ts:8-69`; `packages/plugin-workers-core/src/executor/multi-runtime-task-executor.ts:110-130`). The checked-in version document demonstrates Deno, Python, shell, PowerShell, scheduled examples, and .NET (`workers/runtime/tasks/v1.0.0.json:5-115`). +- **[IMPLEMENTED]** The subprocess runner applies timeout, captures stdout/stderr, and classifies exit/signal/timeout outcomes (`packages/plugin-workers-core/src/executor/adapters/dax-process-runner.ts:27-80`, `packages/plugin-workers-core/src/executor/adapters/dax-process-runner.ts:146-169`). This is direct host-process execution, not a container or VM wrapper. +- **[PARTIAL]** Deno permissions can specify scoped net/read/write/env/run/ffi/import access (`packages/plugin-workers-core/src/domain/task.ts:8-69`) and are translated to Deno flags (`packages/plugin-workers-core/src/executor/adapters/permission-flags.ts:3-19`). If permissions are absent, the adapter explicitly returns `--allow-all` (`packages/plugin-workers-core/src/executor/adapters/permission-flags.ts:3-6`). +- **[DEAD]** The versioned runtime-task schema/model does not carry the executable task domain’s permission object (`workers/runtime/schema.json:82-137`; `packages/runtime-config/mod.ts:68-85`). Even a hypothetical loader-to-registry bridge would default versioned Deno tasks to full permissions unless it injected a policy. +- **[PARTIAL]** Python, .NET, shell, PowerShell, cmd, and executable adapters have no analogous permission mapper. The runner copies the full host environment and overlays task values (`packages/plugin-workers-core/src/executor/adapters/dax-process-runner.ts:83-91`), and PowerShell is launched with execution-policy bypass (`packages/plugin-workers-core/src/executor/adapters/argv-builder.ts:87-107`). No OS-level sandbox, user isolation, allowlist, or resource boundary was found. + +## 9. Persistence and synchronization + +- **[DEAD]** The runtime-versioned filesystem was intended as a source of configuration, but it was not connected to executable services (`config/runtime/mod.ts:3-18`; `packages/runtime-config/mod.ts:206-247`). It therefore was neither an effective source of truth nor synchronized with the real registries. +- **[IMPLEMENTED]** Running workers used the shared `@netscript/kv` abstraction for job definitions, task definitions, and execution state (`plugins/workers/services/src/service-runtime.ts:10-18`). That abstraction auto-selects Redis/Garnet when configured and registered, otherwise Deno KV (`packages/kv/core/auto-detect.ts:121-164`; `packages/kv/core/shared.ts:212-250`); worker entrypoints register the Redis adapter (`workers/bin/combined.ts:1-13`; `plugins/workers/services/src/main.ts:1-19`). Running triggers separately used static generated source definitions plus a direct `Deno.openKv(NETSCRIPT_TRIGGER_KV_PATH)` store for webhook events/idempotency/dead letters (`plugins/triggers/src/runtime/project-trigger-registry.ts:4-15`; `plugins/triggers/src/runtime/kv-trigger-runtime-stores.ts:25-38`). +- **[DEAD]** No filesystem-to-KV import, KV-to-filesystem export, reconciliation loop, version checkpoint, or migration record connects those stores. The CLI’s `.netscript/runtime/*.json` writes are a third disconnected configuration location (`plugins/workers/src/cli/workers-cli-backend.ts:132-159`; `plugins/triggers/src/cli/triggers-cli-backend.ts:164-176`). +- **[PARTIAL]** Generated worker definitions have a one-way, create-if-missing seed into KV (`workers/bin/combined.ts:13-30`; `plugins/workers/bin/runtime.ts:91-110`). KV becomes authoritative after first registration, but no provenance/version field or reconciliation rule records that handoff. Source rebuilds can therefore diverge indefinitely from the persisted definition. +- **[PARTIAL]** Trigger Deno KV can be shared when instances receive the same explicit backend path/URL, but cron and file-watch registrations remain per-process (`plugins/triggers/src/runtime/kv-trigger-runtime-stores.ts:25-28`; `plugins/triggers/src/runtime/cron-trigger-scheduler-adapter.ts:41-83`; `plugins/triggers/src/runtime/watchers-file-watcher-adapter.ts:36-84`). The default scheduler wraps native `Deno.cron`, while its registration map is instance-local (`packages/cron/mod.ts:81-112`; `packages/cron/adapters/deno.adapter.ts:57-122`). Multiple background-processor replicas can therefore each install the same schedule/watch and produce duplicate work unless deployment constrains the replica count. +- **[PARTIAL]** Webhook event save atomically couples the primary record and its list index (`plugins/triggers/src/runtime/kv-trigger-runtime-stores.ts:30-95`), but worker execution transitions are non-atomic read-modify-write (`packages/plugin-workers-core/src/state/execution-state.ts:183-197`). +- **[DEAD]** Direct pointer/version writes have no lock, fsync protocol, transactional group commit, or atomic rename (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:127-158`; `packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:178-209`). Multi-writer deployment updates could lose changes or expose mixed topic versions. +- **[DEAD]** Publication state is not internally verified. Topic copy errors only warn, while pointer updates proceed in a separate pass without checking conflict resolution or destination existence (`packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:123-175`, `packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:178-210`). Even before considering the absent runtime consumer, the filesystem snapshot can be self-inconsistent. + +## 10. Operational limitations and why it was not production-ready + +- **[DEAD]** **Runtime configuration was not runtime.** The only pointer loader/watcher was unconsumed, so checked-in versions, overrides, hot reload, and rollback could not influence workers or triggers (`packages/runtime-config/mod.ts:206-247`, `packages/runtime-config/mod.ts:299-383`). +- **[DEAD]** **No validated admission path.** Loaders parse/cast without schema enforcement, while the checked-in schema rejects a checked-in .NET task (`packages/runtime-config/mod.ts:144-151`; `workers/runtime/schema.json:106-115`; `workers/runtime/tasks/v1.0.0.json:107-115`). +- **[DEAD]** **No atomic publication.** The deployment writer updates multiple version documents and then `current` with direct writes/copies and no transaction (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:127-158`; `packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:153-209`). +- **[DEAD]** **Pointer promotion can outrun content promotion.** Failed/skipped dev-topic copies do not prevent the independent dev-pointer merge, and referenced-file existence is not checked (`packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:123-175`, `packages/cli/src/public/features/deploy/build/build-windows-runtime.ts:178-210`). +- **[DEAD]** **Custom runtime topics stop at packaging.** The writer accepts arbitrary plugin topic generators and adds their paths to `current`, but the only runtime loader ignores keys outside its fixed built-in fields (`packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts:132-154`; `packages/runtime-config/mod.ts:220-247`). +- **[PARTIAL]** **Split-brain configuration.** Static generated registries, worker KV registries, versioned runtime directories, CLI `.netscript/runtime` files, and aspirational Prisma tables all coexist without reconciliation (`plugins/workers/bin/runtime.ts:29-110`; `plugins/workers/src/cli/workers-cli-backend.ts:132-159`; `plugins/workers/database/workers.prisma:1-5`). +- **[DEAD]** **Incomplete task control plane.** The task execution/data plane is real, but no operator-facing registration mutation or version seeder exists (`plugins/workers/services/src/routers/tasks.ts:9-100`; `packages/plugin-workers-core/src/registry/kv-task-registry.ts:11-93`). +- **[PARTIAL]** **Job mutations exceed runtime capability.** APIs can create KV jobs, but the dispatcher normally requires compiled static handlers, and schedule timers do not refresh (`plugins/workers/services/src/routers/jobs.ts:42-83`; `packages/plugin-workers-core/src/runtime/job-dispatcher.ts:25-68`; `plugins/workers/worker/scheduler.ts:139-198`). +- **[PARTIAL]** **Static job configuration goes stale after first seed.** Startup skips any generated definition whose ID already exists in KV, without comparing or updating its fields (`plugins/workers/bin/runtime.ts:91-110`). With version overrides unconsumed, a rebuilt definition and the running registry can silently disagree. +- **[DEAD]** **Trigger cockpit/server mismatch.** The cockpit uses a broad oRPC contract, while the service implements a small unrelated Hono surface (`packages/plugin-triggers-core/src/contracts/v1/triggers.contract.ts:197-261`; `plugins/triggers/services/src/router.ts:15-23`). +- **[PARTIAL]** **Incomplete history.** Only webhook ingress follows the persistent event path; scheduled/file events are process-local, and worker archive/cleanup endpoints are stubs (`plugins/triggers/src/runtime/trigger-processor.ts:40-57`; `plugins/workers/services/src/routers/admin.ts:8-72`). +- **[PARTIAL]** **Durable receipt without durable dispatch.** Webhook ingress persists a pending record before returning 202, but launches processing only in an in-process microtask and has no visible pending-event recovery loop (`packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:97-110`, `packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:156-200`). A crash can strand accepted events indefinitely. +- **[PARTIAL]** **Ambiguous acceptance receipts.** Worker trigger APIs return `triggered: true` but no execution ID before the consumer creates execution state, while the Deno-KV queue adapter does not await its underlying enqueue call (`plugins/workers/services/src/routers/tasks.ts:39-65`; `plugins/workers/services/src/routers/jobs.ts:85-121`; `packages/queue/adapters/deno-kv.adapter.ts:109-125`). This prevents a clean operator handoff from accepted request to durable execution status. +- **[DEAD]** **Task retry is bypassed at the queue boundary.** The dispatcher and listener swallow task failures, so a queue backend sees successful handler completion and cannot apply native retry (`plugins/workers/worker/job-dispatcher.ts:129-196`; `plugins/workers/worker/queue-consumer.ts:49-69`; `packages/queue/interfaces/message-queue.ts:36-48`). +- **[PARTIAL]** **Weak isolation.** Missing Deno permissions become `--allow-all`, other runtimes run directly on the host, and subprocesses inherit the host environment (`packages/plugin-workers-core/src/executor/adapters/permission-flags.ts:3-6`; `packages/plugin-workers-core/src/executor/adapters/dax-process-runner.ts:27-91`). +- **[PARTIAL]** **No visible service authentication.** The workers service is assembled with CORS and logging but no authentication middleware (`plugins/workers/services/src/main.ts:46-71`); the trigger Hono router mounts public health/events/webhook routes without an authentication layer (`plugins/triggers/services/src/router.ts:15-23`). Deployment-level authentication outside these files was not established, so this claim is deliberately scoped to the application services. +- **[PARTIAL]** **Multi-instance duplicate producers.** Cron and file-watch registrations are installed in every background processor and stored in process memory, with no leader election or distributed lease (`plugins/triggers/src/runtime/trigger-processor.ts:27-65`; `plugins/triggers/src/runtime/cron-trigger-scheduler-adapter.ts:131-180`; `plugins/triggers/src/runtime/watchers-file-watcher-adapter.ts:36-189`). +- **[PARTIAL]** **Ambiguous concurrency control.** Aspire declares `TRIGGERS_PROCESSOR_CONCURRENCY=2` for the processor resource (`plugins/triggers/src/aspire/triggers-contribution.ts:17-19`, `plugins/triggers/src/aspire/triggers-contribution.ts:57-77`), while the runtime factory never reads that environment variable and core processing uses a per-definition limit or a default of 10 (`plugins/triggers/src/runtime/trigger-runtime-processor.ts:25-44`; `packages/plugin-triggers-core/src/runtime/trigger-processor.ts:197-223`). The variable may affect external resource orchestration, but it does not tune the in-process trigger concurrency gate. +- **[PARTIAL]** **Misleading CLI semantics.** Trigger `fire` invokes a handler and reports actions without dispatching them; enable/disable writes an unconsumed file (`plugins/triggers/src/cli/triggers-cli-backend.ts:125-176`). Worker `config publish` only reads and echoes JSON rather than publishing it to a running service (`plugins/workers/src/cli/workers-cli-backend.ts:142-159`). + +## Static reachability audit + +- **[IMPLEMENTED]** This continuation repeated repository-wide literal reference searches at subject HEAD for `runtime-config`, `loadRuntimeConfig`, `watchRuntimeConfig`, `loadRuntimeOverrides`, and `registerTask`. Outside its defining module, `@netscript/runtime-config` appears as import-map/package/deployment metadata, and the two function names appear only in a deployment comment claiming the intended consumption (`deno.json:32`; `packages/runtime-config/mod.ts:206-247`, `packages/runtime-config/mod.ts:299-383`; `packages/cli/src/kernel/adapters/windows/servy/servy-environment.ts:237-242`). The CLI `loadRuntimeOverrides` symbol occurs only at its declaration (`packages/cli/src/kernel/adapters/config/runtime-override.ts:107-156`), and `registerTask` occurs only in the registry implementation (`packages/plugin-workers-core/src/registry/kv-task-registry.ts:33-45`). These are static negative results, not proof against computed imports or code outside the repository. +- **[IMPLEMENTED]** Default worker startup constructs a task registry but registers only static **job** definitions (`plugins/workers/bin/runtime.ts:29-44`, `plugins/workers/bin/runtime.ts:91-110`). The service initializer likewise contains only `registerPluginJobs()` and calls `registerJob()` (`plugins/workers/services/src/init.ts:4-80`). Together with the absent task mutation routes (`plugins/workers/services/src/routers/tasks.ts:9-100`), this makes “no first-party task seeding path” stronger than a name search alone. +- **[ASPIRATIONAL]** The combined worker entrypoint’s header advertises “runtime config hot-reload” and “runtime tasks,” but its executable imports are only the combined runtime plus generated job definitions/handlers (`workers/bin/combined.ts:1-30`). The combined runtime then seeds jobs, constructs an empty task registry dependency, and never loads runtime configuration (`plugins/workers/bin/runtime.ts:63-110`). +- **[IMPLEMENTED]** The schema-generator zero-input chain is explicit: the manifest snapshot produces empty schema arrays, a test locks that behavior, command composition forwards those arrays, and the planner iterates only the supplied entries (`packages/cli/src/kernel/adapters/config/plugin-registry.ts:217-239`; `packages/cli/src/kernel/adapters/config/plugin-registry.test.ts:7-35`; `packages/cli/src/public/features/root/public-command-dependencies.ts:256-268`; `packages/cli/src/public/features/generate/runtime-schemas/generate-runtime-schemas.ts:135-173`). No generator execution was needed to establish the empty plan for this path. +- **[PARTIAL]** Trigger transport remains a static mismatch: the cockpit creates a contract client named `triggers-api`/router `triggers` (`apps/playground/lib/api-clients.ts:35-52`), whereas the service directly calls `Deno.serve(..., app.fetch)` over a Hono app containing only `/health`, `/api/v1/events`, and `/api/v1/webhooks` (`plugins/triggers/services/src/main.ts:29-59`; `plugins/triggers/services/src/router.ts:15-23`). Repository-wide search found no `triggersContract` implementation in the service package. A deployed reverse proxy could add routing, but it cannot synthesize the missing definition procedures without another server implementation. + +## Claims the supervisor should re-verify + +1. **[DEAD, weakest inference]** No executable consumer imports `packages/runtime-config/mod.ts`. This is based on repository-wide static reference/import search at HEAD; dynamic import by a computed path or an external deployment wrapper could evade that search. Re-verify with the final packaged dependency graph. +2. **[DEAD, weak inference]** The trigger cockpit cannot communicate with the delivered trigger service because its generated oRPC contract has no handler implementation, while Hono exposes different routes (`packages/plugin-triggers-core/src/contracts/v1/triggers.contract.ts:197-261`; `plugins/triggers/services/src/router.ts:15-23`). Re-verify service-client transport/base-path composition in a built playground. +3. **[PARTIAL, weak inference]** No startup recovery loop reprocesses persisted webhook events left `pending` after a crash. Static ingress/startup inspection found only immediate microtask dispatch, but a recovery worker outside the trigger package could evade this search (`packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:97-110`, `packages/plugin-triggers-core/src/runtime/create-trigger-ingress.ts:156-200`; `plugins/triggers/services/src/main.ts:29-69`). +4. **[PARTIAL, weak inference]** The application services have no visible authentication. Authentication could be imposed by Aspire ingress, a reverse proxy, or an unpublished deployment wrapper not represented in the service routers (`plugins/workers/services/src/main.ts:46-71`; `plugins/triggers/services/src/router.ts:15-23`). +5. **[PARTIAL, weak inference]** The Deno-KV adapter may acknowledge enqueue before the underlying operation settles because it omits `await` (`packages/queue/adapters/deno-kv.adapter.ts:109-125`). Re-verify the exact return/commit semantics of the pinned upstream `DenoKvMessageQueue.enqueue`; the local Redis and AMQP comparison does await it (`packages/queue/adapters/redis.adapter.ts:66-81`; `packages/queue/adapters/amqp.adapter.ts:59-76`). diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/sandbox-isolation-survey.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/sandbox-isolation-survey.md new file mode 100644 index 0000000000..6183dbc331 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/evidence/sandbox-isolation-survey.md @@ -0,0 +1,39 @@ +# Extract — sandbox/isolation technology survey (fetched 2026-08-11) + +For RFC `rfcs/0000-runtime-versioned-automation.md`. Sources fetched via firecrawl search; +primary-source facts preferred; comparison-table numbers are vendor/practitioner-reported, treat as +order-of-magnitude. + +## Deno (primary: docs.deno.com/runtime/fundamentals/security/, /runtime/reference/permissions/) + +- Deno is deny-by-default: no fs/net/env/subprocess/FFI without explicit `--allow-*`; `--deny-*` + takes precedence; permission model enforced by the runtime. +- **`--allow-run` bypasses the sandbox**: subprocesses run with their own OS-level privileges, not + the parent's permission set; `--allow-run=deno` (or a shell) = full escape. Official guidance: + scope to specific executables. +- FFI likewise escapes the sandbox. +- Official untrusted-code guidance: limited permissions + `--frozen` + `--cached-only`; Web Workers + with reduced per-worker permission sets; OS mechanisms (chroot/cgroups/seccomp); or gVisor / + Firecracker / VM for real isolation. I.e. **Deno itself recommends layering an OS/VM boundary for + genuinely untrusted code.** +- Research precedent: Cage4Deno (ACM AsiaCCS 2023) — fine-grained sandbox for Deno _subprocesses_, + confirming the subprocess hole is the known weak point. + +## Isolation primitives (practitioner consensus, Feb–Apr 2026 posts: zylos.ai, cosmonic.com, northflank.com, manveerc.substack.com, beam.cloud) + +| Primitive | Boot | Overhead | Boundary | Notes | +| --------------------------------- | ------ | -------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | +| Containers (runc/rootless) | ~1s+ | 50–200MB | shared kernel — weakest | consensus: NOT sufficient for hostile/AI-generated code | +| gVisor (Sentry user-space kernel) | ~100ms | ~20MB | syscalls intercepted (Systrap/KVM modes) | 10–30% I/O overhead; Modal/Google production | +| Firecracker microVM | ~125ms | ~5MB | KVM hardware, own kernel; jailer seccomp (24 syscalls) | AWS Lambda/Fargate, E2B, Fly.io; gold standard for untrusted code | +| Kata Containers | ~200ms | ~30MB | KVM, K8s-native | per-workload selectable on some platforms | +| V8 isolates | <1ms | ~1–10MB | V8 heap isolation | JS/TS(+wasm) only; Cloudflare Workers/Deno Deploy; process-isolation debate (Fly vs Cloudflare) | +| WASM/WASI component model | <1ms | <1–5MB | capability deny-by-default, no ambient authority | polyglot-if-compiled (Rust/Go/Py/JS/C); no GPU; wasmtime/wasmCloud; Microsoft Wassette (2025) = wasmtime + MCP for agent tools | + +- Managed sandbox products (E2B Firecracker SDK, Modal gVisor, Northflank Kata/FC/gVisor, Fly + Sprites, Beam) demonstrate a mature buy-option market **for isolation/sandbox execution + specifically** (this file's scope is isolation technology only — the broader runtime/workflow + product comparison lives in `competitive-architecture-study.md`); all are cloud-hosted — self-host + fit varies (Northflank BYOC, Beam self-host). +- Recurring architecture: separate "execution adapter" from "security boundary"; layer primitives + (defense in depth); pick per-workload isolation level by trust tier. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/phase-registry.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/phase-registry.md new file mode 100644 index 0000000000..4f826411e0 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/phase-registry.md @@ -0,0 +1,21 @@ +# Phase Registry — docs-rfc-runtime-versioned-automation--supervisor + +RFC/decision-document run (SCOPE-docs overlay; research + architecture, no implementation). + +| Group | Scope | Lane | Status | Evidence | +| -------------------------- | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| G0 Bootstrap | run dir, supervisor identity, overrides | Fable 5 supervisor | done | supervisor.md, drift.md | +| G1 Legacy archaeology | netscript-start-ref runtime-versioned workers/tasks/triggers capability map | archaeology sub-agents + supervisor synthesis | done | evidence/legacy-capability-map.md; slice review PASS | +| G2 Current-state matrix | runtime-config, runtime-schemas gen, workers/triggers runtimes, plugin trees, Aspire, tests/E2E | archaeology sub-agents + bounded disposable proofs | done | evidence/current-state-matrix.md + probes; slice review PASS | +| G3 #1443/#1444 interaction | control-plane vs runtime split; immediate constraints memo | supervisor (read-only peek at ns-1443 worktree + PR #1444) | done | 1444-impact.md + PR #1444 comment 5248826402 | +| G4 RFC synthesis | primary RFC, matrix, diagrams, threat model, migration, E2E acceptance, roadmap drafts | Fable 5 supervisor (authoring) | done | rfc-0001-runtime-versioned-automation.md @ f5997b6a2 (normalized 2026-08-11 → rfcs/0000-runtime-versioned-automation.md, D-10) | +| G5 Draft PR | draft PR vs main, labels/milestone/provenance, phase comments | supervisor | done | draft PR #1446, labels + Backlog/Triage milestone, phase comments | +| G6 PLAN-EVAL | fresh native Codex GPT-5.6 Sol · xhigh adversarial eval | separate Codex session | **done — PASS (cycle 9, 2026-08-11)** | plan-eval.md cycles 1–9 (append-only): C1 9 findings → monotonic narrowing → C6 architecture-clean → C9 all-checklist PASS, no open decisions; eval thread `019fef2b-…03fc` | + +| G7 Competitive study (D-8) | 9-system primary-source comparison, RFC §14.1/§13.1/P-5 integration, +wording scope fixes | Fable 5 supervisor | done | evidence/competitive-architecture-study.md; +commits 811373a87 + 3c918a64e | + +PLAN-EVAL is selected (decision-heavy RFC). IMPL-EVAL: the deliverable is the plan/RFC itself; the +final Sol · xhigh pass is the run's formal evaluator gate. No implementation phase exists to +IMPL-EVAL; if the owner later ratifies implementation, that work gets its own runs. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/plan-eval.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/plan-eval.md new file mode 100644 index 0000000000..dbf7a48ac6 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/plan-eval.md @@ -0,0 +1,969 @@ +# PLAN-EVAL — docs-rfc-runtime-versioned-automation--supervisor + +- Plan evaluator session: fresh Codex GPT-5.6 Sol · xhigh evaluator / 2026-08-11 (owner override + D-2) +- Run: `docs-rfc-runtime-versioned-automation--supervisor` +- Surface / archetype: docs RFC describing future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, and + CLI waves +- Scope overlays: `SCOPE-docs`; adversarial RFC architecture review; no implementation evaluation + +## Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | PASS | `research.md:6-13` records the current baseline; `evidence/current-state-matrix.md:22-26` proves the package/plugin paths were unchanged from the named `origin/main`. I independently re-ran focused reachability searches and inspected the public `RuntimeTask`, `TaskDefinition`, and executor surfaces with `deno doc`. | +| Decisions locked | FAIL | `plan.md:3-4` still calls the plan provisional; the load-bearing O2+O4 ownership choice is only a recommendation with a fallback (`rfc-0001-runtime-versioned-automation.md:416-423`) and is still an owner question (`:519-526`). The consistency and runtime-security contracts in findings 4-6 are also not decided strongly enough to slice. | +| Open-decision sweep | FAIL | The plan contains no sweep classifying each open decision as safe to defer or must resolve now, despite the explicit owner-question list (`rfc-0001-runtime-versioned-automation.md:519-526`). The evaluator sweep below finds six decisions that would force rework. | +| Commit slices (< 30, gate + files each) | FAIL | The five docs-only bullets name neither files nor proving gates (`plan.md:66-74`), and `worklog.md:1-84` has no mandatory `## Design` section. The implementation roadmap is nine epic-sized waves with dependency columns but no per-slice files or gates (`rfc-0001-runtime-versioned-automation.md:457-474`). This fails `plan-protocol.md:34-40` and `run-loop.md:56-73`. | +| Risk register | FAIL | A table exists (`plan.md:56-65`), but it omits the plan's load-bearing risks: cross-family partial activation, out-of-order feed/poll races, schema-skew split fleets, KV/Postgres semantic divergence, non-Deno T1 escape, unauthenticated snapshot integrity, secret output leakage, and unresolved cron ownership. Those omissions leave no mitigating slices or gates. | +| Gate set selected | PASS | For the present docs-only surface, `plan.md:6-13` selects docs-source gates, CI docs skips, and final PLAN-EVAL. Future package/plugin proving gates are still required as part of the corrected implementation slices in finding 9. | +| Deferred scope explicit | PASS | P-1 through P-4 have rationale and entry criteria (`rfc-0001-runtime-versioned-automation.md:448-455`); the single-replica limitation before P-1 is explicit (`:287-290`). This does not make the additional unclassified decisions below safe to defer. | +| jsr-audit surface scan (pkg/plugin) | N/A | This run changes documentation only (`plan.md:6-13`). The future public-package A0 wave names jsr-audit (`rfc-0001-runtime-versioned-automation.md:463-466`), but its corrected slice must apply the full rubric before implementation. | + +## Open-decision sweep (evaluator-run) + +Must resolve before implementation because deferral changes package boundaries, persisted contracts, +or security behavior: + +1. **Control-plane ownership and package archetypes:** decide O2+O4 versus the fallback, then assign + lifecycle behavior, store ports/adapters, service composition, and UI wiring to doctrine-valid + packages. +2. **Activation-set consistency:** decide the transaction boundary and monotonic ordering protocol + across `task@1`, `trigger@1`, and future families, including rollback and stale-feed rejection. +3. **Replica compatibility:** decide activation admission and rollback behavior when deployed + replicas understand different schema majors; indefinite last-known-good divergence is not + convergence. +4. **Store semantics:** decide one behavioral contract that both Postgres and development KV can + satisfy, or explicitly narrow the KV adapter's supported operations. +5. **T1 trust contract:** decide what is actually enforced for + Python/.NET/shell/PowerShell/cmd/executable tasks and what requires T2. A working directory and + cleared environment are not filesystem/network isolation. +6. **Scheduled-work ownership:** resolve `CRON-SUBSYSTEM-DUP` before adding both `task@1.schedule` + and scheduled `trigger@1`; otherwise the RFC deepens the recorded duplicate subsystem. + +Safe to defer only with the RFC's stated entry criteria: P-1 through P-4 +(`rfc-0001-runtime-versioned-automation.md:448-455`). The exact package spelling, two-person +default, and retention defaults may be deferred only to a named pre-publication/persistence slice +with explicit entry criteria; the current owner-question list does not classify them (`:519-526`). + +## Verdict + +`FAIL_PLAN` + +### If FAIL_PLAN — required fixes + +1. **[BLOCKER] Restore the mandatory Design checkpoint, resumability artifact, and current review + surface.** `worklog.md:1-84` has dated progress entries but no `## Design`, although the harness + requires the public surface, domain vocabulary, ports, constants, file-and-gate commit slices, + deferred scope, and contributor path before Plan-Gate + (`.llm/harness/workflow/run-loop.md:56-73`). The run directory also has no `context-pack.md`, + despite that being a mandatory artifact (`.llm/harness/workflow/activation.md:48-63`). Add both + artifacts and make every future implementation file trace to the Design checkpoint. Then update + draft PR #1446's body: as inspected on 2026-08-11, its S3/S4 checkboxes are stale even though the + comments say those slices landed, and it does not contain the current locked decisions, risk + register, slices, and selected gates required by `run-loop.md:75-80`. + +2. **[BLOCKER] Resolve O2+O4 rather than presenting the central ownership decision as both accepted + and open.** The RFC recommends a connector, immediately records a no-connector fallback, and + leaves the choice to the owner (`rfc-0001-runtime-versioned-automation.md:416-423`, `:519-526`). + The comparison does not model the fallback at the same fidelity as O4: it does not name its + deployment unit, service composition, storage/migration owner, client dependency direction, or + how reuse avoids O5-style reinvention. Record one decision with those concrete boundaries and + rationale before ratification; if owner input is required, mark the run blocked at that choice + rather than beginning A0. + +3. **[BLOCKER] Correct the package archetypes and plugin-thinness violation in the chosen ownership + model.** `@netscript/automation-core` is labeled ARCHETYPE-1 while owning a lifecycle state + machine plus store, boundary, and reload ports, and the ARCHETYPE-5 connector is assigned the + management service and Postgres/KV adapters (`rfc-0001-runtime-versioned-automation.md:187-189`, + `:416-420`). Doctrine limits ARCHETYPE-1 to types and small invariants with almost no runtime + (`docs/architecture/doctrine/06-archetypes.md:13-39`), while connector plugins wire core-owned + conventions rather than own them (`:157-174`, + `.llm/harness/archetypes/ARCHETYPE-5-plugin.md:29-43`). The open adapter-relocation debt + specifically places port-to-backend runtime stores/adapters in sibling core packages, not + `plugins/*` (`.llm/harness/debt/arch-debt.md:1832-1880`). Re-archetype or split the + design—typically contracts (A1), lifecycle/runtime behavior (A3), and persistence + integration/adapters (A2 or a justified runtime core)—then leave the connector with composition, + declared resources, and re-exports. Name the exact core primitive and file group each connector + axis wires. + +4. **[BLOCKER] Replace per-family snapshots with an ordered, fleet-safe activation-set protocol and + prove adapter parity.** Grouped activation can span an “explicit atomic set,” but propagation + emits and swaps one snapshot per family (`rfc-0001-runtime-versioned-automation.md:244-253`, + `:265-285`). A trigger revision can therefore become visible before the task revision it + references. A delayed SSE fetch can also overwrite a newer polled state because a content hash + has identity but no monotonic order. Schema mismatch deliberately leaves replicas on different + last-good states with no admission, acknowledgement, deadline, or rollback policy (`:271-278`). + Define a transactionally published activation-set manifest/epoch across all referenced families, + referential validation, compare-and-reject rules for stale/out-of-order feed and polling + responses, compatibility admission for the deployed fleet, partial-fetch/swap failure behavior, + and convergence/rollback SLOs. Separately specify transaction scope, idempotency, audit ordering, + and snapshot-consistency semantics shared by Postgres and KV (`:236-258`), backed by one + adapter-conformance suite; otherwise narrow the KV adapter instead of claiming uniform behavior. + +5. **[BLOCKER] Make T1 security claims match the technologies for every advertised runtime.** J2 + promises capability grants and a sandboxed dry-run for Python/.NET/shell tasks + (`rfc-0001-runtime-versioned-automation.md:58-64`), but T1 maps filesystem/network permissions + only for Deno while calling `cwd` “jailed” and relying on `clearEnv`, kill-tree, and cgroups for + every runtime (`:292-314`). Those controls do not stop a native child from reading arbitrary host + files, opening the network, or spawning processes. This is already recorded debt: all non-Deno + runtimes inherit host OS privilege absent an external sandbox + (`.llm/harness/debt/arch-debt.md:1409-1421`). Deno's official permissions documentation also + states spawned subprocesses run independently of the parent's permission sandbox: + https://docs.deno.com/runtime/reference/permissions/#subprocesses. Either limit non-Deno T1 to + explicitly trusted workloads with non-enforceable grants modeled honestly, or move capability + enforcement for them to an OS/container boundary. Replace “cwd jail” with entrypoint-root + confinement unless a real jail exists, revise TM1/TM2/J2, and add per-runtime negative tests + rather than the single ambiguous network test at + `rfc-0001-runtime-versioned-automation.md:489-492`. + +6. **[BLOCKER] Honor C8 and narrow or strengthen the remaining security guarantees.** C8 requires + the RFC threat model to cover the control-plane child loader's `--allow-read --allow-net`, + lockfile pinning, `--cached-only`, and a future capability prompt (`1444-impact.md:76-80`). The + RFC only names #1444's loader in the schema command + (`rfc-0001-runtime-versioned-automation.md:380-382`); TM7 covers task dependencies, not + consumer-controlled code executing with network access during manifest loading (`:347`). Add that + control-plane threat, trust boundary, and acceptance gate. Also, content hashes do not + authenticate snapshots or defeat a malicious store/MITM, same-transaction audit is not + tamper-evident against the direct-DB attacker TM8 names, and resolving secrets into child env + cannot guarantee secret material “never” enters captured history when the child can print it + (`:323-327`, `:339-348`, `:360-364`). State trusted DB/transport/admin assumptions or add + authenticated snapshots and an independently protected audit sink; describe output redaction as + bounded/best-effort with residual leakage, not an absolute guarantee. + +7. **[HIGH] Correct evidence claims to the strength and time range the reports establish.** “No + released version has ever” and “no executable service ever imported” + (`rfc-0001-runtime-versioned-automation.md:15-25`) overreach a static audit at one legacy commit + that expressly cannot exclude computed imports or external wrappers + (`evidence/legacy-capability-map.md:227-240`). “There was never a control plane” + (`rfc-0001-runtime-versioned-automation.md:94-96`) also erases real KV task CRUD and the current + KV-backed trigger enable/disable behavior (`evidence/current-state-matrix.md:74-90`); the + supported conclusion is that there was no coherent operator-managed, revisioned definition + control plane. Line 107 calls PR #1444's loading fix a fact even though #1444 is still a draft + and the current report expressly did not re-evaluate it + (`evidence/current-state-matrix.md:30-36`); phrase it as a pending/branch dependency. Finally, + Appendix A marks all seven current runtime adapters end-to-end green via P5 + (`rfc-0001-runtime-versioned-automation.md:539-545`), while the report says only Deno and shell + ran and five adapters remain implemented-unproven (`evidence/current-state-matrix.md:140-146`, + `:249-255`). Scope the claims to inspected commits/tags and correct that status. + +8. **[BLOCKER] Complete the D-5 cleanup inventory and settle the competing live surfaces.** Section + 10 promises that no competing surface survives but its table + (`rfc-0001-runtime-versioned-automation.md:425-446`) omits or underspecifies: saga + sample/current/schema emissions (`evidence/current-state-matrix.md:94-101`); the workers local + project-file discovery/direct-execution path (`:74-82`); static generated trigger-registry + publication (`:84-90`); current KV trigger enabled state; Windows + `NETSCRIPT_RUNTIME_CONFIG_DIR`/`NETSCRIPT_TASKS_DIR` emission (`:103-108`); and the boundary + between retained T0 job CRUD/scheduling and new `task@1` lifecycle. It also adds task schedules + while retaining scheduled triggers without resolving the existing live `CRON-SUBSYSTEM-DUP` + decision (`.llm/harness/debt/arch-debt.md:1507-1539`). Expand the inventory to exact files, + commands, generated artifacts, schemas, environment keys, tests, and docs; give each a + keep/fold/delete disposition and owning roadmap slice. Choose the canonical cron path before + either surface is removed or duplicated. This is replacement bookkeeping, not a compatibility + layer. + +9. **[BLOCKER] Re-slice §12 into landable PRs with files, proving gates, and correct dependency + edges.** A1 combines two persistence adapters, audit, snapshot construction, and race tests; A2 + combines plugin scaffolding, API/service, lifecycle validation, change feed, and CLI; A3 and A5 + likewise span several independently risky seams + (`rfc-0001-runtime-versioned-automation.md:457-473`). None names files or per-slice gates, + contrary to `plan-protocol.md:34-40`. The graph is also wrong: A4's management fire/test path + depends on A2, not only A3; A5's management dry-run and secrets policy depend on A2; A7's + run/history/trigger journeys require A3/A4/A5, not only A2 plus the frontend cut. Split contracts + first, then store-port conformance/adapters, lifecycle transactions, ordered snapshot + client/feed, engine-specific reload paths, security tiers, management/CLI, cleanup, and UI. For + each PR-sized slice list touched files and applicable static, fitness, runtime/Aspire, consumer, + publish, and release gates from `.llm/harness/gates/archetype-gate-matrix.md:18-76`. Preserve the + correctly modeled cockpit minimum cut at `rfc-0001-runtime-versioned-automation.md:393-400`. + +## Notes + +- The evaluator worktree branch and commit were verified as `eval/rfc-runtime-versioned-automation` + at `1e97152f3460728416ef763d3a4b548dccd2b1c9`, separate from the Claude authoring worktree. +- The RFC correctly preserves D-10 and rejects static-config collapse + (`rfc-0001-runtime-versioned-automation.md:40-45`, `:501-515`), accepts the clean + redesign/no-compat direction (`:112-120`), avoids hardcoded plugin-family dispatch in the proposed + contribution model (`:180-200`), and models the #922/#934 frontend dependency cut accurately + (`:384-400`). These strengths do not cure the unchecked Plan-Gate boxes. +- Draft PR #1446 body and both phase comments were inspected. The comments record research/evidence + and RFC landing, but the body has not been reconciled to that state or to the required Plan & + Design review shape. PR #1444 was also inspected as an open draft; its impact memo is therefore a + constraint/dependency, not landed-main evidence. +- No RFC/source edits, commits, pushes, issue mutations, labels, or PR comments were performed by + this evaluator. + +PLAN-EVAL: FAIL_PLAN + +## Cycle 2 + +- Plan evaluator session: same dedicated Codex GPT-5.6 Sol · xhigh evaluator session / 2026-08-11 + (owner override D-2), fresh judgment at Cycle-2 commit +- Evaluator worktree: `/home/codex/repos/ns-rfc-plan-eval`, branch + `eval/rfc-runtime-versioned-automation`, clean at `382795e4a87891c21a602d7874e24db3db10ded9` +- Author worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, clean at the same commit + before this verdict append +- Surface / archetype: docs RFC planning future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, and + CLI waves +- Scope overlays: `SCOPE-docs`; adversarial RFC architecture review; no implementation evaluation + +### Cycle-1 finding resolution audit + +| Cycle-1 finding | Cycle-2 result | Evidence | +| -------------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| F1 — Design checkpoint, context pack, PR reconciliation | PARTIAL | `worklog.md:86-108` now has `## Design`, and `context-pack.md:1-25` exists. The live PR body is updated, but it and the Cycle-1 comment assert decisions/fixes that the RFC does not contain; the PR still carries `status:research` while its body says Plan & Design is ready and Cycle 2 is running. | +| F2 — lock O2+O4 ownership | FAIL | §9 still calls O2+O4 a recommendation and explicitly keeps the no-connector fallback available to this evaluator (`rfc-0001-runtime-versioned-automation.md:460-467`), contradicting §15's claim that ownership is locked (`:594-597`). | +| F3 — doctrine-valid archetypes / thin connector | FAIL | ARCHETYPE-1 still owns the lifecycle state machine and store/boundary/reload ports (`:193-195`, `:460-464`), contrary to the no-DI/no-adapter, types-and-small-invariants boundary (`docs/architecture/doctrine/06-archetypes.md:13-39`). §9 also still assigns Postgres/KV adapters to the connector (`rfc-0001-runtime-versioned-automation.md:452-464`), contradicting §5.2 and A1a/A1b, which put them in `automation-runtime` (`:252-255`, `:513-515`). | +| F4 — activation-set/fleet consistency and adapter parity | FAIL | Monotonic epochs and adapter narrowing were added (`:264-290`, `:294-318`), but the manifest is described as only the entries/families an activation “touches,” while a snapshot contains only “every entry” in that manifest (`:264-272`, `:294-304`). It is not specified as the complete desired state, so a one-definition activation either drops untouched definitions on swap or requires an unspecified merge. More importantly, replicas apply asynchronously: a trigger replica at N+1 can enqueue `taskId` while a worker at N resolves that ID from its current snapshot (`:309-322`), so cross-family visibility is not fleet-atomic. | +| F5 — honest T1 contract | PARTIAL | J2, §5.4, and E2E-5 now correctly say non-Deno T1 grants are not enforced (`:61-66`, `:329-351`, `:549-552`). The threat table regresses to “T1 env/cwd jail” and “entrypoint resolution jailed” (`:378-380`) even though §5.4 expressly says entrypoint-root resolution is not an OS jail (`:342`). | +| F6 — C8 and security guarantee narrowing | FAIL | DB/transport/redaction trust assumptions were added (`:387-396`), but §6 has TM1–TM8 only (`:372-385`). It never models #1444's control-plane child loader executing consumer code with `--allow-read --allow-net`, never states the promised lockfile/`--cached-only` loader policy, and has no capability-prompt deferral or acceptance gate required by `1444-impact.md:76-80`. `plan.md:72`, `worklog.md:125-126`, and `context-pack.md:18` falsely claim TM9 exists. | +| F7 — evidence claim strength | PASS | The abstract is scoped to the two inspected commits (`rfc-0001-runtime-versioned-automation.md:15-28`), partial KV/operator surfaces and #1444's draft state are acknowledged (`:96-113`), and Appendix A now distinguishes Deno/shell proof from five implemented-unproven adapters (`:610-619`). Focused `rtk grep` and `deno doc` spot-checks reconfirmed the disconnected runtime-config surface and the `RuntimeTask`/`TaskDefinition` mismatch. | +| F8 — complete clean-break inventory / cron ownership | FAIL | `task@1` no longer owns scheduling, so the new operator cron path is resolved without deleting the live T0 `.schedule()` surface (`:241-248`). The §10 inventory remains incomplete: it does not disposition the current `runtime-config-topic` contribution axis/builder (`packages/plugin/src/domain/constants.ts:15-40`, `packages/plugin/src/config/domain/plugin-contributions.ts:11-37`, `packages/plugin/src/config/builders/plugin-builder.ts:204-216`), workers project-file discovery/direct execution (`plugins/workers/src/cli/local-runtime-backend.ts:276-319`), or generated trigger-registry loader/fallback (`plugins/triggers/src/runtime/project-trigger-registry.ts:6-39`, `:69-95`). Saga emissions, trigger enabled-state retirement, and Windows env-key cleanup appear only as broad roadmap phrases, not as the promised exact §10 inventory (`rfc-0001-runtime-versioned-automation.md:469-490`, `:520-525`). | +| F9 — PR-sized roadmap, gates, dependencies | FAIL | The table is improved, but A2b still combines lifecycle, two propagation modes, and fleet admission across package/plugin roots; A6 is a repository-wide package/CLI/scaffold/Windows/docs/test purge; neither is credibly PR-sized (`:517-525`). The gate mapping is incomplete: A1b/A1c omit required fitness, publishability, and consumer gates; A2b omits fitness/publishability; A6 changes scaffold output but selects only `scaffold-static`, not the mandatory release-gate class (`:503-528`; `archetype-gate-matrix.md:20-40`, `:60-76`). A0 also does not name the oRPC management contract later “hosted” by A2a (`rfc-0001-runtime-versioned-automation.md:418-420`, `:512-517`). | + +### Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | PASS | `research.md:6-13` and `evidence/current-state-matrix.md:22-26` name and rebaseline the current source baseline. I repeated focused tree searches and `deno doc` checks. Live #922 children #923–#934 and draft PR #1446 were re-inspected on 2026-08-11. | +| Decisions locked | FAIL | Ownership is simultaneously “locked,” a recommendation, and subject to a fallback (`plan.md:3-6`; RFC `:460-467`, `:594-597`). The activation-set state model and fleet-atomic behavior are also not decided sufficiently to implement. | +| Open-decision sweep | FAIL | `plan.md:77-84` declares no must-resolve decision open, but the evaluator sweep below finds decisions that change package boundaries and persisted/dispatch contracts. | +| Commit slices (< 30, gate + files each) | FAIL | The current docs-only S1–S5 list is adequate (`plan.md:86-99`), but the RFC's implementation roadmap—the plan being ratified—is not independently landable at A2b/A6 and omits a contract-owning slice (`rfc-0001-runtime-versioned-automation.md:510-528`). | +| Risk register | FAIL | It names the relevant categories, but its child-loader mitigation cites nonexistent TM9/gates (`plan.md:72`), and its partial-activation mitigation does not cover asynchronous cross-engine replicas or complete-snapshot semantics (`:65-68`). | +| Gate set selected | FAIL | §12's abbreviations are defined, but multiple package/plugin slices omit matrix-required fitness, consumer, and publishability gates; scaffold-changing A6 omits the release-gate class (`rfc-0001-runtime-versioned-automation.md:503-528`; `archetype-gate-matrix.md:20-40`, `:60-76`). | +| Deferred scope explicit | PASS | P-1–P-4 have rationale and entry criteria (`rfc-0001-runtime-versioned-automation.md:492-499`), and §15 classifies naming, two-person default, and retention (`:579-597`). | +| jsr-audit surface scan (pkg/plugin) | FAIL | Naming `P`/`jsr-audit` as a future gate is not the required pre-slice application of the rubric to the planned public surfaces. No slow-type/export/import-permission risk scan is recorded, and several public package/plugin slices omit `P` entirely (`plan-gate.md:32-34`; RFC `:503-528`). | + +### Open-decision sweep (evaluator-run) + +The following remain **must resolve now** because deferral changes package boundaries or runtime +correctness: + +1. Decide whether O2+O4 is binding or whether the fallback remains live. If binding, put + lifecycle/runtime ports and adapters in a doctrine-valid runtime/integration core and make every + §9/PR statement agree that the connector composes them only. +2. Define an epoch snapshot as the complete active desired state, including carry-forward and + disable/delete semantics, or explicitly define a deterministic merge protocol. Then close the + cross-replica task/trigger race with revision/epoch-pinned dispatch or a rollout barrier; + per-replica monotonic application is not fleet atomicity. +3. Define how fleet admission treats temporarily absent/stale registrations and schema + downgrade/rollback. “Registered live replica” admission has a time-of-check gap when an old + replica rejoins after activation. +4. Decide and slice the management oRPC contract owner before A2a, rather than having a plugin host + a contract no preceding slice creates. + +The package spelling, two-person default, retention defaults, and P-1–P-4 remain safe to defer under +the RFC's stated entry criteria once the above are resolved. + +### Verdict + +`FAIL_PLAN` + +### If FAIL_PLAN — required fixes + +1. **[BLOCKER] Make ownership genuinely singular and doctrine-valid.** Remove the live fallback or + fully choose it; move store/boundary/reload ports out of the ARCHETYPE-1 contract package, keep + store adapters and lifecycle behavior in an ARCHETYPE-2/3 core, and remove every statement + assigning those adapters to `plugins/automation`. Reconcile §5.1, §5.2, §9, §12, §15, the + plan/worklog/context pack, and PR body/comment. +2. **[BLOCKER] Close the remaining activation races.** Specify that each epoch snapshot materializes + the complete active set; define carry-forward, disable/delete, idempotent reactivation, and + rollback semantics. Add a protocol that prevents a trigger at epoch N+1 from dispatching by bare + ID to a worker at N (for example revision/content-hash-pinned messages with immutable lookup, or + a proven activation barrier). Add absent/rejoining replica admission semantics and correct + E2E-2's stale `expectedActiveRevision` to the RFC's `expectedEpoch` contract + (`rfc-0001-runtime-versioned-automation.md:264-290`, `:294-322`, `:541-543`). +3. **[BLOCKER] Actually honor C8 and remove the T1 jail overclaim.** Add a control-plane loader + threat covering consumer-controlled module execution with read/network access, lockfile and + cached-only behavior, cold-cache failure/allow policy, capability-prompt staging, and a proving + gate. Replace “env/cwd jail”/“resolution jailed” in TM1/TM2 with the actual controls. Cite + durable primary evidence; the RFC's `.llm/tmp/docs/sandbox-isolation-survey-2026-08.md` reference + (`:346`) is absent from the evaluator worktree and is not a reviewable committed/run artifact. + Official Deno documentation confirms subprocesses run independently of the parent permission + sandbox and that `--cached-only` only requires dependencies to be cached. +4. **[BLOCKER] Finish §10 as a file-level replacement inventory.** Include the plugin runtime-config + contribution axis/builder/public exports, generated trigger registry/fallback and its generation + path, workers project-file discovery/direct execution, saga sample/schema emissions, trigger KV + enabled-state port/store, all Windows/environment emitters, tests, generated docs/assets, and the + exact retained T0 job surface. Give each keep/fold/delete/rewrite disposition and one owning + slice. +5. **[BLOCKER] Re-slice and select every required gate.** Split A2b and A6 into reviewable PRs; add + the management contract to A0 or a preceding explicit slice; apply all archetype-required + fitness/publish/consumer/runtime gates to every touched public package/plugin; and assign the + full release-gate class to scaffold/DB/Aspire/published-CLI changing slices. Record the jsr-audit + rubric findings, including slow-type and public-export risks, before those slices are authorized. +6. **[HIGH] Reconcile the live review surface.** The PR body and Cycle-1 comment must not say “all + findings addressed,” “ownership locked,” “connector composition only,” or “TM1–TM9” until the RFC + says those things. Add the canonical checkable Definition of Done and Drift/Debt sections + required by `netscript-pr`, use structured phase tokens, and advance the sole `status:` label + from stale `status:research` to the actual phase when the supervisor posts the next phase + comment. Keep the PR draft and do not claim ready-for-review contrary to `plan.md:55`. + +### Notes + +- The revised RFC still correctly preserves D-10, the clean-break/no-compat direction, the frontend + dependency cut (#923–#932 plus #934, with #933 as the adjacent dogfood surface), the narrowed + development-KV posture, and the honest core statement that non-Deno T1 grants are unenforced. +- The live GitHub PR body, all three comments, labels, draft state, and #922 child issue states were + re-inspected. No GitHub mutation was performed. +- No RFC, plan, worklog, context-pack, source, or other file was edited. No commit or push was made. + This append is the only Cycle-2 filesystem mutation. +- This is the second `FAIL_PLAN`; per `plan-protocol.md:52-55` the unresolved blockers now escalate + to the owner rather than entering an automatic third fix cycle. + +PLAN-EVAL: FAIL_PLAN + +## Cycle 3 + +- Plan evaluator session: same dedicated Codex GPT-5.6 Sol · xhigh evaluator session / 2026-08-11 + (owner override D-2), Cycle 3 explicitly authorized by the owner after the two-FAIL protocol stop +- Evaluator worktree: `/home/codex/repos/ns-rfc-plan-eval`, branch + `eval/rfc-runtime-versioned-automation`, clean at `811373a8741554b096a488d15c64e5fb21864392` +- Author worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, same source commit + before this verdict append +- Surface / archetype: docs RFC planning future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, CLI, + scaffold, DB, Aspire, and frontend waves +- Scope overlays: `SCOPE-docs`; adversarial RFC architecture review; owner-directed + competitive-study review; no implementation evaluation + +### Cycle-1 and Cycle-2 finding resolution audit + +| Prior finding | Cycle-3 result | Evidence | +| -------------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cycle-1 F1 — Design checkpoint, context pack, PR review surface | PARTIAL | The required artifacts exist (`worklog.md:86-108`; `context-pack.md:1-26`) and the live PR is draft with `status:plan-eval`, DoD, and Drift/Debt. They are not current: `plan.md:3-6,83,96-97` still says Cycle 2 is pending and P-1..P-4; `context-pack.md:3,19-23` says post-Cycle-1/two-FAIL escalation pending; the Design checkpoint omits P-5/S6 (`worklog.md:95-105`); the PR body omits S6/D-8/P-5/BG-1..BG-5 and still presents the owner escalation as current. | +| Cycle-1 F2 — binding ownership decision | PASS | §9 now says O2+O4 is binding with no live fallback and evaluates the withdrawn fallback at equal fidelity (`rfc-0001-runtime-versioned-automation.md:474-521`). | +| Cycle-1 F3 — doctrine-valid ownership / plugin thinness | PASS | Contracts contain no ports/adapters (`:193-197`, `:491-494`); runtime behavior, ports, and adapters are core-owned (`:495-500`); the connector is composition-only and names each wired axis (`:501-507`). | +| Cycle-1 F4 / Cycle-2 F2 — complete activation state, pinned dispatch, rejoin admission | PARTIAL | Complete desired-state epochs, carry-forward/tombstones, monotonic application, revision-pinned dispatch, and leased rejoin validation are now real text (`:267-280`, `:302-343`). The corrected protocol introduces an unresolved control-plane-outage failure described in finding 1 below. | +| Cycle-1 F5 — honest T1 contract | PASS | J2, the tier table, the blunt perimeter statement, TM1/TM2, and E2E-5 consistently state that non-Deno T1 grants are not enforced and T1 is not a tenancy boundary (`:61-66`, `:350-378`, `:403-406`, `:640-643`). | +| Cycle-1 F6 / Cycle-2 F3 — C8/TM9 and bounded security guarantees | PARTIAL | TM9 now covers the #1444 loader, warm-cache `--cached-only`, explicit cold-cache network use, loud failure, capability-prompt staging, and A2a's offline gate (`:413`, `:594`). Trust assumptions correctly narrow hashes, audit, and redaction (`:415-424`), but §5.5 retains an absolute secret-history claim contradicted by that residual-risk text (finding 2). | +| Cycle-1 F7 — evidence claim strength | PASS | Claims remain scoped to the inspected commits; partial control-plane surfaces and #1444's draft state are explicit; Appendix A still limits direct adapter proof to Deno+shell (`:15-28`, `:96-113`, `:759-776`). Focused `rtk grep` and `deno doc` checks reconfirmed the disconnected loader and the `RuntimeTask`/executor-contract mismatch. | +| Cycle-1 F8 / Cycle-2 F4 — file-level clean-break inventory | PARTIAL | §10 now has a useful file-level table and resolves most named surfaces (`:542-564`), but it is not the complete file-level inventory it claims; concrete survivors are omitted (finding 3). | +| Cycle-1 F9 / Cycle-2 F5 — PR-sized roadmap, dependencies, gates, JSR scan | PARTIAL | A0 owns the contract; A2d and A6a-c are split; corrected dependency edges and a real JSR pre-scan exist (`:588-623`). Required fitness/publish/release gates are still omitted from multiple rows despite the RFC's opposite assertion (finding 4). | +| Cycle-2 F6 — live PR reconciliation | PARTIAL | The PR is draft, its sole status label is `status:plan-eval`, and DoD/Drift/Debt exist. The body was reconciled to `af4f20f1e` but not to the Cycle-3 head/study, and its S5 state is stale (finding 6). | + +### Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | FAIL | The repository archaeology is present, scoped, and re-baselined (`research.md:6-13`; current matrix `:22-26`). The newly required competitive research is materially incomplete against its claimed 12 owner-named dimensions and contains unsupported/exhaustive claims (finding 5; competitive study `:123-141,145-200`). | +| Decisions locked | FAIL | Ownership, cron, T1, store parity, epoch totals, and schema admission are locked. Control-plane outage behavior is not: lease expiry drains serving replicas while pinned-revision fetch failure immediately dead-letters work (`rfc-0001-runtime-versioned-automation.md:331-343`), with no availability/retry decision. | +| Open-decision sweep | FAIL | `plan.md:77-84` and RFC §15 do not identify the outage/lease/pinned-lookup decision, although choosing fail-closed fleet drain versus last-good availability changes core runtime behavior and tests. | +| Commit slices (< 30, gate + files each) | FAIL | There are fewer than 30 ordered implementation slices with file groups, but several lack their required proving gate classes and the docs-run slice inventory omits S6/Cycle 3 (`rfc-0001-runtime-versioned-automation.md:588-608`; `plan.md:86-99`). | +| Risk register | FAIL | The register covers prior race/security categories but not management/feed outage causing lease-expiry fleet drain or transient immutable-revision lookup causing DLQ (`plan.md:58-75`; RFC `:331-343`). | +| Gate set selected | FAIL | Rows touching public packages/plugins omit `F` and/or `P`, and rows changing DB/Aspire/published CLI shape omit the orthogonal release class (`rfc-0001-runtime-versioned-automation.md:591-608`; `archetype-gate-matrix.md:20-40,60-76`). | +| Deferred scope explicit | PASS | P-1..P-5 have rationale and entry criteria (`rfc-0001-runtime-versioned-automation.md:569-577`), and the remaining naming/policy/default questions are classified with entry criteria (`:728-746`). | +| jsr-audit surface scan (pkg/plugin) | PASS | The pre-scan names Zod/isolated-declaration slow types, explicit oRPC route types, driver-type leakage, and connector re-export risks and assigns them to A0/A1a/connector work (`rfc-0001-runtime-versioned-automation.md:611-619`). This does not cure the missing `P` gates in the slice table. | + +### Open-decision sweep (evaluator-run) + +One must-resolve-now decision remains: define the execution-plane availability contract when the +management service/store is unreachable. The present combination self-drains replicas after a +registration lease lapses and immediately dead-letters a revision-pinned dispatch when its immutable +lookup cannot be fetched (`rfc-0001-runtime-versioned-automation.md:331-343`). The plan must choose +and specify bounded last-good serving versus fail-closed drain, lease-renewal grace/fencing +behavior, and retryable-unavailable versus terminal-not-found/hash-mismatch lookup outcomes. This +changes the runtime state machine, queue semantics, SLOs, and tests, so it is not safe to defer +implicitly. + +All owner questions explicitly listed in §15 remain safe to defer under their entry criteria. P-1 +through P-5 remain staged scope, not hidden implementation decisions. + +### Verdict + +`FAIL_PLAN` + +### If FAIL_PLAN — required fixes + +1. **[BLOCKER] Decide the control-plane-outage and pinned-lookup failure protocol.** A + management/feed outage eventually expires every lease, after which replicas “must re-register ... + before serving”; independently, any inability to fetch a pinned revision is sent directly to DLQ + (`rfc-0001-runtime-versioned-automation.md:331-343`). Distinguish transient unavailable/timeouts + from terminal absent/hash/schema failures, define queue retry/backoff and immutable-revision + caching, and decide whether a replica with a valid last-good snapshot may serve during a bounded + control-plane outage or must self-drain. Add the risk, SLO, and failure tests to A1c/A2d/A3a/A8. + +2. **[BLOCKER] Remove the remaining absolute secret-history guarantee.** §5.5 says secret material + “never enters ... history records” (`rfc-0001-runtime-versioned-automation.md:387-397`), while + the threat-model trust statement correctly admits a child can transform and print a secret past + best-effort redaction (`:415-421`). Make §5.5 use the same bounded guarantee: secrets are not + deliberately persisted as definition/audit fields, captured output is best-effort redacted, and + residual disclosure remains possible. + +3. **[BLOCKER] Complete the cleanup table against the actual tree.** The generic enabled-state row + (`rfc-0001-runtime-versioned-automation.md:557-558`) does not disposition the + port/store/testing/public exports and service/runtime consumers under + `packages/plugin-triggers-core/src/{ports,stores,testing,public}/**` and + `plugins/triggers/{services,src/runtime}/**`. The Windows/environment row (`:559-560`) omits + `packages/cli/src/kernel/adapters/windows/environment/env-file-content.ts`, `env-file-values.ts`, + `kernel/assets/windows/env.template`, the generated embedded asset, and the live + `NETSCRIPT_TASKS_DIR` readers in + `packages/plugin-workers-core/src/executor/adapters/path-resolution.ts` and + `plugins/workers/worker/job-execution.ts`. Name each file group with keep/fold/delete/rewrite and + an owning slice; otherwise D-5 still allows competing runtime-config behavior to survive. + +4. **[BLOCKER] Apply the gate matrix to every roadmap row, not only in prose.** The RFC asserts + every package/plugin slice carries `P` (`rfc-0001-runtime-versioned-automation.md:611-619`), but + A2d, A2c, A3a/b, A4a/b, and A5a/b omit it; A2d and several later core/plugin rows also omit + required `F` (`:596-603`). A1a changes DB wiring, A2a declares Aspire resources/migrations, and + A2c changes the published CLI, yet none names the orthogonal release-gate class required by + `archetype-gate-matrix.md:67-76`. Add `S/F/R/C/P` as applicable to every row and the release + class wherever DB/Aspire/scaffold/published CLI/plugin shape changes; then make the prose and + table agree. + +5. **[BLOCKER] Make the competitive study satisfy the owner-directed dimensions and evidence + standard.** The study says it compares twelve named dimensions + (`competitive-architecture-study.md:9-12,123-141`), but its matrix replaces the required + isolation, control/data-plane, and cockpit-UX rows with four separate versioning rows; several + per-system profiles likewise do not cover the missing dimensions. It also uses a Hacker News post + and n8n community guidance despite describing the study as primary-source-based + (`:3-7,67-74,109-121,218-226`), and elevates unproven exhaustive negatives such as “none of the + nine uses watched files” and “uniform across all nine” (`:155-160`; RFC `:698-700`). Add the + three missing comparison dimensions, cite official product docs/repositories for load-bearing + cells (or mark unknown), and narrow exhaustive conclusions to what the sources establish. Finally + remove or gate the RFC's remaining empirical technology assertion “sub-ms start” + (`rfc-0001-runtime-versioned-automation.md:365`), which contradicts “performance enters this RFC + only as gates” (`:652-657`) and the no-empirical-claims statement (`:721-723`). + +6. **[HIGH] Reconcile all resumability/review artifacts to Cycle 3.** Update `plan.md:3-15,77-99`, + `worklog.md:95-105`, and `context-pack.md:3,19-24` so they name P-5, S6, the owner-authorized + Cycle 3, the current archetypes, and the current slice/gate state. Reconcile the live PR body + likewise: add S6/D-8 and the benchmark/P-5 scope, replace the stale “owner escalation” S5 text + with Cycle-3 state, and mark completed DoD boxes accurately. Keep the PR draft and the sole + `status:plan-eval` label. + +### Notes + +- The corrected `af4f20f1e` changes are present in the actual file; this evaluation does not rely on + the Cycle-2 fix narrative. Ownership/thinness, complete desired-state epochs, revision-pinned + dispatch, leased rejoin validation, TM9/C8, `expectedEpoch`, honest T1 wording, A0 contract + ownership, and A6 splitting were all verified directly. +- The D-10 differentiator, D-4 clean-sheet authority, D-5 no-compat direction, and D-3 frontend + dependency cut remain intact. No hardcoded plugin names were introduced in the proposed + contribution model. +- Primary-source spot checks confirmed the Temporal pinning, Restate immutable-deployment, Hatchet + Postgres, Trigger.dev atomic-deploy, Durable Functions versioning, AWS Step Functions + weighted-alias, Kestra revision/plugin-version, Windmill draft/deploy, and Inngest self-host + claims. The problem is the study's missing dimensions and claims stronger than those sources, not + that every cited comparison is wrong. +- The live PR body, all five comments, labels, milestone assignment, draft state, and head SHA were + re-inspected. No GitHub mutation was performed. +- No RFC, plan, worklog, context-pack, source, issue, comment, label, commit, or branch was changed. + This Cycle-3 append is the only filesystem mutation. + +PLAN-EVAL: FAIL_PLAN + +## Cycle 4 + +- Plan evaluator session: same dedicated Codex GPT-5.6 Sol · xhigh evaluator session / 2026-08-11 + (owner override D-2), Cycle 4 explicitly authorized by the owner +- Evaluator worktree: `/home/codex/repos/ns-rfc-plan-eval`, branch + `eval/rfc-runtime-versioned-automation`, clean at `774f3ee194a854b24576b3e47a304ff979d64ae9` +- Author worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, same source commit + before this verdict append +- Surface / archetype: docs RFC planning future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, CLI, + scaffold, DB, Aspire, and frontend waves +- Scope overlays: `SCOPE-docs`; adversarial RFC architecture and competitive-evidence review; no + implementation evaluation + +### Prior-finding resolution audit + +| Prior finding | Cycle-4 result | Evidence | +| --------------------------------------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Cycle-1 F1 / Cycle-3 F6 — Design checkpoint and current review artifacts | PARTIAL | The artifacts and live PR exist, and PR #1446 is draft at the evaluated head with one `status:plan-eval` label, a milestone, DoD, and Drift/Debt. They are not current: the plan profile still names the superseded existing-package archetypes rather than the selected automation-core/runtime/connector archetypes (`plan.md:15-20`); the context pack says P-1..P-4 and that Cycle 4 was not ordered (`context-pack.md:14-29`); the phase registry says G6 is done after three cycles (`phase-registry.md:13`); and the live PR checks S5 complete while describing Cycle 4 only as a future request. | +| Cycle-1 F2/F3 — binding ownership and doctrine-valid thinness | PASS | O2+O4 is expressly binding with no live fallback; ARCHETYPE-1 is contracts/data only, ARCHETYPE-2/3 owns behavior/ports/adapters, and the ARCHETYPE-5 connector owns composition only (`rfc-0001-runtime-versioned-automation.md:508-541`). | +| Cycle-1 F4 / Cycle-2 F2 / Cycle-3 F1 — activation consistency and outage protocol | PARTIAL | Complete desired-state epochs, carry-forward/tombstones, monotonic swaps, revision-pinned dispatch, cache behavior, transient/terminal failure classes, and leased rejoin validation are present (`:267-280`, `:302-348`). The outage contract is still internally inconsistent and its promised end-to-end proof is absent (finding 1). | +| Cycle-1 F5 — honest T1 contract | PASS | The runtime table, blunt perimeter statement, TM1/TM2, and acceptance test consistently say native-runtime grants are not enforced at T1 and T1 is not a tenancy boundary (`:373-395`, `:423-444`, `:663-666`). | +| Cycle-1 F6 / Cycle-2 F3 / Cycle-3 F2 — C8/TM9 and bounded security claims | PASS | §5.5 now distinguishes deliberate persistence from best-effort captured-output redaction (`:404-417`), matching the threat-model residual-risk statement (`:435-444`). TM9 still pins warm-cache offline loading and loud cold-cache behavior to A2a (`:433`). | +| Cycle-1 F7 — evidence claim strength | PASS | Repository claims remain scoped to inspected commits and status tags; Appendix A still limits execution proof to Deno+shell. Focused tree searches reconfirmed the loader/discovery and cleanup surfaces rather than relying on the fix narrative. | +| Cycle-1 F8 / Cycle-2 F4 / Cycle-3 F3 — complete clean-break inventory | PARTIAL | The requested trigger-enabled, Windows-environment, and `NETSCRIPT_TASKS_DIR` groups are now named (`:562-586`), but additional live runtime-config CLI/deploy plumbing remains undispositioned (finding 2). | +| Cycle-1 F9 / Cycle-2 F5 / Cycle-3 F4 — roadmap gates and sizing | PARTIAL | A2d/A6a-c, file groups, release classes, dependency edges, and the JSR pre-scan are present (`:602-646`), but the table still omits matrix-required gate families for several package/plugin slices (finding 3). | +| Cycle-3 F5 — competitive study integrity | PARTIAL | The missing isolation/control-plane/cockpit rows were added, exhaustive negatives were narrowed, the lighter-source rule is stated, and the T3 empirical number is gone. The expanded study now contradicts its own dimension count and primary-source/citation guarantee, and one new isolation cell is materially weaker than official documentation (finding 4). | + +### Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | FAIL | Repository research is present and exactly re-baselined to current `origin/main` (`research.md:6-13`; verified base and merge-base `2256a67bf`). The competitive research overstates its citation coverage and mislabels a 15-row matrix as 12 dimensions (`competitive-architecture-study.md:3-7,123-144`; finding 4). | +| Decisions locked | FAIL | Ownership, store parity, activation totals, cron, and T1 are locked. “Bounded last-good serving” and “never self-drain” specify different stale-serving contracts, and the text supplies no bound or expiry action (`rfc-0001-runtime-versioned-automation.md:349-360`; finding 1). | +| Open-decision sweep | FAIL | The plan declares the outage question resolved as bounded serving (`plan.md:83-93`), while the RFC specifies indefinite serving with alerts. Choosing a stale-serving bound versus no bound changes runtime state, SLOs, and tests and is therefore not safe to leave contradictory. | +| Commit slices (< 30, gate + files each) | FAIL | The slice count and ordering are acceptable, but required consumer/publish proof is missing from implementation rows (finding 3), the promised outage E2E is absent (finding 1), and the docs S6 fmt gate claimed at `plan.md:109-111` is not green: focused `deno fmt --check` exits 1 for the study plus plan/worklog/context pack. | +| Risk register | FAIL | The outage row exists (`plan.md:81`) but repeats the contradictory contract and assigns A8 outage tests that neither A8 nor §13 names (`rfc-0001-runtime-versioned-automation.md:631,648-673`). | +| Gate set selected | FAIL | Consumer validation is required for ARCHETYPE-2/3/5 and publish validation for touched public packages/plugins (`archetype-gate-matrix.md:60-76`), yet §12 omits `C` from A1a/A1b/A1c/A3a/A4a/A5a and omits `P` from the package/plugin/scaffold-changing A6b (`rfc-0001-runtime-versioned-automation.md:614-628`). | +| Deferred scope explicit | PASS | P-1..P-5 have rationales and entry criteria (`:592-600`); naming, two-person policy, and retention defaults have explicit safe-deferral criteria (`:752-770`). | +| jsr-audit surface scan (pkg/plugin) | PASS | The pre-scan names Zod slow types, isolated declarations, explicit oRPC route types, driver-type leakage, and connector re-export risks with owning slices (`:634-642`). | + +### Open-decision sweep (evaluator-run) + +One implementation-shaping decision remains contradictory: whether a previously admitted replica +serves last-good indefinitely during a control-plane outage or stops serving after a defined bound. +The RFC says both “bounded” and “never self-drain,” then describes only indefinite serving plus a +staleness alert (`rfc-0001-runtime-versioned-automation.md:349-360`). The operator-configured bound, +expiry behavior, and cold-start/no-valid-registration behavior must be explicit if serving is truly +bounded; otherwise the plan and RFC must consistently call the chosen contract unbounded last-good +availability. The chosen behavior needs the promised failure test in A8/§13. + +The §15 owner questions and P-1..P-5 remain safe to defer under their stated entry criteria. + +### Verdict + +`FAIL_PLAN` + +### If FAIL_PLAN — required fixes + +1. **[BLOCKER] Make the outage availability contract singular and prove it end to end.** §5.3 calls + serving “bounded” while requiring replicas never to self-drain and defining no maximum or expiry + transition (`rfc-0001-runtime-versioned-automation.md:349-360`). Choose an actual bound and its + post-bound behavior, or explicitly choose indefinite last-good serving and remove every “bounded” + claim from the RFC, plan, risk row, and PR. Specify cold-start/no-current-registration behavior. + Add the promised management/feed/store-outage scenario—cached revision succeeds, unseen revision + retries then exhausts, reconnect validates/converges—to §13 and A8; today §13 has no outage case + and A8 merely references §13/BG-1 (`:648-673`, `:631`). + +2. **[BLOCKER] Finish the file-level D-5 cleanup inventory, including live CLI and deploy + consumers.** The table removes the store/override directory and Windows writer but omits the + dependency composition that imports/constructs/exports `runtimeConfigStore` + (`packages/cli/src/public/features/root/public-command-dependencies.ts:14-15,87-88,198,260`) and + the public deploy flags/options `--force-runtime-config`, `--fail-on-drift`, `--keep-runtime`, + `forceRuntimeConfig`, plus the runtime-path merge loop + (`packages/cli/src/public/features/deploy/build/build-deploy-command.ts:39-47,61`, + `build-windows-options.ts:1-15`, `build-deploy.ts:23-24`, `build-windows-runtime.ts:82-116`). Add + explicit delete/rewrite dispositions and owning A6 slices for that complete option/DI/merge + surface; otherwise legacy runtime-config controls and compile dependencies survive the claimed + clean break (`rfc-0001-runtime-versioned-automation.md:568-586`). + +3. **[BLOCKER] Apply the selected gate matrix to the table rather than declaring it complete in + prose.** Add required consumer gates to the public ARCHETYPE-2/3/5 slices + A1a/A1b/A1c/A3a/A4a/A5a, and publishability to A6b because it rewrites published CLI/plugin + composition and scaffold output (`rfc-0001-runtime-versioned-automation.md:614-628`; + `archetype-gate-matrix.md:60-76`). Recheck every row by its actual touched archetype and keep + release-class overlays orthogonal. This is the same Cycle-3 gate finding, not genuinely resolved. + +4. **[BLOCKER] Repair the competitive study's evidence contract.** The heading still says “12 + dimensions” although the matrix contains 15 dimension rows after adding isolation, + control/data-plane, and cockpit UX (`competitive-architecture-study.md:123-144`); RFC §14.1 and + the live PR repeat twelve. More importantly, the study promises that every load-bearing cell is + vendor-cited or marked partial/unknown (`:3-7`), but the three added rows contain uncited + absolute cells. For example, Windmill is reduced to “deployment-level isolation” (`:142`) even + though its official security documentation describes configurable per-job PID-namespace and + NSJAIL isolation, with important default/host distinctions + (https://www.windmill.dev/docs/advanced/security_isolation). Cite official sources for every new + load-bearing cell and encode configuration/default nuance or mark the cell unknown/partial. Then + correct the dimension count everywhere. The narrowed negative claims and no-empirical-performance + rule may remain. + +5. **[HIGH] Reconcile and format the complete review surface after the authorized Cycle 4.** Update + the selected archetypes and evaluation state in `plan.md:3-20,95-113`, P-5/Cycle-4 state in + `context-pack.md:3,14-29`, G6 in `phase-registry.md:13`, the stale hold text in + `worklog.md:177-198`, and PR #1446's checked S5/current-state wording. The PR's head SHA, draft + state, labels, milestone, DoD, and Drift/Debt structure are otherwise correct. Run the claimed + focused fmt gate: `docs:links` passes, but `deno fmt --check` currently fails on `plan.md`, + `worklog.md`, `context-pack.md`, and `competitive-architecture-study.md`, contradicting + `plan.md:109-111` and `worklog.md:175,198`. + +### Notes + +- The actual `3c918a64e` text—not its close-out narrative—was evaluated. Secret wording, TM9/C8, + complete activation snapshots, pinned dispatch classifications, leased rejoin validation, + requested trigger/Windows/task-dir inventory additions, release-class additions, and the three new + study dimensions were all verified directly. +- D-10 runtime-versioned differentiation, D-4 clean-sheet authority, D-5 no-compat direction, D-3 + frontend dependency cut, contract-first ownership, plugin thinness, and the prohibition on + hardcoded plugin names remain intact. +- `docs:links` passed with zero broken links/anchors/orphans. Focused formatting failed as reported; + no formatter was run in write mode. The evaluator worktree remained clean. +- Live PR #1446 was re-inspected read-only at head `774f3ee19`: open, mergeable, draft, sole + `status:plan-eval`, milestone assigned, six comments, and no GitHub mutation performed. +- No RFC, plan, worklog, context pack, source, issue, comment, label, commit, or branch was changed. + This Cycle-4 append is the only filesystem mutation. + +PLAN-EVAL: FAIL_PLAN + +## Cycle 5 + +- Plan evaluator session: same dedicated Codex GPT-5.6 Sol · xhigh evaluator session / 2026-08-11 + (owner override D-2), Cycle 5 explicitly ordered by the owner as the deciding pass +- Evaluator worktree: `/home/codex/repos/ns-rfc-plan-eval`, branch + `eval/rfc-runtime-versioned-automation`, clean at `cd3fd1e583fdb8d7755897ef878608e2185a676b` +- Author worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, same source commit + before this verdict append +- Surface / archetype: docs RFC planning future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, CLI, + scaffold, DB, Aspire, and frontend waves +- Scope overlays: `SCOPE-docs`; adversarial RFC architecture and competitive-evidence review; no + implementation evaluation + +### Cycle-4 finding resolution audit + +| Cycle-4 finding | Cycle-5 result | Evidence | +| ----------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| F1 — singular outage availability contract + A8 proof | PARTIAL | §5.3 step 8 now clearly chooses indefinite last-good serving, says the staleness SLO bounds silence rather than serving, defines idle-and-loud empty cold start, and §13 test 8 exercises outage/retry/rejoin (`rfc-0001-runtime-versioned-automation.md:349-365,678-683`). The preceding leased-registration rule still mandates the opposite serving transition on lease lapse (`:344-348`), so the state machine is not singular (finding 1). | +| F2 — complete CLI/deploy clean-break inventory | PASS | §10 now dispositions the CLI DI construction/export and the public deploy flags/options/runtime-path merge loop with owning A6a/A6b slices (`:571-593`). Focused tree searches reconfirmed those are the live composition and deploy surfaces. | +| F3 — full gate families | PASS | Required `C` is present on A1a/A1b/A1c/A3a/A4a/A5a and `P` is present on A6b; public package/plugin rows now carry the selected S/F/R/C/P families as applicable, with orthogonal release classes on DB/Aspire/published-CLI/scaffold surfaces (`:609-639`; `archetype-gate-matrix.md:60-76`). | +| F4 — competitive-study count and evidence contract | PASS | The study explains twelve owner dimensions rendered as fifteen rows, strengthens the legend, gives Windmill's official isolation source and caveats, and marks unassessed dedicated-security/UX cells partial (`competitive-architecture-study.md:124-150`). RFC §14.1 uses the same count model (`rfc-0001-runtime-versioned-automation.md:719-727`). No empirical performance number was reintroduced. | +| F5 — current review surface + formatting | PARTIAL | The plan profile, risk, phase registry, and current worklog entry reflect Cycle 5 (`plan.md:3-23,66-96`; `phase-registry.md:13`; `worklog.md:196-214`), and focused fmt plus `docs:links` are green. The context pack and live PR remain materially stale (finding 2). | + +### Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | PASS | `research.md:6-13` re-baselines exactly to `origin/main`; HEAD's merge-base and current `origin/main` are both `2256a67bf`. Focused `rtk grep` and `deno doc packages/runtime-config/mod.ts` reconfirmed that loader/watcher exports exist without a production consumer and that the distinct runtime task model remains in the current tree. The corrected competitive study is bounded and sourced (`competitive-architecture-study.md:3-12,124-150,231-239`). | +| Decisions locked | FAIL | Ownership, activation totals, store parity, T1, cron, and outage duration are stated with rationale. Lease lapse still has two incompatible serving transitions: step 7 requires re-registration/current-snapshot validation before serving, while step 8 says an expired lease never removes the right to serve and even permits persisted last-good cold start during control-plane outage (`rfc-0001-runtime-versioned-automation.md:344-360`). | +| Open-decision sweep | FAIL | `plan.md:86-96` calls the outage contract resolved, but it does not resolve which rule wins for (a) a continuously running replica whose lease expires or (b) a restarted replica with persisted last-good state while the control plane is unavailable. That choice changes admission/serving state and tests, so it is not safe to leave implicit. | +| Commit slices (< 30, gate + files each) | FAIL | The implementation roadmap is ordered, below 30, PR-sized, and names file groups and proving gates (`rfc-0001-runtime-versioned-automation.md:609-639`). The docs-run S4 gate includes PR-body reconciliation and is marked done (`plan.md:107-108`), but the live body is still at Cycle 3/future-Cycle-4 state; the Design checkpoint also says S1-S5 while the plan has S1-S6 (`worklog.md:103-105`; finding 2). | +| Risk register | FAIL | Risks and mitigations are comprehensive, but the outage mitigation calls the contract singular without addressing step 7's contradictory lease-lapse serving transition (`plan.md:66-84`; RFC `:344-360`). | +| Gate set selected | PASS | §12 defines S/F/R/C/P, applies the archetype matrix to every future package/plugin slice, preserves the frontend overlay, and adds the required release classes (`rfc-0001-runtime-versioned-automation.md:609-639`). | +| Deferred scope explicit | PASS | P-1..P-5 have rationales and entry criteria (`:599-607`); naming, two-person policy, and retention defaults remain explicitly classified with entry criteria (`:766-784`). | +| jsr-audit surface scan (pkg/plugin) | PASS | The pre-scan names Zod slow types, isolated declarations, explicit oRPC route types, driver-type leakage, and connector re-export risks and assigns them to slices before implementation (`:641-649`). | + +### Open-decision sweep (evaluator-run) + +One must-resolve-now state transition remains. Section 5.3 step 7 says any replica whose lease +lapsed must re-register and validate the current snapshot **before serving** and otherwise stays +drained (`rfc-0001-runtime-versioned-automation.md:344-348`). Step 8 says lease expiry governs only +new-epoch admission, never the right to serve, and allows a persisted last-good cold start to serve +during a control-plane outage (`:349-360`). The RFC must distinguish continuously serving, +restarting/rejoining, and empty cold-start cases and state whether “validation” during an outage is +local hash/schema validation or control-plane-currentness validation. This changes the runtime state +machine and cannot be delegated to implementation. + +All §15 owner questions and P-1..P-5 remain safe to defer under their recorded entry criteria. + +### Verdict + +`FAIL_PLAN` + +### If FAIL_PLAN — required fixes + +1. **[BLOCKER] Reconcile §5.3 step 7 with the selected indefinite-serving contract.** The actual + text still says a lapsed-lease replica must re-register and validate the current snapshot before + serving and stays drained on failure (`rfc-0001-runtime-versioned-automation.md:344-348`), + directly contradicting step 8's “expired lease forbids only accepting new epochs” and + never-self-drain rule (`:349-360`). Define separately: (a) an already-serving replica whose lease + expires, (b) a restarted/rejoining replica with persisted last-good state, and (c) a cold replica + with no snapshot. State whether persisted-state validation is local hash/schema validation or + requires control-plane currentness. Make step 7, step 8, the risk/open-decision text, and §13 + test 8 use that one transition model; explicitly test lease expiry while serving and restart with + persisted last-good state. + +2. **[HIGH] Finish the claimed Cycle-5 review-surface reconciliation.** The context pack still opens + “post PLAN-EVAL cycle 1 fix” and says the deliverable has only P-1..P-4 + (`context-pack.md:3,14-19`), while its later paragraph says Cycle 5. The Design checkpoint still + says constants/commit slices S1-S5 (`worklog.md:103-105`) despite plan S6. More importantly, live + PR #1446 at head `cd3fd1e58` still checks S5 complete at Cycle 3, says Cycle 4 is only a future + request, and its DoD references only Cycles 1-3/ordering Cycle 4. Update those current-state + fields through Cycle 5 and accurately check completed DoD items. Keep the PR draft and sole + `status:plan-eval`; no label/state change is requested here. + +### Notes + +- The actual `cd3fd1e58` files—not the fix summary—were evaluated. Cleanup rows, gate letters, + competitive-study qualifications, selected archetypes, outage acceptance test, and formatting + fixes were all verified directly. +- D-10 runtime-versioned differentiation, D-4 clean-sheet authority, D-5 no-compat direction, D-3 + frontend dependency cut, contract-first ownership, plugin thinness, honest T1 boundaries, bounded + secret claims, and TM9/C8 remain intact. +- `docs:links` passed with zero broken links/anchors/orphans; `deno fmt --check` passed on the RFC, + plan, worklog, context pack, phase registry, and competitive study; `git diff --check` passed. +- Live PR #1446 was re-inspected read-only at head `cd3fd1e58`: open, mergeable, draft, sole + `status:plan-eval`, milestone assigned, six comments. Its state/body discrepancy is finding 2. +- No RFC, plan, worklog, context pack, source, issue, comment, label, commit, or branch was changed. + This Cycle-5 append is the only filesystem mutation. + +PLAN-EVAL: FAIL_PLAN + +## Cycle 6 + +- Plan evaluator session: same dedicated Codex GPT-5.6 Sol · xhigh evaluator session / 2026-08-11 + (owner override D-2), Cycle 6 explicitly ordered by the owner as the deciding pass on the + D-9-amended head +- Evaluator worktree: `/home/codex/repos/ns-rfc-plan-eval`, branch + `eval/rfc-runtime-versioned-automation`, clean at `2518791f3fa65de4bbcfe440998cf9b68c48544a` +- Author worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, same source commit + before this verdict append +- Surface / archetype: docs RFC planning future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, CLI, + scaffold, DB, Aspire, production-console, and staged DevTools work +- Scope overlays: `SCOPE-docs`; full adversarial plan gate, Cycle-5 resolution audit, and D-9 + amendment review; no implementation evaluation + +### Cycle-5 finding resolution audit + +| Cycle-5 finding | Cycle-6 result | Evidence | +| --------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| F1 — one lease/serving transition model | PASS | §5.3 now makes local hash/schema-major validation the sole serving precondition and control-plane currentness only a convergence precondition. It explicitly covers lease expiry while serving, persisted-last-good restart without control-plane contact, and empty/corrupt cold start; §13 test 8 exercises all three (`rfc-0001-runtime-versioned-automation.md:344-373,700-718`). | +| F2 — current review surfaces | PARTIAL | The context pack and live PR body now carry Cycle 5/D-9 and the PR is at the evaluated head. The Design checkpoint still says P-1..P-5 and S1-S5 while naming S1-S6 elsewhere, the locked plan sweep still stops at P-5, and the phase registry still calls Cycle 5 the deciding future pass (`worklog.md:95-107`; `plan.md:3-12,89-99,112-118`; `phase-registry.md:13`; finding 1). | + +### D-9 amendment audit + +| Required relationship | Result | Evidence | +| -------------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Two operator surfaces, with #890/#922 sufficient only for production/admin | PASS | §8.2 distinguishes the userland-app production/admin console from a separate DevTools family/host and narrows the #922 minimum cut to surface 1 (`rfc-0001-runtime-versioned-automation.md:489-523`). | +| DevTools staged rather than silently designed here | PASS | P-6 requires a dedicated DevTools RFC, treats #400/#685/#780/#506 as evidence rather than ratified architecture, names consumed stable contracts, and has an implementation-dependent entry criterion (`:514-523,629-638`). | +| Roadmap consistency | PASS | A7 contains list/detail/run/history and lifecycle flows only, explicitly excludes diagnostics/journey views, and carries the #922/#934 dependency cut; P-1..P-6 is a separate staged row (`:649-670`). Backend slices A0-A6 remain frontend-independent (`:525-527,640-670`). | +| General frontend contribution mechanisms not pre-empted | PASS | §8.2 enumerates the five candidate surfaces, says this RFC designs none of their general mechanisms, consumes only the ratified app family, and stages DevTools (`:496-501`). | +| Cross-artifact lock record | FAIL | The hard constraint is updated for D-9, but the formal plan sweep and Design checkpoint omit P-6 and the phase registry is stale (`plan.md:59-65,89-99`; `worklog.md:95-107`; `phase-registry.md:13`). | + +### Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | PASS | `research.md:6-13` still re-baselines to `origin/main`; HEAD's merge-base and current `origin/main` both resolve to `2256a67bf`. Fresh `deno doc packages/runtime-config/mod.ts` plus focused production-use searches reconfirmed the exported loader/watcher, fail-empty behavior, distinct `RuntimeTask` model, and lack of a production consumer. Competitive claims remain qualified and primary-source bounded. | +| Decisions locked | PASS | Ownership, complete activation epochs, revision-pinned dispatch, lease/serving transitions, store parity, T1 limits, cron ownership, and the two-frontend boundary are now unambiguous in the RFC (`rfc-0001-runtime-versioned-automation.md:196-378,489-565`). | +| Open-decision sweep | FAIL | The locked plan explicitly says only P-1..P-5 are deferred, despite new P-6 being a staged decision. P-6 is substantively classified in RFC §11, but it is absent from the artifact the plan-gate designates as the complete sweep (`plan.md:89-99`; RFC `:629-638`). | +| Commit slices (< 30, gate + files each) | FAIL | The RFC's A0-A8 roadmap remains PR-sized, ordered, file-scoped, and gated (`rfc-0001-runtime-versioned-automation.md:640-670`). The docs-run Design checkpoint still says “Commit slices — S1-S5” while the locked plan and constants contain S1-S6, so its claimed reconciliation is false (`worklog.md:103-107`; `plan.md:101-118`). | +| Risk register | PASS | The expanded register covers evidence drift, partial activation, feed/poll ordering, schema skew, store divergence, T1, integrity, secrets, loader policy, cron duplication, outage serving, and frontend dependency sequencing with owners/mitigations (`plan.md:69-87`). D-9's DevTools boundary is also a hard constraint (`:59-65`). | +| Gate set selected | PASS | §12 defines and applies S/F/R/C/P, frontend dependency, and release classes to the future package/plugin slices (`rfc-0001-runtime-versioned-automation.md:640-670`). | +| Deferred scope explicit | PASS | P-1..P-6 each have rationale and entry criteria in §11; §15 separately classifies the only spelling/policy/default questions (`:629-638,802-822`). | +| jsr-audit surface scan (pkg/plugin) | PASS | The pre-scan continues to cover Zod slow types, isolated declarations, explicit oRPC route types, driver leakage, connector thinness, and publish gates before implementation (`:672-680`). | + +### Open-decision sweep (evaluator-run) + +No unresolved runtime architecture decision remains. The Cycle-5 serving-state blocker is genuinely +closed, and D-9 makes the production-console/DevTools ownership boundary a decided split. P-6 is a +safe staged prerequisite because its rationale, consumed contracts, and entry criterion are explicit +in RFC §11. The failure is record integrity: the locked plan's mandatory sweep still claims the +staged set is P-1..P-5, so it is not a complete sweep of the amended plan. + +### Verdict + +`FAIL_PLAN` + +### If FAIL_PLAN — required fixes + +1. **[BLOCKER] Reconcile the formal plan record with D-9/P-6 and the actual slice set.** Change the + locked plan's open-decision sweep from P-1..P-5 to P-1..P-6 and record P-6's safe-deferral + rationale/entry criterion; bring the plan status and G6 phase-registry state through Cycle 6; + change the Design checkpoint's domain vocabulary to P-1..P-6 and “Commit slices — S1-S6.” These + are not optional progress prose: the open-decision sweep and Design checkpoint are plan-gate + inputs, and their current statements contradict RFC §11 and the plan's own S6 row + (`plan.md:3-12,89-99,101-118`; `worklog.md:95-107`; `phase-registry.md:13`). + +2. **[MEDIUM] Finish D-9 terminology reconciliation in the live PR body.** The new locked-decision + item correctly describes two surfaces, but the summary still says a singular “management + cockpit,” old item 9 still says the cockpit as a whole is downstream of #890/#922, and items 12 + and 11 are out of order. Rename those old references to the production/admin console and order + the decision list so the public review surface cannot be read as granting #890/#922 authority + over DevTools. Keep the PR draft and retain `status:plan-eval`. + +### Notes + +- The actual `2518791f3` files—not the fix summary—were evaluated. The lease/serving model, test 8, + D-9 split, A7 narrowing, P-6 staging, backend independence, evidence qualifications, cleanup + inventory, gate letters, security bounds, and competitive-study integration were verified directly + and introduced no architecture regression. +- `docs:links` passed with zero broken links/anchors/orphans; focused `deno fmt --check` passed on + the RFC, plan, worklog, context pack, phase registry, and competitive study; + `git diff --check + cd3fd1e58..HEAD` passed. The evaluator worktree remained clean. +- Live PR #1446 was re-inspected read-only at head `2518791f3`: open, mergeable, draft, sole + `status:plan-eval`, milestone assigned, six comments. No GitHub mutation was performed. +- No RFC, plan, worklog, context pack, phase registry, source, issue, comment, label, commit, or + branch was changed. This Cycle-6 append is the only filesystem mutation. + +PLAN-EVAL: FAIL_PLAN + +## Cycle 7 + +- Plan evaluator session: same dedicated Codex GPT-5.6 Sol · xhigh evaluator session / 2026-08-11 + (owner override D-2), Cycle 7 explicitly ordered by the owner as the final pass +- Evaluator worktree: `/home/codex/repos/ns-rfc-plan-eval`, branch + `eval/rfc-runtime-versioned-automation`, clean at `ed978eb689c69fe98dfd4a72cf642dab209844a8` +- Author worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, same source commit + before this verdict append +- Surface / archetype: docs RFC planning future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, CLI, + scaffold, DB, Aspire, production-console, and staged DevTools work +- Scope overlays: `SCOPE-docs`; full adversarial plan gate and Cycle-6 resolution audit; no + implementation evaluation + +### Cycle-6 finding resolution audit + +| Cycle-6 finding | Cycle-7 result | Evidence | +| ----------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| F1 — formal plan/design/phase record reconciliation | PARTIAL | The plan sweep now classifies P-1..P-6 with P-6's consumed contracts and entry criterion, commit slices now say S1–S6, and G6 is current through Cycle 6 (`plan.md:90-104`; `worklog.md:103-107`; `phase-registry.md:13`). The same Design checkpoint still defines the staged vocabulary as P-1..P-5, its fix note falsely claims P-1..P-6, and the plan/context status narratives still call Cycle 5 the deciding pass (`worklog.md:95-100,236-245`; `plan.md:3-13`; `context-pack.md:3,21-32`; finding 1). | +| F2 — D-9 terminology and decision-list reconciliation in PR #1446 | PASS | The live summary names a production/admin operator console plus separately staged DevTools; locked decision 9 now contains the complete two-surface decision, scopes #890/#922 sufficiency to surface 1, stages DevTools behind P-6, and the list is ordered 1–11 without the old duplicate. The PR remains draft at head `ed978eb68`. | + +### Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | PASS | `research.md:6-13` still re-baselines to `origin/main`; HEAD's merge-base and current `origin/main` are both `2256a67bf`. Fresh `deno doc packages/runtime-config/mod.ts` and focused production-use search reconfirmed the exported loader/watcher and absence of a production consumer. No RFC or evidence file changed after Cycle 6. | +| Decisions locked | PASS | The RFC continues to lock ownership, activation totals/CAS, revision pinning, leased admission versus serving, store parity, T1 limits, cron ownership, and the two-frontend boundary with rationale. Cycle 6 already found no unresolved runtime architecture decision, and `2518791f3..ed978eb68` contains no RFC change. | +| Open-decision sweep | PASS | The plan now covers P-1..P-6, states why P-6 is safe to defer, names the stable contracts it consumes and its entry criterion, and confirms no runtime slice depends on its outcome (`plan.md:90-104`; RFC §11 `rfc-0001-runtime-versioned-automation.md:629-638`). The evaluator sweep found no must-resolve decision. | +| Commit slices (< 30, gate + files each) | PASS | S1–S6 are ordered and name files plus proving gates (`plan.md:106-125`); the RFC's future A0–A8 slices remain below 30, file-scoped, dependency-ordered, and fully gated (`rfc-0001-runtime-versioned-automation.md:640-670`). The Design checkpoint now agrees on S1–S6 (`worklog.md:103-105`). | +| Risk register | PASS | The register continues to cover evidence drift, partial activation, feed/poll ordering, schema skew, adapter divergence, T1, integrity, secrets, loader policy, cron duplication, outage behavior, and frontend sequencing with mitigations/owners (`plan.md:69-88`). | +| Gate set selected | PASS | The docs-source gates and CI skips are explicit, while §12 defines S/F/R/C/P, frontend edges, and release classes for future package/plugin slices (`plan.md:15-23`; RFC `:640-670`). | +| Deferred scope explicit | FAIL | The Design checkpoint contradicts itself: domain vocabulary says prerequisite/staged items P-1..P-5, while its deferred-scope row and the locked plan say P-1..P-6 (`worklog.md:95-107`; `plan.md:90-104`). Because P-6 is the owner-directed D-9 boundary, the plan package does not yet state one unambiguous deferred set. | +| jsr-audit surface scan (pkg/plugin) | PASS | The pre-scan still names Zod/isolated-declaration, explicit oRPC-route, driver-type leakage, connector-thinness, and publish risks and assigns them to future slices (`rfc-0001-runtime-versioned-automation.md:672-680`). | + +### Open-decision sweep (evaluator-run) + +None. P-6 is safe to defer: the RFC defines its purpose, consumes already-scoped management, +history, convergence, and OTel contracts, and prevents this RFC from pre-empting the DevTools host. +The only failure is that the Design checkpoint still omits P-6 from its own domain-vocabulary list +while claiming that omission was fixed. + +### Verdict + +`FAIL_PLAN` + +### If FAIL_PLAN — required fixes + +1. **[BLOCKER] Complete the Cycle-6 record reconciliation against the actual text.** Change the + Design checkpoint's domain-vocabulary range from P-1..P-5 to P-1..P-6 so it agrees with its own + deferred-scope row, the locked plan, RFC §11, and the Cycle-6 fix note + (`worklog.md:95-107,236-245`). Remove the remaining stale evaluation narratives: the locked plan + still calls Cycle 5 the deciding pass and describes S5 only through earlier cycles + (`plan.md:10-13,117-120`), while the context pack still opens post-Cycle-5 and ends at Cycle 5 + (`context-pack.md:3,21-32`). Bring those through Cycle 7 without changing any architecture. + +2. **[HIGH] Reconcile the live PR's evaluation-progress fields after this verdict.** The D-9 wording + fix itself passes, but S5 and Definition of Done still say Cycle 6 is the deciding future pass, + even though Cycle 6 returned FAIL_PLAN and Cycle 7 is now complete. Update only those progress + fields; preserve the corrected two-surface decision, draft state, and sole `status:plan-eval`. + +### Notes + +- The actual `ed978eb68` files—not the fix summary—were evaluated. The plan open-decision sweep, + S1–S6 list, phase registry, and live PR D-9 wording were verified directly. The RFC did not change + after Cycle 6, so its clean architecture judgment stands. +- `docs:links` passed with zero broken links/anchors/orphans; focused `deno fmt --check` passed on + the RFC, plan, worklog, context pack, phase registry, and competitive study; + `git diff --check + 2518791f3..HEAD` passed. The evaluator worktree remained clean. +- Live PR #1446 was re-inspected read-only at head `ed978eb68`: open, mergeable, draft, sole + `status:plan-eval`, milestone assigned, six comments. No GitHub mutation was performed. +- No RFC, plan, worklog, context pack, phase registry, source, issue, comment, label, commit, or + branch was changed. This Cycle-7 append is the only filesystem mutation. + +PLAN-EVAL: FAIL_PLAN + +## Cycle 8 + +- Plan evaluator session: same dedicated Codex GPT-5.6 Sol · xhigh evaluator session / 2026-08-11 + (owner override D-2), Cycle 8 explicitly ordered by the owner as the closing pass +- Evaluator worktree: `/home/codex/repos/ns-rfc-plan-eval`, branch + `eval/rfc-runtime-versioned-automation`, clean at `209961433d062a1e0062db2c556e9a68ce79e9bf` +- Author worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, same source commit + before this verdict append +- Surface / archetype: docs RFC planning future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, CLI, + scaffold, DB, Aspire, production-console, and staged DevTools work +- Scope overlays: `SCOPE-docs`; full adversarial plan gate and Cycle-7 resolution audit; no + implementation evaluation + +### Cycle-7 finding resolution audit + +| Cycle-7 finding | Cycle-8 result | Evidence | +| --------------------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| F1 — Design vocabulary and plan/context progress reconciliation | PARTIAL | The Design checkpoint now says P-1..P-6 and agrees with its deferred-scope row; the context pack now opens post-Cycle-7 and consolidates the evaluation history (`worklog.md:95-107`; `context-pack.md:3,21-25`). The claimed plan update did not land: its status still calls Cycle 5 the deciding pass, and S5 still describes `plan-eval.md` as Cycles 1–5 with only Cycle-3 history (`plan.md:3-13,117-120`; finding 1). | +| F2 — live PR progress reconciliation | PASS | PR #1446's S5 now records Cycle 6 as architecture-clean and Cycle 7 as the final bookkeeping fix, while DoD uses a generic final-PASS condition. The corrected two-surface D-9 decision, draft state, and sole `status:plan-eval` are preserved at head `209961433`. | + +### Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | PASS | `research.md:6-13` remains explicitly re-baselined; HEAD's merge-base and current `origin/main` are both `2256a67bf`. Fresh `deno doc packages/runtime-config/mod.ts` and focused production-use search reconfirmed the load-bearing loader/watcher finding. RFC and evidence files are unchanged since Cycle 6. | +| Decisions locked | PASS | Ownership, activation/CAS, pinned dispatch, lease-versus-serving behavior, adapter parity, T1 limits, cron ownership, cleanup, and the two-frontend boundary remain decided with rationale. No RFC change occurred after the Cycle-6 architecture-clean judgment. | +| Open-decision sweep | PASS | P-1..P-6 are classified with entry criteria; P-6 names consumed contracts and why deferral cannot force runtime rework (`plan.md:90-104`; RFC §11 `rfc-0001-runtime-versioned-automation.md:629-638`). The evaluator found no must-resolve decision. | +| Commit slices (< 30, gate + files each) | FAIL | The substantive S1–S6 and future A0–A8 slices remain ordered, sized, file-scoped, and gated, and the Design checkpoint says S1–S6. However the locked plan's S5 record still claims the evaluator file covers only Cycles 1–5 and omits Cycles 4–7 from its gate history, contradicting the actual append-only artifact (`plan.md:106-123`; `plan-eval.md:454-835`). | +| Risk register | PASS | Risks and mitigations remain complete for evidence, consistency, fleet/schema behavior, adapter parity, T1/security, secrets, loader policy, cron, outage serving, and frontend sequencing (`plan.md:69-88`). | +| Gate set selected | PASS | Docs-source gates and CI skips are explicit; RFC §12 retains S/F/R/C/P, frontend edges, and release classes for future implementation (`plan.md:15-23`; RFC `:640-670`). | +| Deferred scope explicit | PASS | Design, plan, and RFC now consistently identify P-1..P-6, with §15's remaining owner choices independently classified (`worklog.md:95-107`; `plan.md:90-104`; RFC `:629-638,802-822`). | +| jsr-audit surface scan (pkg/plugin) | PASS | The pre-scan continues to name Zod/isolated-declaration, explicit oRPC-route, driver leakage, connector thinness, and publish risks before implementation (`rfc-0001-runtime-versioned-automation.md:672-680`). | + +### Open-decision sweep (evaluator-run) + +None. The RFC architecture and all staged-decision classifications remain complete. The failure is +limited to the locked plan's own status and S5 provenance text, which still describe a superseded +Cycle-5 state despite the Cycle-7 fix note claiming they were updated. + +### Verdict + +`FAIL_PLAN` + +### If FAIL_PLAN — required fixes + +1. **[BLOCKER] Apply the missing `plan.md` progress reconciliation and verify the file, not the fix + note.** Replace the stale Cycle-5-deciding narrative at `plan.md:10-13` with the actual history + through Cycle 8, and update S5 at `plan.md:117-120` so its file range and gate history cover the + append-only evaluator record through the current closing pass. The Design checkpoint, context + pack, live PR, and architecture now pass; do not alter them or reopen RFC decisions. + +2. **[MEDIUM] Bring the supervisor phase row to the same closing pass.** G6 still says Cycles 1–6 + with Cycle 7 as the final future pass and cites `plan-eval.md` Cycles 1–6 + (`phase-registry.md:13`). Update it through Cycle 8 when recording this verdict so the supervisor + record has one current evaluation state. + +### Notes + +- The actual `209961433` files—not the fix summary—were evaluated. The Design P-6 correction, + context pack, and live PR progress fields are genuinely fixed; only the claimed plan edit is + absent. The RFC and evidence did not change, so Cycle 6's clean architecture judgment stands. +- `docs:links` passed with zero broken links/anchors/orphans; focused `deno fmt --check` passed on + the RFC, plan, worklog, context pack, phase registry, and competitive study; + `git diff --check + ed978eb68..HEAD` passed. The evaluator worktree remained clean. +- Live PR #1446 was re-inspected read-only at head `209961433`: open, mergeable, draft, sole + `status:plan-eval`, milestone assigned, six comments. No GitHub mutation was performed. +- No RFC, plan, worklog, context pack, phase registry, source, issue, comment, label, commit, or + branch was changed. This Cycle-8 append is the only filesystem mutation. + +PLAN-EVAL: FAIL_PLAN + +## Cycle 9 + +- Plan evaluator session: same dedicated Codex GPT-5.6 Sol · xhigh evaluator session / 2026-08-11 + (owner override D-2), Cycle 9 explicitly ordered by the owner as the closing pass +- Evaluator worktree: `/home/codex/repos/ns-rfc-plan-eval`, branch + `eval/rfc-runtime-versioned-automation`, clean at `28830c88ae01efad76ea1403784fde881289d555` +- Author worktree: `/home/codex/repos/ns-rfc-runtime-versioned-automation`, same source commit + before this verdict append +- Surface / archetype: docs RFC planning future ARCHETYPE-1/2/3/5/6 package, runtime, plugin, CLI, + scaffold, DB, Aspire, production-console, and staged DevTools work +- Scope overlays: `SCOPE-docs`; full adversarial plan gate and Cycle-8 resolution audit; no + implementation evaluation + +### Cycle-8 finding resolution audit + +| Cycle-8 finding | Cycle-9 result | Evidence | +| --------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| F1 — `plan.md` status and S5 provenance | PASS | The status now records Cycles 3–8, the Cycle-6 architecture-clean judgment, bookkeeping-only later findings, and the closing-pass condition; S5 names append-only `plan-eval.md` Cycles 1–8 and carries the complete 9→6→5→2→bookkeeping history (`plan.md:3-15,119-123`). | +| F2 — phase-registry closing-pass state | PASS | G6 now records Cycles 1–8, architecture clean since Cycle 6, fixed Cycle-7/8 bookkeeping, Cycle 9 as the closing pass, and append-only evaluator evidence through Cycle 8 (`phase-registry.md:13`). | + +### Checklist results + +| Plan-Gate item | Result | Evidence / location | +| --------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Research present and current | PASS | `research.md:6-13` explicitly re-baselines to `origin/main`; HEAD's merge-base and current `origin/main` both resolve to `2256a67bf`. Fresh `deno doc packages/runtime-config/mod.ts` and focused production-use search reconfirmed the exported loader/watcher and absence of production composition. RFC/evidence files remain unchanged since the Cycle-6 architecture-clean judgment. | +| Decisions locked | PASS | The RFC and plan lock ownership, complete activation epochs/CAS, pinned dispatch, leased admission versus serving, store parity, T1 limits, cron ownership, cleanup, and the D-9 two-frontend boundary with rationale (`plan.md:3-15,49-70`; RFC §§5–10). | +| Open-decision sweep | PASS | Naming, two-person policy, and retention defaults are safely assigned to slices; P-1..P-6 have rationale and entry criteria; P-6 names consumed stable contracts and cannot force runtime rework (`plan.md:92-106`; RFC `rfc-0001-runtime-versioned-automation.md:629-638,802-822`). The evaluator found no must-resolve decision. | +| Commit slices (< 30, gate + files each) | PASS | S1–S6 are ordered, file-scoped, and name proving gates with current append-only evaluator provenance (`plan.md:108-128`); future A0–A8 slices remain below 30, dependency-ordered, file-scoped, and gated (RFC `:640-670`). The Design checkpoint agrees on S1–S6 (`worklog.md:103-105`). | +| Risk register | PASS | The plan covers evidence drift, activation atomicity, feed/poll ordering, schema skew, adapter divergence, T1/security, integrity, secrets, loader policy, cron duplication, outage serving, and frontend sequencing with mitigations and owning slices (`plan.md:72-90`). | +| Gate set selected | PASS | `SCOPE-docs`, docs-source gates, intentional CI skips, and final PLAN-EVAL are explicit; RFC §12 applies S/F/R/C/P, frontend dependency, and release classes to future package/plugin slices (`plan.md:17-26`; RFC `:640-680`). | +| Deferred scope explicit | PASS | Design, plan, and RFC consistently identify P-1..P-6 and owner-gated implementation/issue filing, while §15 classifies the remaining spelling/policy/default choices (`worklog.md:95-107`; `plan.md:92-106`; RFC `:629-638,802-822`). | +| jsr-audit surface scan (pkg/plugin) | PASS | The pre-scan names Zod/isolated-declaration, explicit oRPC-route, driver-type leakage, connector-thinness, and publish risks and assigns them to implementation slices (`rfc-0001-runtime-versioned-automation.md:672-680`). | + +### Open-decision sweep (evaluator-run) + +None. All architecture decisions that would force rework are resolved. The remaining P-1..P-6 and +§15 choices are safe to defer under their recorded rationale, consumed contracts, owning slices, and +entry criteria. + +### Verdict + +`PASS` + +### Notes + +- The actual `28830c88a` files—not the fix summary—were evaluated. Both Cycle-8 record findings are + resolved, every plan-gate checklist item is checked, and no regression was found. +- The RFC and evidence did not change after Cycle 6; its clean judgments on evidence integrity, + O2+O4 ownership, epoch/convergence consistency, security honesty, cleanup completeness, roadmap, + doctrine fit, plugin thinness, and competitive-study scope therefore stand. +- `docs:links` passed with zero broken links/anchors/orphans; focused `deno fmt --check` passed on + the RFC, plan, worklog, context pack, phase registry, and competitive study; + `git diff --check + 209961433..HEAD` passed. The evaluator worktree remained clean. +- Live PR #1446 was re-inspected read-only at head `28830c88a`: open, mergeable, draft, sole + `status:plan-eval`, milestone assigned, six comments; its S5/DoD and D-9 decision remain current. + No GitHub mutation was performed. +- No RFC, plan, worklog, context pack, phase registry, source, issue, comment, label, commit, or + branch was changed. This Cycle-9 append is the only filesystem mutation. + +PLAN-EVAL: PASS diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/plan.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/plan.md new file mode 100644 index 0000000000..563502b0a6 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/plan.md @@ -0,0 +1,133 @@ +# Plan — docs-rfc-runtime-versioned-automation--supervisor + +Status: **LOCKED** (post owner-authorized PLAN-EVAL cycles 3–8 + fix cycles; cycle 6 found "no +unresolved runtime architecture decision remains" and every later finding has been record +bookkeeping, each fixed in the following slice; cycle 8's plan/status items are fixed in this edit). +Architecture decisions locked in the RFC: ownership §9; epoch consistency + complete-desired-state +§5.2/5.3; fleet admission + leased registration §5.3; **control-plane-outage availability contract +§5.3-8 (**indefinite** last-good serving, never self-drain, idle-and-loud cold start; pinned-lookup +transient/terminal classes)**; adapter parity/narrowing §5.2; T1 enforcement contract §5.4; cron +ownership §5.1; competitive positioning §14.1 (D-8 study: adopted patterns / non-goals / +differentiators; benchmark gates §13.1; P-5 staged; two-frontend boundary §8.2 per D-9, P-6 staged). +PLAN-EVAL (Sol·xhigh, D-2): eight cycles to date, all FAIL_PLAN with monotonically narrowing +findings (9 → 6 → 5 → 2 → bookkeeping-only from cycle 6 onward); every finding of every cycle is +fixed in-tree; the next pass closes on the reconciled record, and on PASS the RFC is produced for +the owner. PR stays draft until ratification. + +## Profile + +- Intent: RFC / decision document (research + architecture, no implementation). +- Overlay: `SCOPE-docs`. Archetypes the RFC **selects for the future waves**: ARCHETYPE-1 + (`automation-core`, contracts only), ARCHETYPE-2/3 (`automation-runtime`, behavior + ports + + adapters), ARCHETYPE-5 (thin `plugins/automation` connector; plus existing workers/triggers + connectors), ARCHETYPE-6 (`packages/cli` command group). Existing archetypes it _describes_: the + current workers/triggers cores and CLI surfaces under evidence. +- Gates: docs-source gates (doc-lint, scoped fmt/check where applicable), CI docs lane + (`ci:skip-e2e` + `ci:skip-scaffold` on the draft PR — docs-only diff), final Sol·xhigh PLAN-EVAL. + +## Deliverable set (locked) + +1. `rfcs/0000-runtime-versioned-automation.md` — primary RFC, status `Draft`. (The run authored it + under `docs/architecture/rfc/` when no in-repo RFC home existed; the canonical `rfcs/` process + has since landed, and owner directive D-10 normalized the file into it — number `0000` until a + maintainer assigns one at acceptance.) +2. Capability matrix (legacy → current → gap → recommendation) — RFC appendix, sourced from + `evidence/legacy-capability-map.md` + `evidence/current-state-matrix.md`. +3. `1444-impact.md` — delivered early (PR #1444 comment 5248826402). Folded into the RFC. +4. Architecture + deployment diagrams (mermaid, in-RFC), API/config examples, threat model, + **replacement/cleanup plan** (obsolete packages/commands/types/docs/generated files/tests to + remove or rewrite — D-5: no consumer migration/compat layer), E2E acceptance model, phased + roadmap with **draft** epic/issue graph (not filed — owner ratification required). +5. Design-depth core (D-4): runtime **contribution model** (extract the #890 pattern — contracts + package, thin pointer axis, generated registries — test whether runtime automation needs one or + several contribution families; no hardcoded topic switch statements), control/data-plane + boundaries, execution/sandbox **port + adapters over established isolation tech** (survey with + primary sources: Deno permissions/subprocess, containers/rootless, gVisor, Firecracker/microVM, + WASM/WASI/component model, isolates, managed sandbox products; bespoke isolation only on an + evidenced market gap), version/promotion consistency, multi-instance propagation, security, + observability, and a five-option package/plugin ownership comparison (extend-existing / neutral + core package / split contracts+control+client+runtime / thin connector plugin / host-composed + aggregation) judged against doctrine, DX, JSR packaging, deployment topology, trust boundaries. + +## Hard constraints (owner) + +- Preserve the differentiating capability: runtime-versioned tasks/triggers on a running stack (D-10 + standing constraint). No static-config collapse; legacy design not assumed correct. +- **Complete redesign in scope** (D-4): legacy = outcome evidence + three representative operator + journeys only; current mechanisms = candidate seams, not foundations; compare evolutionary vs + clean-sheet vs hybrid honestly. +- **No backward-compatibility/migration layer** (D-5): clean break authorized; transition plan is a + codebase replacement/cleanup plan with an explicit obsolete-surface inventory; compatibility only + with stable doctrine and active framework seams. +- Frontend sequencing (D-3, refined by D-9): #890/#922 (minimum cut #923–#932 + #934; #933 + adjacency) are sufficient **only** for the production/admin userland automation console (RFC §8.2 + surface 1). Developer DevTools (diagnostics, live definitions/state, execution journeys, dev + management affordances) are a distinct host/contribution surface behind the staged P-6 DevTools + RFC, which re-evaluates epic #400 (+ #685/#780/#506 as evidence, not ratified architecture) and + consumes this RFC's management/observability contracts. Two hosts decided, not one ambiguous + cockpit. No parallel Fresh/dashboard seam; backend slices stay frontend-independent. +- Draft PR only; no epic/issue filing; no ready-for-review until owner ratifies. +- #1444 keeps its D-10 boundary; this RFC does not ask it for redesign work. + +## Risk register (expanded per PLAN-EVAL cycle 1) + +| Risk | Mitigation (RFC §, owning slice) | +| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| RFC claims drift from code reality | status tags + path evidence; independent Codex derivation; supervisor spot-checks; F7 scope corrections applied | +| Over-design (faking certainty on staged questions) | §11 prerequisite RFCs with entry criteria; §15 classified deferrals | +| Cockpit dependency mis-modeled | live issue states verified; explicit A7 edges (#923–#932 + #934, plus A3b/A4b/A5b) | +| Cross-family partial activation observed by replicas | single transactional activation-set manifest + epoch (§5.2, A1a) | +| Out-of-order feed vs poll overwrites newer state | strictly monotonic epoch application, stale rejection (§5.3, A1c) | +| Schema-skew split fleet after partial deploy | fleet registration + admission-at-commit + convergence status/SLO + force-drain override (§5.3, A2b) | +| KV/Postgres semantic divergence | one adapter-conformance suite; KV narrowed to single-writer dev, refuses fleet features (§5.2, A1a/A1b) | +| Non-Deno T1 escape / overclaimed sandbox | T1 enforcement contract stated bluntly; per-runtime negative tests incl. honest non-enforcement pins; T2 required for untrusted polyglot (§5.4/§6, A5a) | +| Snapshot integrity vs malicious store/MITM | trust assumptions explicit (TLS + content hashes = integrity-of-identity); signed snapshots bundled with P-3 (§6) | +| Secret leakage via captured output | bounded best-effort redaction, residual risk documented (§6, A5b) | +| Control-plane child loader executes consumer code with net | TM9: lockfile-pinned + --cached-only default, warm-cache-offline acceptance gate (§6, A2a) | +| Cron subsystem duplication deepened | task@1 has no schedule; scheduled trigger is the only operator cron; CRON-SUBSYSTEM-DUP untouched for T0 (§5.1) | +| Sub-agent worktree contention | G1→G2 serialized; evaluator in dedicated worktree | +| Evaluator route blocked | record in drift + lane-policy fallbacks | +| Management/feed outage → lease expiry or pinned-lookup DLQ | §5.3-8 availability contract: **indefinite** last-good serving, never drains (the staleness SLO bounds silence, not serving); idle-and-loud cold start; lookup failures classified transient (queue retry) vs terminal (DLQ); revision cache pre-warmed by snapshots; outage E2E is §13 test 8, exercised in A8 with BG-1 | + +## Open-decision sweep (plan-gate requirement) + +Must-resolve-now items are **resolved in the RFC** (ownership §9; activation consistency §5.2/5.3; +replica admission §5.3; store parity §5.2; T1 contract §5.4; cron ownership §5.1). Remaining open +decisions, each classified: naming → defer to A0 (safe; spelling only); two-person activation +default → defer to A2b (policy hook exists either way); retention defaults → defer to A3b +(conservative caps shipped behind config). **P-1..P-6 deferred with entry criteria (§11)** — P-6 +(DevTools RFC, owner directive D-9) is safe to defer because its rationale, the stable contracts it +consumes (A2b management, A3b history, A2d convergence, §7 OTel vocabulary), and its entry criterion +(after those land) are explicit in RFC §11, and no runtime slice depends on its outcome. The cycle-3 +must-resolve item — execution-plane availability during control-plane outage + pinned-lookup failure +classes — is **resolved** in §5.3 steps 6–8 (indefinite last-good serving with no expiry transition; +local validation gates serving, currentness gates convergence; transient-vs-terminal classification; +revision cache). The two-frontend boundary (D-9) is **decided** in §8.2. No open decision forces +rework if deferred as classified. + +## Commit slices (docs-only run; files + proving gate per slice) + +1. **S1 bootstrap** — files: run dir (`supervisor.md`, `drift.md`, `phase-registry.md`, briefs, + `1444-impact.md`); gate: harness activation checklist. DONE (`e7378bf7c`). +2. **S2 legacy evidence** — files: `evidence/legacy-capability-map.md`; gate: supervisor A1 review + + 2 verbatim spot-checks. DONE (`e7378bf7c`). +3. **S3 current evidence** — files: `evidence/current-state-matrix.md`, + `evidence/current-state-probes/**`; gate: probe exit codes recorded + supervisor A1 review. DONE + (`f5997b6a2`). +4. **S4 RFC** — files: `rfcs/0000-runtime-versioned-automation.md`; gates: `docs:links`, + `deno fmt --check` on the file, PR body reconciliation. DONE + fix cycle 1. +5. **S5 PLAN-EVAL cycles** — files: `plan-eval.md` (evaluator-written, append-only, cycles 1–8 to + date), fix-cycle diffs; gate: verdict recorded per cycle. History: C1 9 findings → C2 (partly + stale-text, D-7) → protocol escalation → owner-authorized C3 6 → C4 5 → C5 2 → C6 + architecture-clean (bookkeeping) → C7/C8 residual record items; every finding fixed in the slice + that followed its cycle. Owner ratification is the closing gate. +6. **S6 competitive study (D-8)** — files: `evidence/competitive-architecture-study.md`, RFC + §14.1/§13.1/P-5, wording corrections; gates: `docs:links` + fmt + cycle-3 evaluator review of the + study. DONE (`811373a87` + fix commit). + +7. **S7 RFC process normalization (D-10)** — files: `git mv` to + `rfcs/0000-runtime-versioned-automation.md` + canonical `0000-template.md` frontmatter + + reference sweep across living run records and the PR body; gates: `docs:links` + + `deno fmt --check` on touched files. DONE. + +Each slice: commit → push (explicit refspec) → draft-PR comment with evidence. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/research.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/research.md new file mode 100644 index 0000000000..c5d030ec06 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/research.md @@ -0,0 +1,94 @@ +# Research — docs-rfc-runtime-versioned-automation--supervisor + +Deep findings feeding the RFC. Sub-agent reports live in `evidence/`; this file is the supervisor +synthesis + verification layer. Status: **complete** — G1 + G2 landed and supervisor-reviewed; +synthesis in the RFC. + +## Re-baseline + +- Branch == `origin/main` @ `2256a67bf` (2026-08-11). No carried-in plan; the launch brief is the + owner's intent statement, verified against the repos below. +- Legacy subject: `/home/codex/repos/netscript-start-ref` @ `6ba9ba0` (= `origin/master`, refreshed + read-only at run start). +- Interacting run: `/home/codex/repos/ns-1443-plugin-ai-orchestrator` (PR #1444, S1–S10 landed, + child-process manifest loader uncommitted at inspection time). + +## Supervisor findings (verified directly) + +### F1 — `@netscript/runtime-config` is a real hot-reload read path, not a stub + +`packages/runtime-config/src/application/loader.ts`: env-resolved dir +(`NETSCRIPT_RUNTIME_CONFIG_DIR`, fallback `dirname(NETSCRIPT_TASKS_DIR)`, fallback `cwd()/runtime`); +`current` pointer file supports **JSON pointer object** or **legacy plain-text version** (mapped to +`/v.json` for topics jobs/sagas/tasks/triggers/features); malformed/missing anything +→ silent empty defaults. `watcher.ts`: `Deno.watchFs` recursive + 300ms debounce → +`loadRuntimeConfig()` → consumer callback; errors swallowed. **No write path, no schema validation, +no history, no audit, no multi-instance story in the package itself.** + +### F2 — the CLI already has an operator write path with atomic promotion semantics + +`packages/cli/src/public/features/config/override/`: +`publishRuntimeOverride(store, topic, version, value)` ("publish a topic payload and atomically +activate its version"), `rollbackRuntimeOverride` ("atomically activate an existing version"), +`setRuntimeOverrideValue` (dotted-path patch), plus a Cliffy command group +publish/rollback/list/get/set/clear/enable/disable ("dashboard-aligned"). Backed by a +`RuntimeConfigStorePort`. G2 must trace the store adapter (filesystem? DB?) and what tests prove. + +### F3 — workers execution is genuinely multi-runtime + +`packages/plugin-workers-core/src/executor/`: `MultiRuntimeTaskExecutor` with adapter map by +`TaskType`; adapters seen: Deno, dotnet, cmd (Windows), generic Dax process runner with streaming +capture; `runtime/runtime-types.ts` has both a **static handler registry** and a **dynamic module +importer** seam for runtime job handlers. G2 to enumerate full adapter set + permission model. + +### F4 — #1444 control-plane loader (read-only inspection, see `1444-impact.md`) + +Owner D-10 decision locks the split: `plugin.ts` manifest-only control plane (child-process load +under consumer deno.json, `clearEnv`, 30s timeout, JSON manifests over stdout marker); +`mod.ts`/`runtime.ts` and `workers|triggers/runtime/**` preserved. Constraints C1–C8 issued to #1444 +(PR comment 5248826402). The RFC builds on: manifests-as-data, additive manifest schema extension, +`generate runtime-schemas` control-plane-only. + +### F5 — Frontend Contribution Layer dependency (owner directive D-3) + +RFC PR #890 **merged** 2026-08-03 (design record `.llm/runs/plan-frontend-contrib--seed/rfc.md`): +plugins ship UI via `defineFrontend()` contributions — data contracts in +`@netscript/plugin-frontend-core`, generated transactional registry, `App.mountApp` sub-apps, +deny-by-default procedure gateway (#934). Implementation epic **#922 open** (milestone 0.0.9), all +children #923–#934 verified OPEN on 2026-08-11. Consequence: the cockpit is specified in this RFC as +a **downstream consumer** of that layer; minimum dependency cut evaluated in plan.md; no cockpit +frontend slice before the required #922 foundation lands; no parallel dashboard seam. #933 (workers +dogfood zone panel/console route/island) is the natural adjacency for the cockpit's first surface. + +## Sub-agent evidence (incorporated on arrival) + +- `evidence/legacy-capability-map.md` — G1, Codex Sol medium (thread in `codex-thread-ids.md`). +- `evidence/current-state-matrix.md` — G2, Codex Sol medium. +- `evidence/competitive-architecture-study.md` — S6, supervisor-authored on primary sources (D-8). +- `evidence/sandbox-isolation-survey.md` — isolation-scoped external survey (committed S5 fix + cycle). + +## Open questions the plan must close + +- OQ1: what actually consumes `loadRuntimeConfig`/`watchRuntimeConfig` in scaffolded apps and plugin + runtime barrels today (is the hot path live end-to-end on a deployed stack)? +- OQ2: `RuntimeConfigStorePort` adapter reality (fs-only? DB? object store?) and its atomicity. +- OQ3: does `generate runtime-schemas` regenerate `schema.json` for the versioned trees, and does + anything validate version documents against it at publish or load time? +- OQ4: triggers runtime processor parity with workers (stores, idempotency, dead-letter reality). +- OQ5: legacy cockpit workflows — which were wired vs aspirational (G1). +- OQ6: multi-instance propagation — what happens today with >1 replica and a pointer flip? + +## Open questions — CLOSED (by G1/G2 evidence) + +- OQ1: **nothing** consumes loader/watcher in any production composition (H1 confirmed; scaffold + glue starts package runtimes without runtime-config). +- OQ2: fs-only `DenoRuntimeConfigStore` (temp+rename pointer activation, read-merge-write pointer + update; P1 race 20/20; no revision/audit fields on the port). +- OQ3: real generator, but baseline snapshots collapse contributions to `schemas: []` → 0 files + written (P3); no admission validation anywhere; sample `$schema` refs dangle. +- OQ4: triggers processor is the strongest engine (tested idempotency/retry/DLQ/defer/enabled); gap + is definitions-static + non-uniform history, not processing. +- OQ5: legacy cockpit — workers list/detail/run wired, no create; triggers pages dead vs service. +- OQ6: nothing propagates; replicas would each need an unregistered watcher; cron/file-watch would + duplicate per replica. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/supervisor.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/supervisor.md new file mode 100644 index 0000000000..bc5c743ca1 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/supervisor.md @@ -0,0 +1,44 @@ +# Supervisor Identity — docs-rfc-runtime-versioned-automation--supervisor + +Written at run start per `workflow/lane-policy.md` § Supervisor identity. + +| Field | Value | +| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Model | Claude Fable 5 (`claude-fable-5`), medium effort | +| Session | Claude Code session `9125bc86-2125-4a58-a594-acbbc89dc636` (https://claude.ai/code/session_01PxfW6uzysZaXSQnyPrD7By), bypass permissions, Remote Control enabled | +| Host | WSL2 Linux (6.18.33.2-microsoft-standard-WSL2), user `codex` | +| Checkout | /home/codex/repos/ns-rfc-runtime-versioned-automation (dedicated worktree) | +| Worktree | /home/codex/repos/ns-rfc-runtime-versioned-automation | +| Branch | `docs/rfc-runtime-versioned-automation` | +| Baseline | `2256a67bf` = `origin/main`, 2026-08-11 | +| Run ID | `docs-rfc-runtime-versioned-automation--supervisor` | + +## Read-only reference surfaces + +| Surface | Path | Constraint | +| ---------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------ | +| Legacy product | /home/codex/repos/netscript-start-ref | read-only; refresh from `origin/master` only; never push/mutate | +| Active #1443 run | /home/codex/repos/ns-1443-plugin-ai-orchestrator | read-only design interaction with PR #1444; never write; never compete with its supervisor | + +## Routes in force + +| Task lane | Provider / model / effort | Role in this run | +| ---------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `planning_decisions` (supervisor) | Claude · Anthropic · **Fable 5 · medium** | RFC orchestrator/synthesis — **owner override**, see below | +| archaeology / current-state verification | Codex · OpenAI · GPT-5.6 Sol (low–medium per slice) | independent code archaeology sub-agents | +| `formal_plan_evaluation` | Codex · OpenAI · **GPT-5.6 Sol · xhigh** | final adversarial PLAN-EVAL of the Claude-authored RFC — **owner override**, see below | + +## Recorded lane/eval overrides (owner directives from the launch brief, 2026-08-11) + +1. **Supervisor model override.** Canonical `planning_decisions` route is Opus 5 · high. The owner + explicitly assigned **native Claude Fable 5 · medium** with bypass permissions and Remote Control + for this complex RFC run. Mirrored in `drift.md` (D-1). +2. **PLAN-EVAL effort override.** Canonical `formal_plan_evaluation` for Claude-authored work is Sol + · high. The owner explicitly requires a fresh native **Codex GPT-5.6 Sol · xhigh** formal + adversarial PLAN-EVAL at the end because the RFC is Claude-authored and unusually complex. + Mirrored in `drift.md` (D-2). +3. **Deliverable shape.** Research + architecture RFC only; disposable smokes/E2E probes allowed + under run evidence; **no implementation** of the selected architecture; draft PR only; no + epic/issue filing and no ready-for-review until owner ratification. +4. **Escalation policy.** No OpenHands/OpenRouter unless the native opposite-family route is blocked + or a genuine third opinion is needed — must be recorded here + `drift.md`. diff --git a/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/worklog.md b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/worklog.md new file mode 100644 index 0000000000..5f0ebf2528 --- /dev/null +++ b/.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/worklog.md @@ -0,0 +1,280 @@ +# Worklog — docs-rfc-runtime-versioned-automation--supervisor + +## 2026-08-11 Bootstrap + +- Run dir scaffolded; supervisor identity + owner overrides recorded (Fable 5 medium supervisor, Sol + xhigh final PLAN-EVAL) — see supervisor.md, drift.md D-1/D-2. +- Baseline verified: branch `docs/rfc-runtime-versioned-automation` == `origin/main` @ `2256a67bf`. +- Read-only surfaces verified present: `/home/codex/repos/netscript-start-ref` (legacy), + `/home/codex/repos/ns-1443-plugin-ai-orchestrator` (#1443/#1444). +- No established `docs/architecture/rfc/` location exists yet (grep over docs/ found no RFC/ADR + tree); this run will create `docs/architecture/rfc/` and record that as a locked decision in + plan.md. + +## 2026-08-11 G3 — #1444 impact memo (early deliverable) + +- Read-only inspection of `/home/codex/repos/ns-1443-plugin-ai-orchestrator`: PR #1444 body, D-10 + owner decision (control-plane/runtime split), uncommitted child-process loader + (`configured-plugin-manifest-loader-child.ts`, `plugin-registry.ts` diff), workspace-mutator + `plugin.ts` registration, barrel stub cleanup. Never wrote in that worktree. +- Wrote `1444-impact.md` (run dir): ratifies the D-10 split, keeps the child loader (clearEnv is + load-bearing), 8 compatibility constraints C1–C8 (notably: manifests stay serializable data, + additive-extensible schema, `deno.jsonc` loader gap, `generate runtime-schemas` stays + control-plane-only, `workers|triggers/runtime/**` untouched). +- Posted to PR #1444: https://github.com/rickylabs/netscript/pull/1444#issuecomment-5248826402 +- G1 legacy archaeology Codex slice launched: thread visible in `codex-thread-ids.md` (gpt-5.6-sol · + medium, worktree = this RFC worktree, legacy repo read-only subject). First launch attempt failed + (runner forwards only --launch-arg values; --brief/--worktree must be inside them) — relaunched + successfully. + +## 2026-08-11 G1 — legacy capability map landed (slice review PASS) + +- Codex Sol·medium thread `019feef8-673d-7c53-98a4-db337494105b`, 6 turns (budget-exhausted at + max-turns but report structurally complete: 15 sections, exec summary, 3 operator journeys, + reachability audit, 5 weakest claims). +- Headline (reshapes the RFC): **the versioned runtime trees were DEAD even in legacy** — loader + + watcher existed but no executable service imported `@netscript/runtime-config`; hot + add/update/rollback never worked end-to-end. Real-but-orphaned data plane: KV task registry + + 7-runtime polyglot executor (per-message KV resolution = live-update capable) with NO operator + registration path. Workers cockpit task pages wired (list/detail/run, no create); triggers cockpit + dead vs delivered Hono service (contract/server mismatch). Permissions: absent → `--allow-all`; + non-Deno adapters inherit host env, no sandbox. Split-brain config across 5 stores. Schemas = + editor artifacts, 2 diverged authorities, no admission validation. +- Supervisor slice review: read full report; spot-checked the 2 most load-bearing claims — (a) no + runtime-config consumers in legacy (grep confirms only type/contribution metadata), (b) + `permission-flags.ts` returns `--allow-all` when permissions absent (verified verbatim). PASS. The + owner's "capability" is best understood as an _aspiration with a working execution engine_, not a + lost working feature. + +## 2026-08-11 Owner mid-run directives + sandbox survey + +- D-4 (complete redesign in scope), D-5 (no compat/migration layer), D-6 (parent hypotheses) — + recorded in drift.md; plan.md + G2 brief updated accordingly. +- External isolation-tech survey extracted to `.llm/tmp/docs/sandbox-isolation-survey-2026-08.md` + (Deno security docs primary; gVisor/Firecracker/WASM-WASI/V8-isolate comparison; managed sandbox + market scan). + +## 2026-08-11 G2 — current-state matrix landed (slice review PASS) + +- Same Codex thread resumed with the G2 brief (fresh-launch attempts hit `duplicate_sender_risk`; + registry-sanctioned resume used instead — recorded, not hidden). 10 turns, report complete: + `evidence/current-state-matrix.md` (255 lines) + probes under `evidence/current-state-probes/`. +- All hypotheses H1–H6 **confirmed** with behavioral proofs: P1 publish/rollback works but + concurrent topic promotion lost an update **20/20 trials** (read-merge-write pointer, no CAS); P2 + watcher reloads and malformed JSON silently yields empty topics; P3 real CLI + `generate runtime-schemas` exits 0 with **0 written** on baseline; P4 versioned `RuntimeTask` is + rejected by the executor (`supports()` false — schema drift proven live); P5 deno+shell execute + through `MultiRuntimeTaskExecutor`. Targeted suites: 22 passed / 0 failed. +- New current-state facts folded into the RFC: trigger v1 router genuinely backs + introspection/event-reads/webhook/enable-disable (honest-pending pattern for the rest); false + immutability (republish overwrites topic doc); loader pointer paths not root-confined; official + samples emit dangling `$schema` refs. +- Supervisor slice review: full read + 2 verbatim spot-checks (`manage-runtime-overrides.ts` + read-merge-write; `routers/v1.ts` enable/disable KV-backed). PASS. + +## 2026-08-11 S4 — RFC authored + +- `docs/architecture/rfc/rfc-0001-runtime-versioned-automation.md`: two-plane architecture, runtime + contribution families (#890 pattern extracted), immutable-revision store + CAS activation + audit, + snapshot propagation (no fs-watch), execution boundary tiers T0–T3 over established isolation tech + (survey extract in `.llm/tmp/docs/`), threat model TM1–TM8, observability/history, management API, + cockpit downstream of #922 minimum cut (#923–#932 + #934, #933 adjacency), ownership decision + O2+O4 with recorded fallback, cleanup inventory (D-5 clean break), staged RFCs P-1…P-4, roadmap + A0–A8, E2E acceptance model, alternatives. Gates: `docs:links` green; `deno fmt` clean; PLAN-EVAL + brief prepared. + +## Design + +Design checkpoint for this docs-only run (the deliverable is the RFC package; implementation designs +live inside the RFC and are re-checkpointed by their own future runs). + +1. **Public surface** — `rfcs/0000-runtime-versioned-automation.md` (status Draft; canonical `rfcs/` + process per `rfcs/README.md`, number `0000` until assigned at acceptance); run-dir artifacts + (`research.md`, `plan.md`, `evidence/*`, `1444-impact.md`, `plan-eval.md`); draft PR #1446 + (body + per-slice phase comments); PR #1444 comment 5248826402 (early impact memo). +2. **Domain vocabulary** — capability status tags (IMPLEMENTED/PARTIAL/ASPIRATIONAL/DEAD; + PROVEN/IMPLEMENTED-UNPROVEN/ABSENT), operator journeys J1–J3, contribution families (`task@1`, + `trigger@1`), activation epochs/sets (complete desired state, revision-pinned dispatch, leased + registration, outage contract), trust tiers T0–T3, threat items TM1–TM9, waves A0–A8 (incl. A2d, + A6a–c), prerequisite/staged items P-1–P-6, benchmark gates BG-1–BG-5, competitive-study verdict + classes (adopt / non-goal / differentiator). +3. **Ports** — none created (docs run). The RFC _specifies_ ports (store/boundary/reload/feed) for + future implementation runs. +4. **Constants** — slice IDs S1–S6; evidence file names fixed in briefs; RFC section anchors cited + by plan-eval. +5. **Commit slices** — S1–S6 as in plan.md §Commit slices, each with files + proving gate. +6. **Deferred scope** — implementation of the selected architecture (owner-gated); issue filing + (owner-gated); §11 P-1..P-6 staged items; §15 classified deferrals. +7. **Contributor path** — a reader starts at the RFC abstract → §4 overview → the section for their + concern; an implementer starts at §12's slice table, which names files + gates per slice; + evidence traceability runs RFC claim → evidence file § → path:line. + +## 2026-08-11 PLAN-EVAL cycle 1 — FAIL_PLAN, fix cycle applied + +- Evaluator: fresh Codex Sol·xhigh thread `019fef2b-…03fc` in dedicated worktree `ns-rfc-plan-eval` + (route matched; verified generator≠evaluator). Verdict FAIL_PLAN, 9 findings (7 blockers + 1 + high + checklist fails). Endorsed: D-10 preservation, clean-break direction, contribution model, + #922 cut modeling. +- Fixes applied (all findings): F1 Design checkpoint added (above), context-pack.md created, PR body + reconciled; F2/F3 ownership DECIDED and re-archetyped (contracts-only core / behavioral runtime + core with store adapters per relocation-debt law / thin connector; no-connector fallback withdrawn + with same-fidelity analysis); F4 activation-set manifest + monotonic epochs + fleet + admission/ack/convergence + adapter conformance suite + honest KV narrowing; F5 T1 enforcement + contract stated bluntly (non-Deno grants declarative+audited, NOT enforced; T2 for untrusted + polyglot); J2/TM1/TM2/E2E-5 rewritten; per-runtime negative tests; F6 TM9 child-loader threat + added (C8 honored); explicit v1 trust assumptions; redaction bounded; audit not tamper-proof vs DB + admin; F7 evidence claims scoped to inspected commits; partial operator surfaces acknowledged; + #1444 described as open-draft dependency; polyglot matrix row downgraded to deno+shell proven; F8 + cleanup inventory expanded (sagas emissions, workers local discovery path, generated trigger + registry, KV enabled-state fold, Windows env keys, T0 boundary) + cron ownership resolved (task@1 + has no schedule; scheduled trigger is the only operator cron surface); F9 roadmap re-sliced A0–A8 + into PR-sized slices with files + gate classes and corrected edges. +- Gates re-run after fixes: `docs:links` green; `deno fmt --check` clean on RFC. + +## 2026-08-11 PLAN-EVAL cycle 2 — FAIL_PLAN; corrected fix set applied; escalation point reached + +- Cycle 2 verdict appended by the same Sol·xhigh evaluator thread at `382795e4a`: FAIL_PLAN. Root + causes split in two: (a) three cycle-1 fixes had silently no-opped (drift D-7 — my patch strings + missed the fmt-rewrapped text), so F2/F3/F6 were evaluated against the OLD text; (b) genuinely new + findings: complete-desired-state snapshot semantics, cross-engine dispatch race (trigger@N+1 → + worker@N), admission time-of-check gap, contract-owning slice missing, gate-set completeness + (fitness/publish per slice; release class for scaffold-changing cleanup), file-level §10 + inventory, PR-surface reconciliation (labels/DoD/claims). +- Full corrected fix set applied WITH per-edit verification (assert-on-miss + grep audit): §5.1 + contracts bullet (no ports/state machine; management contract added); §5.2 ports/adapters in + runtime core; epoch = complete active desired state w/ carry-forward, tombstones, idempotent + reactivation; §5.3 steps 6–7: revision-pinned cross-engine dispatch + leased registration with + rejoin validation; blunt T1 perimeter paragraph; TM1/TM2 corrected (no "jail" overclaim); TM8 + narrowed + TM9 added w/ loader policy + A2a proving gate; §9 DECIDED/binding, fallback withdrawn + at equal fidelity; O4 row corrected; §10 file-level disposition table (incl. plugin + runtime-config-topic axis, trigger registry path, Windows emitters, T0 boundary); §12 re-sliced + (A2b split into A2b/A2d; A6 into A6a/A6b/A6c w/ release class on A6b; ports moved to A1a; full + gate letters; A7 edges incl. A2d); jsr-audit pre-scan recorded (slow-type risks named); E2E-2 + expectedEpoch; E2E-5 per-runtime honesty pins; survey extract committed to + `evidence/sandbox-isolation-survey.md` (was uncommitted `.llm/tmp`). +- Gates re-run: `docs:links` OK; `deno fmt --check` clean. +- **Protocol stop:** two FAIL_PLAN cycles consumed → escalate to owner per + `evaluator/plan-protocol.md` (no automatic third cycle). Fix state is complete and pushed; the + owner may authorize PLAN-EVAL cycle 3 or review directly. + +## 2026-08-11 S6 — Competitive architecture study (owner directive D-8) + +- Primary-source study of Temporal, Restate, Inngest, Trigger.dev, Hatchet, Windmill, Azure Durable + Functions, AWS Step Functions, Kestra + n8n across the 12 owner-named dimensions → + `evidence/competitive-architecture-study.md` (per-system cited profiles, 12×9 matrix, synthesis: 8 + adopted patterns, 4 non-goals, 4 differentiators, benchmark gates BG-1..BG-5, limitations incl. + point-in-time retrieval and no hands-on deployment). +- RFC integration: new §14.1 (adopt/non-goal/differentiator synthesis with §-mappings), §13.1 + executable benchmark gates (no empirical claims), §11 P-5 (weighted/canary activation, Step + Functions alias precedent) + P-4 note (durable-saga versioning lessons), header evidence row. +- Wording corrections per D-8: §11 P-2 "Market survey done" → isolation-technology survey, + explicitly scoped; sandbox survey file scoped to isolation with cross-ref to the study. +- Gates: `docs:links` OK; `deno fmt` clean. + +## 2026-08-11 PLAN-EVAL cycle 3 (owner-authorized) — FAIL_PLAN, all six findings fixed; holding for ratification + +- Cycle 3 at `811373a87`: 5 of 9 prior findings PASS (ownership/thinness, honest T1, evidence + scoping, TM9/C8 core, deferred scope); FAIL_PLAN on 6 narrowed items. Fixes (this commit): + 1. §5.3 step 8 **availability contract decided**: last-good serving, never self-drain; leases gate + admission not serving; step 6 pinned-lookup failures classified transient (queue retry+backoff) + vs terminal (DLQ) with a never-invalidating revision cache pre-warmed by snapshots; outage + tests + risk row assigned to A1c/A2d/A3a/A8. + 2. §5.5 secret guarantee made bounded (aligns with §6 trust assumptions). + 3. §10 cleanup table completed: triggers enabled-state ports/stores/testing/public exports + + consumers; Windows env-file-content/values/template/generated asset; live `NETSCRIPT_TASKS_DIR` + readers (path-resolution.ts, job-execution.ts). + 4. §12 every row now carries its full matrix gate set (F/P added across core/plugin rows) + + release class on A1a (DB), A2a (Aspire/scaffold), A2c (published CLI), A6a, A6b, A8. + 5. Study: isolation / control-data-plane / cockpit-UX matrix rows added; exhaustive negatives + narrowed to retrieved-doc scope (study + RFC §14.1); non-primary-source rule stated (HN + n8n + community = color only, never load-bearing); RFC T3 "sub-ms" empirical claim removed. + 6. plan.md (status/risks/sweep/slices S6), worklog Design vocabulary, context-pack, PR body + reconciled to cycle-3 state. +- (Superseded next entry: the owner subsequently ordered cycle 4.) +- Gates re-run: `docs:links` OK; fmt clean. + +## 2026-08-11 PLAN-EVAL cycle 4 (owner-ordered) — FAIL_PLAN, five findings fixed; cycle 5 is the deciding pass + +- Cycle 4 at `774f3ee19`: ownership/thinness, honest T1, bounded security claims, TM9/C8, and + evidence scoping all PASS by direct verification; five narrowed findings, all fixed here: + 1. **Outage contract made singular**: indefinite last-good serving, explicitly no serving bound or + expiry transition (the staleness SLO bounds silence, not serving); cold start with no control + plane and no persisted snapshot = idle-and-loud; §13 gains test 8 (control-plane outage + end-to-end) exercised in A8; plan risk row + status wording aligned. + 2. Cleanup inventory: added the CLI DI surface (`public-command-dependencies.ts` + runtimeConfigStore) and the public deploy option surface (`--force-runtime-config` / + `--fail-on-drift` / `--keep-runtime` + merge loop across the four build files) → A6a/A6b. + 3. Gate letters completed against the matrix: `C` on A1a/A1b/A1c/A3a/A4a/A5a; `P` on A6b. + 4. Study evidence contract repaired: 15-row/12-dimension count stated correctly everywhere; + Windmill isolation cell now cites the official security_isolation doc (per-job PID namespaces / + NSJAIL, defaults caveated); uncited cells in the added rows marked ◐ not assessed; legend + states the rule. + 5. Artifacts reconciled (plan profile archetypes = selected future shape; context-pack, + phase-registry, this worklog) and `deno fmt` actually run over the run-dir files — + `deno fmt --check` now green on the previously failing five; `docs:links` green. + +## 2026-08-11 PLAN-EVAL cycle 5 + owner directive D-9 — combined fix slice + +- Cycle 5 at `cd3fd1e58`: FAIL_PLAN with only 2 findings (F2 cleanup + F3 gates + F4 study all + PASS). Fixed here: + 1. §5.3 steps 7/8 unified into one transition model: local validation (hash + schema-major) is the + only precondition to SERVING; control-plane currentness gates only CONVERGENCE; three cases (a) + lease-expiry-while-serving keeps executing and leaves the admission quorum, (b) + restart-with-persisted-last-good locally validates and serves without control-plane contact, + (c) no locally valid snapshot = idle-and-loud. §13 test 8 exercises all three. + 2. Review-surface staleness: context-pack opener/state, Design constants S1–S6, PR body (updated + below) brought current. +- Owner directive **D-9** applied (drift log): §8.2 rewritten as **two decided operator surfaces** — + (1) production/admin automation console in the userland app, the only surface #890/#922 are + sufficient for (A7 narrowed accordingly: no diagnostics/journey views); (2) developer DevTools + behind new staged **P-6 DevTools RFC** re-evaluating epic #400 (+ #685/#780/#506 as evidence, not + ratified architecture), consuming this RFC's management/ history/convergence/OTel contracts. + Five-surface taxonomy recorded; this RFC designs none of the general frontend mechanisms. plan.md + D-3 constraint refined; P ranges P-1..P-6. +- Gates: `docs:links` green; `deno fmt --check` green on RFC + run-dir files. + +## 2026-08-11 PLAN-EVAL cycle 6 — architecture clean; record-bookkeeping findings fixed + +- Cycle 6 at `2518791f3`: lease/serving unification PASS; the whole D-9 amendment audit PASS (two + surfaces, P-6 staging, roadmap consistency, no mechanism pre-emption); "no unresolved runtime + architecture decision remains." FAIL_PLAN only on record integrity: plan sweep said P-1..P-5, + Design checkpoint said S1–S5/P-1..P-5, phase registry stale, PR body used singular "cockpit" and + mis-scoped item 9. All fixed here: sweep now P-1..P-6 with P-6 safe-deferral rationale; Design + constants/slices S1–S6 + P-1..P-6; phase registry through cycle 6; PR body reworded (two surfaces, + #890/#922 sufficiency scoped to surface 1 only). +- Cycle 7 launched as the final pass. + +## 2026-08-11 PLAN-EVAL cycle 7 — D-9 PR wording PASS; last vocabulary line + narratives fixed + +- Cycle 7 at `ed978eb68`: PR terminology finding PASS; architecture judgment stands (RFC unchanged + since cycle 6). Remaining: the Design domain-vocabulary line still read P-1–P-5 (same fmt-rewrap + trap as D-7 — the fix note claimed it fixed) and plan/context/PR progress narratives lagged the + cycle count. Fixed with grep verification: vocabulary now P-1–P-6; plan status + S5 slice text + describe cycles 1–7; context pack opens post-cycle-7; PR S5/DoD progress fields updated. Cycle 8 + is the closing pass on the reconciled record. + +## 2026-08-11 PLAN-EVAL cycle 9 — **PASS** + +- Closing pass at `28830c88a`: both cycle-8 record findings PASS; **every plan-gate checklist item + PASS; open-decision sweep: none**; the cycle-6 architecture-clean judgment stands (RFC/evidence + unchanged since). Verdict appended by the evaluator; gates re-verified by it (`docs:links`, + focused fmt, git diff --check) — all green. +- Run closes: RFC produced for the owner (PR #1446 stays draft pending ratification; artifact + file + delivered to the owner). Nine-cycle history preserved append-only in `plan-eval.md`. + +## 2026-08-11 S7 — RFC process normalization (owner-directed, pre-merge) + +- Owner directive: normalize PR #1446 to the canonical in-repo RFC process before merge; no + issue/milestone mutation. +- `git mv docs/architecture/rfc/rfc-0001-runtime-versioned-automation.md + rfcs/0000-runtime-versioned-automation.md` + — number stays `0000` until a maintainer assigns one at acceptance per `rfcs/README.md`. Added the + `0000-template.md` YAML frontmatter (status `Draft`, target-milestone Backlog / Triage; tracking + issue deferred — filing stays owner-gated) and replaced the "establishes `docs/architecture/rfc/`" + authority claim with a pointer to the canonical process. +- Living records updated: plan.md (deliverable, S4, new S7), context-pack.md, phase-registry.md G4, + plan-eval brief, evidence identifiers (`RFC-0001` → `RFC-0000`), 1444-impact.md tail, the + `.llm/2026-08-11-…` run summary, and the PR #1446 body. Preserved verbatim: `plan-eval.md` + (evaluator-authored, append-only — its `rfc-0001-…:line` citations anchor to historical revisions) + and dated historical worklog entries/PR comments. Recorded as drift D-10. +- Gates: `deno task docs:links` + `deno fmt --check` on touched files. diff --git a/rfcs/0002-runtime-versioned-automation.md b/rfcs/0002-runtime-versioned-automation.md new file mode 100644 index 0000000000..5053afa19a --- /dev/null +++ b/rfcs/0002-runtime-versioned-automation.md @@ -0,0 +1,858 @@ +--- +rfc: 0002 +title: Runtime-Versioned Automation — operator-managed workers, tasks, and triggers +status: Accepted +authors: ['@rickylabs'] +created: 2026-08-11 +tracking-issue: https://github.com/rickylabs/netscript/issues/1464 +target-milestone: Backlog / Triage +--- + +# Runtime-Versioned Automation: operator-managed workers, tasks, and triggers + +| | | +| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Status** | **Accepted** — owner-ratified; final adversarial PLAN-EVAL (Codex GPT-5.6 Sol · xhigh) recorded on PR #1446 | +| **Run record** | `.llm/runs/docs-rfc-runtime-versioned-automation--supervisor/` — research, evidence reports, drift, briefs | +| **Tracking** | Refs #1443 · #1445 · PR #1444 (control-plane split, D-10) · downstream of RFC [#890](https://github.com/rickylabs/netscript/pull/890) (merged 2026-08-03) and epic [#922](https://github.com/rickylabs/netscript/issues/922) (open) | +| **Evidence base** | `evidence/legacy-capability-map.md` (netscript-start @ `6ba9ba0`, 15 sections, 3 operator journeys) · `evidence/current-state-matrix.md` (this repo @ `2256a67bf`, hypotheses H1–H6, probes P1–P5) — both Codex-authored, supervisor-verified · `evidence/competitive-architecture-study.md` (9-system primary-source comparison, 2026-08-11) · `evidence/sandbox-isolation-survey.md` | +| **Authority** | This RFC follows the canonical process in [`rfcs/README.md`](README.md) (number `0000` until a maintainer assigns one at acceptance). On ratification, the roadmap in §12 is filed as a draft epic/issue graph; nothing files before that. | + +--- + +## Abstract + +NetScript's founding product promise includes a capability that, at every commit this run inspected +(legacy `netscript-start` @ `6ba9ba0`, this repo @ `2256a67bf`), has never been shipped end to end: +an **operator** — not a developer with a checkout — adds, updates, disables, or rolls back a +versioned task or trigger **on a running deployed stack**, including tasks that wrap legacy or +polyglot scripts (Python, .NET, shell), and watches it execute with full history, from a management +cockpit. + +The archaeology is unambiguous: in legacy `netscript-start` the versioned runtime trees +(`workers/runtime/tasks/v1.0.0.json`, `current` pointers, `schema.json`) were **dead wiring** — a +loader and watcher existed and no executable service ever imported them. What _did_ work was a +KV-backed task registry and a seven-runtime polyglot executor that resolved definitions per message +— live-update capable — with **no operator control plane in front of it**. The current repository +inherits the same split-brain: real engines, real versioned-store primitives, and no production seam +connecting them. + +This RFC designs the capability as it was always intended, on a clean break (owner decision: no +backward-compatibility or migration layer — the feature is pre-production and unused). It proposes: +a **two-plane architecture** (definition control plane / execution data plane); a **runtime +contribution model** extracted from the Frontend Contribution Layer pattern (schema-first contracts, +family-versioned envelopes, generated registries — no hardcoded topic switches); an +**immutable-revision store** with atomic activation, optimistic concurrency, and a full audit trail; +an **execution boundary port** layered over established isolation technology (scoped Deno +permissions → hardened subprocess → container/microVM), never a bespoke sandbox; a management API +and a cockpit specified as a downstream consumer of the frontend contribution layer; and an explicit +**replacement/cleanup inventory** that retires every competing experimental surface. + +## 1. Product intent and operator journeys + +These journeys are the product requirements. They come from the legacy evidence (what the cockpit +and CLI _promised_) and the owner's standing constraint (drift D-10, #1443 run): runtime-versioned +workers/tasks and triggers are an intentional differentiating capability that must not collapse into +compile-time configuration. + +### J1 — Live change and rollback + +An operator opens the cockpit (or CLI), edits a task's timeout/enablement or a trigger's route, +saves as a **draft revision**, validates it, and **activates** it. Every running replica picks it up +without a rebuild or restart. Activation is atomic — no replica ever observes a half-applied change. +The previous revision remains addressable; **rollback is activating it again**. Every step records +who, what, when, and why. + +_Legacy reality: `[DEAD]` — pointer edits changed nothing; enable/disable wrote a file nothing read +(`legacy-capability-map.md` Journey A)._ + +### J2 — Add and run a polyglot task + +An operator registers a new task that wraps an existing Python/.NET/shell script, declares its +runtime, entrypoint, arguments, timeout, and **capability grants** (network, filesystem paths, env), +test-runs it in a dry-run executed at the definition's boundary tier (enforcement guarantees per the +tier table in §5.4 — a polyglot dry-run at T1 is scoped-and-audited, not sandboxed), then activates +it. The task appears in the cockpit, executes on demand or via a scheduled trigger, and its +execution history (status, duration, captured output, correlation) is queryable. + +_Legacy reality: `[PARTIAL]` — the seven-runtime executor genuinely executed anything already in KV, +but no delivered path put an operator's task there; absent permissions meant `--allow-all` +(`legacy-capability-map.md` Journey B, §8)._ + +### J3 — Wire a trigger and audit what it did + +An operator declares a trigger (webhook/schedule/file-watch) that enqueues a worker job, fires a +test event, inspects the resulting event record, execution, and dead-letter state, and disables the +trigger — all live, all audited. + +_Legacy reality: `[PARTIAL]` — webhook ingress → durable event → idempotent processing → job enqueue +worked; the cockpit spoke an oRPC contract the delivered service never implemented; `fire` in the +CLI silently didn't dispatch (`legacy-capability-map.md` Journey C, §7)._ + +## 2. What the evidence actually shows + +Full detail: `evidence/legacy-capability-map.md` and `evidence/current-state-matrix.md` (run +record). The load-bearing findings: + +1. **The versioned trees never drove anything.** In both legacy and current code the + `@netscript/runtime-config` loader/watcher (`current` pointer → `/v.json`, fs-watch, + silent-empty on malformed input) has no executable consumer in any worker or trigger composition. + "Runtime configuration" was never runtime. (Legacy: confirmed by static reachability audit. + Current: hypothesis H1, confirmed by G2 — see matrix.) +2. **The execution engines are real and worth keeping conceptually.** A multi-runtime executor + (deno, python, dotnet, shell, powershell, cmd, executable) with timeout, output capture, and + OTel; a KV task registry resolved per message (live-update capable by construction); a trigger + processor with KV idempotency, DLQ, deferred replay, and bounded concurrency. +3. **There was never a coherent, revisioned operator control plane.** Real-but-partial operator + surfaces did exist — KV-backed worker job CRUD, and (current) KV-backed trigger enable/disable — + but nothing versioned, audited, or connected to the versioned documents: No create/update/delete + for tasks reaches any registry; scheduler timers load once at startup; trigger registries are + compiled TypeScript loaded once; the CLI's enable/disable and `config publish` wrote files + nothing read. +4. **Isolation defaults were dangerous.** Absent Deno permissions became `--allow-all`; non-Deno + runtimes ran directly on the host with inherited environment; PowerShell ran with + `-ExecutionPolicy Bypass`. +5. **Multiple sources of truth, none authoritative.** Static generated registries, KV registries, + versioned filesystem trees, `.netscript/runtime/*.json` CLI writes, and aspirational Prisma + schemas coexisted without reconciliation; deployment could promote a pointer whose documents + failed to copy. +6. **Schema tooling was split and unenforced.** Two diverged schema generators; the checked-in + worker schema rejected the checked-in task document; no loader validated anything against any + schema. On the current baseline, `generate runtime-schemas` receives empty schema sets from the + plugin snapshot (PR #1444 — an open draft at evaluation time — fixes configured-module _loading_ + on its branch; made _meaningful_ by this RFC). + +The design conclusion drawn throughout: **do not resurrect the pointer-file mechanism; build the +control plane the engines always lacked.** + +## 3. Decisions binding this RFC + +| Decision | Source | Consequence here | +| ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| Control-plane/runtime module split: `/plugin.ts` manifest-only + import-safe; `mod.ts` / `runtime.ts` are the app/runtime surfaces | Owner D-10 (#1443 run drift); ratified + constrained by this run's `1444-impact.md` (PR #1444 comment) | §5.1 builds the definition control plane behind the same import-safety law; manifests stay serializable data with additively versioned schemas | +| Complete redesign in scope; legacy bounded to outcomes/journeys | Owner directive (run drift D-4) | §§5–9 are clean-sheet with named reused _concepts_, not reused files | +| **No backward-compatibility or migration layer** | Owner directive (run drift D-5) | §10 is a replacement/cleanup inventory; no dual-read, no compat adapters, no deprecation windows | +| Cockpit is a downstream consumer of the Frontend Contribution Layer | Owner directive (run drift D-3); RFC #890 merged; epic #922 open | §8.2 models the cockpit on #922's contracts; §12 carries explicit dependency edges (#923–#932, #934); no cockpit slice lands before that cut | +| Wrap, don't reinvent; contract-first; doctrine archetypes | `AGENTS.md`, architecture doctrine | Every §5 component names its archetype and upstream primitives | + +## 4. Architecture overview + +Two planes, one contract vocabulary, one source of truth. + +```mermaid +flowchart LR + subgraph CP["Control plane (management service)"] + API[Management API
oRPC contract] + LC[Lifecycle engine
draft → validate → publish → activate] + STORE[(Definition store
immutable revisions + activations + audit)] + VAL[Validation
family schemas + static checks + sandboxed dry-run] + API --> LC --> STORE + LC --> VAL + end + + subgraph XP["Execution plane (per replica)"] + SNAP[Snapshot client
pull + verify + swap] + SCHED[Schedulers / queue consumers / trigger processors] + EXEC[Task executor
runtime adapters × execution boundary] + SNAP --> SCHED --> EXEC + end + + CLI[CLI] --> API + CKPT[Cockpit
frontend contribution, post-#922] --> GW[#934 procedure gateway] --> API + STORE -- "activation events" --> BUS[[Change feed]] + BUS --> SNAP + EXEC -- "history + OTel" --> OBS[(Execution history)] + OBS --> API +``` + +- The **control plane** owns definitions: families, revisions, activations, audit, validation. It + runs inside the management service and never executes operator workloads. +- The **execution plane** owns running: schedulers, trigger processors, queue consumers, and the + executor. It consumes **verified immutable snapshots** and never mutates definitions. +- The seam between them is the **activation snapshot**: a content-addressed, schema-validated + document set. Replicas converge on snapshots; they do not watch files. + +Deployment view (Aspire): + +```mermaid +flowchart TB + subgraph Stack["Deployed stack (Aspire-composed)"] + MGMT["automation management service
(control plane + history API)"] + W1["workers runtime replica(s)"] + T1["triggers runtime replica(s)"] + DB[(Project database
system of record)] + KV[(KV / queue)] + MGMT --> DB + W1 -- snapshot pull / change feed --> MGMT + T1 -- snapshot pull / change feed --> MGMT + W1 --> KV + T1 --> KV + end + OP[Operator] --> CKPT2[Cockpit / CLI] --> MGMT +``` + +## 5. The proposed design + +### 5.1 Runtime contribution model — the #890 pattern, extracted + +The Frontend Contribution Layer solved the same class of problem for UI: plugins contribute +declarative, schema-versioned payloads; the host discovers them through generated, type-checked +registries; nothing is hardcoded per plugin. RFC #890's specific contracts are **not** copied — the +_pattern_ is: + +- **New ARCHETYPE-1 contracts package** (working name `@netscript/automation-core`; final name at + implementation): serializable types, the Zod family schemas, the family envelope, the **management + oRPC contract**, the lifecycle state-transition table (as data), and the error vocabulary. **No + engine code, no ports, no adapters**, no fresh/preact/DB deps, JSR-clean — types and small + invariants only, the same boundary `@netscript/plugin-frontend-core` holds. +- **Family-versioned envelope.** A `DefinitionFamilyDescriptor` identifies `(family, major)` — + initial families `task@1` (workers) and `trigger@1` (triggers). A plugin declares the families it + owns via a **declarative manifest field** (per `1444-impact.md` C2/C3: data, additively + extensible, no functions). Adding a family is additive; changing one is a new major. +- **One schema authority.** Each family ships exactly one Zod schema from which everything derives: + admission validation in the lifecycle engine, `netscript generate runtime-schemas` editor output, + cockpit form generation, and documentation. This retires the legacy two-generator drift (evidence + §2.6) by construction. +- **No hardcoded topics.** The five hardcoded topic names (`jobs|sagas|triggers|features|tasks`) and + every `topic === 'workers'`-shaped branch are replaced by family registration. The `quality:scan` + hardcoded-plugin-name gate already polices the anti-pattern this removes. + +Family payloads for the initial families (illustrative, contract-level): + +```ts +// task@1 — one definition +{ + id: 'transform-data', + name: 'Data transformation', + runtime: 'python', // deno | python | dotnet | shell | powershell | cmd | executable + entrypoint: 'scripts/transform.py', // resolved inside the project bundle root, never absolute + args: ['--mode', 'incremental'], + timeoutMs: 60_000, + retry: { maxAttempts: 3, backoff: 'exponential' }, + capabilities: { // deny-by-default; absence = NOTHING (reverses legacy --allow-all) + net: ['api.internal:443'], + read: ['data/incoming'], + write: ['data/processed'], + env: ['TRANSFORM_MODE'], + secrets: ['s3-archive'], // resolved by the host at spawn, never stored in the definition + }, +} +``` + +```ts +// trigger@1 — one definition +{ + id: 'csv-arrival', + kind: 'file-watch', // webhook | scheduled | file-watch (queue/stream reserved) + match: { paths: ['data/incoming/*.csv'] }, + action: { enqueueTask: 'transform-data', dedupeKey: '{{path}}' }, + enabled: true, +} +``` + +**Scheduling is owned by the trigger family — resolved, not deferred.** `task@1` deliberately has +**no `schedule` field**: a task runs on demand (run-now), from a trigger action, or in a dry-run. +Recurring execution is expressed as a `scheduled` `trigger@1` definition whose action enqueues the +task. This makes the scheduled-trigger path the **single operator-facing cron surface** and stops +this RFC from deepening the recorded `CRON-SUBSYSTEM-DUP` debt (workers `.schedule()` on +code-defined T0 jobs vs `defineScheduledTrigger` — `.llm/harness/debt/arch-debt.md`). The +developer-facing T0 `.schedule()` question remains that debt entry's maintainer call; this RFC +neither preempts it nor adds a third cron path. + +### 5.2 Definition store — immutable revisions, atomic activation, real audit + +**Port + adapters — both live in the runtime core package `@netscript/automation-runtime` (§9), per +the thin-connector law and the recorded adapter-relocation debt; the contracts package carries only +the data shapes they exchange.** The system of record is the **project database (Postgres)** in +production; a **KV adapter** serves local development and DB-less scaffolds. The filesystem is +demoted from source of truth to **interchange format**: `netscript automation export/import` moves +definition sets as git-friendly JSON for review workflows, but the running system never watches +files. + +Store semantics (all families, uniformly): + +- **Revisions are immutable and content-addressed.** `publish` writes + `(family, definitionId, revisionN, contentHash, authoredBy, publishedAt, schemaVersion, body)`. + Republishing identical content is a no-op returning the existing revision. +- **Activation is a transactional epoch.** Every activation — one definition or an explicit + cross-family set — commits, in a single store transaction, an **activation-set manifest**: + `(epoch, entries[(family, definitionId, revision, contentHash)], actor, reason)` where `epoch` is + a store-issued, strictly monotonic integer. The commit takes an `expectedEpoch` precondition and + fails on mismatch — optimistic concurrency for racing operators (fixes evidence H6/P1: the current + store loses a concurrent promotion 20/20). Because the manifest spans every family it touches, a + trigger revision can never become visible before the task revision it references (referential + validation runs at commit); there is no whole-directory pointer whose promotion can outrun its + content (legacy defect §2.5), and no per-family snapshot that can be observed out of order. + **Every epoch materializes the complete active desired state**: entries the activation does not + touch are carried forward automatically by the store into the new epoch's snapshot (operators + activate deltas; replicas only ever see totals). Disable is a carried flag on the active revision; + removal is an explicit tombstone entry in the set; re-activating the already-active revision is an + idempotent no-op that issues no new epoch. +- **Rollback = activate an older revision.** Nothing is ever deleted by rollback; retention is a + policy on drafts and execution history only. +- **Audit is an append-only event stream** on the same transaction: actor identity (from the auth + plugin's session), action, before/after revision, reason string, correlation id. The audit feed is + itself queryable through the management API (J1/J3 requirement). +- **Lifecycle:** `draft → validated → published → active → superseded`, with `disabled` as a flag on + the active revision, not a separate copy. Draft validation runs the family schema, static checks + (entrypoint exists in the bundle, capability grammar, cron validity), and an optional **sandboxed + dry-run** (J2) through the same execution boundary the real run would use, tagged as a test + execution. + +**Adapter parity is a contract, not an aspiration.** The store port's semantics — serializable +publish+activate+audit transaction, monotonic epoch issuance, snapshot-consistent reads, idempotent +re-activation — are pinned by **one adapter-conformance suite** that both adapters must pass. Where +the dev **KV adapter** cannot honestly satisfy a semantic (multi-writer epoch issuance under +concurrency), it is **narrowed, not faked**: the KV adapter is documented and enforced as +single-writer/single-instance development only, and refuses fleet features (replica admission, +convergence tracking) rather than approximating them. Production always runs the Postgres adapter. + +### 5.3 Snapshot propagation — how a running stack converges + +The unit of propagation is the **activation-set snapshot**: the epoch-stamped manifest plus the full +bodies of every entry, content-addressed as a whole. Replica convergence: + +1. **Change feed** (primary): replicas hold a long-poll/SSE subscription to the management service; + an activation event carries `(epoch, snapshotHash)`. +2. **Ordered pull + verify + swap:** the replica fetches the snapshot, verifies the content hash, + validates entries against the family schemas it was compiled with, and swaps its in-memory + definition state atomically. **Epochs are applied strictly monotonically**: a replica at epoch N + rejects any snapshot with epoch ≤ N, so a delayed feed event can never overwrite a newer polled + state (content hashes give identity; the epoch gives order). A partial or failed fetch changes + nothing — the replica stays on its current epoch and retries. +3. **Poll fallback + startup:** on boot and every N seconds, replicas compare epochs (cheap ETag on + the manifest). There is no fs-watch anywhere in the design: `Deno.watchFs` semantics on container + overlay filesystems and network mounts are exactly the operational trap the legacy design would + have hit (research F1). +4. **Fleet admission and acknowledgment:** replicas register with the management service and report + the schema majors they support plus the epoch they run (heartbeat). Activation of a snapshot + containing a family major some registered live replica cannot accept is **rejected at commit** + (override requires an explicit `--force-drain` acknowledging those replicas will hold last-good + until redeployed). Replicas acknowledge each applied epoch; the management surface exposes + **convergence status** (which replicas are at which epoch) with an alerting SLO, and a replica + that cannot validate keeps its last-good state **loudly** — fail-visible, never fail-empty + (reversing the loader's silent-empty semantics, evidence §2.1). Divergence is therefore bounded, + visible, and actionable (roll back to the epoch the stragglers hold, or redeploy them), not + indefinite. +5. **Applying a swap** re-registers schedules/watch registrations through each engine's reload port + (scheduled-trigger adapters refresh timers — fixing "timers load once", evidence §2.3; trigger + processors re-install definitions). Executors need nothing: they resolve definitions per dispatch + from the current snapshot, the one property the legacy KV path already had right. +6. **Cross-engine dispatch is revision-pinned, not name-pinned.** Convergence is asynchronous, so a + trigger replica at epoch N+1 may enqueue work while a worker replica still runs epoch N. Trigger + actions therefore enqueue `(taskId, revision, contentHash)` — never a bare id — and the worker + dispatcher resolves the **pinned revision** from the immutable revision store (cache-through; + revisions never change, so the lookup is always safe) regardless of its own epoch. Pinned-lookup + failures are **classified, not conflated**: transient outcomes (management service/store + unreachable, timeout) surface as queue-native retry with backoff under the message's retry + budget; terminal outcomes (revision absent, content-hash mismatch, unsupported schema major) + dead-letter immediately and loudly. Because revisions are immutable and content-addressed, + replicas keep a **local revision cache** (snapshot bodies pre-warm it; entries never invalidate), + so a pinned lookup needs the network only for a revision the replica has never seen. Fleet + atomicity is therefore not required for correctness — only for freshness, which convergence + tracking already bounds. +7. **Registration is leased — leases gate epoch admission, never serving.** Replica registrations + carry a heartbeat TTL. Admission (step 4) counts only replicas with live leases. **Two + validations exist and must not be conflated**: _local validation_ (content-hash integrity + + schema-major compatibility against the families the replica was compiled with) is the only + precondition to _serving_ a snapshot; _control-plane currentness_ (re-registering and + fetching/validating the current snapshot) is the precondition to _converging to new epochs_, + never to serving an already locally-validated one. The lease closes the admission-time-of-check + gap by keeping lapsed replicas out of the admission quorum until they re-register — not by + stopping their execution. +8. **Availability contract (decided): indefinite last-good serving — a replica never self-drains.** + There is deliberately **no serving bound and no expiry transition**; the staleness SLO bounds + _silence_ (alerting), not _serving_. One transition model for the three cases, all using the two + validations of step 7: + - **(a) Continuously serving replica whose lease expires** (missed heartbeats or full + control-plane outage): keeps executing its last-good snapshot indefinitely, drops out of the + admission quorum, is marked stale past the SLO; on reconnect it re-registers, validates the + current snapshot, and converges — or, on schema-major mismatch, keeps serving last-good loudly + per step 4's force-drain rules. + - **(b) Restarted/rejoining replica with persisted last-good state**: locally validates the + persisted snapshot (hash + schema-major — no control-plane contact required) and serves it + under the same stale-marking rules; converging to anything newer requires re-registration and + current-snapshot validation as in (a). If local validation fails (corrupt or + compiled-incompatible persisted state), it falls to (c). + - **(c) Cold start with no locally valid snapshot**: idle-and-loud — registers nothing, serves + nothing, invents nothing, retries registration with backoff until the control plane answers. + Activations committed during an outage simply find fewer acked replicas — visible as + non-convergence, resolvable by rollback or redeploy. The one deliberate consequence: during an + outage, work pinned to a revision the replica has _never seen_ rides the transient-retry class + of step 6 and can eventually dead-letter — mitigated in practice by the revision cache covering + everything the replica has ever run. + +Multi-instance single-fire semantics for schedules and file-watches (leader lease vs distributed +lock vs queue-native delay) is **staged** — see §11 prerequisite RFC P-1. Until it lands, the +deployment shape constrains scheduled/file-watch processors to one replica (as legacy Aspire config +already implicitly did) while webhook and queue paths scale out. + +### 5.4 Execution model — runtime adapters × execution boundary + +The proven concept from the evidence is kept: **`MultiRuntimeTaskExecutor` with per-runtime +adapters** (argv construction for the seven runtimes survives as a concept — it is the polyglot +differentiator). The redesign separates what the legacy code conflated: + +- **Runtime adapter** (how to invoke: `deno run`, `python`, `dotnet`, …) — a compatibility concern. +- **Execution boundary** (what it may touch) — a security concern, a separate port with layered + adapters chosen **per trust tier**, never rolled ourselves: + +| Tier | Workload | Boundary adapter | Technology (all established, see survey) | +| ---- | -------------------------------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| T0 | First-party compiled jobs (today's `jobs`) | in-process | none needed — already app code | +| T1 | Operator-defined tasks (this RFC's default) | **hardened subprocess** | Deno runtime: capability grants are **enforced** as explicit `--allow-*` flags (empty ⇒ no flags — deny-by-default, reversing legacy `--allow-all`), with `--frozen`/`--cached-only`. All runtimes: `clearEnv` + explicit env allowlist (no host env inheritance), entrypoint-root confinement at _resolution_ time (not an OS jail), timeout + kill-tree, cgroup CPU/memory caps where the host provides them. **For non-Deno runtimes (python/dotnet/shell/powershell/cmd/executable) T1 capability grants are declarative + audited, NOT enforced** — a native child can read host files, open sockets, and spawn processes; enforcement for polyglot requires the T2 OS boundary (recorded debt: non-Deno runtimes inherit host OS privilege absent an external sandbox) | +| T2 | Untrusted / multi-tenant / marketplace definitions | **container / microVM boundary** | gVisor or Firecracker-class isolation behind the same port; staged (§11 P-2) — required before any marketplace or tenant-facing story | +| T3 | Capability-scoped pure compute | **WASM/WASI component** | staged research (§11 P-2); attractive (vendor-reported fast instantiation, deny-by-default ABI — verify at P-2, no empirical claim here) but polyglot-incomplete | + +Grounding (run evidence `evidence/sandbox-isolation-survey.md`, committed in the run dir, plus +Deno's primary documentation — https://docs.deno.com/runtime/fundamentals/security/ and +https://docs.deno.com/runtime/reference/permissions/#subprocesses): Deno's own security +documentation states `--allow-run` subprocesses escape the permission sandbox and recommends OS or +VM isolation for genuinely untrusted code — so T1 is honest about being a _scoping_ boundary for +semi-trusted operator content, and T2 exists as a port adapter rather than a bespoke sandbox. A +child process with Deno flags is a permission scope, **not** a tenancy boundary; the RFC never +claims otherwise. Stated once, bluntly: **T1's enforceable perimeter is exactly (a) Deno-runtime +permission flags, (b) environment content, (c) resolution-time path confinement, (d) lifetime and +resource caps.** Everything else at T1 — filesystem/network scoping for native runtimes — is a +declared, audited intent that only T2 can enforce. The management API surfaces each definition's +tier so this is a visible operational fact, not fine print. + +Reliability semantics (uniform, in the dispatcher not the adapters): deadlines enforced by the +boundary; **retry driven by the queue's native nack/redelivery** — the dispatcher rethrows task +failures instead of swallowing them (fixing evidence §2.3's dead `maxRetries`); idempotency keys on +trigger-originated dispatches (keeping the trigger processor's proven KV idempotency + DLQ); +cancellation as a first-class management action that signals the boundary; per-definition +concurrency caps and per-family quotas. + +### 5.5 Secrets, identity, and RBAC + +- Definitions reference secrets **by name** (`capabilities.secrets`); the execution host resolves + them at spawn into the child environment. Secret material is never deliberately persisted: it does + not appear as definition fields, snapshot content, or audit-event payloads by construction. For + **captured execution output** the guarantee is the bounded best-effort redaction of §6's trust + assumptions — a child that transforms and prints a secret can defeat redaction, and that residual + disclosure risk is documented, not denied. +- Management API actions require an authenticated principal (auth plugin session); RBAC is + role-per-action (`author`, `approver`, `operator`, `viewer`) with an optional two-person rule + (`author ≠ activator`) as policy, enforced in the lifecycle engine — policy data lives with the + store so the CLI and cockpit get identical enforcement. +- The audit stream (§5.2) is the compliance surface; execution history (§7) links back to the + activation that made the executed revision live. + +## 6. Threat model + +Assets: host integrity, project data, secrets, stack availability, audit integrity. + +| # | Threat | Vector | Mitigation (§) | +| --- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| TM1 | Malicious/compromised operator publishes a hostile task | Management API | RBAC + two-person activation (5.5); capability deny-by-default where enforceable (5.4 tier table); clearEnv + env allowlist + resolution-time path confinement at T1; T2 for untrusted tenancy; full audit (5.2) | +| TM2 | Task escapes its scope | `--allow-run`/FFI, host env, path traversal in entrypoint | capabilities grammar forbids `run`/`ffi` at T1 by default (Deno-enforced); entrypoint-root confinement at resolution time — not an OS jail (5.4); `clearEnv` (5.4); non-Deno scope escape is possible by design at T1 (unenforced grants, 5.4) — T2 boundary for real hostility | +| TM3 | Poisoned definition alters behavior in flight | store tampering, snapshot MITM | immutable content-addressed revisions; snapshot hash verification before swap (5.3); DB as single writer | +| TM4 | Replay/duplication floods workers | webhook replay, replica double-fire | trigger idempotency keys + KV claims (proven engine, 5.4); single-fire staging constraint (5.3); per-family quotas | +| TM5 | Secret exfiltration via definitions or logs | env dumps, history output capture | secrets-by-name resolution (5.5); history redaction of granted-secret env names (7); audit never stores bodies of secret values | +| TM6 | Availability: runaway task starves the stack | fork bombs, infinite loops | deadlines + kill-tree + cgroup caps (5.4); concurrency caps; DLQ isolates poison messages | +| TM7 | Supply chain: task pulls hostile dependencies at run time | `deno run` remote imports, pip | T1 Deno: `--cached-only`/`--frozen` per Deno guidance; polyglot runtimes documented as trusting their local toolchain until T2; staged marketplace trust = P-3 | +| TM8 | Audit evasion | direct DB writes, log tampering | audit appended in the same transaction as the mutation (5.2); management service is the only writer role in production; not tamper-evident against a hostile DB admin (trust assumptions below); independent audit sink staged with P-3 | +| TM9 | Control-plane code execution at manifest load | configured `plugin.ts` modules run in the #1444 child loader with `--allow-read --allow-net` | per `1444-impact.md` C8: `clearEnv` child + 30s timeout (shipped in #1444); this RFC adds the loader policy — lockfile-pinned resolution with `--cached-only` as the warm-cache default, network permitted only for an explicit cold-cache install step, cold-cache failure is a loud error (never a silent fallback); capability prompt staged with P-3; proving gate: manifest load succeeds with network disabled once the cache is warm (slice A2a) | + +**Trust assumptions (v1, explicit):** the project database and its admins are trusted (audit is +recorded evidence, not a tamper-proof ledger); the management-service transport is authenticated TLS +inside the stack (snapshot integrity relies on that channel plus content hashes — hashes give +integrity-of-identity, not authentication; a signed-snapshot upgrade is bundled with P-3); secret +redaction of captured output is **bounded best-effort** (known secret values and granted env names +are redacted; a child that transforms and prints a secret defeats redaction — residual risk stated +in the operator docs). Residual risk at T1 is stated, not hidden: a task granted broad capability +can misuse it, and non-Deno grants are unenforced (§5.4); T1 is a scoping-and-accountability +boundary. Anything beyond that trust level must run at T2, and the roadmap orders T2 before any +tenant-facing exposure. + +## 7. Observability and execution history + +- **OTel**: every dispatch opens `netscript.automation.execute` with attributes (`family`, + `definition.id`, `revision`, `runtime`, `boundary.tier`, `trigger.correlation`); lifecycle actions + emit `netscript.automation.lifecycle` events (publish/activate/rollback). Trigger processing keeps + its existing trace parenting. Spans and history records share the execution id. +- **Execution history** is a first-class store (same DB in production): queued → running → + completed/failed/killed/timed-out transitions written by CAS (fixing the read-modify-write race, + evidence legacy §6), captured stdout/stderr (bounded, secret-redacted), exit classification, + duration, and the `(revision, snapshotHash)` that ran — so "what exactly executed" is always + answerable (J2/J3). +- **Acceptance returns an address.** Run-now and trigger-fire return the execution id at enqueue + time (fixing "triggered: true and nothing to look at", evidence legacy §6). +- Scheduled and file-watch events flow through the same durable event path as webhooks (closing the + history gap where only webhooks persisted). + +## 8. Management surface + +### 8.1 API and CLI + +One oRPC management contract (in the contracts package) serves CLI and cockpit identically: +family/definition/revision CRUD-by-lifecycle, activation set operations, dry-run, execution history +queries, audit queries, and an SSE change feed. The CLI (`netscript automation …`) becomes the +single command surface; the `config override` group and workers-plugin +`config-edit`/`config-publish` duplicates are retired (§10). + +`netscript generate runtime-schemas` is reimplemented over family schemas (single authority, §5.1) +and finally has meaningful output by construction; its configured-module loading contract is #1444's +(child-process, import-safe, manifest-only). + +### 8.2 Operator frontends — two surfaces, decided (owner directives D-3 + D-9) + +**Decision: production operator management and developer diagnostics are two distinct hosts and two +distinct contribution surfaces — not one ambiguous "cockpit."** RFC +[#890](https://github.com/rickylabs/netscript/pull/890) is merged and real, but it ratifies +primarily the **userland `app` contribution family** (routes/islands/zones/nav/theme plus the +deny-by-default procedure gateway [#934](https://github.com/rickylabs/netscript/issues/934)); it +does not settle the complete frontend contribution problem. Five contribution surfaces exist in that +larger problem — (1) userland UI via the `app` family; (2) Fresh UI +registry/component/style-dictionary extensions generated into userland (potentially extending the +CLI's fresh-ui commands); (3) deferred Vite plugin contribution; (4) a first-class **DevTools +contribution family/host**; (5) SDK contribution, owned by its separate RFC. **This runtime RFC +designs none of those general mechanisms.** It consumes (1) and stages (4). + +**Surface 1 — production/admin automation console (this RFC's A7, in the userland app).** Ships as +frontend contributions from the automation connector (§9), rendered by the host app per #890's `app` +family: list/detail/run/history pages per automation family, draft-edit forms generated from family +schemas, activate/rollback flows, client data access exclusively through the #934 gateway — no +bespoke Fresh seam, no direct service URLs. For **this surface only**, #890/#922 are sufficient. +Minimum dependency cut from epic [#922](https://github.com/rickylabs/netscript/issues/922) (all +children verified OPEN 2026-08-11): Wave-0 proofs #923–#927 (they gate contract freeze), Wave-1 +spine #928 (contracts) · #929 (pointer axis) · #930 (registry emissions) · #931 (host runtime) · +#932 (scaffold wiring), plus #934. #933 (workers dogfood panel) is the natural first surface to +extend rather than duplicate; later DX/testing slices (#935+) are _not_ on the critical path. + +**Surface 2 — developer DevTools (staged behind P-6, NOT built by this RFC).** Runtime diagnostics, +live definition/state inspection, execution-journey visualization, and developer-facing management +affordances belong to a dedicated **DevTools contribution family/host** that #890 did not ratify. +The Dev Dashboard epic [#400](https://github.com/rickylabs/netscript/issues/400) and its design +record (#685, draft visual PR #780, older #506) predate the modern RFC profile — they are +**evidence, not a ratified DevTools architecture**. A new dedicated **DevTools RFC** (§11 P-6) +re-evaluates #400 against the modern contribution model and consumes the stable contracts this RFC +produces: the management oRPC contract (§8.1), the audit/history stores (§5.2, §7), the convergence +surface (§5.3), and the OTel vocabulary (§7). A7 deliberately does not claim diagnostics or journey +views; building them on the app family would pre-empt the DevTools architecture. + +Every backend section of this RFC (§§5–7, 8.1) is frontend-independent and may proceed before either +surface lands; **no frontend slice of either surface may start before its stated dependency** +(roadmap §12 edges; P-6 for surface 2). + +## 9. Package and plugin ownership + +Five options were compared (per owner directive; evaluation criteria: doctrine fit, dependency +direction, JSR packaging, plugin extensibility, deployment topology, trust boundaries, DX/token +cost, whether a central service is genuinely needed): + +| Option | Shape | Verdict | +| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| O1 | Extend `runtime-config` + workers/triggers in place | ✗ — preserves the split-brain and hardcoded topics; `runtime-config`'s contract (silent-empty fs snapshots) is the opposite of §5.3; retired instead | +| O2 | One framework-neutral core package (contracts, lifecycle, ports) | ✓ as the foundation — but contracts alone ship no service, storage, or UI | +| O3 | Split contracts / control-plane / client / runtime packages day one | ✗ now — speculative package multiplication before a consumer exists (doctrine anti-pattern); revisit only if dependency direction forces it | +| O4 | Thin central **connector plugin** composing the management service, Aspire resources, migrations, telemetry, and (post-#922) frontend — adapters/ports live in the runtime core; engines stay in workers/triggers cores | ✓ — matches the existing plugin contribution machinery (services, migrations, Aspire, frontend-to-be); gives the control plane a deployable home without welding it into either engine plugin | +| O5 | No central home; host app composes axes directly | ✗ — every consumer re-implements lifecycle/API/cockpit; the "each host re-invents discovery" failure #890 §1 already documented | + +**DECIDED: O2 + O4, corrected to doctrine. This is binding; there is no live fallback.** Three +homes, each inside its archetype's limits: + +1. **`@netscript/automation-core` — ARCHETYPE-1, contracts only**: family envelope, `task@1` / + `trigger@1` Zod schemas, the management oRPC contract, lifecycle state-transition table (data), + error vocabulary. No ports, no adapters, no engine code — doctrine limits ARCHETYPE-1 to types + and small invariants (`docs/architecture/doctrine/06-archetypes.md`). +2. **`@netscript/automation-runtime` — ARCHETYPE-2/3 behavioral core**: the **ports** + (store/boundary/reload/feed), the lifecycle engine, validation pipeline, epoch/snapshot builder + and client, the adapter-conformance suite, and the **store adapters (Postgres, narrowed dev-KV)** + on `@netscript/kv`/db primitives. Port→backend adapters live in a core package — the placement + law the open `PLUGIN-RUNTIME-ADAPTER-RELOCATION` debt (`.llm/harness/debt/arch-debt.md`) already + established; this RFC follows it from day one. +3. **`plugins/automation` — ARCHETYPE-5 thin connector, composition only**: hosts the management + service entry that binds the automation-core contract to automation-runtime lifecycle calls, + declares Aspire resources and the store migrations, re-exports the consumer surface, and + (post-#922) carries the cockpit frontend contributions. It owns **no adapter, no port, no + lifecycle logic**. Each connector axis names what it wires: service → runtime lifecycle engine; + migrations → runtime store schema; telemetry → core span vocabulary; frontend → management + contract procedures. + +`plugin-workers-core` / `plugin-triggers-core` register their families and implement the engine-side +reload/dispatch ports; the workers/triggers connector plugins stay thin. The control plane's +deployment unit is the connector's declared management service — one per stack, horizontally passive +(any instance serves; the store serializes epochs). + +The previously recorded no-connector fallback is **withdrawn**, with the comparison made at equal +fidelity: without `plugins/automation`, the management service and migrations would live in workers +or triggers (wrong owner — each drags the other's families in, inverting dependency direction), in +the host app (every consumer re-composes the control plane — the O5 failure #890 §1 documented), or +in a required core service package (a deployment unit the plugin system already expresses as a +connector). Only the connector keeps `plugins/automation → +automation-runtime → automation-core` +acyclic and installation optional. Naming is the sole open item (§15), deferred safely to A0. + +## 10. Replacement and cleanup inventory (clean break, D-5) + +No consumer migration is owed. On implementation, the selected architecture **replaces** the +following; each is deleted or rewritten in the wave that supersedes it (§12), so no competing +experimental surface survives: + +| Surface | Disposition | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `packages/runtime-config` (loader, watcher, types) | **Retire the package.** The name may be reclaimed by the contracts package only if confusion-free; fs-pointer semantics do not survive | +| CLI `config override` group + `RuntimeConfigStorePort` + `deno-runtime-config-store` + `runtime-override.ts` loaders | **Remove**; superseded by `netscript automation` over the management API. The temp+rename activation idea survives _conceptually_ in the KV/DB adapters' atomicity requirements | +| Workers-plugin `config-edit` / `config-publish` / `.netscript/runtime/*.json` writes | **Remove** (evidence H5: duplicate, non-functional DX) | +| Scaffolded `workers/runtime/**`, `triggers/runtime/**` trees + `current` pointers + `schema.json` emissions | **Stop scaffolding**; replaced by export/import interchange (§5.2) and generated editor schemas from family schemas. Existing scaffold output is unused by any runtime — deleting the emitters breaks nothing (pre-production, D-5) | +| Windows deploy runtime-config writer + its schema generator (second authority) | **Remove**; deployment carries snapshots, not pointer trees | +| Dead Prisma schemas for workers/tasks/executions and trigger definitions | **Rewrite** as the connector's real migrations (store + history + audit) | +| `RuntimeTask` (permissive) vs `TaskDefinition` (rich) dual task models | **Collapse** into the `task@1` family schema — one model, one authority | +| Legacy trigger cockpit contract (`triggers.contract.ts` v1, unimplemented server) | **Supersede** by the management contract; the trigger _engine_ contracts remain | +| README/doc claims of deploy-free operator behavior (`runtime-config`, workers, triggers READMEs) + the Windows env-builder comment claiming loader/watcher wiring | **Rewrite** with the shipped reality — docs may not promise what no composition delivers (evidence: G2 "documented but unproven" list) | +| Tests locking the above (e.g. the empty-`schemas` snapshot test) | **Rewrite** with their surfaces; the PLAN-EVAL green-gate rule (no test deleted without recorded rationale) applies per slice | + +**File-level dispositions** (the working checklist wave A6a–A6c executes; `del` = delete, `fold` = +behavior moves into the new architecture then the file goes, `rw` = rewrite in place, `keep` = +survives as-is): + +| Files (current repo) | Disposition → owning slice | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `packages/runtime-config/**` (loader, watcher, types, tests, README) | del → A6a | +| `packages/cli/src/kernel/ports/runtime-config-store-port.ts`, `kernel/adapters/config/runtime-config/**`, `kernel/adapters/config/runtime-override.ts` | del → A6a | +| `packages/cli/src/public/features/config/override/**` (`override-group`, `runtime-lifecycle-command`, `manage-runtime-overrides` + tests) | del → A6a (CLI replaced by `netscript automation`, A2c) | +| `plugins/workers/src/cli/local-runtime-backend.ts` project-file discovery + direct-execute + `config-edit`/`config-publish` | fold (dry-run via management API; optional `automation import` authoring aid) → A5b/A6a | +| `packages/plugin/src/domain/constants.ts` `runtime-config-topic` axis entry, `config/domain/runtime-config-topic-contribution.ts`, `config/domain/plugin-contributions.ts` topic wiring, `config/builders/plugin-builder.ts` topic builder, `abstracts/plugin-runtime-config-topic-contribution.ts`, public re-exports | fold → the family-declaration manifest field (§5.1) in A0/A2a, then del → A6a | +| `packages/cli/src/kernel/adapters/config/plugin-registry.ts` `{ schemas: [] }` projection + `plugin-registry.test.ts` placeholder pin | rw → A6a (family-schema discovery; test rewritten with rationale) | +| `packages/cli/src/public/features/generate/runtime-schemas/**` | rw over family schemas (keep planner/duplicate-owner/dry-run behaviors) → A6a | +| `plugins/workers/src/cli/official-sample-configuration.ts` runtime-tree/sample emissions (workers + sagas + triggers docs, dangling `$schema` refs) + `copy-official-plugin-samples*` tests | del emissions, rw tests → A6b | +| `plugins/workers/src/adapter/resources/glue/runtime.stub.ts`, `plugins/triggers/src/adapter/resources/glue/runtime.stub.ts` | rw → snapshot-client bootstrap (A3a/A4a); scaffold emission updated → A6b | +| `plugins/triggers/src/runtime/project-trigger-registry.ts` (+ `.netscript/generated/plugin-triggers/**` generation path, `triggers/mod.ts` fallback) | fold → `automation import --from-registry` authoring input (A4a); load-once boot path del → A6b | +| Trigger KV enabled-state store + `routers/v1.ts` enable/disable backing | fold → revision lifecycle (A4b); store del → A6b | +| `packages/cli/src/kernel/adapters/windows/runtime/runtime-config-writer.ts`, `windows/runtime/runtime-config-schema.ts`, `servy-environment.ts` `NETSCRIPT_RUNTIME_CONFIG_DIR`/`NETSCRIPT_TASKS_DIR` emission + wiring comment, `deploy/build/build-windows-runtime.ts` runtime-config passes | del/rw → A6b | +| `packages/runtime-config` references in `kernel/constants/jsr-specifiers.ts`, `scaffold-workspace-packages.ts`, `maintainer/domain/local-packages.ts`, `kernel/assets/agent-docs.generated.ts` | rw (regenerate) → A6b | +| `RuntimeTask`/`TriggerOverride` types and every import site | del with the package → A6a (family schemas are the one model) | +| READMEs claiming deploy-free operator behavior (`packages/runtime-config/README.md`, `plugins/workers/README.md`, `plugins/triggers/README.md`) + doc-site pages citing them | rw to shipped reality → A6c | +| T0 job surface: code-defined jobs + `.schedule()` + KV job CRUD routes | keep, with CRUD narrowed to read/enable/disable → A3b; `.schedule()` fate stays with `CRON-SUBSYSTEM-DUP` | +| Trigger enabled-state full surface: `packages/plugin-triggers-core/src/{ports,stores,testing,public}/**` enabled-state port/store/test-double/public exports + their consumers in `plugins/triggers/services/**` and `plugins/triggers/src/runtime/**` | fold → revision-lifecycle flag (A4b); port/store/testing/public exports + consumer wiring del/rw → A6a (core) + A6b (plugin composition) | +| Windows env plumbing beyond the writer: `packages/cli/src/kernel/adapters/windows/environment/env-file-content.ts`, `env-file-values.ts`, `kernel/assets/windows/env.template`, the generated embedded asset | rw (drop runtime-config/tasks-dir keys; regenerate asset) → A6b | +| Live `NETSCRIPT_TASKS_DIR` readers: `packages/plugin-workers-core/src/executor/adapters/path-resolution.ts`, `plugins/workers/worker/job-execution.ts` | fold → bundle-root resolution from the definition's snapshot context (A3a/A5a); env-var path del → A6b | +| CLI dependency composition importing/constructing/exporting `runtimeConfigStore` (`packages/cli/src/public/features/root/public-command-dependencies.ts`) | rw (drop the store from the DI surface with the override group) → A6a | +| Public deploy option surface for runtime-config: `--force-runtime-config` / `--fail-on-drift` / `--keep-runtime`, `forceRuntimeConfig` plumbing, and the runtime-path merge loop (`packages/cli/src/public/features/deploy/build/build-deploy-command.ts`, `build-windows-options.ts`, `build-deploy.ts`, `build-windows-runtime.ts`) | del flags/options + merge loop with the Windows runtime writer → A6b (published-CLI shape change; covered by A6b's release class + A6a's `P`) | + +`generate runtime-schemas`, the executor adapters/argv builder, the KV idempotency/DLQ machinery, +and Aspire contribution shapes are **kept as concepts** and rebuilt against the new contracts where +their current form doesn't fit. + +## 11. Staged decisions — prerequisite RFCs, not faked certainty + +| ID | Question | Why staged | Entry criterion | +| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | +| P-1 | Distributed single-fire (leader lease vs lock vs queue-delay) for schedules/file-watches across replicas | Correctness under partitions deserves its own adversarial review; single-replica constraint is a safe interim | before the stack advertises horizontal scaling of scheduled/file-watch processors | +| P-2 | T2 boundary selection (gVisor vs Firecracker-class vs managed sandbox service) + T3 WASM/WASI component tier | **Isolation-technology** survey done (`evidence/sandbox-isolation-survey.md` — scoped to isolation options, not a general market study); selection depends on deployment targets (self-host vs cloud) the owner hasn't fixed | before any marketplace/tenant-facing definition source | +| P-3 | Definition provenance/signing for third-party definition bundles | No third-party source exists yet | with P-2 | +| P-4 | Saga/stream automation families (`saga@1`, `stream@1`) | Prove the model on task/trigger first; family mechanism makes this additive. If `saga@1` adopts durable/replayed execution, the studied systems' versioning lessons (Temporal pinning, DF breaking-change taxonomy — competitive study) apply there | after task@1 + trigger@1 ship | +| P-5 | Weighted/canary activation (route a fraction of dispatches to a newer revision) | Proven pointer-model extension (AWS Step Functions weighted aliases — competitive study §Synthesis-8); needs convergence tracking first | after A2d lands | +| P-6 | **DevTools RFC** (D-9): first-class DevTools contribution family/host for runtime diagnostics, live definitions/state, execution journeys, dev management affordances — re-evaluates epic #400 (+ #685 / draft PR #780 / older #506 as evidence, not ratified architecture) | #890 ratified the userland app family only; a DevTools host is a distinct surface this RFC must not design (§8.2 surface 2); it consumes this RFC's stable management/observability contracts | after A2b (management contract), A3b (history), A2d (convergence) land | + +## 12. Roadmap (draft — files only on owner ratification) + +Slices are PR-sized, green-gated, independently landable. Gate classes come from +`.llm/harness/gates/archetype-gate-matrix.md`: **S** = static (scoped check/lint/fmt wrappers + +`quality:scan` + `arch:check`), **F** = fitness/doctrine, **R** = runtime (targeted behavioral +tests), **C** = consumer (clean-consumer install/E2E selection), **P** = publish (jsr-audit + +`publish:dry-run`). **FE** marks the frontend dependency edge (blocked by the #922 minimum cut, +§8.2); everything else is frontend-independent. File groups name the primary touched roots. + +| Slice | Scope (files) | Gates | Depends on | +| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------- | +| A0 | `packages/automation-core/`: family envelope + `task@1`/`trigger@1` Zod schemas + **management oRPC contract** + lifecycle state-transition table (data) + error vocabulary — no ports (§9) | S F P | — | +| A1a | `packages/automation-runtime/`: the **ports** (store/boundary/reload/feed) + store conformance suite + Postgres adapter + migrations schema; epoch transaction incl. carry-forward totals + audit + CAS race tests (the P1 20/20 race becomes a regression test) | S F R C P + release class (DB shape) | A0 | +| A1b | `packages/automation-runtime/adapters/kv/`: narrowed dev-KV adapter passing the conformance suite's single-writer subset; explicit refusal of fleet features | S F R C P | A1a | +| A1c | `packages/automation-runtime/`: snapshot builder + client (epoch ordering, verify, last-good, ack, revision cache + pinned lookup with transient/terminal classification) incl. simulated-feed race and outage tests | S F R C P | A1a | +| A2a | `plugins/automation/`: connector skeleton — manifest (`plugin.ts` per #1444), management service composition binding the A0 contract to runtime-core calls, Aspire resource + migration declarations; TM9 loader-policy gate (warm-cache offline load) | S F R C P + release class (Aspire/scaffold shape) | A1a | +| A2b | `packages/automation-runtime/` + `plugins/automation/`: lifecycle engine end-to-end (draft/validate/publish/activate/rollback) bound to the A0 contract | S F R C P | A2a, A1c | +| A2d | `packages/automation-runtime/` + `plugins/automation/`: change feed (SSE + poll) + leased fleet registration/admission/convergence surface + outage availability tests (§5.3-8) + BG-1 | S F R C P | A2b, A1c | +| A2c | `packages/cli/`: `netscript automation` command group over the management contract (no direct store access) | S F R C P + release class (published CLI shape) | A2b | +| A3a | `packages/plugin-workers-core/` + `plugins/workers/`: snapshot client wiring + revision-pinned per-dispatch resolution (cache + failure classes) + dispatcher rethrow; BG-2 | S F R C P | A1c | +| A3b | `packages/plugin-workers-core/`: execution history store (CAS transitions, revision+epoch linkage, bounded capture) + OTel attributes; run-now/trigger APIs return the execution id; KV job CRUD narrowed to read/enable/disable (§10) | S F R C P | A3a | +| A4a | `packages/plugin-triggers-core/` + `plugins/triggers/`: trigger reload port + snapshot-driven definitions; durable scheduled/file-watch event path (uniform history) | S F R C P | A1c, A3a | +| A4b | `plugins/automation/` + `plugins/triggers/`: management fire/test that dispatches through the real processor; enabled-state folded into revision lifecycle (KV enabled-store retired) | S F R C P | A2b, A4a | +| A5a | `packages/plugin-workers-core/executor/`: T1 boundary — deny-by-default Deno flags, clearEnv/env allowlist, entrypoint-root confinement, kill-tree, cgroup caps; per-runtime negative tests including the honest non-Deno non-enforcement pins; BG-5 | S F R C P | A3a | +| A5b | `plugins/automation/` + executor: secrets-by-name resolution + bounded output redaction; dry-run executions through the boundary via the management API | S F R C P | A2b, A5a | +| A6a | §10 purge, package/CLI half: `runtime-config` pkg, CLI override group/store/loaders, workers duplicate CLI + discovery source, plugin `runtime-config-topic` axis, trigger enabled-state core surface, dual task models; `generate runtime-schemas` re-pointed at family schemas; every test deletion carries recorded rationale | S F C P + release class (published CLI/package shape) | A2c, A3b, A4b, A5b | +| A6b | §10 purge, scaffold/deploy half: sample/runtime-tree emissions (workers/sagas/triggers), glue stubs re-pointed, generated trigger-registry boot path removed, Windows writer/schema/env-file emitters + template/generated asset, `NETSCRIPT_TASKS_DIR` readers, regenerated constants/assets | S F C P + release class (`scaffold.runtime` + scaffold-static — scaffold output changes) | A6a | +| A6c | §10 docs half: READMEs + doc-site pages rewritten to shipped reality | docs-source gates | A6a, A6b | +| A7 **FE** | `plugins/automation/frontend/`: **production/admin automation console only** (§8.2 surface 1): list/detail/run/history + draft/validate/activate/rollback flows via the #890 `app` family + #934 gateway; extends #933's workers dogfood surface; deliberately NO diagnostics/journey views (those are §8.2 surface 2, staged behind the P-6 DevTools RFC) | S F R C P + #890 design gates | A2b, A2d, A3b, A4b, A5b, **#923–#932 + #934** | +| A8 | `packages/cli/e2e/`: §13 acceptance suite + BG-1/BG-4 measurements selected into `e2e:cli`; release-gate registration | R C + release class | A2–A6 (A7 for cockpit journeys) | +| P-1..P-6 | Prerequisite RFCs / staged extensions (§11) | — | as stated in §11 | + +**jsr-audit pre-scan (rubric applied to the planned public surfaces, recorded now):** the two new +packages publish Zod schema **values** — the known slow-type risk class — so A0/A1a must export +explicit inferred types (`export type Task = z.infer<…>`) with `isolatedDeclarations`-clean +signatures and keep schema values typed, never anonymous; the oRPC contract export must carry +explicit route types (the `plugin-triggers-core` sanctioned-cast lesson); `automation-runtime`'s +Postgres adapter must not leak driver types across its public surface (structural delegate pattern, +per the sagas Prisma-store precedent); the connector surface stays re-exports only. Every +package/plugin slice carries `P` (jsr-audit + `publish:dry-run`) before merge; findings at slice +time are review-blocking, not notes. + +Corrected edges called out from evaluation: A4b (management fire/test) depends on **A2b**, not only +the engine work; A5b (dry-run + secrets policy) depends on **A2b**; A7 requires **A3b/A4b/A5b** +(run/history/trigger journeys), not only A2 plus the frontend cut. + +## 13. E2E acceptance model + +A dedicated suite (extending the `e2e:cli` harness patterns) proves the journeys on a scaffolded +stack with the automation connector + workers + triggers installed, Aspire-started: + +1. **Live add (J2):** publish + activate a `python` task via the management API; assert execution + without any process restart; assert history record carries revision + capture. +2. **Live update + rollback (J1):** activate revision 2 (changed schedule), assert timers refreshed; + roll back to revision 1 with a stale `expectedEpoch` (assert precondition failure), then + correctly; assert audit trail shows both operators. +3. **Trigger wiring (J3):** activate a webhook trigger; POST an event twice with one idempotency + key; assert single job execution, durable event records, and correlation from event → execution → + span attributes. +4. **Failure isolation:** activate a task that exits non-zero and one that exceeds its deadline; + assert retry per policy, DLQ entry, kill-tree, and that unrelated tasks kept executing. +5. **Capability enforcement, per runtime and per tier:** a Deno task with no `net` grant fails to + reach the network (enforced denial visible in history, not silent); a shell task at T1 + **succeeds** at the same access — asserted deliberately, pinning the documented non-enforcement + honestly — and the same shell task under the T2 boundary (once P-2 lands) is denied. +6. **Audit/telemetry completeness:** every mutation above appears in the audit query; every + execution has a span with the standard attributes. +7. **(Post-P-1) multi-replica convergence:** two workers replicas converge on an activation within + the propagation SLO; scheduled work fires once. +8. **Control-plane outage (§5.3-8):** stop the management service under load — dispatches pinned to + cached revisions keep succeeding on last-good; a dispatch pinned to a never-seen revision retries + with backoff and exhausts to the DLQ (transient class); convergence status marks the replica + stale past the SLO; a replica whose **lease expires while serving** keeps executing and leaves + the admission quorum (case a); a **restarted replica with persisted last-good state** locally + validates (hash + schema-major) and serves it without control-plane contact (case b); a + cold-started replica with no locally valid snapshot stays idle-and-loud (case c); on reconnect + each re-registers, validates the current snapshot, and converges. Exercised in A8 alongside + BG-1/BG-4. + +Suite cost places it in the release-gate class (`.llm/harness/gates/release-gates.md`), not the +per-slice loop. + +### 13.1 Benchmark gates (executable, implementation-stage) + +Per the competitive study's no-empirical-claims rule, performance enters this RFC only as **gates**: +each ships as a reproducible measurement against a pinned reference environment (documented in its +slice PR), with an owner-ratified budget asserted in CI — the gate is the existence and enforcement +of the measurement, not a number claimed today. + +| Gate | Measures | Lands in | +| ---- | ------------------------------------------------------------------------------------- | ------------------------- | +| BG-1 | activation → all-replica convergence latency (p50/p95, 3 replicas) with SLO assertion | A2d, exercised in A8 | +| BG-2 | per-dispatch overhead of revision-pinned lookup vs direct registry read (warm cache) | A3a micro-bench | +| BG-3 | epoch commit transaction latency (publish+activate+audit) on the reference Postgres | A1a conformance perf case | +| BG-4 | sustained execution-history write rate without queue growth on the reference stack | A8 | +| BG-5 | T1 boundary spawn overhead per runtime (deno/python/shell) vs bare subprocess | A5a | + +## 14. Alternatives considered + +- **Evolutionary repair** (wire `runtime-config` into the engines, add mutation endpoints to the + existing stores): rejected — it preserves fs-watch semantics that fail on container/network + filesystems, silent-empty error handling, five competing config locations, and hardcoded topics; + the repair cost approaches the rebuild cost without reaching the contribution model. (Kept as the + honest baseline the PLAN-EVAL should price against.) +- **Pure KV source of truth** (grow the working KV registries into the control plane): rejected for + production — no transactional audit, weak query surface for history/cockpit, and the KV + abstraction's auto-detect behavior makes the system of record deployment-dependent. KV remains the + dev-adapter and the queue/idempotency substrate. +- **Static-config collapse** (tasks/triggers as compile-time app exports only): explicitly + prohibited by the owner (D-10) — it deletes the differentiating capability. +- **Bespoke sandbox**: rejected per the survey; every tier maps to maintained technology behind a + port (§5.4), and Deno's own documentation directs untrusted execution to OS/VM isolation. + +### 14.1 Competitive architecture study (owner-directed; evidence: `evidence/competitive-architecture-study.md`) + +Nine directly analogous systems were compared on primary sources across the twelve owner-named +dimensions (rendered as fifteen matrix rows — versioning is split into four) (definition/versioning, +activation/rollback, live mutation, scheduling ownership, consistency, idempotency/retries, +history/audit/telemetry, isolation, control/data plane, extensibility, cockpit UX, self-hosting): +Temporal, Restate, Inngest, Trigger.dev, Hatchet, Windmill, Azure Durable Functions, AWS Step +Functions, and the operator/low-code group Kestra + n8n. The full matrix, per-system profiles, and +citations live in the study; the load-bearing conclusions: + +**Adopted established patterns** (independent convergence across vendors, each mapped to the section +that already specifies it): immutable versions + explicit activation pointer with +rollback-as-re-point (Step Functions versions/aliases; Trigger.dev `--skip-promotion`/`promote`; +Restate immutable deployments; Kestra/n8n revisions → §5.2); **in-flight work pinned to its starting +version** (Temporal pinned workflows, Restate pinned invocations, Durable Functions instance-version +association → §5.3 step 6); database as transactional system of record with file trees demoted to +authoring/interchange (Hatchet, Inngest self-host, Windmill; no retrieved documentation shows a +studied system consuming watched files as its runtime source → §5.2); server-owned scheduling +attached to definitions in every system where the retrieved sources document scheduling (→ §5.1, +P-1); app-hosted execution with explicit sync/poll convergence (Inngest app sync, Temporal workers → +§5.3); draft→publish cockpit UX with version history (Windmill, Kestra, n8n → §8.2); +plugin-versioned extensibility precedent (Kestra plugin versioning/hot-reload → §5.1); +weighted/canary activation as a staged pointer-model extension (Step Functions weighted aliases → +§11 P-5). + +**Deliberate non-goals (v1)**: replay-determinism durable execution for tasks/triggers — the studied +durable-execution systems pay a permanent versioning tax for it (Durable Functions maintains a +breaking-change taxonomy and four mitigation strategies); `task@1` is single-shot with engine +retries, and durable multi-step orchestration stays in the saga domain (P-4 imports these lessons if +`saga@1` goes durable). Also non-goals: an external/managed control plane (Step Functions' model is +managed-only; NetScript's control plane ships inside the stack), node-graph visual programming as +the authoring model, and a compute marketplace before P-2/P-3. + +**NetScript differentiators the study defends**: in-framework composition (definitions live in the +consumer's app and compose with auth/DB/streams/sagas/Aspire — every studied system is an adjacent +server or SaaS); operator wrapping of **existing project-local polyglot scripts** with declared, +per-tier-honest capability grants (Windmill is nearest but owns code in its own workspace model); +**contribution-family extensibility** (third-party plugins add definition _families_, schema-first); +one control plane across heterogeneous engines. + +**No empirical performance claims** are made about NetScript or any studied system. Performance is +expressed only as the executable benchmark gates BG-1…BG-5 (§13.1), each landing in a named slice +with a pinned reference environment and CI-enforced regression. + +- **Buy a managed sandbox service** (E2B/Modal-class): viable only for cloud deployments; noted as a + possible T2 adapter in P-2, not a foundation — NetScript stacks must remain self-hostable. + +## 15. Open questions for the owner — classified + +Every decision this RFC leaves open, with its deferral class (per the plan-gate open-decision sweep; +everything else in this document is **decided**): + +1. **Package/plugin naming** (`@netscript/automation-core`, `@netscript/automation-runtime`, + `plugins/automation`) — **safe to defer to slice A0** (pure spelling; structure is locked in §9). + Entry criterion: named before the A0 PR opens. +2. **Two-person activation default** (author ≠ activator on production scaffolds) — **safe to defer + to slice A2b** (the lifecycle engine carries the policy hook either way). Entry criterion: + default chosen before A2b merges; shipping default-off requires an owner sentence in the A2b PR + body. +3. **History/output retention defaults** (size caps, TTL) — **safe to defer to slice A3b**, which + ships conservative caps behind config; entry criterion: defaults ratified in the A3b review. + +Decisions that would have forced rework are **not** deferred: ownership/packaging (§9, locked), +activation-set consistency + ordering (§5.2/5.3, locked), fleet/schema admission (§5.3, locked), +store adapter parity/narrowing (§5.2, locked), the T1 enforcement contract (§5.4, locked), and +scheduled-work ownership (§5.1, locked). + +--- + +_Appendix A — capability matrix: see `evidence/legacy-capability-map.md` (legacy) and +`evidence/current-state-matrix.md` (current) in the run record; the matrix table below is the +synthesis._ + +## Appendix A — Legacy → current → gap → disposition matrix + +Status legend: ✅ worked end-to-end · 🟡 partial/disconnected · ❌ absent/dead. Disposition: +**K**eep concept · **R**edesign · **D**elete. + +| Capability | Legacy | Current | Gap | Disposition (RFC §) | +| ----------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | --------------------------------------------------------- | +| Versioned definition documents | 🟡 files existed, nothing read them | 🟡 loader/watcher tested but unconsumed (H1); official samples emit `current` + `v1.0.0.json` docs whose `$schema` refs point at files nothing generates; republish overwrites the topic doc in place (no real immutability) | no consumer, no validation, no immutability | R → immutable revisions in store (5.2) | +| `current` pointer promotion | ❌ non-atomic writer, unconsumed | 🟡 temp+rename activate but read-merge-write pointer updates — probe P1 lost a concurrent topic promotion 20/20 trials; loader pointer paths not root-confined (H6) | no CAS, no audit, fs-only | R → CAS activation + audit (5.2) | +| Hot add/update/rollback on running stack | ❌ never wired | ❌ never wired (H1) | the whole point | **R** → snapshot propagation (5.3) | +| Polyglot task execution (7 runtimes) | ✅ engine real (KV-resolved per message) | 🟡 engine real; P5 proved deno+shell live, the other five adapters are implemented-unproven | no operator path in; unsafe defaults | **K** engine concept; R control plane + T1 boundary (5.4) | +| Task scheduling | ❌ tasks never scheduled (jobs only, load-once) | 🟡 same (H2) | schedule on definition, live refresh | R (5.3, 5.4) | +| Trigger engine (idempotency, DLQ, replay) | ✅ core engine | ✅ core engine richer (H3) | definitions static, overrides unconsumed | **K** engine; R definition family (5.1) | +| Trigger management (fire/test/enable) | ❌ CLI no-ops; cockpit contract unserved | 🟡 v1 oRPC router genuinely backs introspection, event reads, webhook ingress, and KV enable/disable; other mutations/streaming honestly throw pending (H3) | full lifecycle incl. fire-that-dispatches | R → management API (8.1) | +| Schema generation | ❌ two authorities, empty output, unenforced | 🟡 real generator, empty inputs on baseline (H4) | single authority + admission | R → family schemas (5.1) | +| Execution history | 🟡 KV records, non-atomic transitions, no address returned | 🟡 same class (G2) | durable, addressable, complete | R (7) | +| Cockpit | 🟡 workers read/run wired; triggers dead; no create | ❌ absent | full lifecycle UX | R, blocked on #922 cut (8.2) | +| Permissions/sandbox | ❌ `--allow-all` default, host env inherited | ❌ same executor defaults (G2) | deny-by-default + tiers | R (5.4, 6) | +| Multi-instance propagation | ❌ none (duplicate cron/watch per replica) | ❌ none (H6) | convergence + single-fire | R (5.3) + P-1 | +| Operator CLI | ❌ misleading no-ops | 🟡 `config override` real but orphaned; duplicate workers CLI (H5) | one honest surface | R (8.1), D duplicates (10) | + +_(Current-column cells marked H1–H6/P5/G2 are sourced from `evidence/current-state-matrix.md`; this +appendix is updated if the final G2 report contradicts any cell.)_