unknown-knowledge 2.1.0 → 3.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,25 +1,78 @@
1
1
  # AGENTS.md — navigation contract + runtime loop (PRD §7)
2
2
 
3
- > Paths in this document are client-relative relative to the vendored kit
4
- > root after init (`ontology/…`, `engine/…`, `protocol/…`). In the kit repo
5
- > itself these live under `payload/`. Commands are written to run from the
6
- > **repo root** with the kit dir at its default name `unknown-knowledge/`;
7
- > substitute your chosen kit dir name if it differs.
3
+ > Commands below run from the **repository root**. Store and protocol paths
4
+ > in prose are relative to the store/kit root in the layout table below;
5
+ > source-of-truth pointers and survey-scope paths are repository-relative.
8
6
 
9
7
  You are a coding agent in a repo seeded with the unknown-knowledge kit: three
10
8
  YAML stores that map the system, a deterministic engine that checks the map,
11
9
  and this protocol. This file is the platform-agnostic contract — per-platform
12
10
  wrapper files are thin pointers here. Follow it on every request.
13
11
 
14
- Two `--root` conventions, stated once:
12
+ **First action: read this contract before recursive product-source filename
13
+ or content discovery.** Locating and reading top-level agent instructions and
14
+ necessary top-level configuration is permitted. Before reading product source,
15
+ read the relevant KB catalogs and the entries they name, following the store
16
+ navigation contract below. A resolver hit does not replace these reads.
17
+ Targeted reads of source paths supplied by the KB are expected GATHER behavior;
18
+ source search after a coverage miss follows this contract's fallback rules.
19
+ These are agent instructions, not a host tool firewall.
20
+
21
+ ## Layout and command roots
22
+
23
+ Read the entry instructions and necessary top-level configuration to identify
24
+ the layout before invoking the engine. These are the supported conventions:
25
+
26
+ | Location | Seeded client (default name) | Kit's own repository |
27
+ |---|---|---|
28
+ | Store/kit root | `unknown-knowledge/` | `.` |
29
+ | Ontology and knowledge | `unknown-knowledge/ontology/`, `unknown-knowledge/knowledge/` | absent by design; `payload/templates/` contains seed templates, not live stores |
30
+ | Decisions catalog | `unknown-knowledge/decisions/_catalog.yaml` | `decisions/_catalog.yaml` |
31
+ | Canonical protocol | `unknown-knowledge/protocol/AGENTS.md` | `payload/protocol/AGENTS.md` |
32
+ | Engine commands | `unknown-knowledge/engine/<command>.js` | `payload/engine/<command>.js` |
33
+ | Confirmed survey scope | `survey-scope.yaml` at repository root | `survey-scope.yaml` at repository root, if confirmed |
34
+ | Finding logs | `unknown-knowledge/logs/` | `logs/` |
35
+
36
+ Two `--root` conventions:
15
37
 
16
38
  - Every store-reading CLI (`resolve.js`, `preflight.js`, `validate.js`,
17
- `validate-values.js`, `audit.js`, `survey-map.js`) takes `--root` as the
18
- **repo root** (default: cwd). The stores are auto-located at
19
- `<root>/unknown-knowledge/`; source-of-truth pointers resolve against the
20
- repo root (§9.1).
39
+ `validate-values.js`, `commit-check.js`, `audit.js`, `survey-map.js`) takes `--root` as the
40
+ **repo root** (default: cwd). Store readers auto-locate
41
+ `<root>/unknown-knowledge/` when present, otherwise stores at `<root>/`.
42
+ When both layouts exist, read repository-root `.unknown-knowledge.json`: its
43
+ sole `kitRoot` field explicitly selects `"unknown-knowledge"` or `"."`.
44
+ Without that selection the ambiguous layout refuses. Keep `--root` at the
45
+ repository root; stage configuration with migrations for commit checks.
46
+ `survey-map.js` reads `<root>/survey-scope.yaml`; source-of-truth pointers
47
+ also resolve against the repo root (§9.1).
21
48
  - `log-entry.js` takes `--root` as the **kit dir** (the directory containing
22
- `logs/`), e.g. `--root unknown-knowledge`.
49
+ `logs/`), e.g. `--root unknown-knowledge` in a seeded client, `--root .`
50
+ in the kit's own repository.
51
+
52
+ For the kit's own decision-store use case, stay at the repository root:
53
+
54
+ ```
55
+ node payload/engine/resolve.js "engine language" --json --root .
56
+ node payload/engine/preflight.js --json --root .
57
+ ```
58
+
59
+ Then enter `decisions/_catalog.yaml` and read the named entries using the
60
+ shared lifecycle rules below. The resolver searches concepts/leaves, not
61
+ decision text; zero hits cannot establish that a decision is absent. Missing
62
+ ontology/knowledge warnings are expected in this decision-only layout.
63
+
64
+ If working from another directory, supply an absolute repo root to store
65
+ commands and an absolute store/kit root to logging. Do not use `--root payload`
66
+ or `--root unknown-knowledge` to make source pointers work by accident.
67
+ An initializer `--root <name>` selects the seed destination; it is **not**
68
+ a store-reader configuration flag. Renamed client directories are not
69
+ auto-discovered by the current engine. Honor explicit configuration only
70
+ where the invoked command supports it; if entry instructions name an
71
+ unsupported root, or the expected catalog cannot be read, report the layout
72
+ problem and stop that navigation path. Do not interpret missing-store
73
+ warnings in an unexpected layout as empty knowledge, guess alternative roots,
74
+ or repair custom-root discovery during the task. Ambiguous layouts that the
75
+ engine refuses are failures, not query misses.
23
76
 
