Filed by the epic PM for #15939 (session_015c5G6TmpMKgnusmTpD7Ntt) as a surrounding finding, not as part of that epic. ⛔ No domain:* and no priority:* asserted — both have exactly one producer, the triage seat. ⚠️ Triage's first touch is owed before this can be dispatched.
Surfaced by the at-tier contract review of PR #17986 (review comment 5652813288), then verified independently by the epic PM at that PR's head db55ea6dde, 2026-09-13T10:52Z.
The defect
packages/core/PHASE2_IMPLEMENTATION.md carries two copy-pasteable registerPlugin examples. Seven of their keys are spellings the schema now refuses, so a reader who copies either block verbatim gets a validation failure, not a running plugin.
// :30-37 — the health-monitor example
monitor.registerPlugin('my-plugin', {
interval: 30000, // :31
timeout: 5000, // :32
failureThreshold: 3,
successThreshold: 1,
autoRestart: true, // :35
maxRestartAttempts: 3, // :36
restartBackoff: 'exponential', // :37
// :68-74 — the hot-reload example
hotReload.registerPlugin('my-plugin', {
enabled: true,
watchPatterns: ['src/**/*.ts'], // :70
debounceDelay: 1000, // :71
| lines |
keys |
retired by |
:35 :36 :37 :70 |
autoRestart, maxRestartAttempts, restartBackoff, watchPatterns |
the #15678-era retirements on these same two defs — already false today, before anything in the #15939 epic |
:31 :32 :71 |
interval, timeout, debounceDelay |
PR #17986 (#17780), the kernel/plugin-lifecycle-advanced.zod.ts card of the #15939 epic |
Each of the seven has a live retiredKey() tombstone, so the failure is a loud refusal carrying the rename prescription, not a silent strip. That is the tombstones working as designed; the example is what is wrong.
Why this is category (a) and not an Acceptance note
The triage rubric's own dividing line: an example that fails when copied verbatim is (a) — the test is not documentation-versus-code and not whether the file ships. Both blocks fail on their first retired key.
It does not ship. packages/core/package.json files is ['dist', 'README.md', 'CHANGELOG.md'], so this reaches contributors reading the repo, not installers. That bears on priority. It does not change the classification.
Why it was not fixed inside PR #17986
Recorded so the decision is auditable rather than re-derived:
The review's diagnosis of how it was missed is the actionable half and is repeated here for whoever takes this: PR #17986's consumer sweep excluded packages/core wholesale, on the reasoning that core was the package being changed. That exclusion is what hid an in-package doc from a rename that package participated in.
Suggested shape
Repair both blocks to the current spellings, and check the rest of the file in the same pass rather than only these seven lines — a document already stale in seven places is unlikely to be stale in exactly seven.
Adjacent open card on the same file — ⚠️ not a duplicate
#16208 is open against PHASE2_IMPLEMENTATION.md sections 4 and 5, about two prose notes describing the @objectstack/core/security subpath that PR #16205 repaired. Different defect, different lines, same file. Whoever schedules these should either fold them into one round or sequence them, because two independent cards editing one markdown file will conflict. Filed separately rather than appended to #16208 because folding an unrelated defect into an existing card hides it from that card's own acceptance.
Dedupe
search_issues over this repo for the file name, the stale-example shape and the retired keys ⇒ 7 results, 2 open. #16208 as above (adjacent, not duplicate); #17378 is the same shape on a different file (plugin-spec.mdx, an unsatisfiable version range). The three closed PHASE2_IMPLEMENTATION.md hits (#15931, #14919) are the subpath defect and a PluginSecurityScanner question, neither about key spellings. ⚠️ Declared limit: this was a semantic search, not an exhaustive title enumeration.
Refs: PR #17986 (falsifies 3 of the 7) · #17780 · #15939 (the epic, which this is deliberately not a sub-issue of) · #16208 (adjacent, same file)
Filed by the epic PM for #15939 (⚠️ Triage's first touch is owed before this can be dispatched.
session_015c5G6TmpMKgnusmTpD7Ntt) as a surrounding finding, not as part of that epic. ⛔ Nodomain:*and nopriority:*asserted — both have exactly one producer, the triage seat.Surfaced by the at-tier contract review of PR #17986 (review comment
5652813288), then verified independently by the epic PM at that PR's headdb55ea6dde, 2026-09-13T10:52Z.The defect
packages/core/PHASE2_IMPLEMENTATION.mdcarries two copy-pasteableregisterPluginexamples. Seven of their keys are spellings the schema now refuses, so a reader who copies either block verbatim gets a validation failure, not a running plugin.:35:36:37:70autoRestart,maxRestartAttempts,restartBackoff,watchPatterns:31:32:71interval,timeout,debounceDelaykernel/plugin-lifecycle-advanced.zod.tscard of the #15939 epicEach of the seven has a live
retiredKey()tombstone, so the failure is a loud refusal carrying the rename prescription, not a silent strip. That is the tombstones working as designed; the example is what is wrong.Why this is category (a) and not an Acceptance note
The triage rubric's own dividing line: an example that fails when copied verbatim is (a) — the test is not documentation-versus-code and not whether the file ships. Both blocks fail on their first retired key.
It does not ship.
packages/core/package.jsonfilesis['dist', 'README.md', 'CHANGELOG.md'], so this reaches contributors reading the repo, not installers. That bears on priority. It does not change the classification.Why it was not fixed inside PR #17986
Recorded so the decision is auditable rather than re-derived:
kernel/plugin-lifecycle-advanced.zod.tsduration keys carry their unit in the key name #17986 does not change whether the example works. It already throws today at:35onautoRestart. Patching only the three lines that PR falsifies would leave a copy-paste equally broken while widening a card that had no business touchingpackages/coredocs.The review's diagnosis of how it was missed is the actionable half and is repeated here for whoever takes this: PR #17986's consumer sweep excluded
packages/corewholesale, on the reasoning that core was the package being changed. That exclusion is what hid an in-package doc from a rename that package participated in.Suggested shape
Repair both blocks to the current spellings, and check the rest of the file in the same pass rather than only these seven lines — a document already stale in seven places is unlikely to be stale in exactly seven.
Adjacent open card on the same file —⚠️ not a duplicate
#16208 is open against
PHASE2_IMPLEMENTATION.mdsections 4 and 5, about two prose notes describing the@objectstack/core/securitysubpath that PR #16205 repaired. Different defect, different lines, same file. Whoever schedules these should either fold them into one round or sequence them, because two independent cards editing one markdown file will conflict. Filed separately rather than appended to #16208 because folding an unrelated defect into an existing card hides it from that card's own acceptance.Dedupe
search_issuesover this repo for the file name, the stale-example shape and the retired keys ⇒ 7 results, 2 open. #16208 as above (adjacent, not duplicate); #17378 is the same shape on a different file (plugin-spec.mdx, an unsatisfiable version range). The three closedPHASE2_IMPLEMENTATION.mdhits (#15931, #14919) are the subpath defect and aPluginSecurityScannerquestion, neither about key spellings.Refs: PR #17986 (falsifies 3 of the 7) · #17780 · #15939 (the epic, which this is deliberately not a sub-issue of) · #16208 (adjacent, same file)