Own knowledge-index generation in BCQuality (runtime + CI), not the consumer

The index is now produced by BCQuality itself: Entry's preparation step
rebuilds knowledge-index.json over the live, already-pruned clone at the start
of every run, and a new CI workflow validates the generator's health
(determinism, full coverage, selection-input integrity). Consumers no longer
invoke or know about the index.

Rebuilding over the pruned clone (vs shipping a committed full-corpus index)
keeps the index exact for any consumer policy: it can never list a denied
article, so policy-excluded rules cannot leak into discovery. READ now states
the index is discovery-only -- a finding must cite an article opened in full,
and rows whose file is absent are discarded before ranking.

- skills/entry.md: new 'Preparation -- knowledge index' precondition
- skills/read.md: index ownership + discovery-only invariant
- microsoft/skills/review/*.md (6): 'BCQuality builds' (not 'the filter emits')
- agent-consumption.md 5a: runtime+CI ownership rationale
- .github/workflows/knowledge-index.yml + scripts/Test-KnowledgeIndex.ps1: generator guard
- .gitignore: never commit the runtime index

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Copilot 2026-06-04 14:21:14 +02:00
parent 455ee4b58e
commit 5c4bb480c9
12 changed files with 136 additions and 10 deletions

View file

@ -140,7 +140,7 @@ Consumers that surface sample code to an end user or agent SHOULD cite the sampl
The standard workflow for finding applicable files:
1. Collect candidates from the knowledge index (`knowledge-index.json`) when the consumer provides one: it lists every filtered article with the frontmatter, `keywords`, `title`, and `description` that steps 2-3 need, so candidates are enumerated without opening each file. Absent an index, collect candidates by path (typically by `domain` subfolder, across enabled layers).
1. Collect candidates from the knowledge index (`knowledge-index.json`). BCQuality maintains it: Entry's preparation step (see [entry.md](entry.md)) regenerates it over the live, already-filtered clone, so it lists exactly the articles that survived the consumer's layer/allow-deny pruning, each with the frontmatter, `keywords`, `title`, and one-line `description` that steps 2-3 need — candidates are enumerated without opening each file. The index is **discovery metadata only**: it tells you *which* files to open, it does not substitute for them. A finding MUST cite only an article that was opened and read in full; an index row whose file is absent from the clone MUST be discarded *before* ranking or worklisting, and its metadata MUST NOT seed a finding. Absent an index, collect candidates by path (typically by `domain` subfolder, across enabled layers).
2. Filter by frontmatter using the matching rules above. Files that are not applicable are discarded.
3. Rank or narrow by `keywords` relevance to the task.
4. Resolve conflicts via layer precedence.