ytdb-slate 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +218 -117
  2. package/docs/blast-radius.md +460 -0
  3. package/docs/context-budget.md +205 -273
  4. package/docs/delivery-packages.md +177 -0
  5. package/docs/design-principles.md +94 -91
  6. package/docs/model-routing.md +401 -773
  7. package/docs/pr-publishing.md +129 -65
  8. package/docs/review-rules.md +499 -295
  9. package/docs/track-workflow.md +664 -410
  10. package/docs/user-notes.md +206 -0
  11. package/docs/writing-guidance.md +190 -159
  12. package/extension/artifact-names.ts +3 -6
  13. package/extension/base-model.ts +15 -5
  14. package/extension/config.ts +79 -0
  15. package/extension/episodes.ts +368 -333
  16. package/extension/failover.ts +191 -312
  17. package/extension/handoff.ts +115 -79
  18. package/extension/index.ts +80 -174
  19. package/extension/logical-model-adapters.ts +302 -0
  20. package/extension/logical-model-definitions.ts +121 -0
  21. package/extension/logical-model-recovery.ts +296 -0
  22. package/extension/logical-model-render.ts +131 -0
  23. package/extension/logical-model-resolver.ts +256 -0
  24. package/extension/logical-model-runtime.ts +251 -0
  25. package/extension/mode.ts +286 -394
  26. package/extension/model-default.ts +6 -8
  27. package/extension/notify.ts +2 -2
  28. package/extension/observations.ts +104 -15
  29. package/extension/paths.ts +4 -1
  30. package/extension/prompt-docs.ts +2 -2
  31. package/extension/render.ts +12 -26
  32. package/extension/request-throttle.ts +362 -0
  33. package/extension/slate-files.ts +1 -1
  34. package/extension/state.ts +178 -315
  35. package/extension/threads.ts +896 -1402
  36. package/extension/tools.ts +65 -152
  37. package/extension/worker-extensions.ts +137 -36
  38. package/extension/worker-reminder.ts +61 -0
  39. package/extension/worker.ts +453 -45
  40. package/extension/writing-check.mjs +46 -24
  41. package/extension/writing-reminder.ts +122 -54
  42. package/extension/writing.ts +215 -62
  43. package/package.json +6 -6
  44. package/docs/model-failover.md +0 -242
  45. package/docs/thread-cache-cost.md +0 -227
  46. package/extension/model-profiles.ts +0 -967
  47. package/extension/model-router.ts +0 -1168
  48. package/extension/route.ts +0 -1294
  49. package/extension/thread-choice.ts +0 -1207
package/README.md CHANGED
@@ -1,163 +1,246 @@
1
- # ytdb-slate
1
+ # ytdb-slate: Agent orchestration for the pi coding agent
2
2
 