24
77
  ## The SSOT contract — the map is never the fact
25
78
 
@@ -41,11 +94,23 @@ never truth. The rules that follow from this:
41
94
 
42
95
  ## Store navigation contract
43
96
 
44
- Three stores, one navigational grammar: **`_catalog.yaml` `_rules.yaml`
45
- entries** (`classes/*.yaml`, tree leaves, `entries/*.yaml`). Enter through
46
- the catalog, honor the rules file, then read the entry the catalog names —
47
- never grep the store tree cold, and never raw-traverse the repo (triage
48
- `engine/survey-map.js` output instead).
97
+ Enter through the relevant catalog before recursive product-source filename
98
+ or content discovery. Honor the actual rules for that store, then read the
99
+ entry the catalog names. Targeted source reads from those pointers are GATHER;
100
+ they do not require rediscovering the repository. Never grep the store tree
101
+ cold or raw-traverse the repo; unresolved tasks use the survey map below.
102
+
103
+ | Store | Navigation order |
104
+ |---|---|
105
+ | Ontology | `ontology/_catalog.yaml` → `ontology/_rules.yaml` → catalog-named class/concept files |
106
+ | Knowledge | `knowledge/_catalog.yaml` → `knowledge/_rules.yaml` → catalog-named leaves |
107
+ | Decisions | `decisions/_catalog.yaml` → this document's **Gate rules** and **Decisions-authoring path** (shared lifecycle rules) → catalog-named entries |
108
+
109
+ There is no required `decisions/_rules.yaml`. Do not search for or invent one.
110
+ For a decision question, read the relevant entries' `status`, `supersedes`,
111
+ and `superseded-by` fields and follow those IDs through the catalog until the
112
+ current decision is reached. An older title or preserved reasoning is history,
113
+ not current policy; report broken or cyclic chains instead of guessing.
49
114
 
50
115
  | Store | Truth anchor | Points | Write gate |
51
116
  |---|---|---|---|
@@ -90,34 +155,188 @@ Query terms are positional (joined into one query); results come scored with
90
155
  entry points. Exit 0 = the lookup ran (hits or none); exit 2 = it never ran —
91
156
  stop, that is an engine failure, not an empty result.
92
157
 
