chore: Split docs/knowledge/ into a harvest-only tree and a notes tree, and add audit-scale group queries - #61
Merged
Conversation
#56) A `<sub>` sha digests the whole source file, not the entry. Every entry harvested from one document therefore carries the same value, and an edit to an entry's text changes no sha. The next harvest cannot see the edit: it regenerates the original text, or it writes a duplicate. Hand-written knowledge under the harvested tree was scheduled for silent deletion. The corpus is now two trees under docs/knowledge/: - harvested/ — what the documents say. Roles spec, design, styleguide. Generated by knowledge-harvest. Never hand-edited. 38 topic files, 1457 entries, INDEX.md, SOURCES.md. - notes/ — what the implementation found. Role review, a manual sha: marker. Hand-written. 3 files, 5 entries. A note overrides the harvested entry it names. docs/knowledge/README.md states that contract once. INDEX.md and SOURCES.md point at it rather than restating it, because a harvest overwrites both. Query surface (scripts/knowledge.mjs): - Reads both trees. Every entry carries an `origin`, and `--origin` selects one. - `--prefix HTTP` selects a whole requirement family. It is the audit-scale filter that `--req` cannot express. An unknown prefix exits 2, validated against appendix C. - Every entry carries a stable key, <topic>/<8 hex>, digested from the entry text. A note cites that key. The CLI resolves the citation, prints `[overridden by notes/...]` on the harvested entry, and resolves one on demand with `--key`. The key changes when the rule's text changes, which is when the note needs a fresh check. - An empty filter value is refused. `--topic ''` and the one-character typo `--topic 'a,b,'` matched every entry and printed the whole corpus. - A zero-result query tests each filter alone before it blames one. It used to report "PAGE-11 is canonical but no entry cites it yet" for `--prefix HTTP --req PAGE-11`, which is false: three entries cite PAGE-11, and none of them cites an HTTP ID. - The parser strips a BOM and accepts CRLF. A CRLF topic file parsed to zero entries, with no error. Two checks: - `bun run verify:knowledge-structure` — blocking, and the first step in ci.yml because it is pure Node over Markdown and needs no build. It rejects a review or invented role under harvested/, a Superseded entry there, an entry with no provenance line, a `<sub>` that cites outside the three source roots SOURCES.md names, a note that is not review-role, and a .md stranded at the root of docs/knowledge/ — which is where a harvest without `--corpus docs/knowledge/harvested` writes. It refuses to report OK below 1000 harvested entries, so a failing parse cannot pass vacuously. - `bun run knowledge:drift` — a hand-run report, deliberately not in CI. It compares each SOURCES.md sha against the file on disk, and it reports every note citation that no entry carries any more. Three sources drift today, all in docs/sdk-design-nodejs/. The 16 styleguide sources are NOT VERIFIABLE off the harvest machine, which is expected and never a failure. Migration: - Four resolved Conflicts entries are split. Each statement stays in harvested/. Each resolution is a note that names the statement by key. - The PAGE-11 erratum moves to notes/pagination.md, under Superseded. The inline erratum marker it duplicated is removed from the harvested Reference entry, which now prints the override tag instead. - deliberate-deviations.md leaves the corpus, with its SOURCES.md row. A register accumulates rows, so any harvest of one is a stale fraction of it. The copy held 13 entries against a 17-item register, at a three-revision-old sha, with two entries substantively false. notes/deliberate-deviations.md is the pointer. docs/open-items.md is the second register under the same rule. Documentation: - .claude/skills/knowledge-lookup/SKILL.md rewritten. Phase start is two queries, `--origin note` and `--section conflicts`; they are different sets, and a conflict with no override tag is still open. Adds the audit query as a stated exception to the rule against broad topic queries, the API-surface audit group, the audit loop, and the prefix-to-chapter table that completes the roll-up path. Frozen counts removed. - CLAUDE.md records the two trees, both checks, and the citation convention. - 107 corpus citations in packages/, test/, tests/ and .changeset/ are repointed to harvested/. Two cited the deleted file and now cite the ledger. docs/superpowers/ keeps its pre-split paths: those files are dated records of what a phase planned, and they are not retro-edited. docs/open-items.md section O records three gaps: the global knowledge-harvest skill still defaults --corpus to the tree no query reads (O1), a note's key citation is checked by a report and not by a gate (O2), and the docs/superpowers/ paths are deliberate (O3). H13 is raised in priority: a blocking gate now depends on a parser that no CI job tests. No changeset. No published package surface changes. Verified: test:scripts 85 pass, lint 0, build 0, test 2175 pass / 0 fail, structure gate OK, drift 44 OK / 3 DRIFT / 5 note citations resolve.
Wahbeh-Mohammad
force-pushed
the
56-split-docsknowledge-into-a-harvest-only-tree-and-a-notes-tree-and-add-audit-scale-group-queries
branch
from
August 31, 2026 19:41
f920f86 to
2b3a197
Compare
Contributor
Author
|
Must an unresolvable note key fail the gate? Today a report finds it. A gate would make a re-harvest that orphans a note a red build. The cost is that the harvest cannot land until the same commit updates the notes. Recorded as O2. |
Wahbeh-Mohammad
deleted the
56-split-docsknowledge-into-a-harvest-only-tree-and-a-notes-tree-and-add-audit-scale-group-queries
branch
August 31, 2026 19:47
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.
Closes #56.
What changed
docs/knowledge/is now two trees.harvested/holds what the source documents say. The roles arespec,designandstyleguide. Theknowledge-harvestskill generates this tree.Nobody edits it by hand. It holds 38 topic files, 1457 entries,
INDEX.mdand
SOURCES.md.notes/holds what the implementation found. The role isreview, with amanual
sha:marker. A person writes each note by hand. The tree holds 3files and 5 entries. A note overrides the harvested entry that it names.
A
<sub>line records the sha256 of the whole source file. It does not recordthe sha of the entry. Every entry from one document therefore carries the same
value, and an edit to an entry text changes no sha. The next harvest cannot see
the edit. The harvest then writes the original text again, or it writes a
duplicate. A correction inside
harvested/was therefore scheduled for silentdeletion. This split removes that failure.
docs/knowledge/README.mdstates the contract one time.INDEX.mdandSOURCES.mdpoint to it, because a harvest overwrites both files.Query surface (
scripts/knowledge.mjs)origin. Use--origintoselect one tree.
--prefix HTTPselects a whole requirement family. This is the audit-scalefilter.
--reqcannot express it. An unknown prefix exits 2. The CLIvalidates the prefix against appendix C.
<topic>/<8 hex>, made from the entry text.A note cites that key. The CLI resolves the citation. It prints
[overridden by notes/...]on the harvested entry. Use--keyto resolve akey on demand. The key changes when the rule text changes. That is the moment
when the note needs a new check.
--topic '', and the one-charactererror
--topic 'a,b,', matched every entry and printed the whole corpus.For
--prefix HTTP --req PAGE-11the CLI reported "PAGE-11 is canonical butno entry cites it yet". That statement is false. Three entries cite PAGE-11.
None of them cites an HTTP ID.
entries, and the CLI gave no error.
Two checks
bun run verify:knowledge-structureis blocking. It is the first step inci.yml, because it runs plain Node over Markdown and needs no build. Itrejects a
reviewrole or an invented role underharvested/. It rejects aci.yml, because it runs plain Node over Markdown and needs no build. Itrejects a
reviewrole or an invented role underharvested/. It rejects aSupersededentry there. It rejects an entry with no provenance line. Itrejects a
<sub>that cites a path outside the three source roots thatSOURCES.mdnames. It rejects a note that does not carry thereviewrole.It rejects a
.mdfile at the root ofdocs/knowledge/, because a harvestwithout
--corpus docs/knowledge/harvestedwrites there, and no query readsthat location. The check refuses to report OK below 1000 harvested entries,
so a failed parse cannot pass over an empty tree.
bun run knowledge:driftis a report. It stays out of CI. It compares eachSOURCES.mdsha against the file on disk. It also reports each note citationthat no entry carries. Three sources drift today. All three are in
docs/sdk-design-nodejs/. The 16 styleguide sources areNOT VERIFIABLEaway from the harvest machine. That state is expected. It is never a failure.
Migration
Conflictsentries are split. Each statement stays inharvested/. Each resolution becomes a note. Each note names its statementby key.
PAGE-11erratum moves tonotes/pagination.md, underSuperseded. Theinline erratum marker is removed from the harvested
Referenceentry. Thatentry now prints the override tag instead.
deliberate-deviations.mdleaves the corpus, together with itsSOURCES.mdrow. A register collects rows over time, so a harvest of a register is a
stale part of it. The copy held 13 entries against a 17-item register, at a
sha three revisions old, and two entries were false.
notes/deliberate-deviations.mdis the pointer.docs/open-items.mdis thesecond register under the same rule.
Documentation
.claude/skills/knowledge-lookup/SKILL.mdis rewritten. Phase start is twoqueries:
--origin noteand--section conflicts. The two sets aredifferent. A conflict without an override tag is still open. The skill adds
the audit query as a stated exception to the rule against a broad topic
query. It records the API-surface audit group and the audit loop. It adds the
prefix-to-chapter table that completes the roll-up path. Frozen counts are
removed.
CLAUDE.mdrecords the two trees, both checks, and the citation convention.packages/,test/,tests/and.changeset/nowpoint at
harvested/. Two citations named the deleted file. They now namethe ledger.
docs/superpowers/keeps the paths from before the split. Thosefiles are dated records of what a phase planned. Nobody edits them later.
Open items
docs/open-items.mdsection O records three gaps. O1: the globalknowledge-harvestskill still usesdocs/knowledge/as its default--corpus, and no query reads that location. O2: a report checks a note keycitation, and no gate checks it. O3: the
docs/superpowers/paths stay as theyare, on purpose. H13 rises in priority, because a blocking gate now depends on
a parser that no CI job tests.
No changeset. No published package surface changes.
Reviews done
Three Opus reviewers ran in parallel against the frozen staged snapshot. Each
reviewer received the issue, the snapshot and one lens. No reviewer saw another
reviewer's report. No reviewer could edit, stage or run a mutating command.
boundaries, failure paths and the state after each failure.
Pass 1 accepted the shape. It reported no redesign. Passes 2 and 3 therefore
stand. The three reports gave 25 distinct findings after removal of duplicates.
The session ruled on each finding and applied the fixes. The reviewers applied
nothing.
Findings applied
entries, and the gate reported OK over the hole. A hand-written entry with no
provenance line, or with an invented role, passed every rule. The key
mechanism had no way to resolve a key, so the override existed only as prose
inside one note. All three are fixed.
unresolved conflicts from view. Phase start is two queries again. The
override tag separates a resolved conflict from an open one, and the tag
survives
--brief.citations are repointed. The paths under
docs/superpowers/stay, andCLAUDE.mdstates why.docs/open-items.mdsection O is that record.one is corrected or removed.
scripts/uses. The file is nowknowledge-drift.mjs, which followsknowledge.mjsandchangeset.mjs.Findings rejected
Conflictsstatement, because thesource document now carries an erratum. The snippet still shows the ordering
that the statement describes, and the deletion breaks the entry count that
the issue states. The statement stays. The override tag now shows the
resolution from the statement.
configuration does not apply the rule to
.mjsfiles. Pass 3 reported theviolation against the styleguide rule itself. Pass 3 is correct. The function
is split.
Verification after the fixes
bun run test:scriptsbun run lintbun run buildbun run testbun run verify:knowledge-structurebun run knowledge:drift