Repository navigation
docs(core): repair four copy-fails in PHASE2_IMPLEMENTATION.md - #18712
Merged
Merged
Conversation
The sandbox example wrote `blockedHosts`, a key `SandboxConfigSchema` does not declare: `safeParse` succeeds and silently strips it, so a reader who copies that security block blocks nothing and is told nothing. Both the schema and `sandbox-runtime.ts` spell it `deniedHosts`. The `Integration with Kernel` block passed `kernel.logger` to five constructors; that field is `private` on `ObjectKernel` and `protected` on `KernelBase`, with no public getter, so the block never compiled. Build the `ObjectLogger` those constructors take with `createLogger` instead. Drop the auto-recovery / auto-restart-with-backoff claims: `health-monitor.ts` reports and does not act, and the keys that configured a restart were retired under ADR-0049. Also repair the hot-reload feature bullet, the `npm test` line in a pnpm workspace, and the dead MICROKERNEL_IMPROVEMENT_PLAN.md link. Claude-Session: https://claude.ai/code/session_01CqmCgU5RGDoJYhHUMVp2af Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 24 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
This was referenced Sep 17, 2026
huangyiirene
marked this pull request as ready for review
September 17, 2026 16:34
huangyiirene
pushed a commit
that referenced
this pull request
Sep 17, 2026
A census instrument, not a gate: it exits 0 on every census outcome, is wired into no CI job and no package test/lint chain. It extracts fenced ts/typescript/tsx blocks from Markdown at the root of every package under packages/, compiles them in one tsc program against a `paths` map generated from each package's own exports map, and reports the number two ways — raw (upper bound) and under a tolerance rule that forgives only what a legitimately partial block can produce (lower bound). Two controls run on every census. GREEN_CONTROL must compile, so an unbuilt workspace refuses instead of reporting a catastrophe made of nothing. FIRING_CONTROL reconstructs the pre-#18712 `kernel.logger` block and must be caught with TS2341 — and, because that block ends in an elision marker, it is also the standing proof that an exclusion-style elision rule would have hidden the one defect in this family anyone has measured. Claude-Session: https://claude.ai/code/session_01CqmCgU5RGDoJYhHUMVp2af Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Sep 17, 2026
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 28, 2026
…bjectstack-ai#18751) Part of objectstack-ai#18715 — this PR answers the card's own "⛔ Not measured" question with a number. It deliberately does **not** close the blind spot: nothing here gates anything, so the half left open is the wiring decision, which is a new required gate and therefore the maintainer's floor (live precedent: the PR parked in the decision box for that reason, referenced in the dispatch). objectstack-ai#18715 stays open on merge. Clause-②: no ## What landed One file: `scripts/measure-markdown-ts-blocks.mjs`, 1086 lines, a member of the existing `scripts/measure-*.mjs` family (8 prior members). It is a measurement instrument, not a gate: - it exits 0 on **every** census outcome; - it is wired into no CI job, no `package.json` script, no package `test`/`lint` chain; - it exits non-zero for exactly one reason — **the instrument itself could not run**. "Could not run" is a failure, not a skip. Usage: `node scripts/measure-markdown-ts-blocks.mjs` (census, 12s on a warm build) · `--json` · `--only PATH` · `--controls-only` · `--self-test` (30 batteries, no build needed). ## The census Population: `*.md` at the root of every directory under `packages/` that carries a `package.json` — 76 package roots, 141 Markdown files, **1002 fenced `ts`/`typescript`/`tsx` blocks**. `content/docs/**` is a different population with its own gates and is out of scope. Three numbers, because two would hide the answer inside the convention (see below). RAW counts a block failing on any diagnostic; TOLERANT counts it failing on any diagnostic **outside** the forgiven set; WELL-FORMED AND WRONG counts blocks that parse as a TypeScript module and still fail — the class the repaired `kernel.logger` block belonged to. | stratum | files | blocks | RAW | TOLERANT | WELL-FORMED AND WRONG | |:--|--:|--:|--:|--:|--:| | **HAND-WRITTEN** (repairable by an author) | 54 | 282 | **195** (69.1%) | **76** (27.0%) | **58** (20.6%) | | **CHANGELOG.md** (release-owned history) | 46 | 720 | 646 (89.7%) | 356 (49.4%) | 109 (15.1%) | | sub-stratum: the literal `packages/*/*.md` glob the card names | 42 | 654 | 574 (87.8%) | 314 (48.0%) | 131 (20.0%) | RAW is an **upper bound** — it counts fragments that were never meant to stand alone. TOLERANT is a **lower bound**, and that is the direction that matters: a forgiven "cannot find name" leaves that name typed `any`, so every downstream use of it goes unchecked. Real defects hide behind an elision; they never appear because of one. The honest sentence is "between TOLERANT and RAW".⚠️ The two strata are reported separately and never summed. `CHANGELOG.md` is compiled by `changeset version` from `.changeset/*.md` and is release-owned: its blocks are before/after migration snippets that **deliberately** document removed APIs (57 of its counted diagnostics are TS2305 "has no exported member"). A failing block there is frequently correct documentation, and it cannot be repaired in a code PR at all. Diagnostic composition over the whole corpus: ``` forgiven elided-name 1297 diagnostics in 527 blocks TS2304x1275 TS2503x20 TS2552x2 COUNTED syntax 772 diagnostics in 265 blocks TS1005x370 TS1128x170 TS1109x115 TS1127x73 COUNTED semantic 332 diagnostics in 141 blocks TS2305x57 TS2300x56 TS2451x49 TS18004x47 COUNTED implicit-any 65 diagnostics in 42 blocks TS7006x54 TS7031x8 TS7008x2 TS7023x1 forgiven doc-local-path 12 diagnostics in 9 blocks TS2307x12 COUNTED unpublished-subpath 8 diagnostics in 7 blocks TS2307x8 forgiven missing-ambient-environment 1 diagnostic in 1 block TS2593x1 ``` Per-file breakdown (blocks / RAW fail / TOLERANT fail), every file carrying at least one TOLERANT failure: ``` 259 229 141 packages/spec/CHANGELOG.md 4 4 4 packages/plugins/plugin-auth/ARCHITECTURE.md 33 29 23 packages/services/service-automation/CHANGELOG.md 7 7 4 packages/plugins/plugin-auth/CHANGELOG.md 37 35 22 packages/runtime/CHANGELOG.md 9 9 4 packages/plugins/plugin-sharing/CHANGELOG.md 50 46 19 packages/objectql/CHANGELOG.md 6 4 4 packages/services/service-analytics/CHANGELOG.md 25 23 15 packages/metadata-protocol/CHANGELOG.md 7 6 4 packages/services/service-datasource/CHANGELOG.md 18 16 12 packages/lint/CHANGELOG.md 4 4 4 packages/triggers/trigger-record-change/CHANGELOG.md 20 18 11 packages/cli/CHANGELOG.md 4 4 3 packages/client/README.md 27 25 11 packages/client/CHANGELOG.md 7 7 3 packages/core/CHANGELOG.md 23 23 10 packages/rest/CHANGELOG.md 4 3 3 packages/drivers/driver-memory/README.md 14 14 9 packages/client-react/README.md 8 8 3 packages/plugins/plugin-hono-server/CHANGELOG.md 17 15 9 packages/drivers/driver-mongodb/CHANGELOG.md 3 3 3 packages/rest/README.md 10 10 9 packages/metadata/CHANGELOG.md 15 13 3 packages/spec/DEVELOPMENT_PLAN.md 10 10 8 packages/platform-objects/CHANGELOG.md 20 20 8 packages/runtime/README.md ... 2 each: client-react/CHANGELOG, metadata-core/CHANGELOG, 33 27 7 packages/drivers/driver-sql/CHANGELOG.md plugin-audit/CHANGELOG, plugin-auth/README, 10 9 6 packages/core/ADVANCED_FEATURES.md plugin-reports/CHANGELOG, service-i18n/CHANGELOG, 12 12 6 packages/plugins/plugin-security/CHANGELOG.md service-job/README, service-queue/CHANGELOG, 11 7 5 packages/services/service-automation/README.md service-realtime/README, service-sms/CHANGELOG, 7 5 5 packages/spec/V3_MIGRATION_GUIDE.md service-storage/CHANGELOG, spec/PLUGIN_STANDARDS, 14 12 4 packages/drivers/driver-memory/CHANGELOG.md trigger-record-change/README, trigger-schedule/CHANGELOG, trigger-schedule/README ... 1 each: cli/README, driver-mongodb/README, driver-turso/README, mcp/CHANGELOG, mcp/README, observability/README, knowledge-ragflow/README, service-cache/README, service-cluster/CHANGELOG, service-i18n/README, service-package/README, service-queue/README, service-settings/CHANGELOG, service-storage/README, spec/README, spec/REST_API_PLUGIN, spec/ZOD_SCHEMA_AUDIT_REPORT, types/CHANGELOG, types/README, verify/CHANGELOG 33 file(s) with TS blocks and zero TOLERANT failures. ``` The full per-block record, with every diagnostic, is `node scripts/measure-markdown-ts-blocks.mjs --json`. ## The elision convention — the design question, and why the obvious answer is disqualified The card says the convention is the real design question, not the extraction. It is, and the obvious answer fails. ⛔ **Exclusion is disqualified, and this PR proves it rather than asserting it.** The obvious rule is: a block carrying an elision marker (`// ...`) is skipped. Run that rule against the one failure this repository has already measured — the pre-objectstack-ai#18712 `kernel.logger` block in `packages/core/PHASE2_IMPLEMENTATION.md`, `tsc --noEmit --strict` exit 2 with TS2341 — and it is **excluded**, because that block ends with the line `// ... plugin registration code ...`. An exclusion rule would have hidden the only defect in this family anyone has ever measured. The instrument reports the exclusion reading on every run, labelled disqualified, so the number cannot hide inside the convention: | reading | hand-written | CHANGELOG | |:--|--:|--:| | [disqualified] EXCLUSION | 188 fail of 272 considered, 10 blocks skipped | 642 fail of 716 considered, 4 blocks skipped | ✅ **The rule used is a TOLERANCE rule.** Every block is compiled; what a legitimately partial block can *produce* is forgiven and nothing else is: - forgiven — TS2304 / TS2552 / TS2503: a name or namespace the block elided. - forgiven — TS2307 on a **relative** specifier (`./my-kernel`, `./objectstack.config.js`): the reader's own file. - forgiven — "cannot find name `it` / `describe` / `process`", and a third-party module that ships no declarations: the reader's ambient environment. - counted — everything else, including TS2341 (private member), TS2339, TS2345, TS2305 / TS2724, and **TS2307 on an `@objectstack/*` specifier**. The `paths` map is generated from each package's own `exports` map, so an unresolved one means the document tells a reader to import a subpath the package does not publish. - counted — syntax. A tolerance rule that forgave TS1xxx would forgive a typo. **The forward convention, for what tolerance cannot absolve.** A block that is a bare fragment — a method-signature listing, half an object literal — produces syntax errors, and those need an explicit declaration. Proposed spelling: an info-string tag, ` ```ts partial `. Zero blocks carry it today, so it contributes nothing to this census; the instrument reads it, and counts how many blocks would need one: **18 hand-written**, 239 in CHANGELOGs. ## The firing control An instrument that finds zero failures and was never shown capable of finding one has measured nothing. Two controls run on **every** census, through the identical extractor, normalisation and compiler path as corpus blocks, and the run **refuses to print a census** if either misbehaves: - `GREEN_CONTROL` must compile. Its failure means the workspace is not built — the state in which every other block would report TS2307 and the census would read as a catastrophe made of nothing. - `FIRING_CONTROL` is the pre-objectstack-ai#18712 `kernel.logger` block, reconstructed line-for-line from that PR's diff. It must be reported failing, must carry TS2341, must survive the tolerance rule, and must still carry its elision marker. Observed, every run: ``` GREEN_CONTROL compiles clean — `@objectstack/*` resolves through the built exports maps. FIRING_CONTROL reports 5 diagnostic(s) including TS2341 at block line 13 — the pre-objectstack-ai#18712 `kernel.logger` block, reconstructed from that PR's diff, is caught. FIRING_CONTROL also carries an elision marker, so the EXCLUSION reading SKIPS it. ``` Five TS2341, at block lines 13–17: one per constructor the block passed `kernel.logger` to. ⭐ **The firing control earned its keep during this task.** The instrument was first written against `ts.createProgram` + `getPreEmitDiagnostics`, then rewritten onto the `tsc` binary because `check:parse-guard` correctly forbids the parser API outside `scripts/ts-parse.mjs` (and `createProgramChecked` is the wrong tool here — it exits 3 on the first syntactic diagnostic, and blocks that do not parse are this census's subject). The first binary version reported **zero** diagnostics for the firing control, and the control refused the run. Cause, a measured property of the CLI: **when any file in a program has a syntax error, tsc reports the syntax errors and never type-checks ANY file.** One pass over this corpus returned 772 TS1xxx and not one semantic diagnostic. Hence two passes: pass 1 finds the blocks that do not parse, pass 2 re-runs over the ones that do. Without the firing control this would have shipped as "the corpus has no type errors". Cross-check: over all 1002 corpus blocks, the binary implementation and the compiler-API one it replaced agree on **every** block's verdict — raw, tolerant and well-formed-and-wrong — with zero disagreements. ## Wiring options, with costs, for the maintainer's letter Nothing below is done in this PR. What it would take for the number to reach zero is stated first, because it decides everything else. **Reaching zero, hand-written stratum:** 76 blocks across 31 files — 58 repairs (a block that parses and is wrong) plus 18 explicit `partial` tags (a block that is a signature listing or a fragment). **Reaching zero, CHANGELOG stratum: impossible in principle.** Those files are release-owned, compiled from changesets, and deliberately show removed APIs. Any gate whose population includes `CHANGELOG.md` is a gate that can never be green without rewriting published release history. ⇒ **The only gate-able population is hand-written package-root Markdown.** 1. **Leave it unwired (what this PR does).** Cost: zero CI time. The number is known only when someone runs it — the declared-not-enforced shape this family of cards is about, mitigated only by the instrument being cheap (12s) and carrying its own controls. 2. **Advisory job, printing the census on every PR.** Cost: it resolves through built `.d.ts`, so it must piggyback on a job that has already built (or pay a full build). Nothing blocks. Risk: an advisory red rides `main`'s merge ref into every later PR until someone stanches it. 3. **Shrink-only ratchet with a checked-in per-file baseline.** Cost: a required job (maintainer's floor) plus a baseline artefact and its merge-driver discipline. Opening number to hold: 76 hand-written TOLERANT failures. Buys: the number can only go down, and grandfathered debt is visible rather than forgotten. 4. **Gate at zero over hand-written package-root Markdown.** Cost: the 76-block entry price above, paid before the gate can be armed, plus the `partial` tag convention landing first. Buys: the strongest guarantee, and the only one that makes the card's class genuinely closed. 5. **Diff-scoped gate — only blocks a PR adds or edits.** Cost: block identity across edits; today's debt is grandfathered on day one. Buys: catches the PR-objectstack-ai#18712 class at the moment it is written, at near-zero entry price.⚠️ Grandfathering is exactly the failure mode objectstack-ai#15931 demonstrated, so this option is only honest if the standing debt number is recorded somewhere that gets re-read — which is what option 3 is for. 3 + 5 together is the combination with no known hole. ## Verification - `node scripts/measure-markdown-ts-blocks.mjs --self-test` — 30 cases pass, 30 batteries at or above the pinned floor of 30. Roster-and-handshake shape copied from `scripts/check-agent-model-declared.mjs`; needs no build. - `node scripts/measure-markdown-ts-blocks.mjs` — exit 0, both controls fire, 12s under the shared verify lock. - All 26 gates `scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derives for this diff: **26/26 exit 0**. Two were red on the first draft and drove real corrections — `check:parse-guard` (the parser-API rule) and `check:entry-guard` (the import guard). - `eslint . --no-inline-config --format json` — the **union**, not a narrowing: 6830 files governed by eslint's own config, 0 errors, 0 warnings, at `3c64a03c4e`. - Control-character self-scan over the new file: no match. - `skip-changeset`, measured with a positive control rather than assumed: the new file's basename has 0 hits anywhere under any package's built `dist/`; the positive control `ObjectKernel` has 4 hits in `packages/core/dist`; no package's `files[]` names a path outside its own directory, so a repo-root `scripts/` file cannot enter any tarball. ## Acceptance notes - **Not repaired, by instruction.** 58 hand-written blocks parse and are wrong. A sample, all real: `packages/runtime/README.md` — TS2339, `Property 'use' does not exist` on the promise the kernel builder returns, because the front-page example chains `.use(...)` without awaiting it (the type in the diagnostic is a Promise parameterised by ObjectKernel; spelled out here because a raw angle-bracket fragment does not survive this surface); `packages/plugins/plugin-auth/README.md` — `'plugins' does not exist in type 'ObjectKernelConfig'`; `packages/services/service-job/README.md` — `'timeout' does not exist in type 'JobScheduleOptions'. Did you mean 'timeoutMs'?`; `packages/drivers/driver-mongodb/README.md` — `'driver' does not exist in type 'ObjectStackDefinitionInput'`; `packages/services/service-cache/README.md` — the documented `MyCache` class does not implement `ICacheService`. - **The sharpest instance found, not filed by me:** `packages/spec/V3_MIGRATION_GUIDE.md` tells a reader to import `@objectstack/spec/hub`, `@objectstack/core/errors` and `@objectstack/core/plugin`. None of the three is in its package's `exports` map, so the import fails for anyone who copies it. This is the `check-published-readme-exports` family arriving through a document that gate's population does not reach — `V3_MIGRATION_GUIDE.md` is not in `@objectstack/spec`'s `files[]`. Reported to the dispatching seat with dedupe words rather than filed here, to keep this PR a census. - **Noted, not filed:** the census counts `packages/*/CHANGELOG.md` because they are package-root Markdown, and they dominate the raw number (720 of 1002 blocks). They are structurally unrepairable in a code PR. Successor: whoever writes the wiring letter — the stratum split exists precisely so that reader does not have to re-derive it. - **No census snapshot is committed.** A number checked into a file is a number that rots; the instrument regenerates it in 12 seconds. The census lives in this PR body and in the report comment on objectstack-ai#18715. - Population note: the card's example glob is `packages/*/*.md`, which misses nested package roots such as `packages/plugins/plugin-auth/`. The instrument measures every package root and reports the card's literal glob as a named sub-stratum, so both readings are available and neither is assumed. <sub>⚠️ **Line count corrected by the dispatching seat, not by the author.** This body first read 「918 lines」, which was the count at the first commit, before the two-pass `tsc` rewrite; the landed file at `3c64a03c4e` is **1086** lines (`git show … | wc -l`, taken by the seat). The author found the slip after the single permitted body write and reported it rather than patching, because the role file allows a dev exactly one body write in the `POST /pulls` stroke and routes later changes through its report to the seat. ⛔ Nothing else in this body was changed, and everything else in it was re-verified by the author at the landed head.</sub> --- _Generated by [Claude Code](https://claude.ai/code)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #18620
Clause-②: no
packages/core/PHASE2_IMPLEMENTATION.mdcarried four copy-fails that the edit boundary of PR #18615 (the seven retired key spellings) deliberately left alone. Triage refused to split the card, so all four land here in one sweep of one file.packages/specwas read-only for this work: the schemas were read to learn the right spelling, never edited.Every reading below was re-taken on this branch's head. The card's line numbers moved after PR #18615 landed, so each anchor was located by content.
The four items are NOT one species
Exactly one of them is a silently dropped key. The other three are a compile failure and stale prose.
1.
blockedHosts— a key the runtime silently drops, in a security exampleThe sandbox example wrote
blockedHosts.SandboxConfigSchema(packages/spec/src/kernel/plugin-security-advanced.zod.ts:392) declaresdeniedHosts, andsandbox-runtime.ts:261-262readsconfig.network.deniedHosts. Thenetworkobject is a plainz.object, not.strict(), and there is noretiredKeytombstone forblockedHosts— so the parse succeeds and the key is stripped with no diagnostic at all.Measured against the schema source, the documented block beside a positive control:
A reader who copied that block got a sandbox that did not deny the host it named, and was told nothing.
blockedHostsoccurred exactly once repo-wide before this PR (that documentation line) and occurs zero times after it. The Features bullet above the block said "allowed/blocked hosts" and now says "allowed/denied hosts", matching the filesystem bullet beside it.Species: a silently dropped key. This is the only one of the four.
2.
kernel.logger— a compile failure by member visibility, not a dropped keyThe
Integration with Kernelblock passedkernel.loggerto five constructors.ObjectKerneldeclaresprivate logger: ObjectLogger(packages/core/src/kernel.ts:107),KernelBasedeclaresprotected logger: Logger(packages/core/src/kernel-base.ts:36), and neither class has a public getter. The block never compiled, so nothing about it ever reached a runtime that could drop anything.Measured with
tsc --noEmit --strict, the documented line against the repaired one:The repair builds the
ObjectLoggerthose five constructors take withcreateLogger— already exported from@objectstack/corethrough thelogger.jsbarrel — from the same config the kernel is given, rather than reaching into the kernel. The whole repaired block is what the exit-0 run above typechecked.Species: an example that fails when copied, by member visibility. No metadata key is involved.
3. Prose advertising a capability no runtime delivers
The intro claimed "auto-recovery" and the Features list claimed "Auto-restart with backoff strategies (fixed, linear, exponential)".
packages/core/src/health-monitor.ts:160states the opposite in as many words: "Monitors plugin health status. It REPORTS; it does not act on what it finds." The three keys that once configured a restart were retired under ADR-0049 and deleted from this file's examples by PR #18615, which is how the prose became conspicuous.The intro now says the monitor reports and that acting on a report belongs to the host, and the untrue Features bullet is replaced by the true integration point the example already demonstrates — polling
getHealthStatusandgetHealthReport. The adjacent bullets were checked rather than assumed: therecoveringstatus is real and asserted byhealth-monitor.test.ts, so that bullet stands.Species: stale prose, Prime Directive #10. No key.
4. Three observations in the same file
MICROKERNEL_IMPROVEMENT_PLAN.mdwas linked from the References section. Repo-wide the name occurred once — that link — and no such file exists at the repo root or anywhere else, while its siblingARCHITECTURE.mddoes. The dead link is removed.npm testin a pnpm workspace is nowpnpm --filter @objectstack/core test, which is what the package's owntestscript answers to. The three test files the section lists all exist.HotReloadConfig.watchPatternswas retired in [finding] HotReloadManager.startWatching watches nothing and logs "File watching started" at info; watchPatterns has no reader and watchHandles is never populated #12428 because no watcher was ever constructed, and this file's own body already tells the reader that file watching is the host's job. The bullet is folded into the debounce bullet, which now namesscheduleReloadand says the host runs the watcher.Species: stale prose and one dead reference. No keys.
Changeset: measured, not guessed
packages/core/PHASE2_IMPLEMENTATION.mdsits at a package root, outside every fast-track path, so whether it ships is a property of@objectstack/core'sfiles[], which is["dist", "README.md", "CHANGELOG.md"].The reading, taken after a real build of
@objectstack/coreand its dependency closure:npm pack --dry-run --jsoninpackages/corelists 16 tarball entries. The non-dist/entries areCHANGELOG.md,LICENSE,README.mdandpackage.json.PHASE2_IMPLEMENTATION.mdis not among them.dist,README.md,CHANGELOG.md,package.json,LICENSE) for symbols unique to this diff:PHASE2_IMPLEMENTATION0 files,MICROKERNEL_IMPROVEMENT_PLAN0 files,Auto-restart with backoff strategies0 files,blockedHosts0 files.PluginSandboxRuntimehits 4 published files (dist/index.cjs,dist/index.js,dist/index.d.cts,dist/index.d.ts), so the grep was capable of finding something.Verdict forced by that reading: this diff publishes nothing from any released package, so it takes
skip-changesetrather than a patch changeset.Clause-②: nostands after the diff was written: the schema is untouched, no accept set moves, and no surface is published.scripts/pm/check-widening-tells.mjs --declaration noexits 0 on this diff but reports it NOT MEASURED — no declared surface covers a Markdown file — so that exit is recorded as evidence about no surface rather than as a clearance.Verification
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackfrom the tool's own change set: 39 families. 37 exited 0. Reconciled with--rancarrying every exit code: 39 derived, 37 run, 2 NOT MEASURED, 0 UNRUN.check:dual-build-cjs-loadsandcheck:lean-entry-closure, both exit 3 PREREQUISITE NOT MET: they load built output for every package in the tree and 74 or more packages have nodist/. A whole-treepnpm buildis CI's run, not this card's; declared as a narrowing rather than reported as a pass.pnpm --filter @objectstack/core typecheckexit 0 (three legs:tsc --noEmit,tsconfig.examples.json,check:test-typecheck).pnpm --filter @objectstack/core testexit 0 — 51 test files, 1316 tests passed.pnpm --filter '@objectstack/core...' buildexit 0 (core plus its dependency closure), run before every gate and measurement that readsdist/.pnpm lintnarrowed to a measurement rather than skipped. ESLint's universe read fromeslint.config.mjsitself: every config block'sfilesis a{ts,tsx,mts,cts,js,jsx,mjs,cjs}glob and no block names Markdown. ESLint's own count over the changed file, from--format json: 1 result, 0 errors, and the one message is "File ignored because no matching configuration was supplied." Invariance over untouched files: the config enables no type-aware linting anywhere — noparserOptions.project, no typed rules, as the config's own recorded measurement at line 328 states — so this diff cannot move any other file's verdict.pnpm check:nul-bytesexit 0, plus a direct control-character scan of the changed file, which found none.scripts/pm/os-verify-lock.shwith a stable slot; every verdict above is read from itsVERDICT command-exitline.Measurements taken at
b6606cdc2d, which is the only commit on this branch.Acceptance notes
## Referencessection still links[Protocol Definitions](../spec/src/system/), while the Phase 2 components this file documents are Kernel-domain schemas underpackages/spec/src/kernel/. The link resolves to a directory that exists, so it is not dead and nothing fails when copied — a documentation nit, none of the three filable classes. Noted, not filed. No PR and no person is queued on this file today, so there is no carrier for it beyond the next sweep of the document.needs:contract-reviewis the dispatching seat's label. This PR neither hangs it, removes it, nor waits on it; its presence and the--pairexit code are reported to the seat as readings.Generated by Claude Code