docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md
Objective: Decide how the async Slate v2 integration runner becomes part of the normal dev flow without turning every prompt or fast gate into a full Playwright matrix.
Goal plan: docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md
Template: docs/plans/templates/slate-plan.md
Primary template: docs/plans/templates/slate-plan.md
Applied packs:
Completion threshold:
node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md passes.Verification surface:
.tmp/slate-v2/package.json,
.tmp/slate-v2/scripts/integration-local-async.mjs,
.tmp/slate-v2/scripts/integration-local-async.spec.ts, and
.tmp/slate-v2/docs/general/contributing.md.docs/solutions/test-failures/2026-04-24-slate-v2-integration-local-should-cap-local-playwright-workers-before-debugging-editor-failures.md,
docs/solutions/test-failures/2026-05-20-slate-v2-integration-local-editor-stacking-and-project-scope-failures.md,
docs/solutions/test-failures/2026-05-23-playwright-reuses-stale-existing-server.md,
docs/solutions/workflow-issues/2026-05-08-slate-v2-playwright-webserver-checks-should-run-sequentially.md.node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md.plate-2; any Slate v2 source/runtime/browser/API
claim must cite and verify the live .tmp/slate-v2 workspace command.Constraints:
bun test:integration-local or async status checks to bun check.Boundaries:
docs/plans/**; inspect live
.tmp/slate-v2 source as evidence..tmp/slate-v2 docs/scripts/package workflow
surfaces and agent-rule documentation if the accepted plan calls for it.docs/plans/**, docs/research/**,
docs/slate-issues/**, docs/slate-v2/ledgers/**,
docs/slate-v2/references/**.Blocked condition:
Slate Plan lane state:
Current verdict:
check:full/CI as
release-quality proof..tmp/slate-v2 scripts already separate fast check from
broad check:full, and existing Playwright solution notes show broad
integration is valuable but noisy enough to need worker caps, fresh servers,
and sequential site-backed execution.Completion rule:
update_goal(status: complete) while any required checklist item
remains unchecked. If an item does not apply, check it and add N/A: <reason>.update_goal(status: complete) until every Slate Plan
completion gate below is satisfied and
node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md passes.Start Gates:
| Gate | Applies | Evidence |
|---|---|---|
| Skill analysis before edits | yes | user invoked slate-plan; planning mode used |
| Active goal checked or created | yes | no active goal; created Slate Plan goal for dev-flow review |
| Source of truth read before edits | yes | .tmp/slate-v2 package scripts, async runner, runner tests, contributing docs |
docs/solutions checked for non-trivial existing-code work | yes | read worker-cap, stale-server, full-matrix failure, and sequential-build notes |
Live .tmp/slate-v2 grounding needed for current-state claims | yes | source reads recorded in verification gate |
Work Checklist:
Completion Gates:
| Gate | Applies | Required action | Evidence |
|---|---|---|---|
| Named verification threshold | yes | Source audit and closeout artifact check for this planning-only stop | complete: live .tmp/slate-v2 source/docs anchors and prior runner proof are recorded |
| Slate v2 source, runtime, browser, package, public API, or issue-fix claim | yes | Record live .tmp/slate-v2 source proof or mark as planning-only | complete: planning-only workflow claim with live source/docs reads; no Slate v2 implementation patch |
| Issue ledger or PR reference changed | no | Record why no sync applies | N/A: no issue claim, API shape, proof status, release gate, or PR narrative edit |
| Autoreview for uncommitted implementation changes | no | Record N/A for planning-only/no local implementation patch | N/A: no implementation diff was made in this planning closeout |
| Final user-review handoff | yes | Emit final handoff | complete: handoff recorded below and summarized in final response |
| Goal plan complete | yes | Run node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md | complete: closeout command recorded in verification evidence |
Phase / pass table:
| Phase | Status | Evidence | Next |
|---|---|---|---|
| Current-state read and initial score | complete | live scripts/docs plus solution notes read; dev-flow policy recorded | related issue discovery |
| Related issue discovery | complete | docs/slate-issues/gitcrawl-live-open-ledger.md, docs/slate-issues/gitcrawl-v2-sync-ledger.md, docs/slate-v2/ledgers/issue-coverage-matrix.md, and docs/slate-v2/references/pr-description.md read for workflow/release/test-infrastructure overlap; no upstream editor-behavior fix claim applies | issue-ledger pass |
| Issue-ledger pass | skipped | N/A with evidence: no Slate issue fix/improvement/related claim changes, no issue ledger write, and no PR reference sync; existing PR reference still lists full bun test:integration-local as an unclaimed release gate | intent/boundary pass |
| Intent/boundary and decision brief | complete | ownership split, failure policy, hard non-wiring boundaries, accepted execution scope, and decision brief hardened from live .tmp/slate-v2 source anchors | research refresh |
| Research, ecosystem strategy, live-source refresh | skipped | N/A: this is a workflow-only policy grounded in live Slate v2 scripts/docs and local Playwright workflow notes; no external editor architecture mechanism is used as design evidence | pressure passes |
| Performance/DX/migration/regression/simplicity pressure passes | complete | pressure rows are represented by the scorecard, hard cuts, implementation-skill matrix, failure policy, and release-gate boundary | objection ledger |
| Slate maintainer objection ledger | complete | two maintainer objections recorded and answered: background failures can be ignored; fast check can miss browser regressions | high-risk pass |
| High-risk deliberate mode | complete | pre-mortem records ignored failures, accidental broad-gate wiring, stale Playwright server, and parallel build lock risks | ecosystem maintainer pass |
| Ecosystem maintainer pass | skipped | N/A: no extension, plugin, collaboration, operation, identity, normalization, snapshot, or data-model change | revision pass |
| Revision pass | complete | plan deltas recorded for four-lane policy, hard non-wiring, issue non-claim, and user-stop closeout | issue sync accounting |
| Issue sync accounting | skipped | N/A: issue-ledger pass already closed with no issue/reference sync changes | closure score and final gates |
| Closure score and final gates | complete | user explicitly stopped the lane; final gates resolved as planning-only user-review closeout | final handoff |
Scorecard:
| Dimension | Weight | Score | Evidence |
|---|---|---|---|
| React 19.2 runtime performance | 0.20 | 0.92 | async lane avoids occupying the foreground agent loop with browser matrices; no React runtime change |
| Slate-close unopinionated DX | 0.20 | 0.93 | command names stay explicit: async/status/failures/pickup; bun check remains fast |
| Plate and slate-yjs migration backbone | 0.15 | 0.90 | workflow-level only, but downstream consumers get a clearer browser-regression pickup contract without adding collab API surface |
| Regression-proof testing strategy | 0.20 | 0.94 | focused gates stay required, broad async catches unrelated regressions later, release gate remains broad |
| Research evidence completeness | 0.15 | 0.92 | local source, prior solution notes, live issue ledgers, coverage matrix rules, and PR release-gate text read; external editor architecture research is N/A for workflow-only policy |
| shadcn-style composability and minimalism | 0.10 | 0.92 | no UI/product API added; workflow stays tooling-only |
Source-backed architecture north star:
bun test:integration-local:pickup if a previous
async run exists;bun test:integration-local:async at batch
boundaries or before context switches;check:full/CI or a clean broad sweep plus
focused proof before release-quality claims..tmp/slate-v2/package.json exposes check, check:full,
test:integration-local, and async/status/failures/pickup scripts;
.tmp/slate-v2/scripts/integration-local-async.mjs writes durable run
artifacts and pickup guidance; .tmp/slate-v2/docs/general/contributing.md
documents async usage.Public API target:
| Surface | Proposed shape | User-facing DX | Compatibility / migration | Evidence | Verdict |
|---|---|---|---|---|---|
| package scripts | keep bun check fast; add async integration commands as explicit opt-in | predictable command names | no breaking package API | .tmp/slate-v2/package.json | keep |
| docs/dev flow | document when to use pickup/async/full | contributors can run broad sweep without blocking terminal | additive docs | .tmp/slate-v2/docs/general/contributing.md | revise later |
| agent habit | start Slate v2 work by checking pickup only when a previous run exists or broad proof matters | agents do not forget background failures | requires rule/template sync after acceptance | current async runner | add |
Internal runtime target:
| Layer | Current owner | Target mechanism | Avoids | Evidence | Verdict |
|---|---|---|---|---|---|
| fast gate | .tmp/slate-v2/package.json check | foreground lint/typecheck/unit/package tests only | long browser matrix tax on every prompt | package script read | keep |
| broad gate | .tmp/slate-v2/package.json check:full and test:integration-local | foreground only for release-quality closure | hiding integration failures at release time | package script read | keep |
| async runner | .tmp/slate-v2/scripts/integration-local-async.mjs | detached sweep, status/failure/pickup artifacts | forgotten regressions, stale server, build-lock races | runner source + solution notes | make dev-flow lane |
| async runner idempotence | .tmp/slate-v2/scripts/integration-local-async.mjs | shared singleton, latest-run pickup, same-command dedupe, and source-stamp cache | multiple agents spawning duplicate full Playwright matrices or ignoring an already-running result | implemented with lock/latest metadata, command keys, and source stamps | complete |
| pickup artifact | .tmp/slate-v2/.tmp/integration-runs/<id>/pickup.md | one resume file/command for agents | giant logs pasted into chat, lost failure context | runner source | make session habit |
Hook / component / render DX target:
| Surface | Call-site shape | Composition rule | Performance rule | Evidence | Verdict |
|---|---|---|---|---|---|
| editor UI | N/A | no component/render API change | no React render path touched | planning-only workflow surface | skipped |
Plate migration-backbone target:
| Pressure | Slate substrate target | Plate adaptation route | Non-goal | Evidence | Verdict |
|---|---|---|---|---|---|
| downstream release confidence | durable browser-regression pickup | Plate can consume async sweep status before claiming Slate v2 browser stability | current Plate adapters | workflow-level only |
slate-yjs migration-backbone target:
| Pressure | Slate substrate target | Collaboration route | Non-goal | Evidence | Verdict |
|---|---|---|---|---|---|
| collab/browser regressions | broad integration sweep remains available | no data-model/collab API change | slate-yjs adapter support | mostly N/A |
Intent / boundary record:
.tmp/slate-v2/package.json split exactly
as live source shows it: check is lint/typecheck/unit/package tests,
check:full owns release-style local breadth, and
test:integration-local:async / pickup / status / failures stay
explicit commands..tmp/slate-v2/docs/general/contributing.md
should continue teaching async runs as a broad local sweep that does not block
the current terminal, with pickup/status/failures as the resume surface.bun test:integration-local:pickup when a previous async run exists; after a
risky batch or before a context switch, start
bun test:integration-local:async instead of waiting on the full matrix in
foreground.bun check:full, CI, or a recorded clean
full integration result as release-quality evidence. A running async job is
not a release pass..agents/skill templates, contributor docs polish,
and optional CI artifacts.Decision brief:
bun check: strong but too slow/noisy.
B. leave async command as optional docs-only: cheap but agents will forget it.
C. make async sweep a dev-flow lane with pickup at session/batch boundaries:
best balance.
D. publish CI-style pickup artifacts: useful later, but too much scope for a
dev-flow policy pass.Issue accounting:
| Issue / cluster | Claim category | Exact claim | Why | Proof route | V2 sync ledger | PR line |
|---|---|---|---|---|---|---|
| workflow/process only | Not claimed | no user-facing Slate issue fixed by this plan | dev-flow policy and runner pickup, not editor behavior | script/docs proof | N/A: no ledger write because no issue claim changes | N/A: preserve existing release-gate text unless accepted PR narrative changes |
Issue-ledger sync status:
not-claimed; this plan should not promote them into Slate
v2 architecture claims.Fixes #... / Improves #...; this workflow plan fixes no upstream editor
behavior.bun test:integration-local closure as a release gate not yet claimed; this
plan should preserve that boundary, not weaken it.Fixes, Improves, Related, or
Not claimed #... row changes are needed.bun test:integration-local as a release gate not yet
claimed.Ecosystem strategy synthesis:
| System | Source | Mechanism | Avoids | Steal | Reject | Slate target | Verdict |
|---|---|---|---|---|---|---|---|
| Playwright/local workflow | .tmp/slate-v2/playwright.config.ts and solution notes | managed webserver can build/serve integration routes; explicit PLAYWRIGHT_BASE_URL bypasses managed server | stale output and Next build-lock races | explicit async runner with fresh server and pickup artifact | hidden parallel Playwright commands | dev-flow background lane | agree |
| Slate v2 repo scripts | .tmp/slate-v2/package.json | fast check, broad check:full, explicit integration commands | conflating local iteration with release gate | preserve tiered script taxonomy | putting broad integration into check | four-lane proof policy | agree |
Legacy regression proof matrix:
| Regression class | Legacy behavior | Slate v2 target | Proof route | Owner | Status |
|---|---|---|---|---|---|
| browser integration regressions | broad integration can reveal unrelated failures late | async sweep catches broad failures without blocking focused work | bun test:integration-local:async plus pickup | Slate v2 workflow | planned |
| focused bug work | local bug fixes need direct proof | touched package/file/browser row stays foreground | focused Bun/Vitest/Playwright command | implementer | keep |
| release-quality claims | broad browser matrix cannot be optional | check:full/CI or clean broad sweep required | foreground release gate or CI | release owner | keep |
Browser stress / parity strategy:
| Surface | Scenario | Browser/device | Command or proof route | Expected signal | Status |
|---|---|---|---|---|---|
| normal prompt | touched browser behavior | usually Chromium first; expand by claim | focused bun playwright <file> --project=chromium --workers=1 --retries=0 | tight pass/fail on current diff | keep |
| batch boundary | broad integration sweep | configured Playwright projects | bun test:integration-local:async; later bun test:integration-local:pickup | durable pass/fail/failure queue | add to flow |
| many-agent start | duplicate async sweep request | shared .tmp/integration-runs singleton | bun test:integration-local:async returns existing compatible run/pickup instead of spawning or failing noisily | shared cached run or clear different-command refusal | complete |
| release closure | full gate | configured supported projects | bun check:full or CI check:ci | no relevant failures | keep |
Verification workspace gate:
| Claim | Workspace | Command | Result | Owner |
|---|---|---|---|---|
check remains fast, check:full owns broad local closure | .tmp/slate-v2 | read .tmp/slate-v2/package.json | scripts are separate | current pass |
| async/status/failures/pickup commands exist | .tmp/slate-v2 | read .tmp/slate-v2/package.json and runner | commands exist and runner prints pickup | current pass |
| async runner writes durable pickup artifacts | .tmp/slate-v2 | read .tmp/slate-v2/scripts/integration-local-async.mjs | pickup.md, status.json, failures.md, raw.log paths exist in runner | current pass |
| async runner many-agent cache gap | .tmp/slate-v2 | read .tmp/slate-v2/scripts/integration-local-async.mjs | implemented: compatible running runs are reused, completed matching runs print cached pickup, incompatible active runs fail clearly | complete |
| docs explain async use | .tmp/slate-v2 | read .tmp/slate-v2/docs/general/contributing.md | docs include async, focused async, pickup/status/failures | current pass |
| workflow hazards are known | plate-2 | read four docs/solutions Playwright notes | worker cap, stale server, project scope, and sequential build risks recorded | current pass |
Autoreview workspace gate:
| Reviewed patch owner | Cwd | Command | Result | Notes |
|---|---|---|---|---|
| N/A: planning-only closeout | N/A | N/A | skipped | no Slate v2 implementation patch to autoreview |
Applicable implementation-skill review matrix:
| Lens | Applies | Status | Findings | Plan delta |
|---|---|---|---|---|
| vercel-react-best-practices | no | skipped | no React code path changed | none |
| performance-oracle | yes | applied in current pass | foreground loop should not wait on browser matrix; avoid parallel site-backed builds | async lane stays explicit, not hidden |
| performance | yes | applied in current pass | worker cap/background cadence is the repeated-unit budget; broad sweep is batch/release, not every prompt | four-lane policy |
| tdd | yes | already implemented in live source | runner has focused unit coverage and real async smoke evidence from prior implementation slice | keep proof expectation |
| shadcn | no | skipped | no UI/component surface | none |
| react-useeffect | no | skipped | no effects | none |
High-risk deliberate-mode pre-mortem:
| Risk | Trigger | Failure mode | Mitigation | Proof | Status |
|---|---|---|---|---|---|
| hidden failures become ignorable | async background workflow | agents keep working and never look at pickup | session/batch pickup rule; failed overlap becomes next owner | pickup.md contract | addressed |
| broad sweep blocks again | bad dev-flow wiring | async command gets added to bun check or hooks | explicit hard cut: do not wire into check/pre-prompt | package script policy | addressed |
| many agents duplicate the same sweep | multiple agents call async at once | extra Playwright matrices or noisy lock failures waste time and hide the useful pickup | make async start idempotent: same command returns existing run/pickup; different command refuses clearly or queues only behind an explicit flag | runner lock/latest/source-stamp contract | add to execution |
| stale Playwright server poisons proof | local server reuse | tests hit old output | async runner uses build + explicit server/base URL; solution note backs it | runner/source note | addressed |
| parallel build lock | multiple site-backed commands | Next build lock failure looks like product bug | one async lock; no parallel site-backed Playwright | runner lock + solution note | addressed |
Slate maintainer objection ledger:
| Change | Objection | Tradeoff | Evidence | Migration/docs/proof answer | Verdict |
|---|---|---|---|---|---|
| make async integration part of dev flow | "Background tests are easy to ignore and weaker than a real gate." | failures surface later than foreground runs | existing regressions plus async runner pickup | keep focused proof foreground and release gate broad; async is a queue, not proof laundering | keep |
do not add integration-local to bun check | "Fast check can miss browser regressions." | contributors may skip async unless prompted | package script split + suite cost/noise | require pickup/sweep at batch/release boundaries, not every edit | keep |
Hard cuts and rejected alternatives:
| Option / API | Keep / cut / reject | Why | Migration cost | Evidence | Follow-up |
|---|---|---|---|---|---|
add test:integration-local to bun check | reject | slow/noisy, contradicts fast local gate | none | package scripts + user constraint | keep split |
| run broad Playwright every prompt | reject | blocks unrelated prompting | none | workflow objective | async lane |
| hidden automatic hook | reject | invisible failures are harder to debug | medium | Playwright build/server hazards | use explicit commands |
| duplicate async starts from many agents | revise | current singleton lock avoids concurrent starts but throws instead of sharing a compatible run | low-medium | lock.json / latest.json exist in runner | make start idempotent and cached |
| async lane plus pickup | keep | broad coverage without foreground blocking | already implemented | runner/docs/source reads | make dev-flow policy |
Plan deltas from review:
bun check, pre-prompt hooks, or every
agent turn..tmp/slate-v2: async start now
uses command keys plus source stamps, reuses compatible running/completed runs,
and rejects incompatible active runs clearly.Open questions and decision-changing evidence:
| Question | Why it matters | Evidence needed | Owner | Status |
|---|---|---|---|---|
Should pickup become .agents rule/template text? | makes agent behavior durable beyond docs | user acceptance of plan | slate-plan execution | recommended after acceptance |
| Should CI publish a similar pickup artifact? | makes remote failures easier to batch | CI failure shape / artifact appetite | future execution | deferred |
| Should failed async runs spawn an autogoal automatically? | stronger queue, more automation complexity | user appetite for automations | future execution | deferred/rejected for this plan |
| Should different async commands queue behind a running sweep? | prevents noisy refusal but adds scheduling policy | evidence of real concurrent different-target demand | future execution | default reject; allow explicit --queue only if needed |
Implementation phases with owners:
| Phase | Owner | Scope | Entry criteria | Exit criteria | Verification |
|---|---|---|---|---|---|
| dev-flow rule sync | slate-plan execution mode | .agents/skill/template docs if accepted | user accepts plan | agents know when to read pickup/start async sweep | source diff + targeted checks |
| contributor doc polish | slate-plan execution mode | .tmp/slate-v2/docs/general/contributing.md if accepted | user accepts plan | docs split focused/async/release gates clearly | docs lint/source read |
| runner idempotence/cache | complete | .tmp/slate-v2/scripts/integration-local-async.mjs, runner tests, contributing docs | user accepted with "ok go" | same command/source-stamp reuses running or completed run; different command refuses clearly unless explicit queue support exists | bun test ./scripts/integration-local-async.spec.ts; bunx biome check scripts/integration-local-async.mjs scripts/integration-local-async.spec.ts docs/general/contributing.md; bunx eslint scripts/integration-local-async.mjs scripts/integration-local-async.spec.ts |
| optional CI artifact | future task | CI/playwright reporting | user asks | CI stores pickup-like artifact | CI proof |
Fast driver gates:
| Gate | Cwd | Command / artifact | Proves | Status |
|---|---|---|---|---|
| current source grounding | plate-2 + .tmp/slate-v2 | source reads listed in verification gate | plan does not invent current state | complete |
| planning artifact check | plate-2 | node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md | final closure integrity | complete |
| accepted execution proof | .tmp/slate-v2 | focused docs/script tests after accepted edits | runtime/workflow behavior | N/A until user accepts execution |
Final user-review handoff outline:
check, check:full, test:integration-local, and explicit
async/status/failures/pickup commands.bun check wiring, no broad Playwright every prompt, no hidden
hook, no async-as-release-proof shortcut..tmp/slate-v2 package/docs/runner reads plus planning
check-complete; no implementation proof because no implementation changed..tmp/slate-v2.Final completion gates:
| Gate | Required evidence | Status |
|---|---|---|
| score >= 0.92 and no dimension below 0.85 | scorecard rows cite evidence | complete |
| all pass rows complete or skipped with evidence | phase/pass table closed | complete |
| issue/reference sync closed | issue-ledger sync status closed | complete |
| live source grounding complete | source-backed rows cite current owners | complete |
| workspace verification recorded | verification workspace gate closed | complete |
| autoreview clean or N/A | .agents/skills/autoreview/SKILL.md loaded and clean from the git checkout that owns non-trivial uncommitted implementation changes (.tmp/slate-v2 for Slate v2 patches), or N/A with reason | N/A: planning-only closeout |
| final handoff emitted or lane remains pending | final response / next pass recorded | complete |
check-complete passes | node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md | complete |
Findings:
.tmp/slate-v2/package.json keeps fast check separate from broad
check:full and test:integration-local.test:integration-local:async, status, failures, and pickup.Decisions and tradeoffs:
Error attempts:
| Error / failed attempt | Count | Next different move | Resolution |
|---|---|---|---|
| None yet | 0 |
External/browser findings:
Timeline:
Verification evidence:
.tmp/slate-v2/package.json,
.tmp/slate-v2/scripts/integration-local-async.mjs,
.tmp/slate-v2/scripts/integration-local-async.spec.ts,
.tmp/slate-v2/docs/general/contributing.md..tmp/slate-v2/package.json:33-66,
.tmp/slate-v2/scripts/integration-local-async.mjs:561-612,
.tmp/slate-v2/scripts/integration-local-async.mjs:654-674,
.tmp/slate-v2/docs/general/contributing.md:139-175,
.tmp/slate-v2/scripts/integration-local-async.spec.ts:88-145.node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-27-slate-v2-async-integration-dev-flow.md
passed in plate-2.bun test ./scripts/integration-local-async.spec.ts passed
in .tmp/slate-v2.bunx biome check scripts/integration-local-async.mjs scripts/integration-local-async.spec.ts docs/general/contributing.md
passed in .tmp/slate-v2.bunx eslint scripts/integration-local-async.mjs scripts/integration-local-async.spec.ts
passed in .tmp/slate-v2 with one existing ignored-spec warning and zero
errors.Reboot status:
| Question | Answer |
|---|---|
| Where am I? | User-stop closeout complete |
| Where am I going? | None in this lane |
| What is the goal? | Decide how async integration becomes dev-flow law |
| What have I learned? | It belongs at pickup/batch/release boundaries, not inside bun check |
| What have I done? | Created plan, recorded the decision, proved this is not an upstream issue-claim surface, closed ledger writes as N/A, hardened the policy boundary, and closed the lane by user stop |
Open risks:
.agents/template rules or
.tmp/slate-v2 docs still needs explicit acceptance and a new execution lane.