Skip to content

docs(spec): KnowledgeSource docblock says runtime registration, not governed metadata - #17653

Merged
os-bill merged 1 commit into
mainfrom
claude/issue-17464-knowledge-source-docblock-v2
Sep 11, 2026
Merged

docs(spec): KnowledgeSource docblock says runtime registration, not governed metadata#17653
os-bill merged 1 commit into
mainfrom
claude/issue-17464-knowledge-source-docblock-v2

Conversation

@os-bill

@os-bill os-bill commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Part of #17464

  • Clause-②: no

The docblock above KnowledgeSourceSchema claimed, verbatim:

Canonical KnowledgeSource. Stored as metadata, versioned, and
environment-scoped exactly like a view or a flow.

None of the three is true. This PR corrects the prose. No schema, no registry entry, no key — the diff is one docblock plus its changeset.

Supersedes #17649

#17649 carried the identical content, but its single commit message also carried the card relation, which the contract puts in the PR body only (check:partof-closing-keyword, RULE 2). On an already-pushed branch nothing clears that red, and amend / rebase / force-push are forbidden here — so this is a fresh branch off current main with a card-trailer-free commit message, ⛔ not a rewrite of anything published. #17649 is superseded and its branch is left in place.

Content byte-identity was proven rather than assumed: both paths hash-match 7bd20c60ea exactly (git hash-object compared against git rev-parse 7bd20c60ea:PATH), so the reviewed text is unchanged. gen:schema and gen:docs were re-run on the newer base and again produced no artefact change.

Fork (a) vs (b) — the measurements support (a): the PROSE is wrong

The card allowed for the possibility that the registry, not the sentence, is the defect. It is not, on three independent grounds measured on this tree:

  1. No ruling exists that KnowledgeSource ought to be governed metadata. grep -rln "KnowledgeSource\|knowledge source" docs/adr/ returns zero files — no ADR in this repo mentions it at all.
  2. The rest of the contract already says service-level, consistently. IKnowledgeService (packages/spec/src/contracts/knowledge-service.ts) declares registerSource / unregisterSource / listSources / getSource; KnowledgeServicePlugin takes a sources option and calls registerSource for each at init(); KnowledgeService holds them in a plain process-lifetime Map.
  3. The liveness ledger says the same from the other side. packages/spec/liveness/agent.json, row props/knowledge, status dead: "restrict retrieval at the knowledge-service/source level; describe grounding in instructions".

So the sentence was the outlier, and the sentence is what moves. ⛔ Nothing here assumes (b) will happen later — the new text describes only what is true today.

The three prerequisite readings (re-taken on origin/main, ⛔ not inherited from the card)

The card's counts were taken on the installed @objectstack/spec 17.4.0. These were re-taken against the tree under test, with the import resolution proven to the worktree build (import.meta.resolve reported file:///home/user/objectstack-issue-17464/packages/spec/dist/kernel/index.mjs), base bc2bf01c8a.

1 · The docblock still carried the sentence. Anchored by content, ⛔ not by line. The sentence wraps across a line break, so a contiguous grep reads 0 — a mistyped anchor, not an absence. Whitespace-flattened first, then counted by occurrence:

naive contiguous grep                                        -> 0   (MISTYPED ANCHOR)
flattened, "Stored as metadata, versioned, and
            environment-scoped exactly like a view or a flow." -> 1
LIT  CONTROL "Canonical KnowledgeSource."                     -> 1
DARK CONTROL nonsense variant of the same sentence            -> 0

Census over tracked files only (git ls-tree, so the built dist/ cannot pollute it): the phrase exactly like a view or a flow occurs in exactly 1 tracked file — the target.

2 · Registry read, with the card's own control reproduced.

COUNT listMetadataTypeSchemaTypes() = 26
knowledge-shaped (/know/i)          = []
CONTROL view  => true      CONTROL flow  => true      CONTROL skill => true
CONTROL agent => true      CONTROL tool  => true
DARK CONTROL zzz_nonsense => false

3 · No stack-authoring route — with a LIT control.

ObjectStackDefinitionSchema top-level key COUNT = 44
knowledge-shaped keys                           = []
controls present: skills, agents, tools, views, flows  => all true

PROBE base only (additive control)          => ACCEPTED
PROBE LIT CONTROL skills:[valid skill]      => ACCEPTED     <- the probe DOES find an
                                                               authoring route for a type
                                                               that has one
PROBE knowledgeSources:[KS]                 => REJECTED: Unrecognized key(s) ...
PROBE knowledge:[KS] / knowledge_sources    => REJECTED: Unrecognized key(s) ...
PROBE DARK CONTROL zzz_nonsense:1           => REJECTED: Unrecognized key(s) ...  (identical text)

⚠️ One run was discarded and is reported rather than silently retried. The first lit-control attempt used a malformed skill payload and came back REJECTED (3 issues). Reading the full message showed field-level errors inside skills.0 (label / tools required) — a recognized key failing its element schema, not an unrecognized-key refusal. The probe was re-run with a valid skill, which is the ACCEPTED line above.

The correction

The replacement docblock states what the schema actually is — the shape of a runtime registration — names both routes a source arrives by, and records that retrieval is restricted per-source at the service level. It explicitly contrasts against view / flow / skill / agent / tool so the next reader does not have to re-derive the measurement above.

Changeset: patch on @objectstack/spec, graded honestly

⛔ Not skip-changeset: this text is published twice over. files[] ships dist and src/**/*.zod.ts.