3
3
  [![CI status](https://github.com/JetBrains/ytdb-slate/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/JetBrains/ytdb-slate/actions/workflows/ci.yml)
4
4
 
5
- Slate is a thread-weaving orchestration extension for the [pi coding agent](https://pi.dev).
5
+ **Slate is a thread-weaving orchestration extension for the [pi coding agent](https://pi.dev).** It helps you guide long coding tasks while focused worker sessions research, implement, and review bounded parts of the work.
6
6
 
7
- The orchestrator (your main pi session) dispatches **bounded actions** to persistent **worker threads**. Each completed action is compressed by an LLM into an **episode** — a durable, structured record (intent, actions, findings, artifacts, open issues, handoff notes) that the orchestrator composes into further dispatches instead of re-reading raw transcripts. Slate also injects a mandatory workflow doctrine. Its design and review gates scale with the confirmed change class. Optional umbrella **draft-PR publishing** covers tracks.
7
+ You stay in the main session and decide what to build. Slate manages context, delegates actions, preserves useful results, and applies a risk-based development workflow.
8
8
 
9
- An opt-in **model-failover** map adds high availability: when a model API fails, the orchestrator, worker threads, and episode compression each retry once on a configured equal-quality alternative. A second opt-in, **action-level model routing**, gives each dispatched action a model and an effort level chosen to be up to the task and no more, so cost is bounded per action instead of per session.
9
+ - [Start using Slate](#start-using-slate)
10
+ - [Understand how Slate works](#how-slate-works)
11
+ - [See the roadmap](#where-slate-is-going)
12
+ - [Configure Slate](#configuration)
13
+ - [Read the safety boundaries](#safety-and-trust)
14
+ - [Open the complete reference](#shipped-docs)
10
15
 
11
- ## Why Slate?
16
+ ## Start using Slate
12
17
 
13
- Long-horizon agentic work fails on context management, not model capability. Existing architectures each solve a piece of the problem and trade away the rest. Compaction is unpredictably lossy; naive subagents isolate context but hand back only a single response string; markdown plans go stale and get under-executed. Rigid task trees can't adapt to information discovered mid-task, and planner/executor stacks synchronize through compress-and-return boundaries that risk dropping critical state.
18
+ You need an installed and authenticated [pi coding agent](https://pi.dev/docs/latest/quickstart). From your project directory, install a pinned Slate version into the project:
14
19
 
15
- Slate's answer is the **thread**: the orchestrator dispatches one bounded action at a time; the worker executes it and returns an **episode**. The orchestrator keeps the reactivity of a plain agent loop while gaining the context isolation, compaction, and parallelism that the single-context loop lacks.
20
+ ```bash
21
+ pi install -l npm:ytdb-slate@<version>
22
+ ```
16
23
 
17
- | Aspect | ReAct | Markdown plan | Task trees | RLM (Recursive Language Models) | Devin / Manus / Altera | Claude Code / Codex subagents | Slate |
18
- | --- | --- | --- | --- | --- | --- | --- | --- |
19
- | Planning | implicit | file | explicit tree | REPL | planning agent | plan mode | implicit / adaptive — no upfront static plan |
20
- | Decomposition | none | none | direct tree | REPL functions | task-based | subagent delegation | implicit |
21
- | Synchronization | single thread | single thread | gated steps | REPL return | reduce & return | message passing | episodes |
22
- | Intermediate feedback | per step | per step | on task failure | on execution end | after compress | message passing | per episode |
23
- | Context isolation | none | none | per subtask | per subcall | subagent | subagent | per thread |
24
- | Context compaction | none | none | task-based | REPL slicing | subagent compress | compaction | episode compress |
25
- | Parallel execution | none | none | none | in REPL | Altera only | native | native |
26
- | Expressivity | high | high | low | high | medium | medium | high |
27
- | Adaptability | yes | if plan updated | no | limited — no mid-run course correction | yes | limited by message passing | yes |
24
+ The `-l` option records the package in `.pi/settings.json`. Pi may ask you to trust the project before it loads project settings and extensions.
28
25
 
29
- Characterizations of third-party systems reflect their publicly described designs at the time of writing. The taxonomy is adapted from the Random Labs technical report introducing the thread-weaving "Slate" architecture (its agent ships as the npm package `@randomlabs/slate`); ytdb-slate is an independent implementation of that architecture for pi.
26
+ Pinned package specifications such as `@<version>` are deliberately skipped by `pi update --extensions` and `pi update --all`. Moving the pin is a conscious project change. Review Slate's shipped workflow documents before you update it.
30
27
 
31
- **Threads are not subagents:**
28
+ Start a new interactive pi session, then turn on orchestrator mode:
32
29
 
33
- - **Per-episode feedback.** Each thread executes one bounded action and hands control back. The orchestrator adapts after every episode — reactive like a ReAct loop — instead of firing off a subagent and hoping the result comes back usable.
34
- - **Compaction at a chosen boundary.** Compression happens at a predictable point — action completion — instead of mid-stream when context overflows. The compression itself is still LLM-performed and lossy, but the boundary is chosen, not forced.
35
- - **Episodes compose.** One thread's episode can seed another thread's context, so conclusions travel across the system by reference. Subagents pass back a single response string; episodes are durable, structured, reusable records.
30
+ ```text
31
+ /slate on
32
+ ```
36
33
 
37
- Full rationale: [`docs/design-principles.md`](docs/design-principles.md), shipped in the package — if this summary and that document disagree, the document wins.
34
+ Try a request that gives Slate a clear outcome and leaves planning open:
38
35
 
39
- ## Feature development workflow
36
+ ```text
37
+ Add input validation to the account settings endpoint. First research the relevant code and tests. Show me the proposed tracks and risks before implementation.
38
+ ```
40
39
 
41
- In orchestrator mode, Slate injects a mandatory track-based development workflow. Project configuration can extend it through `doctrineExtraPath`. Configuration cannot replace it.
40
+ Slate will ask for required decisions before it edits code. It will delegate implementation work to worker threads after the workflow gates allow that work.
42
41
 
43
- Slate uses four change classes. Evaluate these tests in order. The first match
44
- sets the class:
42
+ To leave orchestrator mode, run `/slate off`. Running `/slate` with no argument toggles the mode. See [Everyday commands](#everyday-commands) for handoff, resume, and routing commands.
45
43
 
46
- 1. **Risky:** The change touches concurrency, durability, recovery,
47
- transactional semantics, security, or user data. This class also covers a
48
- public API or behavioral change, or a silent failure mode.
49
- 2. **Complex:** The shape is unclear, several parts interact, or a live design
50
- alternative exists.
51
- 3. **Trivial:** The change is an obvious fix with no behavioral change, and one
52
- reviewer pass covers it.
53
- 4. **Medium:** Otherwise.
44
+ ## How Slate works
54
45
 
55
- After classification, follow these workflow steps:
46
+ Slate uses four terms throughout this README:
56
47
 
57
- 1. **Classification and research** — the orchestrator proposes the change class, and the user confirms it. A research log is required for medium changes and above.
58
- 2. **Design gates** — medium changes need high-level design approval before implementation. Complex and risky changes add an adversarial review between two user approvals.
59
- 3. **Track split** — the orchestrator owns the split. Size determines tracks and marker commits, not workflow gates.
60
- 4. **Per-track loop** — each track gets implementation, fixes, and mandatory user review. Agent code review is skipped only when the whole change is trivial.
61
- 5. **Delivery** — the user performs the squash merge when draft publishing is enabled. Otherwise, the squashed commit carries the workflow log's key content.
48
+ - **Main session:** the interactive pi session where you set goals, answer questions, and review results. In orchestrator mode, this session acts as the **orchestrator**.
49
+ - **Bounded action:** one focused unit of work with a clear limit and expected result.
50
+ - **Worker thread:** a new isolated pi session that performs one bounded action. A follow-up action uses another new worker thread.
51
+ - **Episode:** a durable, structured summary of one worker action. It retains intent, actions, findings, artifacts, open issues, and handoff notes.
62
52
 
63
- Trivial changes have no high-level design gate. Every change keeps mandatory user review of its track diff. Umbrella draft-PR publishing activates only when `workflow.draftPRs` is `true`.
53
+ The orchestrator dispatches bounded actions and adapts after each episode. A large language model compresses successful work and failed partial work into the episode. A failure without a worker response uses a fixed episode and no compression call.
64
54
 
65
- This summary is orientation only; the shipped docs listed below are normative.
55
+ Later actions can receive earlier episode identifiers through `context`. Slate loads those episodes into the new worker prompt. The main session can therefore compose prior results without re-reading every raw worker transcript.
66
56
 
67
- ## Model failover
57
+ ### What Slate adds
68
58
 
69
- Slate can ride through model API outages. The opt-in `modelFailover` map in `.pi/slate.json` (trusted projects only) maps a model (`provider/id`) to an equal-quality alternative; on an eligible model API failure — not an abort or a context overflow, and for the orchestrator and worker sites only after pi's own retries are exhausted — the affected site (orchestrator, worker thread, or episode compression) retries once on the mapped model (single hop, never chained). An orchestrator failover — like the handoff adoption that re-applies a parent session's model — would otherwise leave pi's global model defaults changed, so Slate restores them on a best-effort basis unless `preserveGlobalModelDefault` is `false`. The map is empty by default (feature off) and read once at session start. Full semantics: the `modelFailover` row in [Configuration](#configuration) and the shipped [`docs/model-failover.md`](docs/model-failover.md) — if they disagree, that document wins.
59
+ - **Context isolation.** Each worker receives the context for one action instead of the full history of the main session.
60
+ - **Compaction at an action boundary.** Compression happens when the action ends. Compression remains model-performed and lossy, but the boundary is deliberate rather than forced by a full context window.
61
+ - **Adaptive planning.** Control returns to the orchestrator after each episode. New evidence can change the next action.
62
+ - **Composable results.** Episodes are durable records that later worker threads can use by reference.
63
+ - **Parallel work.** Independent bounded actions can run in parallel while each action keeps its own worker context.
64
+ - **Risk-based review.** User-approved risk proofs select workflow gates and agent reviewers instead of applying every review to every change.
70
65
 
71
- ## Action-level model routing
66
+ Slate follows the thread-weaving architecture introduced by the Random Labs technical report for its `@randomlabs/slate` agent. ytdb-slate is an independent implementation of that architecture for pi.
72
67
 
73
- Slate can pick the model and the effort level per dispatched action rather than running every action on whatever model the orchestrator happens to be on. `router.models` in `.pi/slate.json` (trusted projects only) is a closed list of `provider/id` specs. Each action uses its `model` and `effort` arguments when present. Otherwise, it uses the thread's base model and a level DERIVED for the model it routes to. That level is the lowest one with a capability measurement, never a fixed default. The list is empty by default. An empty list disables candidate-list enforcement, base seeding, effort derivation, and the router's window, billing, and substitution paths. Per-action `model` and `effort` arguments stay active on both router states. Slate always checks an explicit effort against pi's vocabulary, and against the ladder of the model it routes to whenever it has that model's profile data. An action that omits `model` plans for the thread's pre-router pin, and a thread with no pin gives it no plan target. An action that omits `effort` resolves no level. In both cases the worker session returns to what it opened on. [`docs/model-routing.md`](docs/model-routing.md) holds the full contract, including the known cases where the model or level that runs differs. Only models Slate ships a benchmark profile for can be routed to; entries pi cannot serve, or has no profile for, are dropped with a warning naming them.
68
+ The full rationale is in [`docs/design-principles.md`](docs/design-principles.md). If this summary and that document disagree, the document wins.
74
69
 
75
- Router startup warnings have two classes. One class is a configuration fault. It reports project configuration that Slate ignored or dropped. A configuration fault also covers problems the user can stop by adding a model, credential, or failover entry.
70
+ ## Where Slate is going
76
71
 
77
- The addition must go into their project configuration or pi credentials. Removing the model named by a warning does not meet this second test. Slate always shows configuration faults.
72
+ > **Planned work:** The two priorities below describe future changes. They are not current Slate features.
78
73
 
79
- The other class is a model data note. It reports shipped research data that project configuration cannot correct. Slate hides those notes by default.
74
+ Spend more time deciding what to build, and less time checking code or managing agents. We are working toward that goal with two priorities:
80
75
 
81
- With this repository's six-model list and pi's stock registry, Slate hides eleven notes. Slate shows one discoverability line instead. A local registry override can change that count. The line names the hidden warning count and the `router.showWarnings` setting. A hidden note can still affect which model runs an action.
76
+ 1. **Guide changes through design, not code.** Review the design without having to read the code yourself. We plan to add design documents at several levels, from system goals to component details, and keep them updated as work progresses. Agents will still review code quality and check that changes follow your approved design.
77
+ Follow [#361](https://github.com/JetBrains/ytdb-slate/issues/361), [#402](https://github.com/JetBrains/ytdb-slate/issues/402), [#403](https://github.com/JetBrains/ytdb-slate/issues/403), and [#404](https://github.com/JetBrains/ytdb-slate/issues/404).
82
78
 
83
- What the code enforces is deliberately narrower than what the routing data advises. The dispatch guards refuse an unlisted model, a level off the target model's ladder and a level the provider rejects outright; they warn about — and mark — an unmeasured level, refusing it only when `router.allowUnmeasuredEffort` is `false`; and the context-window guard substitutes a wider listed model instead of ever blocking an action. The obligations that come from the profile data itself — keeping review and gate actions on measured levels, and honoring a REFUSE such as `anthropic/claude-fable-5`'s for zero-data-retention work — are stated in the doctrine for the orchestrator to honor; they are **not** code-enforced guards. Full semantics: the `router.*` rows in [Configuration](#configuration) and the shipped [`docs/model-routing.md`](docs/model-routing.md) — if they disagree, that document wins.
79
+ 2. **Keep working while agents run.** Asynchronous threads will let the main session continue without waiting for each result. A redesigned terminal interface will make it easier to follow and control their work. Clear, accurate usage and cost reports will show where your resources go.
80
+ Follow [#269](https://github.com/JetBrains/ytdb-slate/issues/269), [#296](https://github.com/JetBrains/ytdb-slate/issues/296), [#212](https://github.com/JetBrains/ytdb-slate/issues/212), and [#38](https://github.com/JetBrains/ytdb-slate/issues/38).
84
81
 
85
- ## Optional writing guidance
82
+ ## Current workflow and behavior
86
83
 
87
- Set `writing.check` to `true` to add writing guidance and human-only telemetry. In orchestrator mode, Slate adds a doctrine rule that states the convention. It also adds a status value such as `writing 1/4`. This value means that one of four measured prose turns had a fail-level finding. Each worker gets a shorter preamble reminder about sentence length, semicolons, and contractions.
84
+ ### Feature development workflow
88
85
 
89
- The option has prompt cost. Each orchestrator system prompt contains the doctrine rule. You pay for this text on every turn. Each worker session also gets a gated preamble addition. Both additions are absent when the option is off. The worker preamble then stays byte-identical to its pre-feature form.
86
+ In orchestrator mode, Slate injects a mandatory track-based development workflow. Project configuration can extend it through `doctrineExtraPath`. Configuration cannot replace it.
90
87
 
91
- > **No conformance claim:** This is a dictionary-free proxy. It embeds no controlled vocabulary and claims no ASD-STE100 conformance.
88
+ Eleven focus areas name specific risks. They cover
89
+ concurrency defects, data loss, security weaknesses, performance degradation,
90
+ test-quality defects, unreadable user-facing prose, licensing exposure,
91
+ non-local logic defects, consumer contract breaks, governing-rule defects, and
92
+ unreported failures.
92
93
 
93
- The shipped CLI checks plain files, JSONL records, and unified diffs. See [`docs/writing-guidance.md`](docs/writing-guidance.md) for its rules, limits, output, and command examples.
94
+ During planning, the orchestrator writes an independent risk record for the change and for every track. Each record has one line for every focus area. A `NAMED` line carries a four-part proof. User approval makes that area proved. User rejection makes it `SKIPPED`. Only proved areas add gates or routine implementation reviewers. A track with at least one proved area gets one general Reviewer I plus every required area specialist. A track with no proved area gets no routine implementation reviewer.
94
95
 
95
- Set `writing.remind` to `true` to add context-paced reminders after eligible tool results. Context-paced means Slate waits for configured context growth between reminders. The reminders are hidden from the normal TUI. They repeat five writing requirements and the scope exclusion before the next assistant response. This option remains off unless `writing.check` is also `true`.
96
+ The workflow follows these steps:
96
97
 
97
- ## Install
98
+ 1. **Plan and confirm.** The orchestrator proposes all eleven focus lines. The user alone approves or rejects each `NAMED` proof.
99
+ 2. **Design.** A proved `DESIGN-TRIGGERING` area requires a high-level design. The user validates it before focus reconfirmation and one adversarial design review per proved `DESIGN-TRIGGERING` area. Final design approval follows.
100
+ 3. **Implement tracks.** Each track is one coherent, independently mergeable unit with its own focus set. About 400 added plus removed lines is a planning guideline. The orchestrator estimates before splitting work. The implementer estimates during work and stops at a coherent boundary near the guideline. A small overrun may finish the nearest coherent unit and must include its reason. Lockfiles, migration files, and generated output do not count.
101
+ 4. **Review and deliver.** When a track has a proved area, one Reviewer I and every required area specialist inspect it in separate review actions. A zero-area track reports routine implementation review as `NOT REQUIRED`. Tracks with a proved `DESIGN-TRIGGERING` area require blocking user acceptance. Other tracks do not. Where a marker applies, it follows required machine gates, the packet, and resolution of blocking user notes. Per-track mode uses the user-merged commit instead. Final change acceptance is always blocking.
98
102
 
99
- Install into a project (pinned, project-scoped — recorded in `.pi/settings.json`):
103
+ Draft pull request publishing activates only when `workflow.draftPRs` is `true`. The orchestrator then asks once whether every track gets its own pull request. A yes answer requires user merges in sequence and a fresh branch from updated `main` for each next track. A no answer keeps one umbrella draft pull request.
100
104
 
101
- ```bash
102
- pi install -l npm:ytdb-slate@<version>
103
- ```
105
+ This summary provides orientation only. The [shipped workflow documents](#shipped-docs) are normative.
106
+
107
+ ### Logical-model routing and recovery
108
+
109
+ Every `thread` call names a provider-free logical `model` and a short `reason`. The active policy fixes effort, exact physical routes, capability and cost ratings, guidance, cautions, and bounded recovery order. Slate resolves one immutable policy when the parent session starts. Dispatch, compression, main-session recovery, doctrine, and `/slate effective` share it.
110
+
111
+ The shipped ordinary pool has six definitions. A trusted project can replace membership, add complete definitions, replace selected fields, and exclude members. The independent compressor list defaults to Sonnet at `medium`. Untrusted projects use home preferences over the shipped policy and consume no project router data. Critical errors block logical work. Legacy physical-router keys produce named warnings and receive no automatic migration.
104
112
 
105
- > **Note on pinning:** pinned specs (`@<version>`) are deliberately skipped by `pi update --extensions` / `pi update --all`. Bumping the pin is a conscious project change — review Slate's shipped workflow docs for changes when you do.
113
+ Pi retries the active physical route first. Slate advances only after Pi reports known retry exhaustion. Recovery tries another permitted provider for the same logical model before it moves through the ordinary or compressor order. Unknown outcomes and cancellation stop recovery. One operation owns recovery. An overlapping operation receives a visible busy refusal. Slate does not queue or replay it.
114
+
115
+ Pi 0.85.1 model and effort switches are session-only unless persistence is requested. Slate retains its saved-default compatibility guard for explicit persistence and older behavior. Slate retains bounded completed worker output when compression fails or is cancelled. A failed episode write can prevent an episode. A failed final state save can leave episode bytes without a proved durable reference. Both failures remain visible.
116
+
117
+ A remembered later compressor starts later actions at that entry and does not move backward until preference reset. This is an accepted limitation. `extension/index.ts` is the supported package entry. Logical-runtime exports and retry-evidence exports are internal and unstable. Retry-evidence exports classify provider retry outcomes. [`docs/model-routing.md`](docs/model-routing.md) defines the complete contract.
118
+
119
+ ### Writing guidance
120
+
121
+ Writing guidance and checker findings are active in orchestrator mode when the project is trusted or a home configuration file exists. Slate adds one doctrine rule for writing and another for design discipline. It also adds a status value such as `writing 2 fail, 3 style / 10 turns` in interactive sessions. The value reports model-visible findings in the latest ten measured prose turns. Each worker with permitted Slate settings gets a shorter reminder about reader understanding, semicolons, and contractions.
122
+
123
+ The guidance has prompt cost. Each orchestrator system prompt contains both doctrine rules. You pay for this text on every turn. Each worker with permitted Slate settings also gets the preamble addition.
124
+
125
+ The shipped command checks plain files, JSON Lines records, and unified diffs. See [`docs/writing-guidance.md`](docs/writing-guidance.md) for its rules, limits, output, and command examples.
126
+
127
+ Slate sends hidden reminders after completed turns. The default cadence is four completed turns. A model-visible finding can trigger an immediate reminder when that option is enabled. The reminder carries the writing and conversation title, three retained style rules, ten writing requirements, and seven design requirements. A findings section appears only when the latest measured turn carries a model-visible finding. The requirements exclude research logs, worker task text, and this project's agent instruction file.
128
+
129
+ ## Everyday commands
130
+
131
+ | Command | Current behavior |
132
+ | --- | --- |
133
+ | `/slate on` | Turn on orchestrator mode. Slate removes tactical tools from the main session and expects delegation through worker threads. |
134
+ | `/slate off` | Turn off orchestrator mode and restore the earlier tool set. |
135
+ | `/slate` | Toggle orchestrator mode. |
136
+ | `/slate effective` | Show the effective logical-model policy and remembered route selections. |
137
+ | `/slate handoff [focus]` | Prepare a new-session handoff, with an optional focus. |
138
+ | `/slate resume` | Clear a context-budget pause and accept user prompts again. |
139
+
140
+ ## Community
141
+
142
+ Join the [Slate Zulip community](https://youtrackdb.zulipchat.com/#narrow/channel/634235-slate) to share what you are building, ask for help, or discuss the project.
106
143
 
107
144
  ## Configuration
108
145
 
109
- Optional config file: `slate.json` in the project's pi config dir (`.pi/slate.json`). It is honored **only in trusted projects** (see [Trust](#trust)).
146
+ ### Configuration files and merging
147
+
148
+ Slate reads two optional configuration files at session start:
149
+
150
+ - Home: `<getAgentDir()>/slate.json`, normally `~/.pi/agent/slate.json`. Pi's `PI_CODING_AGENT_DIR` environment variable can select another agent directory.
151
+ - Project: `<cwd>/.pi/slate.json`, read **only when the project is trusted**.
152
+
153
+ Project values override home values. Objects merge recursively. Arrays, scalar values, and explicit `null` replace the home value. Arrays never append. Slate applies its existing setting validators after the merge.
154
+
155
+ A missing file is valid. An unreadable file, invalid JSON, or a root that is not an object produces a warning naming that file. Any such error in a permitted file blocks model routing, even when the other file is valid.
156
+
157
+ Home preferences also apply in untrusted projects. Without a home file, existing project behavior and defaults stay unchanged. Configuration edits require a new session.
158
+
159
+ Paths in `orchestratorPromptDocs`, `workerPromptDocs`, `doctrineExtraPath`, and `reviewPerspectivesPath` belong to the file that supplies the value. Relative home paths start at the agent directory. Relative project paths start at the project root, not `.pi`. Absolute paths stay absolute. See [Safety and trust](#safety-and-trust) for the security boundary.
160
+
161
+ Pi can refresh a prompt cache by sending background requests. Slate disables those requests in every worker because they bypass its request limits. This does not disable prompt caching for ordinary worker requests. The main session and saved pi settings stay unchanged.
162
+
163
+ ### Common starting point
164
+
165
+ Create `.pi/slate.json` when you want new interactive sessions to start in orchestrator mode:
166
+
167
+ ```json
168
+ {
169
+ "orchestratorModeDefault": true
170
+ }
171
+ ```
172
+
173
+ The project must be trusted before Slate reads this file. Start a new session after any configuration change.
174
+
175
+ ### Complete option reference
110
176
 
111
177
  | Key | Type | Default | Semantics |
112
178
  | --- | --- | --- | --- |
113
179
  | `orchestratorModeDefault` | boolean | `false` | Start fresh interactive sessions with orchestrator mode ON. |
114
- | `episodeModel` | string | newest available Anthropic Sonnet, else the orchestrator's own base model | Model (`provider/id`) used to compress a finished action into an episode. Never the model an action was routed to: an episode is read by every later consumer of the thread, so one cheap route must not degrade the record. An unusable value is reported and the default is used. |
115
180
  | `workerTools` | string[] | `["read", "bash", "edit", "write", "grep", "find", "ls"]` | Tools available to worker threads (an empty list also falls back to the default). |
116
- | `workerExtensions` | string[] | `[]` | Regex patterns (matched **unanchored**) selecting which of the host session's already-loaded extensions also load into every worker thread; each matched extension's tools are added **on top of** `workerTools`. Empty (default) means workers load no extensions. The orchestrator keeps its restricted tool set but its doctrine is told what was whitelisted. Invalid patterns are dropped with a warning at session start. |
117
- | `maxConcurrent` | number | `4` | Maximum number of worker actions running concurrently (must be ≥ 1 — unenforced: a value of 0 or less silently hangs all dispatches). Excess dispatches wait in a queue; actions on the same thread always run in dispatch order. Default rationale: shipped `docs/design-principles.md` §5 (repo-local note). |
181
+ | `workerExtensions` | string[] | `[]` | Regex patterns (matched **unanchored**) selecting which of the host session's already-loaded extensions also load into every worker thread; each matched extension's tools are added **on top of** `workerTools`. Empty (default) means workers load no project or discovered extensions. Slate still supplies one internal reminder component. The orchestrator keeps its restricted tool set but its doctrine is told what was whitelisted. Invalid patterns are dropped with a warning at session start. |
182
+ | `cacheKeyEnabled` | boolean | `true` | Add one OpenAI Responses prompt cache key to all workers in the current main Slate session. Another main session receives another key. `false` disables key injection. It does not disable request throttling. Provider requests with `cacheRetention: "none"`, including worker summaries, keep that opt-out and receive no forced key. |
183
+ | `cacheKeyShards` | number | ignored | This removed partitioning key has no effect. Slate reports it once at session start. Remove it from `slate.json`. |
184
+ | `requestThrottle.enabled` | boolean | `true` | Pace OpenAI Responses worker requests. `false` disables pacing. It does not disable cache-key injection. The scope includes worker turns, failover requests, history compaction, and branch summaries. It excludes orchestrator requests, episode compression, other provider interfaces, other sessions and processes, and direct tool requests. |
185
+ | `requestThrottle.maxRequestsPerMinute` | number | `12` | Maximum logical SDK requests admitted for one actual `provider/id` in the preceding 60 seconds. The value must be a whole number from 1 through 1000. Provider network retries inside one SDK request do not consume another admission. Different models have independent counters. This threshold is request pacing, not a cache-hit or provider-rate-limit guarantee. |
186
+ | `requestThrottle.baseWaitMs` | number | `1000` | Base delay before a blocked request rechecks capacity. The value must be a whole number from 1 through 60000. A positive minimum prevents a repeated zero-delay loop. |
187
+ | `requestThrottle.jitterMs` | number | `1000` | Uniform random extra delay from zero through this inclusive bound before a blocked request rechecks. The value must be a whole number from 0 through 60000. Admission is approximately fair. It is not first-in-first-out and does not promise a bounded wait. |
188
+ | `maxConcurrent` | number | `4` | Maximum number of worker actions running concurrently (must be ≥ 1 — unenforced: a value of 0 or less silently hangs all dispatches). Excess actions wait for a global concurrency slot. Every action has its own thread. Default rationale: shipped `docs/design-principles.md` §5 (repo-local note). |
118
189
  | `contextBudget` | number \| object | `256000` (Anthropic models: `400000`) | Absolute orchestrator context budget (tokens) at which Slate auto-pauses and prepares a fresh-session handoff — semantics, defaults, per-model overrides, and rationale in [`docs/context-budget.md`](docs/context-budget.md). |
119
- | `orchestratorPromptDocs` | string[] | `[]` | Project markdown files (paths relative to the project root) whose **contents** are appended to the orchestrator system prompt. |
120
- | `workerPromptDocs` | string[] | `[]` | Project markdown files whose **contents** are appended to every worker-thread system prompt. |
121
- | `workflow.draftPRs` | boolean | `false` | Enable umbrella draft-PR publishing for tracks. |
122
- | `workflow.followUpIssues` | boolean | `false` | When true, the orchestrator asks which suggestions become follow-up issues in the project tracker. Suggestions are always reported whatever the value. |
123
- | `writing.check` | boolean | `false` | Add the writing doctrine rule, per-turn status, and worker guidance. An absent option is silently off. A malformed `writing` value, or a non-boolean `check` value, warns and defaults to off. Unknown `writing` keys warn and are ignored. See [`docs/writing-guidance.md`](docs/writing-guidance.md). |
124
- | `writing.remind` | boolean | `false` | Send a hidden reminder after an eligible tool result. All gates must pass: orchestrator mode, project trust, `writing.check`, this option, no pause, cadence or handoff force, and one-per-round control. See [`docs/writing-guidance.md`](docs/writing-guidance.md). |
125
- | `writing.remindPercent` | number | `10` | Set cadence as a percentage of Slate's current effective context budget. The value must be finite and in `(0, 100]`. The interval has an 8,192-token floor and no cap. A handoff force bypasses this threshold. See [`docs/writing-guidance.md`](docs/writing-guidance.md). |
126
- | `doctrineExtraPath` | string | — | Project markdown whose **content** is appended to the orchestrator doctrine (project-specific workflow additions). |
127
- | `reviewPerspectivesPath` | string | — | Project review charters, each declaring its own finding-ID prefix. The doctrine references this **path**; the orchestrator reads the file alongside the shipped review rules. |
128
- | `modelFailover` | object (string → string) | — (empty, failover off) | Map of `provider/id` → equal-quality alternative model; on a model API failure the affected site retries once on the mapped model (worker/orchestrator sites only after pi's own retries are exhausted; episode compression has no pi retry loop). Read once at session start — see [`docs/model-failover.md`](docs/model-failover.md). |
129
- | `preserveGlobalModelDefault` | boolean | `true` | Put pi's global model defaults (`defaultProvider`, `defaultModel`, `defaultThinkingLevel`) back after a Slate-initiated model switch — orchestrator failover and handoff adoption — so the switch stays session-scoped. `false` turns that restore off at both sites (the switches themselves are unaffected), leaving each one persisted in pi's global settings. Best-effort: Slate reverts only a value its own switch produced, and can stand down or give up — limits in [`docs/model-failover.md`](docs/model-failover.md). |
130
- | `router.models` | string[] | `[]` (empty — routing off) | Closed list of models (`provider/id`) an action may use. Empty or absent means the router is OFF. Slate enforces no candidate list, seeds no thread base, derives no effort level, and runs no router-only window, billing, or substitution path. Per-action `model` and `effort` arguments stay active on both router states. Slate still checks explicit effort against pi's vocabulary and the routed model's ladder when it has that model's profile data. An action that omits `model` plans for the thread's pre-router pin, and a thread with no pin gives it no plan target. An action that omits `effort` resolves no level. In both cases the worker session returns to what it opened on. The known cases where the model or level that runs differs are listed in [`docs/model-routing.md`](docs/model-routing.md). A listed model becomes routable only if Slate has its benchmark profile, pi registers it, and credentials are configured. Slate drops other entries with a warning. If all entries drop, routing turns off with one summary warning. Slate reads and resolves the list once per session. See [`docs/model-routing.md`](docs/model-routing.md). |
131
- | `router.allowUnmeasuredEffort` | boolean | `true` | What happens when an explicitly requested effort level is on the target model's ladder but has no capability measurement in Slate's profiles: `true` dispatches it with a ⚠ notice and marks the episode `(unmeasured level)`; `false` refuses the dispatch. Either way a level that is off the model's ladder, or one the provider rejects outright, is refused, and a level Slate DERIVES for an action is always a measured one. |
132
- | `router.showWarnings` | boolean | `false` | Reveal model data notes about Slate's shipped routing research. Configuration faults are never hidden. See [`docs/model-routing.md`](docs/model-routing.md). |
133
-
134
- Example `.pi/slate.json` (the `docs/agents/...` paths are placeholders — point them at markdown files that actually exist in **your** project):
190
+ | `orchestratorPromptDocs` | string[] | `[]` | Markdown files whose paths follow the source rules above and whose **contents** are appended to the orchestrator system prompt. |
191
+ | `workerPromptDocs` | string[] | `[]` | Markdown files whose **contents** are appended to every worker-thread system prompt. |
192
+ | `workflow.draftPRs` | boolean | `false` | Enable draft-PR publishing. Before implementation, ask once whether each track gets its own pull request or all tracks share one umbrella pull request. |
193
+ | `workflow.followUpIssues` | boolean | `false` | When true, the orchestrator asks which deferred items become tracked issues. Deferred items are always reported whatever the value. |
194
+ | `workflow.routingRecommendations` | boolean | `false` | Before final acceptance, add an evidence-bounded model-routing field for logical models dispatched during the current change. The enabled field always appears. It reports when no change is recommended and never edits routing files. |
195
+ | `writing.check` | boolean | ignored | This ignored writing key remains accepted for compatibility. Remove it from `slate.json`. Guidance is automatic during orchestrator mode when the project is trusted or a home file exists. See [`docs/writing-guidance.md`](docs/writing-guidance.md). |
196
+ | `writing.remind` | boolean | ignored | This ignored writing key remains accepted for compatibility. Remove it from `slate.json`. Reminder gates require orchestrator mode, permitted Slate settings, no pause, and a ready trigger. Delivery is limited to one reminder per response round. See [`docs/writing-guidance.md`](docs/writing-guidance.md). |
197
+ | `writing.remindPercent` | number | ignored | This retired key remains accepted and ignored. Slate emits a notice. Replace it with `writing.remindTurns`, which counts completed turns instead of a token-budget share. |
198
+ | `writing.remindTurns` | number | `4` | Set the reminder cadence in completed turns. The value must be a whole number from 1 through 20. An invalid value warns and falls back to `4`. See [`docs/writing-guidance.md`](docs/writing-guidance.md). |
199
+ | `writing.remindOnFinding` | boolean | `true` | Send a reminder on the turn after a measured turn with a model-visible finding. An invalid value warns and falls back to `true`. `writing.findings: false` disables this trigger. |
200
+ | `writing.sentenceWordLimit` | number \| boolean | `25` | Set the sentence-length house-style limit in words. The value must be a whole number from 10 through 200, inclusive, or `false` to turn the rule off. See [`docs/writing-guidance.md`](docs/writing-guidance.md). |
201
+ | `writing.statusWindowTurns` | number | `10` | Set the whole-number status window from 3 through 100 measured turns. An invalid value warns and falls back to `10`. The status line reports model-visible fail and style counts in this window. |
202
+ | `writing.findings` | boolean | `true` | Include the latest model-visible writing findings in the hidden reminder. An invalid value warns and falls back to `true`. Measurement and the status line continue when this value is `false`. |
203
+ | `doctrineExtraPath` | string | — | Markdown whose **content** is appended to the orchestrator doctrine (project-specific workflow additions). |
204
+ | `reviewPerspectivesPath` | string | — | Review charters, each declaring its own finding-ID prefix. The doctrine references this **path**; the orchestrator reads the file alongside the shipped review rules. |
205
+ | `router.models` | object | shipped six-model pool | Ordinary membership and definitions. `include` replaces the starting membership, including with an empty list. `add` accepts complete new definitions. `replace` changes selected fields. `exclude` applies last. Within each model definition, lists and provider maps replace shipped fields. The home and project configuration files merge first. |
206
+ | `router.compressor.models` | array of `{ model, effort }` | `[{"model":"claude-sonnet-5","effort":"medium"}]` | Independent ordered compressor list. An explicit empty list blocks work. |
207
+
208
+ ### Extended example
209
+
210
+ The `docs/agents/...` values below are placeholders. Point them at Markdown files that exist in your project.
135
211
 
136
212
  ```json
137
213
  {
138
214
  "orchestratorModeDefault": true,
139
- "episodeModel": "anthropic/claude-sonnet-5",
215
+ "cacheKeyEnabled": true,
216
+ "requestThrottle": { "enabled": true, "maxRequestsPerMinute": 12, "baseWaitMs": 1000, "jitterMs": 1000 },
140
217
  "maxConcurrent": 4,
141
218
  "orchestratorPromptDocs": ["docs/agents/orchestrator-guidelines.md"],
142
219
  "workerPromptDocs": ["docs/agents/thread-guidelines.md"],
143
- "workflow": { "draftPRs": true, "followUpIssues": false },
144
- "writing": {
145
- "check": true,
146
- "remind": false,
147
- "remindPercent": 10
148
- },
220
+ "workflow": { "draftPRs": true, "followUpIssues": false, "routingRecommendations": false },
221
+ "writing": { "remindTurns": 4, "remindOnFinding": true, "sentenceWordLimit": 25, "statusWindowTurns": 10, "findings": true },
149
222
  "doctrineExtraPath": "docs/agents/workflow-additions.md",
150
223
  "reviewPerspectivesPath": "docs/agents/review-perspectives.md",
151
- "modelFailover": { "anthropic/claude-sonnet-5": "openai/gpt-5.2" },
152
- "router": { "models": ["openai/gpt-5.6-luna", "anthropic/claude-opus-5"] }
224
+ "router": {
225
+ "models": { "include": ["luna-6", "claude-opus-5.5"] },
226
+ "compressor": { "models": [{ "model": "claude-sonnet-5", "effort": "medium" }] }
227
+ }
153
228
  }
154
229
  ```
155
230
 
156
- Older Slate releases warn about these reminder keys and ignore them. Use a Slate release whose documentation includes these keys.
231
+ Remove `writing.check` and `writing.remind` when copying an older configuration. Current Slate reports these ignored writing keys.
232
+
233
+ ### Document path warning
234
+
235
+ > **Silent skip:** document-path errors produce no warning. Slate skips missing, unreadable, or empty files selected by `orchestratorPromptDocs`, `workerPromptDocs`, and `doctrineExtraPath`. For `reviewPerspectivesPath`, Slate omits the pointer only when the file is missing. Slate does not read that file at injection time, so an unreadable or empty file is still cited. Verify your paths after copying the example.
236
+
237
+ ## Safety and trust
157
238
 
158
- > **Silent skip:** the project-file keys fail silently — no error is shown. For the content-injected keys (`orchestratorPromptDocs`, `workerPromptDocs`, `doctrineExtraPath`) a missing, unreadable, or empty file is skipped and nothing is injected. For `reviewPerspectivesPath` the pointer is omitted only when the file is missing — the file is not read at injection time, so an unreadable or empty file is still cited. Verify your paths after copying the example.
239
+ ### Worker extensions (`workerExtensions`)
159
240
 
160
- **Worker extensions (`workerExtensions`).** By default worker threads load no extensions. This key is a list of regex patterns that select extensions the **host session has already loaded** and load them into every worker too. Each pattern is matched **unanchored** (unlike `contextBudget.overrides`, which is anchored) against a load unit's recorded source spec (e.g. `npm:pi-web-search@1.3.1`), its load-unit path, or the entry path of any tool that unit contributes, so a bare package name matches:
241
+ By default worker threads load no project or discovered extensions. Slate supplies one internal reminder component to every worker session. After tool results reach its handler, the component tells the worker to issue independent tool calls in one turn. It sends the reminder once for each such turn. The reminder persists in the worker transcript and stays hidden from the user in the normal terminal interface. The component is not gated on project trust.
242
+
243
+ This key is a list of regex patterns that select extensions the **host session has already loaded** and load them into every worker too. Each pattern is matched **unanchored** (unlike `contextBudget.overrides`, which is anchored) against a load unit's recorded source spec (e.g. `npm:pi-web-search@1.3.1`), its load-unit path, or the entry path of any tool that unit contributes, so a bare package name matches:
161
244
 
162
245
  ```json
163
246
  {
@@ -165,41 +248,59 @@ Older Slate releases warn about these reminder keys and ignore them. Use a Slate
165
248
  }
166
249
  ```
167
250
 
168
- Every worker then gets the fetch and web-search tools **on top of** `workerTools` (and on top of the per-dispatch `tools` argument of the `thread` tool — those two govern the built-in tools only). The orchestrator itself does **not** gain these tools — orchestrator mode keeps its restricted set — but its doctrine gains a rule naming each whitelisted extension and its tools, so it knows what it can delegate. pi's discovery, project-trust gating, and dedup remain the only ingress: a worker can never load an extension the host is not running, an extension that registers no tools cannot be whitelisted, and a host started with extensions disabled offers nothing to whitelist.
251
+ Every worker then gets the fetch and web-search tools **on top of** `workerTools` (and on top of the per-dispatch `tools` argument of the `thread` tool — those two govern the built-in tools only). The orchestrator itself does **not** gain these tools — orchestrator mode keeps its restricted set — but its doctrine gains a rule naming each whitelisted extension and its tools, so it knows what it can delegate.
252
+
253
+ For project and discovered extensions, pi's discovery, project-trust gating, and dedup remain the only ingress. A worker cannot load a whitelisted extension that the host is not running. An extension that registers no tools cannot be whitelisted. A host started with extensions disabled offers nothing to whitelist. Slate's internal reminder component is the separate always-loaded input described above.
169
254
 
170
255
  **What to know before whitelisting** — it reaches past Slate's isolation, so it is an operator decision:
171
256
 
172
257
  - **Delegation is unbounded.** Slate guarantees only that no worker obtains Slate's own `thread`/`threads`/`episode` tools. A whitelisted extension that ships its own sub-agent or delegation tool under any other name gives workers delegation Slate can neither detect, bound, nor account for.
173
- - **Credential and filesystem reach.** Inside a worker the extension has the same filesystem and credential access it has in the host; Slate's read-only settings snapshot blocks pi-settings writes and nothing else.
174
- - **Unsynced model-scoped tools.** Worker sessions never fire the session-start event, so an extension whose tool set is model-scoped stays unsynced and may offer a tool the worker's model cannot serve (e.g. pi-web-search's `url_context` on a non-Google worker model) — the call simply fails and the episode records it.
175
- - **Abort.** A third-party extension may ignore the abort signal, so its network activity can outlive an abort or a context-budget pause.
258
+ - **Credential and filesystem reach.** Inside a worker the extension has the same filesystem and credential access it has in the host. Slate's read-only settings snapshot blocks pi-settings writes and nothing else.
259
+ - **Worker lifecycle.** Slate completes each selected extension's `session_start` before the worker action begins. A startup failure blocks the action. Slate emits one `session_shutdown` before it disposes the worker, including after startup or action failure and during host shutdown.
260
+ - **Abort.** A third-party extension may ignore the abort signal, so its network activity can outlive an abort or a context-budget pause. During a pause, Slate still allows orchestrator state-save workers while it refuses new user prompts.
176
261
  - **Cost.** Provider-native tool billing can escape Slate's worker cost accounting.
177
- - **Pathological patterns.** The patterns are regexes from your own trusted config — the same file that already steers models, prompts, and tool lists — matched with no time bound while the extension set is resolved once per session. A pattern with catastrophic backtracking can stall that resolution; treat it as a footgun to avoid, not a privilege boundary.
262
+ - **Pathological patterns.** The patterns are regexes from your own trusted config — the same file that already steers models, prompts, and tool lists — matched with no time bound while the extension set is resolved once per session. A pattern with catastrophic backtracking can stall that resolution. Avoid such patterns. They are not a privilege boundary.
178
263
 
179
264
  The load-time recursion guard behind this — and the risks it does and does not cover — is in [`docs/design-principles.md`](docs/design-principles.md).
180
265
 
181
- ## Trust
266
+ ### Worker provider registrations
267
+
268
+ Every worker inherits host extension provider registrations that are absent after the worker session is constructed. This behavior is independent of `workerExtensions`. It supports provider-only extensions that register no tools. The worker's own registration wins by provider id, even when one side uses a native provider and the other uses the config form. A built-in provider is not an extension registration, so a host extension override of a built-in is inherited.
182
269
 
183
- Slate reads project configuration (`.pi/slate.json`) and injects project files (`orchestratorPromptDocs`, `workerPromptDocs`, `doctrineExtraPath`, `reviewPerspectivesPath`) **only in trusted projects**. In untrusted projects Slate runs with built-in defaults and injects nothing from the working tree.
270
+ Inheritance happens after worker session construction and before route authentication or the first model request. Slate copies current registrations and reuses their provider functions. Nested config values and native provider objects can remain shared by reference. A worker uses its own pi credential resolution, but inherited provider authentication callbacks and configured keys can read or update the same credential files and third-party state that the host uses. Slate does not copy host event handlers such as `before_provider_headers`, `before_provider_request`, or `after_provider_response`. Provider extensions that depend on those handlers will not behave the same in a worker.
271
+
272
+ A worker extension can register the same provider id during construction. Its registration takes precedence. Slate does not synchronize later host changes or intercept later worker registrations. Pi can merge a later partial worker registration with inherited config. That merge can retain inherited credentials while changing the endpoint. This accepted startup-only boundary requires extension authors to replace provider configuration carefully. Compatibility with specific third-party provider extensions has not been verified.
273
+
274
+ ### Project trust boundary
275
+
276
+ Slate excludes untrusted project Slate configuration and content selected through that configuration. Home preferences remain active, including documents and host extensions selected by those preferences. A home document path can point into a working tree, so select those paths carefully.
277
+
278
+ Home preferences do not change pi's project-trust decision. Pi's independent instruction loading stays unchanged. In particular, this feature does not filter pi's `AGENTS.md` context files. Slate still requires project trust before it restores pending handoff state. Worker pi settings remain nonpersistent.
184
279
 
185
280
  ## Shipped docs
186
281
 
187
- In orchestrator mode, Slate appends a short **doctrine** (a block of numbered rules) to the orchestrator's system prompt each turn. The doctrine does not embed the workflow docs — it cites them by **absolute path**, resolved inside the installed package (not your project), and the orchestrator reads them on demand. Those embedded paths are also why the block's character count depends on your install location; [`docs/context-budget.md`](docs/context-budget.md) has the measured sizes, with and without the optional rules, and the arithmetic for your own install:
282
+ This section is the complete reference document roster.
283
+
284
+ In orchestrator mode, Slate appends a short **doctrine**, which is a block of numbered rules, to the orchestrator system prompt each turn. The doctrine does not embed the workflow documents. It cites them by absolute path inside the installed package, and the orchestrator reads them when needed.
285
+
286
+ The embedded paths make the block size depend on your install location. [`docs/context-budget.md`](docs/context-budget.md) gives measured sizes with and without optional rules. It also gives the arithmetic for your own installation.
188
287
 
189
- - `docs/track-workflow.md` — the class-scaled workflow for research, high-level design, adversarial review, and track review
190
- - `docs/pr-publishing.md` — umbrella draft-PR publishing (cited only when `workflow.draftPRs` is `true`)
191
- - `docs/review-rules.md` — review discipline and finding rules
192
- - `docs/design-principles.md` — Slate's own design rationale
193
- - `docs/model-failover.md` — the opt-in `modelFailover` map (**reference documentation** — unlike the entries above it is not workflow doctrine and is not cited by the doctrine)
194
- - `docs/context-budget.md` — the orchestrator `contextBudget`: defaults, per-model overrides, the window clamp, and the pricing rationale (also **reference documentation**, not cited by the doctrine)
195
- - `docs/writing-guidance.md` — the optional writing convention, `writing.check` behavior, status line, and checker CLI
196
- - `docs/model-routing.md` — the action-level model routing reference. It covers the three `router` keys, model eligibility, omitted effort, and dispatch guards. It also covers first-session warnings. The doctrine cites this absolute path only while the routing rule renders. This path is fourth normally and fifth when `workflow.draftPRs` is on. The rule renders the live list because it depends on the session registry and credentials.
288
+ - [`docs/blast-radius.md`](docs/blast-radius.md) defines the eleven focus areas, proof requirements, track constraints, and review coverage.
289
+ - [`docs/context-budget.md`](docs/context-budget.md) defines `contextBudget` defaults, per-model overrides, the window clamp, and pricing rationale. It is reference documentation and is not cited by the doctrine.
290
+ - [`docs/delivery-packages.md`](docs/delivery-packages.md) — the compact track and change package format, read only before package preparation
291
+ - [`docs/design-principles.md`](docs/design-principles.md) gives Slate's design rationale.
292
+ - [`docs/model-routing.md`](docs/model-routing.md) defines the logical-model policy, exact defaults, configuration, common recovery, history, and accepted limitations. The doctrine cites its absolute path for trusted sessions.
293
+ - [`docs/pr-publishing.md`](docs/pr-publishing.md) defines per-track and umbrella draft pull request publishing. The doctrine cites it only when `workflow.draftPRs` is `true`.
294
+ - [`docs/review-rules.md`](docs/review-rules.md) defines reviewer composition, the combined test-quality role, evidence standards, findings, and fix gates.
295
+ - [`docs/track-workflow.md`](docs/track-workflow.md) defines the focus-area lifecycle for research, design, implementation, review, and delivery.
296
+ - [`docs/user-notes.md`](docs/user-notes.md) defines how Slate records, classifies, and resolves user notes during development.
297
+ - [`docs/writing-guidance.md`](docs/writing-guidance.md) defines the writing convention, ignored writing keys, status line, and checker command.
197
298
 
198
- Project-specific additions layer on top — they extend, not replace, the shipped doctrine — via two distinct mechanisms:
299
+ Project-specific additions extend the shipped doctrine. They do not replace it:
199
300
 
200
- - **Content injection**: `doctrineExtraPath` (appended to the doctrine itself, re-read at each prompt assembly) and `orchestratorPromptDocs` / `workerPromptDocs` (appended to the respective system prompts).
201
- - **Pointer**: `reviewPerspectivesPath` is cited by path from the doctrine's review rule and read on demand, like the shipped docs.
301
+ - **Content injection:** `doctrineExtraPath` appends content to the doctrine and is read again at each prompt assembly. `orchestratorPromptDocs` and `workerPromptDocs` append content to their respective system prompts.
302
+ - **Pointer:** `reviewPerspectivesPath` is cited by path from the doctrine's review rule and read when needed, like the shipped documents.
202
303
 
203
304
  ## License
204
305
 
205
- Apache-2.0 — see [LICENSE](LICENSE).
306
+ Apache-2.0. See [LICENSE](LICENSE).