93
- **Zero resolution is a normal outcome** (common in month one — bootstrap is
94
- deliberately non-exhaustive). Proceed **without store claims**: fall back to
95
- search within the paths `survey-scope.yaml` includes, and append a
96
- `retrieval-miss` finding (RECORD, below) only when the topic plausibly should
97
- be mapped an unmapped area the scope excludes is expected, not a miss.
98
-
99
- ### 2. PREFLIGHT deterministic verdicts on what you resolved
158
+ Leaf results expose `superseded-by`: direct incoming claims derived from other
159
+ leaves' `relates.supersedes`. Follow the listed accession and file when looking
160
+ for current evidence, and repeat hop by hop with a visited-ID set. Several
161
+ successors are several claims; do not choose by date, score, or list order.
162
+ Read target metadata to compare `applies` jurisdictions with the request
163
+ (empty means universal) and inspect stage and freshness before selecting
164
+ evidence. Metadata-only navigation does not add a target to the evidence set.
165
+ Before relying on a selected successor's claims or gathering its cited source,
166
+ run `preflight.js --leaves <IDs> --today <YYYY-MM-DD>` with the current
167
+ evaluation date, following PREFLIGHT below. Check every selected successor;
168
+ do not require a verdict for a candidate rejected during metadata navigation.
169
+ Resolver metadata is navigation, never target preflight or proof that a
170
+ successor applies. Historical requests can still use the predecessor's source;
171
+ an unresolved conflict, cycle, or inapplicable successor is not a current answer.
172
+
173
+ **Zero resolution is a normal outcome**, not proof of missing evidence.
174
+ Use this recovery path before source search:
175
+
176
+ 1. **PREFLIGHT store health even with zero hits**: run `preflight.js --json
177
+ --root .` without concept/leaf selectors. Follow its outcome; an exit 2
178
+ stops the task. A lookup over a broken or unsupported store is not a miss.
179
+ 2. Inspect relevant catalogs using the store navigation contract. Use the
180
+ terms, titles, aliases and named entries there to recover the subject.
181
+ Retry resolution when a catalog supplies a new relevant term; preflight
182
+ recovered concepts/leaves before gathering their evidence. Decisions are
183
+ recovered directly through their catalog and lifecycle links.
184
+ 3. Stop reformulating when the task is resolved or the relevant catalog
185
+ entries supply no new lead. Do not repeat equivalent queries or generate
186
+ an unbounded synonym loop; the stopping condition is exhausted catalog
187
+ evidence, not an arbitrary retry count.
188
+ 4. Only the unresolved portion proceeds to **Scoped fallback** below. If
189
+ catalog recovery found the answer, gather the named evidence and record
190
+ `retrieval-struggle` for the wording friction, not `retrieval-miss`.
191
+
192
+ ### Scoped fallback — unresolved evidence only
193
+
194
+ Read **`<repo-root>/survey-scope.yaml`**, not a file under the seeded kit
195
+ directory. Its include/exclude values are repository-relative path prefixes;
196
+ exclusions win. `.` includes root-level files only, not every subtree.
197
+ If no confirmed scope exists, use the bootstrap scope gate before source
198
+ search; a proposed map is not an agreed boundary. Do not widen scope yourself.
199
+ An unreadable or malformed scope must be reported, never replaced with a
200
+ guessed path or interpreted as an empty knowledge base.
100
201
 
101
202
  ```
102
- node unknown-knowledge/engine/preflight.js --concepts K-101,K-102 --json --root .
203
+ node unknown-knowledge/engine/survey-map.js --json --root .
103
204
  ```
104
205
 