BEFORE (dist built from old src):  "exactly like a view or a flow"  -> 1x .d.ts + 1x .d.mts
AFTER  (dist rebuilt):             same phrase                      -> 0
                                   new phrase                       -> 2  (.d.ts + .d.mts)
                                   LIT CONTROL "Canonical KnowledgeSource" -> 2

Measured over 126 built declaration files. The changeset is committed, not a working-tree edit, so the gate that reads it out of git can see it.

Generators

gen:schema and gen:docs were run; both produced no artefact change. content/docs/references/ai/knowledge-source.mdx mirrors the file-level header docblock, not this per-schema one — consistent with the 1-file census above. ⛔ Nothing generated was hand-edited.

Verification — all at 7bd20c60ea

Gate families derived mechanically with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (it takes its own change set from the merge base), then reconciled with --ran carrying a recorded exit code per family:

Run reconciliation — 75 derived, 73 run, 2 NOT-MEASURED, 0 UNRUN.
  • 73 green. Includes check:docs, check:api-surface, check:authorable-surface, check:llms-txt, check:liveness, check:nul-bytes, check:published-files, check:changeset-no-major, check:empty-changeset, check:spec-docblock-symbol-anchors.
  • 2 NOT MEASURED (exit 3), declared: check:dual-build-cjs-loads and check:lean-entry-closure both refuse their own prerequisite — they read built output and 83 workspace packages have no dist/ in this worktree. Clearing them needs a repo-wide pnpm build; that is CI's Build Core. ⛔ Recorded as NOT MEASURED, ⛔ not as green.
  • 6 gates were discarded and re-run, not silently retried. check:doc-formula-expressions, check:api-surface, check:browser-reachable-entries, check:dual-source-exports, check:entry-nameability, check:exported-any first returned a prerequisite refusal (dist stale against the edited src; one at exit 3, five at exit 1 — a refusal does not always arrive as exit 3). After rebuilding @objectstack/spec, @objectstack/formula and @objectstack/lint, all six are green. The whole @objectstack/spec check family (17 gates) was additionally re-run on the rebuilt tree, since a green taken against a stale dist is a false green.

Tests / typecheck (affected package is @objectstack/spec; the published surface is byte-unchanged apart from TSDoc, so no consumer owes a test):

pnpm --filter @objectstack/spec typecheck  -> exit 0
   check:test-typecheck: OK — 54 file(s) / 259 error(s) / 144 pinned signature(s) held
pnpm --filter @objectstack/spec test       -> exit 0
   Test Files  473 passed (473)
   Tests       13429 passed (13429)

Both ran through scripts/pm/os-verify-lock.sh; verdicts read from the printed VERDICT command-exit line, ⛔ never from a bare status after a pipe.

Lint — a declared narrowing, with its three readings. pnpm lint is a repo-wide scan CI owns; this PR ran the narrowed set and proves the narrowing excluded nothing:

  1. Population, read from eslint's own config via ESLint#isPathIgnored over git ls-files: 6615 files are under lint.
  2. Files actually linted, counted from --format json: 2packages/spec/src/ai/knowledge-source.zod.ts (0 errors, 0 warnings) and the changeset .md, whose only message is File ignored because no matching configuration was supplied. eslint --no-inline-config exited 0.
  3. Invariance for the other 6613. This repo runs one eslint.config.mjs and it never enables type-aware linting for any file — no parserOptions.project, no typed @typescript-eslint rules. The config states this in its own words at eslint.config.mjs:326-329, with a positive control recorded there. A TSDoc edit inside one file therefore cannot move any untouched file's verdict.

Acceptance notes (out of scope, ⛔ not filed)


Generated by Claude Code

…overned metadata

The docblock above `KnowledgeSourceSchema` claimed it is "Stored as
metadata, versioned, and environment-scoped exactly like a view or a
flow". Measured on this tree: `listMetadataTypeSchemaTypes()` returns 26
governed types with none knowledge-shaped (controls `view`, `flow`,
`skill`, `agent`, `tool` all present), `ObjectStackDefinitionSchema` has
44 top-level keys with none knowledge-shaped, and
`defineStack({ knowledgeSources: [...] })` is refused with the generic
unrecognized-key message — identical to a `zzz_nonsense` dark control —
while `defineStack({ skills: [a valid skill] })` is accepted as the lit
control.

No ADR says it ought to be a governed metadata type; the rest of the
contract already says the opposite (`IKnowledgeService.registerSource`,
`KnowledgeServicePlugin({ sources })`, the process-lifetime source Map,
and the `agent.knowledge` liveness row). The prose was the outlier, so
the prose is what moves: the replacement states the schema is the shape
of a runtime registration, names both routes a source arrives by, and
says retrieval is restricted per-source at the service level.

Prose only — no schema, no registry, no key. `gen:schema` and `gen:docs`
produced no artefact change. The card relation is declared in the pull
request body, which is its only carrier.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/spec/src/ai/knowledge-source.zod.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/src/ai/knowledge-source.zod.ts) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 135 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json d07fc178b9ae778e3dca988c641d18065d8f392bpackageMentionDocs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:ai tooling labels Sep 11, 2026
@os-bill
os-bill marked this pull request as ready for review September 11, 2026 14:03
@os-bill
os-bill added this pull request to the merge queue Sep 11, 2026
Merged via the queue into main with commit 132dd13 Sep 11, 2026
36 checks passed
@os-bill
os-bill deleted the claude/issue-17464-knowledge-source-docblock-v2 branch September 11, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:ai size/s tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants