ytdb-slate 0.5.1 → 0.6.1
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.
- package/README.md +25 -0
- package/docs/context-budget.md +135 -48
- package/docs/model-routing.md +7 -8
- package/docs/review-rules.md +66 -13
- package/docs/writing-guidance.md +444 -0
- package/extension/handoff.ts +39 -10
- package/extension/index.ts +4 -1
- package/extension/mode.ts +211 -4
- package/extension/paths.ts +13 -8
- package/extension/state.ts +11 -0
- package/extension/threads.ts +1 -0
- package/extension/worker.ts +15 -2
- package/extension/writing-check.mjs +1061 -0
- package/extension/writing-reminder.ts +184 -0
- package/extension/writing.ts +127 -0
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# ytdb-slate
|
|
2
2
|
|
|
3
|
+
[](https://github.com/JetBrains/ytdb-slate/actions/workflows/tier-1.yml)
|
|
4
|
+
|
|
3
5
|
Slate is a thread-weaving orchestration extension for the [pi coding agent](https://pi.dev).
|
|
4
6
|
|
|
5
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. On top of that, Slate injects a mandatory workflow doctrine: research before design, design review, adversarial review, and track review — with optional umbrella **draft-PR publishing** for tracks. 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.
|
|
@@ -57,6 +59,18 @@ Slate can pick the model and the effort level per dispatched action rather than
|
|
|
57
59
|
|
|
58
60
|
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.
|
|
59
61
|
|
|
62
|
+
## Optional writing guidance
|
|
63
|
+
|
|
64
|
+
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.
|
|
65
|
+
|
|
66
|
+
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.
|
|
67
|
+
|
|
68
|
+
> **No conformance claim:** This is a dictionary-free proxy. It embeds no controlled vocabulary and claims no ASD-STE100 conformance.
|
|
69
|
+
|
|
70
|
+
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.
|
|
71
|
+
|
|
72
|
+
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`.
|
|
73
|
+
|
|
60
74
|
## Install
|
|
61
75
|
|
|
62
76
|
Install into a project (pinned, project-scoped — recorded in `.pi/settings.json`):
|
|
@@ -82,6 +96,9 @@ Optional config file: `slate.json` in the project's pi config dir (`.pi/slate.js
|
|
|
82
96
|
| `orchestratorPromptDocs` | string[] | `[]` | Project markdown files (paths relative to the project root) whose **contents** are appended to the orchestrator system prompt. |
|
|
83
97
|
| `workerPromptDocs` | string[] | `[]` | Project markdown files whose **contents** are appended to every worker-thread system prompt. |
|
|
84
98
|
| `workflow.draftPRs` | boolean | `false` | Enable umbrella draft-PR publishing for tracks. |
|
|
99
|
+
| `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). |
|
|
100
|
+
| `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). |
|
|
101
|
+
| `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). |
|
|
85
102
|
| `doctrineExtraPath` | string | — | Project markdown whose **content** is appended to the orchestrator doctrine (project-specific workflow additions). |
|
|
86
103
|
| `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. |
|
|
87
104
|
| `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). |
|
|
@@ -99,6 +116,11 @@ Example `.pi/slate.json` (the `docs/agents/...` paths are placeholders — point
|
|
|
99
116
|
"orchestratorPromptDocs": ["docs/agents/orchestrator-guidelines.md"],
|
|
100
117
|
"workerPromptDocs": ["docs/agents/thread-guidelines.md"],
|
|
101
118
|
"workflow": { "draftPRs": true },
|
|
119
|
+
"writing": {
|
|
120
|
+
"check": true,
|
|
121
|
+
"remind": false,
|
|
122
|
+
"remindPercent": 10
|
|
123
|
+
},
|
|
102
124
|
"doctrineExtraPath": "docs/agents/workflow-additions.md",
|
|
103
125
|
"reviewPerspectivesPath": "docs/agents/review-perspectives.md",
|
|
104
126
|
"modelFailover": { "anthropic/claude-sonnet-5": "openai/gpt-5.2" },
|
|
@@ -106,6 +128,8 @@ Example `.pi/slate.json` (the `docs/agents/...` paths are placeholders — point
|
|
|
106
128
|
}
|
|
107
129
|
```
|
|
108
130
|
|
|
131
|
+
Older Slate releases warn about these reminder keys and ignore them. Use a Slate release whose documentation includes these keys.
|
|
132
|
+
|
|
109
133
|
> **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.
|
|
110
134
|
|
|
111
135
|
**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:
|
|
@@ -143,6 +167,7 @@ In orchestrator mode, Slate appends a short **doctrine** (a block of numbered ru
|
|
|
143
167
|
- `docs/design-principles.md` — Slate's own design rationale
|
|
144
168
|
- `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)
|
|
145
169
|
- `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)
|
|
170
|
+
- `docs/writing-guidance.md` — the optional writing convention, `writing.check` behavior, status line, and checker CLI
|
|
146
171
|
- `docs/model-routing.md` — action-level model routing: the two `router` keys, how a model becomes routable, how an omitted effort level resolves, the dispatch guards, and the warnings a first routed session emits. Unlike the two entries above it **is** cited by the doctrine, by absolute path, but only while the routing rule renders — it is the extra embedded path that appears with the rule, the fourth normally and the fifth when `workflow.draftPRs` is also on, which the size arithmetic in `docs/context-budget.md` accounts for. The routable model list itself is never read from this file: the rule renders it live from the session's own resolution, because that set depends on your registry and credentials.
|
|
147
172
|
|
|
148
173
|
Project-specific additions layer on top — they extend, not replace, the shipped doctrine — via two distinct mechanisms:
|
package/docs/context-budget.md
CHANGED
|
@@ -108,6 +108,32 @@ Rationale: the clamp guarantees the pause fires before pi's
|
|
|
108
108
|
auto-compaction and leaves room to write the handoff brief; the
|
|
109
109
|
half-window floor keeps small-window models usable.
|
|
110
110
|
|
|
111
|
+
## Writing-reminder cadence
|
|
112
|
+
|
|
113
|
+
The effective budget also sets the optional hidden writing-reminder cadence.
|
|
114
|
+
When `writing.check` and `writing.remind` are both true, Slate computes:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
interval = max(8192, floor(effectiveBudget × remindPercent / 100))
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`remindPercent` defaults to 10 and accepts a finite value in `(0, 100]`. The
|
|
121
|
+
context-window clamp therefore shortens the cadence on a model whose configured
|
|
122
|
+
budget does not fit. Slate checks the cadence after tool results. One reminder
|
|
123
|
+
slot can fire after each assistant response.
|
|
124
|
+
|
|
125
|
+
A successful handoff adoption sets `forceNext`. The next eligible tool result
|
|
126
|
+
then bypasses token cadence and missing usage. It does not bypass trust,
|
|
127
|
+
orchestrator mode, `writing.check`, `writing.remind`, or pause gates. Slate
|
|
128
|
+
commits the cadence mark only when pi starts delivery of the custom message.
|
|
129
|
+
|
|
130
|
+
The current hidden message is 320 ASCII characters, including its `[slate]`
|
|
131
|
+
header, five reminder requirements, blank separator, and scope exclusion. That
|
|
132
|
+
is about 80 tokens at four characters per token. This count is for the exact
|
|
133
|
+
rendered production string, without JSONL framing or provider-role overhead. The
|
|
134
|
+
message enters conversation context only when a reminder fires. Later requests
|
|
135
|
+
resend it with the rest of the conversation.
|
|
136
|
+
|
|
111
137
|
## Compaction policy
|
|
112
138
|
|
|
113
139
|
In orchestrator mode, for budget-driven configs only: a
|
|
@@ -129,69 +155,131 @@ you pay its input tokens every turn.
|
|
|
129
155
|
|
|
130
156
|
**Its size depends on where the package is installed.** That is not
|
|
131
157
|
obvious, and it catches anyone who measures: the doctrine cites the
|
|
132
|
-
shipped docs by ABSOLUTE path, so three to
|
|
133
|
-
|
|
158
|
+
shipped docs by ABSOLUTE path, so three to six full filesystem paths
|
|
159
|
+
are embedded in the block — three at minimum
|
|
134
160
|
(`track-workflow.md`, `review-rules.md`, `design-principles.md`),
|
|
135
161
|
plus `pr-publishing.md` when `workflow.draftPRs` is on, plus
|
|
136
|
-
`model-routing.md` when the routing rule renders
|
|
137
|
-
|
|
162
|
+
`model-routing.md` when the routing rule renders, plus
|
|
163
|
+
`writing-guidance.md` when `writing.check` is on. Every additional
|
|
164
|
+
character in the installed `docs/` directory therefore costs 3–6
|
|
138
165
|
characters of doctrine.
|
|
139
166
|
|
|
140
|
-
|
|
141
|
-
Slate's own automated
|
|
142
|
-
occurrence of the installed `docs/` DIRECTORY
|
|
143
|
-
filename. That makes them install-invariant by
|
|
144
|
-
|
|
145
|
-
58-character one, which give identical portable counts — and it
|
|
146
|
-
makes the arithmetic one multiplication:
|
|
167
|
+
The figures below are **portable characters**, defined exactly as
|
|
168
|
+
Slate's own automated `doctrine-budget` check defines them: the
|
|
169
|
+
block with each occurrence of the installed `docs/` DIRECTORY
|
|
170
|
+
removed, keeping the filename. That makes them install-invariant by
|
|
171
|
+
construction and makes the arithmetic one multiplication:
|
|
147
172
|
|
|
148
173
|
> rendered characters = portable + (embedded paths × length of your
|
|
149
174
|
> installed `docs/` directory)
|
|
150
175
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
176
|
+
`doctrine-budget` in `verification/resolver-checks.mjs` is the
|
|
177
|
+
definition of record for this convention and its enforced bounds.
|
|
178
|
+
This table is a measured snapshot, not a second authority. It uses
|
|
179
|
+
the same shipped-profile fixture as that check. The six-model rows
|
|
180
|
+
use the six models in this repository's `.pi/slate.json`. Every row
|
|
181
|
+
states its full basis, because router state, model count, `draftPRs`,
|
|
182
|
+
and `writing.check` each move the number. Rows with the same fixture
|
|
183
|
+
and basis must agree with `verification/README.md`. A different basis
|
|
184
|
+
must be named instead of presented as the same measurement:
|
|
185
|
+
|
|
186
|
+
| router | models | `draftPRs` | `writing.check` | paths | portable | lines |
|
|
155
187
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
156
|
-
| off | — | off | 3 | 1,929 | 38 |
|
|
157
|
-
| off | — | on | 4 |
|
|
158
|
-
|
|
|
159
|
-
|
|
|
160
|
-
| on |
|
|
161
|
-
| on |
|
|
188
|
+
| off | — | off | off | 3 | 1,929 | 38 |
|
|
189
|
+
| off | — | off | on | 4 | 2,999 | 60 |
|
|
190
|
+
| off | — | on | off | 4 | 1,948 | 38 |
|
|
191
|
+
| off | — | on | on | 5 | 3,018 | 60 |
|
|
192
|
+
| on | `.pi/slate.json` six | off | off | 4 | 3,879 | 58 |
|
|
193
|
+
| on | `.pi/slate.json` six | off | on | 5 | 4,949 | 80 |
|
|
194
|
+
| on | `.pi/slate.json` six | on | off | 5 | 3,898 | 58 |
|
|
195
|
+
| on | `.pi/slate.json` six | on | on | 6 | 4,968 | 80 |
|
|
196
|
+
| on | all 9 shipped | off | off | 4 | 4,434 | 61 |
|
|
197
|
+
| on | all 9 shipped | off | on | 5 | 5,504 | 83 |
|
|
198
|
+
| on | all 9 shipped | on | off | 5 | 4,453 | 61 |
|
|
199
|
+
| on | all 9 shipped | on | on | 6 | 5,523 | 83 |
|
|
162
200
|
|
|
163
201
|
An untrusted project reads the first row whatever its `slate.json`
|
|
164
|
-
says: no project config is loaded, so
|
|
165
|
-
|
|
166
|
-
|
|
202
|
+
says: no project config is loaded, so no optional rule renders. Line
|
|
203
|
+
counts do not vary with the install path. Enabling `draftPRs` costs
|
|
204
|
+
19 portable characters plus one embedded path. Enabling
|
|
205
|
+
`writing.check` costs 1,070 portable characters, adds 22 lines to the
|
|
206
|
+
whole doctrine, and adds one embedded path. Considered alone, the
|
|
207
|
+
writing rule is 1,070 portable characters / 23 lines. Its leading
|
|
208
|
+
newline becomes the separator when appended.
|
|
167
209
|
|
|
168
210
|
Two parts of the block grow with configuration rather than with the
|
|
169
211
|
path:
|
|
170
212
|
|
|
171
213
|
- The routing rule is a live table with ONE ROW PER ROUTABLE MODEL,
|
|
172
214
|
so what renders is the models you CONFIGURE — not the nine Slate
|
|
173
|
-
ships profiles for.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
first six average 171.
|
|
215
|
+
ships profiles for. In this snapshot it is 1,950 portable
|
|
216
|
+
characters and adds 20 doctrine lines for six configured models;
|
|
217
|
+
for all nine it is 2,505 characters and adds 23 lines. The six
|
|
218
|
+
model rows are 146–181 characters; all nine are 146–183. The
|
|
219
|
+
legend adds a one-off clause per marker it has to explain, so
|
|
220
|
+
growth is not only the sum of new rows.
|
|
180
221
|
- The worker-extension rule grows per whitelisted extension and per
|
|
181
|
-
tool that extension contributes, so it has no fixed size
|
|
222
|
+
tool that extension contributes, so it has no fixed size. One
|
|
182
223
|
extension contributing two tools measured 373 portable characters
|
|
183
224
|
/ 7 lines.
|
|
184
225
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
226
|
+
The table above isolates the shipped rules. Two representative bases include
|
|
227
|
+
worker extensions and support verification decisions:
|
|
228
|
+
|
|
229
|
+
| basis | models | worker extensions | paths | portable | lines | rough tokens |
|
|
230
|
+
| --- | ---: | --- | ---: | ---: | ---: | ---: |
|
|
231
|
+
| current `.pi/slate.json` dogfood config | 6 | real 2 units / 4 tools | 6 | 5,884 | 90 | ≈1,471 |
|
|
232
|
+
| stable maximal fixture | 9 | synthetic 2 units / 4 tools, every rendered field at its cap | 6 | 6,870 | 93 | ≈1,718 |
|
|
233
|
+
|
|
234
|
+
The dogfood row uses `workflow.draftPRs: true`, `writing.check: true`, and the
|
|
235
|
+
six models in `.pi/slate.json`. Its extension basis is
|
|
236
|
+
`pi-smart-fetch@0.3.12` plus `pi-web-search@1.3.1`. Those packages resolve to two
|
|
237
|
+
units and four tools. Their worker-extension rule is 916 portable characters /
|
|
238
|
+
11 lines. Raw size remains symbolic: `portable + 6 × length(installed docs
|
|
239
|
+
directory)`. No maintainer checkout path belongs in this shipped document.
|
|
240
|
+
|
|
241
|
+
The stable maximal row uses all nine shipped profiles, draft PRs, and writing.
|
|
242
|
+
Its direct post-resolution worker fixture has two units and four tools. Unit
|
|
243
|
+
labels are 128 characters. Tool names are 64 characters. Descriptions are 140
|
|
244
|
+
characters.
|
|
245
|
+
|
|
246
|
+
Those are the renderer caps. The fixture uses safe ASCII letters. It is
|
|
247
|
+
independent of installed extension labels, descriptions, versions and other
|
|
248
|
+
prose. The worker rule measures 1,347 characters against its 1,600-character
|
|
249
|
+
verification budget.
|
|
250
|
+
|
|
251
|
+
`doctrine-budget` caps that representative maximal doctrine at 7,200 portable
|
|
252
|
+
characters. The measured 6,870 leaves 330 characters, or 4.6 percent of the
|
|
253
|
+
7,200-character bound. A positive control adds one capped tool
|
|
254
|
+
and three copies of the largest measured model row. It measures 7,634 portable
|
|
255
|
+
characters and exceeds the bound by 434. These figures are verification budgets,
|
|
256
|
+
never runtime limits. Arbitrary user extension rosters can exceed them.
|
|
257
|
+
|
|
258
|
+
The exact values are maintenance tripwires. A deliberate doctrine wording,
|
|
259
|
+
requirement roster, renderer cap, or fixture change requires a fresh render
|
|
260
|
+
through `doctrine-budget`. Update its exact expectations and every published
|
|
261
|
+
figure in the same commit. Keep the positive control steps unchanged unless the
|
|
262
|
+
fixture design itself changes.
|
|
263
|
+
|
|
264
|
+
Against a 256,000-token context budget, these blocks remain small. At four
|
|
265
|
+
characters per token as a rough estimate, the shipped-rule table ranges from
|
|
266
|
+
about 482 tokens to about 1,381 tokens. The current dogfood basis is about 1,471
|
|
267
|
+
tokens. The representative maximum is about 1,718 tokens, or 0.67 percent of the
|
|
268
|
+
default budget.
|
|
269
|
+
|
|
270
|
+
No tokenizer was run, and tables are denser than prose. The block is re-sent on every request rather than paid once. These figures show how
|
|
271
|
+
much headroom Slate consumes before conversation content.
|
|
272
|
+
|
|
273
|
+
### Worker writing preamble
|
|
274
|
+
|
|
275
|
+
The doctrine table does not include the worker preamble. It belongs
|
|
276
|
+
to each worker session's system prompt, not to the orchestrator's
|
|
277
|
+
per-turn doctrine. The feature-off preamble is 226 bytes. With
|
|
278
|
+
`writing.check` on it is 384 bytes, a 158-byte increase (the
|
|
279
|
+
157-byte guidance plus its separating space). These are UTF-8 byte
|
|
280
|
+
counts; the current text is ASCII, so its character counts happen to
|
|
281
|
+
be identical. This separate figure states the worker-session cost
|
|
282
|
+
without presenting it as orchestrator doctrine.
|
|
195
283
|
|
|
196
284
|
## Worker threads: the routing window guard
|
|
197
285
|
|
|
@@ -293,9 +381,8 @@ number.
|
|
|
293
381
|
compaction can land in the same cycle and the handoff brief is
|
|
294
382
|
written from compacted context — episodes and thread state survive
|
|
295
383
|
on disk, so handoff still functions.
|
|
296
|
-
- The doctrine sizes above cover the
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
has less room for.
|
|
384
|
+
- The doctrine sizes above cover the stated fixtures only. A project that
|
|
385
|
+
injects `doctrineExtraPath` or `orchestratorPromptDocs` pays for those on top.
|
|
386
|
+
A larger worker-extension roster also adds context beyond the representative
|
|
387
|
+
fixtures. Slate imposes no runtime doctrine-size limit. This content simply
|
|
388
|
+
leaves less room under the context budget.
|
package/docs/model-routing.md
CHANGED
|
@@ -447,14 +447,13 @@ model's ladder is unreadable.
|
|
|
447
447
|
- **In the orchestrator's own system prompt, every turn:** the
|
|
448
448
|
doctrine gains a routing rule — a table with one row per routable
|
|
449
449
|
model, plus the rules for reading it. This is the surface you do
|
|
450
|
-
not see, and it is the router's standing cost: 1,
|
|
451
|
-
20 lines for six configured models, 2,
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
characters with routing off). Those are PORTABLE characters — the
|
|
450
|
+
not see, and it is the router's standing cost: 1,950 characters /
|
|
451
|
+
20 added doctrine lines for six configured models, 2,505 / 23 for
|
|
452
|
+
all nine. In the current snapshot a model row costs 146–183
|
|
453
|
+
characters, plus a one-off legend clause for each marker it
|
|
454
|
+
introduces. Configuring the router roughly doubles Slate's
|
|
455
|
+
always-loaded block (1,929 characters with routing and writing
|
|
456
|
+
off). Those are PORTABLE characters — the
|
|
458
457
|
doctrine with each occurrence of the installed `docs/` directory
|
|
459
458
|
removed, filenames kept — because the doctrine embeds absolute doc
|
|
460
459
|
paths and its raw size therefore depends on where the package is
|
package/docs/review-rules.md
CHANGED
|
@@ -37,14 +37,45 @@ automatically).
|
|
|
37
37
|
|
|
38
38
|
## 3. Choose perspectives by what the change touches
|
|
39
39
|
|
|
40
|
-
There is no fixed roster — compose perspectives per change.
|
|
41
|
-
|
|
40
|
+
There is no fixed roster — compose perspectives per change. Every
|
|
41
|
+
perspective has this first step before its specific charter: run
|
|
42
|
+
`node /path/to/slate/extension/writing-check.mjs --diff PATH --format text`
|
|
43
|
+
over the review diff, using the package root that contains this document.
|
|
44
|
+
Report fail-level matches in changed prose governed by the reviewed
|
|
45
|
+
project's writing convention. Diff mode deliberately selects only prose
|
|
46
|
+
file types; inspect user-facing strings and comments in source files
|
|
47
|
+
directly. For this package, [writing-guidance.md](writing-guidance.md)
|
|
48
|
+
defines the convention, its scope and its exclusions.
|
|
49
|
+
|
|
50
|
+
The checker is diagnostic, not authoritative. It embeds no controlled
|
|
51
|
+
vocabulary and establishes no ASD-STE100 conformance. A clean run does
|
|
52
|
+
not prove that writing is good, and a match is not automatically a
|
|
53
|
+
defect. Apply the project's convention scope before grading output:
|
|
54
|
+
|
|
55
|
+
- `fail`: in convention-governed changed text, normally `should-fix`;
|
|
56
|
+
use `blocker` only when the underlying defect prevents safe or correct
|
|
57
|
+
delivery. In excluded text, it is advisory only.
|
|
58
|
+
- `warning`: normally at most a `suggestion`; raise it only when
|
|
59
|
+
independent evidence establishes a more consequential defect.
|
|
60
|
+
- `house-style`: at most a `suggestion` when the applicable convention
|
|
61
|
+
calls for the change; otherwise report nothing.
|
|
62
|
+
- `advisory`: never a defect by itself. File a finding only when
|
|
63
|
+
independent review establishes an underlying defect, graded on its
|
|
64
|
+
own consequences.
|
|
65
|
+
|
|
66
|
+
Reviewer judgment governs every class. The checker cannot decide
|
|
67
|
+
meaning, factual accuracy, claim truth, document structure, topic unity,
|
|
68
|
+
or instruction completeness; those usually matter more than a
|
|
69
|
+
mechanical match. Each bullet below is the remainder of that
|
|
70
|
+
perspective's charter:
|
|
42
71
|
|
|
43
72
|
- **Code baseline** (any production/test code change): correctness &
|
|
44
73
|
bugs (logic, null safety, resource leaks, lifecycle); code quality
|
|
45
74
|
(readability, duplication, error handling); test quality (do tests
|
|
46
75
|
verify behavior, cover the change, and would they fail on
|
|
47
|
-
regression?).
|
|
76
|
+
regression?). Verify documentation claims about the code under review
|
|
77
|
+
against the implementation already being read. A contradiction is a
|
|
78
|
+
code-baseline finding, not work to leave for a prose specialist.
|
|
48
79
|
- **Specialists**, added when the change touches their domain:
|
|
49
80
|
- concurrency — any defect requiring reasoning about thread
|
|
50
81
|
interleavings (locks, shared state, atomicity);
|
|
@@ -60,14 +91,26 @@ bullet below is that perspective's charter:
|
|
|
60
91
|
domain specialists). Each charter in that file MUST declare its own
|
|
61
92
|
stable finding-ID prefix (uniqueness rules in §4). Compose them per
|
|
62
93
|
change exactly like the built-in perspectives above.
|
|
63
|
-
- **Non-code
|
|
64
|
-
guidance like this file)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
94
|
+
- **Non-code baseline** (docs, prompts, process rules, extension
|
|
95
|
+
guidance like this file): internal consistency & cross-references;
|
|
96
|
+
factual and instruction completeness (can a reader execute this
|
|
97
|
+
without guessing?); context budget (what becomes always-loaded vs
|
|
98
|
+
on-demand); and safety of any scripts/hooks/config touched. This
|
|
99
|
+
baseline applies instead of the code baseline unless a mixed diff
|
|
100
|
+
also changes code.
|
|
101
|
+
- **Text specialist**, added when a change ships user-facing or
|
|
102
|
+
licensing-adjacent prose: licensing and provenance exposure;
|
|
103
|
+
coherence with the project's writing convention; proportionality and
|
|
104
|
+
duplication; register, audience fit, structure, and accuracy as
|
|
105
|
+
prose. User documentation, command help, release notes, prompts, and
|
|
106
|
+
public-facing messages normally trigger it. Do not dispatch it solely
|
|
107
|
+
for a short internal code comment, test name, fixture string, or
|
|
108
|
+
mechanical label unless the text is licensing-adjacent or its prose
|
|
109
|
+
risk independently warrants review.
|
|
110
|
+
- **Mixed diffs**: scope each reviewer to its charter. Code reviewers own
|
|
111
|
+
claims that describe their in-scope code even when those claims live
|
|
112
|
+
in documentation. They do not take on the rest of the non-code or text
|
|
113
|
+
charter, and non-code reviewers do not take on code correctness.
|
|
71
114
|
- Selection is a judgment call, not a rigid filter — when in doubt,
|
|
72
115
|
include the perspective. Risk/complexity changes how deep iteration
|
|
73
116
|
goes (§6), never which perspectives run.
|
|
@@ -156,13 +199,19 @@ review dispatch:
|
|
|
156
199
|
library code instead of assuming its semantics.
|
|
157
200
|
- Enumerate cases exhaustively along the changed execution paths
|
|
158
201
|
(branches, error paths, boundary values); mark each case as checked
|
|
159
|
-
or explicitly out of scope.
|
|
202
|
+
or explicitly out of scope. For prose, enumerate the affected
|
|
203
|
+
audiences, reader tasks, claims, definitions, cross-references,
|
|
204
|
+
examples, exceptions, and boundary conditions instead of execution
|
|
205
|
+
paths.
|
|
160
206
|
- Back every defect claim (blocker or should-fix) with a concrete
|
|
161
207
|
counterexample: the input, state, or interleaving that triggers the
|
|
162
208
|
defect, traced through the code.
|
|
163
209
|
- Back every correctness claim ("no issue here") with a justification
|
|
164
210
|
for why no counterexample exists — not merely the absence of one
|
|
165
|
-
found.
|
|
211
|
+
found. For prose, proof of absence means a bounded, reproducible check
|
|
212
|
+
of the relevant set. Examples include checker output, targeted
|
|
213
|
+
searches, re-resolved references, and comparison with authoritative
|
|
214
|
+
sources. State explicitly what those checks cannot establish.
|
|
166
215
|
- Before finalizing, run an alternative-hypothesis check: "if the
|
|
167
216
|
opposite verdict were true, what evidence would exist?" — then look
|
|
168
217
|
for that evidence.
|
|
@@ -170,3 +219,7 @@ review dispatch:
|
|
|
170
219
|
sought → confirmed / refuted / refined) instead of wandering.
|
|
171
220
|
- Derive the final verdict explicitly from the stated definitions and
|
|
172
221
|
claims, not from overall impression.
|
|
222
|
+
- Treat a fix series as a changed artifact that needs review. Verify the
|
|
223
|
+
addressed finding, then review the fix diff and the cumulative result
|
|
224
|
+
for new paths, claims, and regressions. Clearing the original finding
|
|
225
|
+
does not clear defects introduced by its fix.
|