105
- One verdict per concept `trusted` / `quarantined` / `unknown` computed by
106
- engine code, never by your judgment. Store-wide failures degrade every
107
- requested verdict to `unknown`. Exit codes: 0 all trusted, 1 quarantines
108
- present, 2 engine failure / check-never-ran. What you DO with a verdict is
109
- the conduct policy below. Add `--log --today <YYYY-MM-DD>` so quarantine
110
- findings auto-append (one fragment per quarantined concept).
206
+ In the kit repo, use `node payload/engine/survey-map.js --json --root .`.
207
+ Confirm the map reports `scope.source: survey-scope.yaml`. Search only
208
+ relevant candidate paths or directories named by this map, within its
209
+ confirmed includes and excluding every configured exclusion. A directory
210
+ histogram is not permission to recurse into excluded children: bound any
211
+ filename/content search accordingly. Non-candidate files in those directories
212
+ may hold evidence; lack of an extractor-shaped candidate is not absence.
213
+ The map covers tracked files minus its built-in denylist. Honor those limits
214
+ and disclose `unsurveyed` paths rather than searching around them.
215
+
216
+ Report the boundary reached and classify the outcome:
217
+
218
+ | Outcome | RECORD behavior |
219
+ |---|---|
220
+ | Existing indexed evidence recovered through different catalog wording | `retrieval-struggle`, naming the recovered IDs and paths |
221
+ | Required in-scope fact or pointer still missing after catalog recovery and bounded search | `retrieval-miss`, naming the searched paths and any consulted IDs; do not claim absence beyond the surveyed scope |
222
+ | Topic outside the agreed scope | Expected absence; explain the boundary, without automatically logging an index defect or searching excluded material |
223
+ | Unsupported layout, unreadable store/scope, or an engine check that never ran | Report the concrete failure; do not recast it as a retrieval miss |
224
+
225
+ General knowledge can explain a concept if clearly attributed. It cannot
226
+ establish undocumented company policy or other company-specific facts. Findings
227
+ use `log-entry.js` and the capture content policy below; do not copy the user's
228
+ question or source contents into a finding.
229
+
230
+ For recovery findings, `consulted` accepts `concepts` (`K-NNN`) and `leaves`
231
+ (`L-NNNNNN`) only. Decision paths belong in `summary`; there is no
232
+ `consulted.decisions` field. Ordinary decision-catalog navigation is expected,
233
+ not itself wording friction: log a struggle only when retrieval was indirect.
234
+
235
+ Preserve each command's own exit code and stderr in walkthrough evidence.
236
+ Resolver exit 0 includes zero hits. Survey-map exit 1 discloses blind spots;
237
+ exit 2 means the engine check failed. A search tool's no-match status or a
238
+ failed file read is that tool's outcome, not an engine failure. Do not combine
239
+ commands so the last command's status hides earlier outcomes.
240
+
241
+ ### 2. PREFLIGHT — check every concept and leaf you rely on
242
+
243
+ Maintain the **evidence set**: the concept IDs and leaf accessions whose
244
+ claims will support your answer or action. Select every one explicitly in
245
+ preflight, whether found by the resolver or through the catalogs. Merely
246
+ visible related candidates need not be checked unless you rely on them.
247
+
248
+ Mixed concept-and-leaf request (replace these IDs with your evidence set):
249
+
250
+ ```sh
251
+ node unknown-knowledge/engine/preflight.js --concepts K-101,K-102 --leaves L-000100,L-000200 --today <YYYY-MM-DD> --log --json --root .
252
+ ```
111
253
 
112
- With an empty/omitted `--concepts`, preflight validates store health only and
113
- exits on the store verdict — the zero-resolution branch still preflights.
254
+ Leaf-only request no ontology hit is needed to check knowledge:
255
+
256
+ ```sh
257
+ node unknown-knowledge/engine/preflight.js --leaves L-000100 --today <YYYY-MM-DD> --log --json --root .
258
+ ```
259
+
260
+ Replace `<YYYY-MM-DD>` with the **current evaluation date** on every run,
261
+ including concept-only and store-health runs. The engine never reads the
262
+ clock; omitting the date skips freshness checks. `--log` appends quarantine
263
+ findings for selected quarantined concepts. Use `--concepts` only for concept
264
+ IDs and `--leaves` for accessions; there is **no decision-preflight flag**.
265
+ Read decision lifecycle and supersession records when selecting rationale,
266
+ and check any supporting concepts or leaves you rely on through these flags.
267
+
268
+ **GATHER can expand the evidence set.** Read entry metadata to navigate, but
269
+ before relying on a newly reached `class-elsewhere` target, `depends-on`
270
+ prerequisite, replacement/successor, or other supporting entry, return to
271
+ PREFLIGHT with its ID. Incremental batches are fine: each relied-upon concept
272
+ and leaf must have a verdict from this run before its claims support the
273
+ answer or action. Following a redirect does not transfer its verdict to the
274
+ target. Before answering or acting, reconcile the evidence set with the
275
+ returned `verdicts` and `leaf-verdicts`; resolver metadata is not a substitute.
276
+
277
+ Keep these four checks separate:
278
+
279
+ - **Store health** says whether the stores loaded. Only when BOTH selectors
280
+ are empty/omitted does preflight run in store-health-only mode, with no
281
+ selected verdicts. The zero-resolution branch still checks health, but a
282
+ health pass never checks a leaf's claims.
283
+ - **Review eligibility** comes from the declared lifecycle/stage. Draft or
284
+ proposed records and leaves missing `facets.stage` are `unknown`. Legacy
285
+ leaves without stage remain loadable for inspection and remediation; an
286
+ absent stage never establishes promotion. A declared `verified` stage is metadata,
287
+ not authenticated proof that a human approved the evidence.
288
+ - **Freshness** uses the leaf's `verified` date and `volatility` against
289
+ `--today`. Stale is distinct from quarantined and unknown. No declared
290
+ volatility means time-governance **exemption**, not proof of freshness;
291
+ static knowledge never ages out, which also does not verify its source.
292
+ - **Original-source verification** still requires GATHER's source reads.
293
+ Even `trusted` reports the attributable engine checks, not an independent
294
+ reading of citations. The engine remains offline; the host follows sources.
295
+
296
+ Exit 0 means every selected record is trusted. Exit 1 means completed checks
297
+ found quarantined or stale records: apply the permitted conduct below and
298
+ keep stale claims visibly unverified; browsing never authorizes promotion or
299
+ timestamp refresh. **Exit 2 stops the governed task**, including draft/proposed,
300
+ missing-stage, skipped-check `unknown` results and malformed-store failures.
301
+ Report the blocking result; do not continue GATHER/ACT. Store-wide
302
+ failures degrade every requested verdict to `unknown`. Never cache verdicts.
114
303
 
115
304
  ### 3. GATHER — read the fact, not the map
116
305
 
117
- Follow each resolved concept's `source-of-truth` pointer and **read the
118
- file**. One targeted read per fact. Knowledge leaves: read the leaf body and
119
- follow `class-elsewhere` redirects. Never substitute a summary, an
120
- `enumerates` list, or a leaf heading for the artifact.
306
+ Follow each selected concept's `source-of-truth` pointer and **read the
307
+ file**. Knowledge leaves: read the body and follow the citations, including
308
+ external URLs, using the host agent's source-reading tools. The engine stays
309
+ offline and never executes client code. Catalog titles, summaries,
310
+ `enumerates` lists and leaf headings locate evidence; none replaces reading
311
+ the original artifact or cited source.
312
+
313
+ Follow redirects, dependencies and successors through the records and return
314
+ to PREFLIGHT for newly selected concepts/leaves before gathering their sources
315
+ or relying on their claims. Read decision entries themselves for team rationale,
316
+ including lifecycle and supersession; a preserved historical decision is not
317
+ current policy. Use the existing navigation rules to select applicable evidence.
318
+
319
+ If a citation cannot be retrieved, disclose that access failure and which claim
320
+ remains unverified. An unavailable source is not proof that a fact is absent.
321
+ For an unresolved organizational fact, follow scoped fallback and RECORD's
322
+ finding rules; the stores are not an exhaustive account of world knowledge.
323
+ Successful browsing does not promote a leaf or refresh its `verified` date.
324
+
325
+ **Attribute the answer or action to what you actually read.** Cite the relevant
326
+ concept/leaf IDs and source paths or URLs; cite decision IDs for team rationale.
327
+ Use concise natural prose, without mandatory headings, to distinguish:
328
+
329
+ - Organizational facts supported by the applicable records and artifacts.
330
+ - External source facts, within the source's scope; vendor advice alone does
331
+ not establish this organization's implementation, policy or contract.
332
+ - General knowledge used to explain a gap, and inference from evidence where
333
+ it could otherwise sound like a recorded organizational fact.
334
+ - Unresolved gaps, inaccessible evidence, and stale/quarantined records that
335
+ remain unverified under the client's permitted exit-1 conduct.
336
+
337
+ Never fill an undocumented organizational fact with general knowledge or
338
+ inference. Reconcile the relied-upon evidence set before answering or acting;
339
+ this guidance does not permit GATHER or ACT after any exit-2 result.
121
340
 
122
341
  ### 4. ACT — execute, then attribute before committing
123
342
 
@@ -143,9 +362,13 @@ never a gate.
143
362
 
144
363
  Where the client has wired the seeded hooks (`hooks/pre-commit`,
145
364
  `hooks/reverse-lookup`), both of these run automatically: the pre-commit hook
146
- runs the blocking validation before the commit exists, and the reverse-lookup
147
- hook runs the `--paths` lookup over the staged diff. Each is a thin wrapper
148
- around the command above and exits with its code, unchanged so a wired repo
365
+ runs both whole-store validators through `engine/commit-check.js` before the
366
+ commit exists, and the reverse-lookup hook runs the `--paths` lookup over the
367
+ staged diff. Attribution never limits the gate to a concept subset (D-012).
368
+ Both validators read the same isolated Git index snapshot; unstaged and
369
+ untracked evidence cannot change the result. Snapshot preparation or cleanup
370
+ failure is exit 2: stop. Each hook is a thin wrapper around its engine command
371
+ and exits with its code, unchanged — so a wired repo
149
372
  enforces this step mechanically rather than depending on you to remember it.
150
373
  Run the commands yourself anyway: seeing the findings before the commit is
151
374
  cheaper than being refused by it, and a hook the client never wired enforces
@@ -158,19 +381,44 @@ See capture obligations below. Findings, misses, and gaps are appended via
158
381
 
159
382
  ## Conduct-on-verdict policy (D-011)
160
383
 
161
- > **CLIENT-EDITABLE.** Verdicts are deterministic engine facts; what a
162
- > session does about one is policy in this markdown, which you (the client)
163
- > own. The table below is the recommended default quarantine-and-continue.
164
- > A stricter shop may edit `quarantined` to fail-stop. What is NOT editable:
165
- > the engine's verdicts, exit codes, and evidence — and a policy edit must
166
- > never tell an agent to bypass a gate or trust quarantined claims.
167
-
168
- | Verdict / outcome | Conduct (recommended default) |
169
- |---|---|
170
- | `trusted` | Proceed. The verdict is fresh this run; never cache it. |
171
- | `quarantined` | **Quarantine-and-continue**: continue the task, but do NOT trust the concept's claims — gather from the source artifact directly (falling back to survey-scoped search if the pointer itself is the problem), and make sure the quarantine finding was appended (run preflight with `--log --today <date>`; it does this for you). |
172
- | `unknown` | Treat as unverified draft/proposed concepts and store-wide degradations land here. Work from the source artifact; do not present store claims as checked. |
173
- | exit 2 — engine failure / check-never-ran | **STOP.** A check that never ran is a blocking defect, never a silent pass. Report the engine error; do not proceed as if preflight passed. |
384
+ > **CLIENT-EDITABLE.** Verdicts are deterministic engine facts; conduct
385
+ > belongs to this markdown. The engine's `next-action` field is a stable code
386
+ > in JSON and in human output (`next: <code>`). Look up that code below.
387
+ > Clients may edit the conduct wording (for example, make `repair-evidence`
388
+ > fail-stop). Never change the engine's verdicts, exit codes, or evidence to
389
+ > enforce a policy, and never tell an agent to bypass a gate or trust
390
+ > quarantined claims.
391
+
392
+ **Apply the command exit first. Exit 2 means STOP**, including an `unknown`
393
+ verdict for a draft/proposed record, a missing review stage, a skipped check, a store failure, or an
394
+ incomplete command. Report the blocking result. Do not continue GATHER/ACT,
395
+ even if another row says `proceed`; an action code is not permission to cross
396
+ this gate. A command that failed before returning verdicts may have no code.
397
+ Do not infer that checks never ran from every exit 2: an output or logging
398
+ failure can occur after computation. Report what the diagnostics establish.
399
+ The repair/review actions below describe the next recovery step after the stop,
400
+ not permission to repair or promote records automatically.
401
+
402
+ | `next-action` code | Verdict / condition | Conduct (recommended default) |
403
+ |---|---|---|
404
+ | `proceed` | `trusted` | Proceed to GATHER if the command permits it. Follow the original evidence; trust is limited to this run's attributable checks. Never cache verdicts. |
405
+ | `repair-evidence` | `quarantined` concept or leaf | **Quarantine-and-continue** on exit 1: do not trust the record's claims. Gather from the source artifact or cited sources directly; use confirmed survey scope if an artifact pointer is broken. Keep the record untrusted until error-severity evidence is repaired through the human gate and preflight reruns. Ensure required quarantine findings are recorded: `--log --today <date>` automatically logs selected quarantined concepts only; leaf findings use `log-entry.js` with `consulted.leaves`. |
406
+ | `review-status` | `unknown`, pre-promotion concept | Stop on exit 2; report unverified status and skipped value checks. Request human review of the concept before promotion, then rerun preflight. Direct source verification is not a way to continue this stopped task. |
407
+ | `review-stage` | `unknown`, pre-promotion or missing-stage leaf | Stop on exit 2; report the leaf as unverified and distinguish a declared draft/proposed stage from missing `facets.stage` using `stage` and `reason`. Request moderator review before establishing a promotion state, then rerun preflight. Keep legacy records available for inspection; never fill in `verified` stage automatically. Do not gather citations to continue this stopped task. |
408
+ | `repair-store` | `unknown`, store-wide failure | Stop; report loader diagnostics. The store must be repaired before preflight can run its checks. Rerun after authorized repair. |
409
+ | `reverify-leaf` | `stale` | On exit 1, continue with the claim visibly unverified; follow the cited evidence directly. Ask the steward to reverify the leaf through the human gate. Browsing alone never authorizes promotion or updating `verified`. |
410
+ | `supply-verified-date` | `unknown`, time-governed leaf has no usable verification date | Stop on exit 2; request human verification and a valid `verified` date, then rerun preflight. Never invent a timestamp. Current structural `missing-verified` / `malformed-verified` findings take precedence and normally produce `repair-evidence`; this code retains the undated fallback. |
411
+ | `supply-evaluation-date` | `unknown`, freshness check skipped | Stop on exit 2; rerun preflight with the current evaluation date via `--today <YYYY-MM-DD>` before gathering or relying on the leaf. |
412
+
413
+ These rows apply only to selected evidence. Metadata-only candidate navigation
414
+ before the gate remains permitted as described in RESOLVE; it does not establish
415
+ checked claims or permit continued navigation after exit 2. On exit 1, only
416
+ the conduct explicitly permitted by the client's table may continue. A
417
+ missing/malformed verification date is identifiable in `evidence` even when
418
+ structural findings take precedence over an undated time result. Source
419
+ collection leaves stale and quarantined records unverified; static or absent
420
+ volatility exempts age checks, never review or source verification.
421
+ An unfamiliar code is not an all-clear: report the contract mismatch and stop.
174
422
 
175
423
  ## Gate rules
176
424
 
@@ -222,6 +470,27 @@ secrets**. The `session` field is an opaque ID. Committed fragments are
222
470
  permanent git history in this repo and are reviewable content like any other
223
471
  PR change.
224
472
 
473
+ **Missing evidence is different from missing wording.** After scoped source
474
+ and catalog navigation, an undocumented organizational fact stays
475
+ **unestablished**. General knowledge can explain what telemetry providers or
476
+ safeguards usually do; it cannot establish which ones this organization uses.
477
+ An in-scope evidence gap is a `retrieval-miss`; a fact recovered through
478
+ another term or catalog is a `retrieval-struggle`. Expected absence outside
479
+ `survey-scope.yaml` is neither a demand to search excluded paths nor warrant
480
+ for taxonomy expansion.
481
+
482
+ For an in-scope miss, the helper may record permitted `residue` and
483
+ `resolved-context` from the resolver alongside `consulted` IDs and paths.
484
+ Review tokens before persisting them: these fields are not an exception to
485
+ the content policy, and a query can contain secrets or identifying text.
486
+ Omit unsafe tokens; never paste the question into a summary. Findings record
487
+ navigation evidence, not the missing company fact. Reflect judges independent
488
+ corroboration; a later cited addition goes through `protocol/skills/kb-build.md`.
489
+
490
+ For later answers about a recorded gap, follow PREFLIGHT for each consulted
491
+ leaf itself (a concept verdict does not cover its leaves), then GATHER its
492
+ cited evidence. Preserve the source's limits and attribute accession and source.
493
+
225
494
  ## Decisions-authoring path (§3.5)
226
495
 
227
496
  When your work surfaces a decision — a trade-off taken, a graduation of
@@ -19,6 +19,28 @@ promotable.** A claim with no traceable source never becomes a leaf; it
19
19
  parks as a gap-log entry (step 2) so the demand signal survives without the
20
20
  store vouching for it.
21
21
 
22
+ ## Closing an organizational evidence gap
23
+
24
+ A reflect handoff must say whether the source exists but was hard to reach,
25
+ or the organizational fact is still unestablished after scoped navigation.
26
+ Only the former can be repaired by a search term or pointer alone. For the
27
+ latter, name the consulted IDs/paths, permitted residue/context and the
28
+ missing evidence in the steward-facing recommendation; do not invent a
29
+ provider, safeguard or policy from general knowledge. Expected out-of-scope
30
+ absence warrants no taxonomy expansion.
31
+
32
+ `knowledge-reflect.md` owns independent corroboration, literary warrant and
33
+ rejection/reopening rules. A lone miss stays under-corroborated; copying it
34
+ into three fragments does not justify a handoff. Reflect recommends knowledge
35
+ work but never writes leaves. A human bringing a source directly may invoke
36
+ this skill without manufacturing a reflect cluster: the five steps below
37
+ still apply, including citation review and the separate promotion gate.
38
+
39
+ Approval to investigate or draft is not approval to promote. A rejected or
40
+ unapproved proposal stays unpublished; if retained as a draft it remains
41
+ `draft` (preflight `unknown`). Do not mark its findings resolved or mint
42
+ vocabulary to make an unknown organizational fact appear covered.
43
+
22
44
  ## This skill is thin orchestration
23
45
 
24
46
  Every mechanical step below **names the engine command that performs it**.
@@ -123,7 +145,7 @@ state:
123
145
  ```
124
146
  node unknown-knowledge/engine/log-entry.js create --log gaps --date 2026-07-09 \
125
147
  --root unknown-knowledge \
126
- --entry '{"summary":"kb-build item not promotable: export-precision claim lacks any citation; nearest leaf L-000100","consulted":{"leaves":["L-000100"]}}'
148
+ --entry '{"summary":"L-000100 knowledge/_catalog.yaml","consulted":{"leaves":["L-000100"]}}'
127
149
  ```
128
150
 
129
151
  `--date` is injected, never wall-clock; the summary carries leaf ids,
@@ -196,6 +218,13 @@ this skill makes on top of the schema:
196
218
  verdicted `unknown` by preflight, which is correct and not a defect:
197
219
  nothing has certified it yet. Promotion is a moderator's act after the
198
220
  citations are checked, never the author's.
221
+ Leaf preflight reports this expected pre-promotion `unknown` with exit 2,
222
+ which still stops governed retrieval and claim reliance. In this authoring
223
+ workflow, an explicit human instruction to draft permits committing the
224
+ unpromoted draft for review after both `validate.js` and `validate-values.js`
225
+ exit 0 and the normal commit gates pass. Submission does not certify its
226
+ claims or authorize promotion. Loader errors and failed checks still require
227
+ repair.
199
228
  - **`notes`** — every leaf carries a `scope` note (what it covers and
200
229
  pointedly does not) and every write appends a `revision` note with
201
230
  `date` (initial entry, or what changed); add `class-here` when step 1
@@ -277,8 +306,9 @@ frontmatter came from step 2 or step 3.
277
306
  node unknown-knowledge/engine/validate.js --root .
278
307
  ```
279
308
 
280
- This is the same command the `hooks/pre-commit` hook runs, so a commit that
281
- would fail here is refused before it exists running it now is how you see
309
+ The `hooks/pre-commit` hook runs this check and whole-store value validation
310
+ through `engine/commit-check.js`, so a commit that would fail here is refused
311
+ before it exists — running it now is how you see
282
312
  the findings first, not a substitute for the hook.
283
313
 
284
314
  - **Exit 0** — done drafting. Hand the change to the human gate: the leaf,
@@ -301,3 +331,28 @@ node unknown-knowledge/engine/resolve.js --paths knowledge/L-00/L-000110-svg-ass
301
331
 
302
332
  The skill declares done only on an exit-0 run that saw the final draft —
303
333
  a verdict is per-run, never carried (D-011).
334
+
335
+ **Closing the gap happens after drafting.** Structural validation checks
336
+ shape and resolving references; it does not read citations or prove human
337
+ approval. Hand the reviewer the actual sources read, claim-to-source mapping,
338
+ scope and revision notes, provenance, catalog row and applicable typed
339
+ `concepts`/`paths`/`relates` edges. Never add unrelated edges just to fill a
340
+ field. A citation's authority tier does not itself certify company policy.
341
+
342
+ After the human approves the cited content and promotion, apply that reviewed
343
+ change through this write path, including any required time metadata. Run
344
+ `validate.js` and `validate-values.js`, then regenerate discovery and check
345
+ it with the same injected date:
346
+
347
+ ```sh
348
+ node unknown-knowledge/engine/derive.js --write --today 2026-09-10 --root .
349
+ node unknown-knowledge/engine/derive.js --check --today 2026-09-10 --root .
350
+ ```
351
+
352
+ Use the actual review date in place of the example. Keep the approved change
353
+ and its validation in the normal PR gate; only then resolve the associated
354
+ findings through `log-entry.js`. Verify the original question in a fresh
355
+ session: resolve, run `preflight.js --leaves <accession> --today <date>` on
356
+ each consulted leaf, read its body and cited evidence, then answer with the
357
+ accession and source attribution. A catalog hit, derived excerpt or concept
358
+ preflight alone does not establish that the new knowledge is usable.