unknown-knowledge 2.1.0

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.
Files changed (147) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +167 -0
  4. package/cli/.gitkeep +0 -0
  5. package/cli/commands/init-copy.js +90 -0
  6. package/cli/commands/init.js +386 -0
  7. package/cli/init-copy.js +24 -0
  8. package/cli/init.js +24 -0
  9. package/cli/kit.manifest.yaml +256 -0
  10. package/cli/lib/copy-payload.js +334 -0
  11. package/cli/lib/generate-wrappers.js +162 -0
  12. package/package.json +36 -0
  13. package/payload/adapter-fixtures/README.md +53 -0
  14. package/payload/adapter-fixtures/html/EXPECTED.yaml +50 -0
  15. package/payload/adapter-fixtures/html/sample.html +38 -0
  16. package/payload/adapter-fixtures/md/EXPECTED.yaml +65 -0
  17. package/payload/adapter-fixtures/md/sample.md +32 -0
  18. package/payload/adapter-fixtures/pdf/EXPECTED.yaml +45 -0
  19. package/payload/adapter-fixtures/pdf/sample.pdf +0 -0
  20. package/payload/adapter-fixtures/txt/EXPECTED.yaml +31 -0
  21. package/payload/adapter-fixtures/txt/sample.txt +18 -0
  22. package/payload/docs/README.md +102 -0
  23. package/payload/docs/boundaries.md +60 -0
  24. package/payload/docs/ci-wiring.md +109 -0
  25. package/payload/docs/steward-guide.md +238 -0
  26. package/payload/engine/audit.js +34 -0
  27. package/payload/engine/commands/audit.js +289 -0
  28. package/payload/engine/commands/derive.js +334 -0
  29. package/payload/engine/commands/ingest.js +124 -0
  30. package/payload/engine/commands/log-entry.js +85 -0
  31. package/payload/engine/commands/phoenix.js +206 -0
  32. package/payload/engine/commands/preflight.js +530 -0
  33. package/payload/engine/commands/resolve.js +1678 -0
  34. package/payload/engine/commands/survey-map.js +351 -0
  35. package/payload/engine/commands/validate-values.js +315 -0
  36. package/payload/engine/commands/validate.js +1426 -0
  37. package/payload/engine/derive.js +34 -0
  38. package/payload/engine/ingest.js +34 -0
  39. package/payload/engine/lib/anchor-signatures.js +126 -0
  40. package/payload/engine/lib/boot.js +39 -0
  41. package/payload/engine/lib/call-numbers.js +133 -0
  42. package/payload/engine/lib/cli.js +147 -0
  43. package/payload/engine/lib/coverage.js +849 -0
  44. package/payload/engine/lib/decomposition.js +225 -0
  45. package/payload/engine/lib/derived.js +494 -0
  46. package/payload/engine/lib/engine-refusal.js +40 -0
  47. package/payload/engine/lib/exit-codes.js +14 -0
  48. package/payload/engine/lib/extractor-kinds.js +955 -0
  49. package/payload/engine/lib/format-adapters.js +802 -0
  50. package/payload/engine/lib/id-grammars.js +178 -0
  51. package/payload/engine/lib/iso-date.js +55 -0
  52. package/payload/engine/lib/kit-root.js +101 -0
  53. package/payload/engine/lib/load-stores.js +1624 -0
  54. package/payload/engine/lib/log-entry.js +196 -0
  55. package/payload/engine/lib/phoenix.js +628 -0
  56. package/payload/engine/lib/scoring.js +150 -0
  57. package/payload/engine/lib/suppressions.js +172 -0
  58. package/payload/engine/lib/time-verdicts.js +282 -0
  59. package/payload/engine/lib/usage-error.js +14 -0
  60. package/payload/engine/lib/validate-record.js +504 -0
  61. package/payload/engine/log-entry.js +34 -0
  62. package/payload/engine/phoenix.js +39 -0
  63. package/payload/engine/preflight.js +34 -0
  64. package/payload/engine/resolve.js +34 -0
  65. package/payload/engine/survey-map.js +34 -0
  66. package/payload/engine/validate-values.js +34 -0
  67. package/payload/engine/validate.js +34 -0
  68. package/payload/extractor-fixtures/.gitkeep +0 -0
  69. package/payload/extractor-fixtures/README.md +29 -0
  70. package/payload/extractor-fixtures/swift/strings-keys/EXPECTED.yaml +8 -0
  71. package/payload/extractor-fixtures/swift/strings-keys/sample.strings +15 -0
  72. package/payload/extractor-fixtures/swift/swift-const-array/EXPECTED.yaml +7 -0
  73. package/payload/extractor-fixtures/swift/swift-const-array/sample.swift +21 -0
  74. package/payload/extractor-fixtures/swift/swift-enum/EXPECTED.yaml +8 -0
  75. package/payload/extractor-fixtures/swift/swift-enum/sample.swift +30 -0
  76. package/payload/extractor-fixtures/swift/yaml-keys/EXPECTED.yaml +6 -0
  77. package/payload/extractor-fixtures/swift/yaml-keys/sample.yaml +23 -0
  78. package/payload/extractor-fixtures/swift/yaml-map-keys/EXPECTED.yaml +7 -0
  79. package/payload/extractor-fixtures/swift/yaml-map-keys/sample.yaml +15 -0
  80. package/payload/extractor-fixtures/ts/dir-modules/EXPECTED.yaml +12 -0
  81. package/payload/extractor-fixtures/ts/dir-modules/sample-modules/alpha.widget.ts +1 -0
  82. package/payload/extractor-fixtures/ts/dir-modules/sample-modules/beta.widget.ts +1 -0
  83. package/payload/extractor-fixtures/ts/dir-modules/sample-modules/gamma.widget.ts +1 -0
  84. package/payload/extractor-fixtures/ts/dir-modules/sample-modules/helpers/format.ts +3 -0
  85. package/payload/extractor-fixtures/ts/dir-modules/sample-modules/widgets.test.ts +2 -0
  86. package/payload/extractor-fixtures/ts/json-keys/EXPECTED.yaml +7 -0
  87. package/payload/extractor-fixtures/ts/json-keys/sample.json +5 -0
  88. package/payload/extractor-fixtures/ts/json-map-keys/EXPECTED.yaml +7 -0
  89. package/payload/extractor-fixtures/ts/json-map-keys/sample.json +13 -0
  90. package/payload/extractor-fixtures/ts/ts-const-array/EXPECTED.yaml +6 -0
  91. package/payload/extractor-fixtures/ts/ts-const-array/sample.ts +13 -0
  92. package/payload/extractor-fixtures/ts/ts-enum/EXPECTED.yaml +7 -0
  93. package/payload/extractor-fixtures/ts/ts-enum/sample.ts +11 -0
  94. package/payload/extractor-fixtures/ts/ts-object-keys/EXPECTED.yaml +6 -0
  95. package/payload/extractor-fixtures/ts/ts-object-keys/sample.tsx +23 -0
  96. package/payload/extractor-fixtures/ts/ts-union/EXPECTED.yaml +5 -0
  97. package/payload/extractor-fixtures/ts/ts-union/sample.ts +9 -0
  98. package/payload/hooks/pre-commit +37 -0
  99. package/payload/hooks/reverse-lookup +66 -0
  100. package/payload/package.json +3 -0
  101. package/payload/protocol/.gitkeep +0 -0
  102. package/payload/protocol/AGENTS.md +239 -0
  103. package/payload/protocol/derived-layer.md +174 -0
  104. package/payload/protocol/new-kind-pipeline.md +179 -0
  105. package/payload/protocol/registry-warrant.md +162 -0
  106. package/payload/protocol/skills/kb-build.md +303 -0
  107. package/payload/protocol/skills/knowledge-audit.md +183 -0
  108. package/payload/protocol/skills/knowledge-bootstrap.md +229 -0
  109. package/payload/protocol/skills/knowledge-reflect.md +397 -0
  110. package/payload/schemas/catalog.schema.json +32 -0
  111. package/payload/schemas/decision-entry.schema.json +122 -0
  112. package/payload/schemas/finding.schema.json +77 -0
  113. package/payload/schemas/gap.schema.json +52 -0
  114. package/payload/schemas/graduation-categories.schema.json +64 -0
  115. package/payload/schemas/knowledge-leaf.schema.json +194 -0
  116. package/payload/schemas/miss.schema.json +45 -0
  117. package/payload/schemas/ontology-concept.schema.json +115 -0
  118. package/payload/schemas/phoenix-event.schema.json +76 -0
  119. package/payload/schemas/registry.schema.json +57 -0
  120. package/payload/schemas/rules.schema.json +14 -0
  121. package/payload/schemas/survey-scope.schema.json +23 -0
  122. package/payload/templates/decisions/_catalog.yaml +7 -0
  123. package/payload/templates/decisions/_registries/graduation-categories.yaml +42 -0
  124. package/payload/templates/decisions/phoenix-event.yaml +74 -0
  125. package/payload/templates/decisions/reflect-mint-proposal.yaml +100 -0
  126. package/payload/templates/decisions/registry-minting.yaml +58 -0
  127. package/payload/templates/decisions/trust-graduation.yaml +120 -0
  128. package/payload/templates/decisions/trust-revocation.yaml +106 -0
  129. package/payload/templates/knowledge/_catalog.yaml +9 -0
  130. package/payload/templates/knowledge/_registries/anchor.yaml +42 -0
  131. package/payload/templates/knowledge/_registries/authority-tiers.yaml +32 -0
  132. package/payload/templates/knowledge/_registries/domains.yaml +43 -0
  133. package/payload/templates/knowledge/_registries/form.yaml +38 -0
  134. package/payload/templates/knowledge/_registries/jurisdictions.yaml +20 -0
  135. package/payload/templates/knowledge/_registries/operations.yaml +18 -0
  136. package/payload/templates/knowledge/_registries/stage.yaml +53 -0
  137. package/payload/templates/knowledge/_rules.yaml +6 -0
  138. package/payload/templates/new-kind/README.md +107 -0
  139. package/payload/templates/new-kind/descriptor.example.yaml +18 -0
  140. package/payload/templates/new-kind/fixture/EXPECTED.yaml +6 -0
  141. package/payload/templates/new-kind/fixture/demo-anchor.list +2 -0
  142. package/payload/templates/new-kind/fixture/sample.list +7 -0
  143. package/payload/templates/new-kind/parser.example.js +98 -0
  144. package/payload/templates/ontology/_catalog.yaml +6 -0
  145. package/payload/templates/ontology/_rules.yaml +6 -0
  146. package/payload/wrappers/cursor.mdc +15 -0
  147. package/payload/wrappers/pointer.md +10 -0
@@ -0,0 +1,115 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:unknown-knowledge:schema:ontology-concept",
4
+ "title": "Ontology concept (PRD §3.1)",
5
+ "description": "One concept record inside an ontology class file. Truth anchor: the artifact — source-of-truth pointers reference the repo inward. Prose fields (summary, definition) are navigation, never the fact. IDs are minted at PR time within the class's declared range and are immutable once published (§3.5); range membership, duplicate detection, and ref resolution are loader/structural-validator checks (KK-04/KK-05), not record-local. Class files carry the store-file envelope in $defs/storeFile. Schema evolution is additive-only (§3.5, D-013).",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["id", "term", "class", "summary", "status"],
9
+ "properties": {
10
+ "id": {
11
+ "type": "string",
12
+ "pattern": "^K-[0-9]+$",
13
+ "description": "K-NNN, within the class's declared range; immutable once published."
14
+ },
15
+ "term": { "type": "string" },
16
+ "class": {
17
+ "type": "string",
18
+ "description": "Class file this concept belongs to; class files define id ranges. Taxonomy is per-project."
19
+ },
20
+ "summary": { "type": "string" },
21
+ "definition": {
22
+ "type": "string",
23
+ "description": "Prose = navigation, never the fact."
24
+ },
25
+ "aliases": { "type": "array", "items": { "type": "string" } },
26
+ "source-of-truth": {
27
+ "type": "array",
28
+ "minItems": 1,
29
+ "items": { "type": "string" },
30
+ "description": "File OR folder paths into the repo. Multi-entry semantics (§3.5): the first entry is the primary owner; additional entries are secondary references only. Every enumerates descriptor's source must name a listed entry. Point at a folder for identity, at a file for facts."
31
+ },
32
+ "owned-by": { "type": "string" },
33
+ "used-by": {
34
+ "type": "array",
35
+ "items": { "$ref": "#/$defs/conceptRef" },
36
+ "description": "Typed refs; must resolve (checked by the structural validator)."
37
+ },
38
+ "confusable-with": {
39
+ "type": "array",
40
+ "items": { "$ref": "#/$defs/conceptRef" },
41
+ "description": "Explicit disambiguation; must resolve."
42
+ },
43
+ "rationale": {
44
+ "type": "array",
45
+ "items": { "$ref": "#/$defs/decisionRef" },
46
+ "description": "Optional refs into decisions/."
47
+ },
48
+ "status": {
49
+ "enum": ["active", "draft", "deprecated", "proposed"],
50
+ "description": "§3.5 semantics: draft/proposed = structural checks only; active = all checks blocking-grade; deprecated = pointer/value checks demote to warnings."
51
+ },
52
+ "last-verified": { "$ref": "#/$defs/isoDate" },
53
+ "enumerates": {
54
+ "type": "array",
55
+ "items": { "$ref": "#/$defs/enumeratesDescriptor" },
56
+ "description": "OPTIONAL — presence makes the concept rung-2 (value agreement, diffed both ways)."
57
+ }
58
+ },
59
+ "$defs": {
60
+ "conceptRef": { "type": "string", "pattern": "^K-[0-9]+$" },
61
+ "decisionRef": {
62
+ "type": "string",
63
+ "pattern": "^D-([0-9]+|[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9-]+)$"
64
+ },
65
+ "isoDate": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
66
+ "enumeratesDescriptor": {
67
+ "type": "object",
68
+ "additionalProperties": false,
69
+ "required": ["kind", "source", "values"],
70
+ "description": "The claim of an enumerable value set plus the extractor recipe to re-derive it. A malformed descriptor is a hard error, never skipped (PRD §4).",
71
+ "properties": {
72
+ "kind": {
73
+ "type": "string",
74
+ "pattern": "^[a-z0-9][a-z0-9-]*$",
75
+ "description": "Extractor kind name (e.g. ts-const-array, swift-enum, dir-modules). Open set: clients author later kinds."
76
+ },
77
+ "source": {
78
+ "type": "string",
79
+ "description": "Must name a listed source-of-truth entry (§3.5)."
80
+ },
81
+ "symbol": {
82
+ "type": "string",
83
+ "description": "Declaration symbol inside the source, where the kind needs one."
84
+ },
85
+ "emit": {
86
+ "type": "string",
87
+ "description": "Which facet the kind emits where both are legitimate (e.g. Swift case names vs raw values, §3.5)."
88
+ },
89
+ "pattern": {
90
+ "type": "string",
91
+ "description": "dir-modules option: filename filter over the directory listing (e.g. `*.route.ts`). Grammar: `*` matches any run of characters, everything else is literal, the whole name must match. Presence pins the FILE facet — without it the kind emits subdirectory names."
92
+ },
93
+ "strip": {
94
+ "type": "string",
95
+ "description": "dir-modules option: suffix removed from every emitted name (strip `.route.ts`: home.route.ts → home). A facet name that does not carry the suffix is a hard error, never emitted unstripped."
96
+ },
97
+ "values": {
98
+ "type": "array",
99
+ "items": { "type": "string" },
100
+ "description": "Strings only, compared byte-exact and case-sensitive, as sets (§3.5). YAML 1.1 coercion is a real trap (no → false, on → true): quote such values. The loader hard-errors on non-string scalars."
101
+ }
102
+ }
103
+ },
104
+ "storeFile": {
105
+ "type": "object",
106
+ "additionalProperties": false,
107
+ "required": ["schema-version", "entries"],
108
+ "description": "Ontology class-file envelope. Every store file carries schema-version (§3.5); evolution is additive-only.",
109
+ "properties": {
110
+ "schema-version": { "type": "integer", "minimum": 1 },
111
+ "entries": { "type": "array", "items": { "$ref": "#" } }
112
+ }
113
+ }
114
+ }
115
+ }
@@ -0,0 +1,76 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:unknown-knowledge:schema:phoenix-event",
4
+ "title": "Phoenix event mapping (knowledge/_phoenix/<event>.yaml)",
5
+ "description": "A governed bulk re-taxonomy: the leaf-granular mapping that rewrites a drifted subtree's facets and bumps each touched leaf's edition (UCS-1154). A phoenix event is the ONLY thing that bumps edition in v2. It lands as an ordinary PR — a reviewable diff, not a migration project — carrying this mapping, the leaf rewrites the engine applied from it, the registry mintings the new values needed, and a Decisions entry recording why. The mapping is retained IN the store after the event, because it is what lets the structural validator confirm, from the working tree alone, that every non-1 edition was sanctioned by a phoenix event rather than typed by hand. Identity is never touched: a leaf keeps its accession id across a phoenix event, so nothing that cites it notices, and citations never chase reclassification. The mapping is leaf-granular because class-level rules cannot express a SPLIT — when one class's material divides across two successors, only a per-leaf table can say which leaf went where.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["schema-version", "event", "decision", "scope", "leaves"],
9
+ "properties": {
10
+ "schema-version": { "type": "integer", "minimum": 1 },
11
+ "event": {
12
+ "type": "string",
13
+ "pattern": "^P-[0-9]{3,}$",
14
+ "description": "The event's id (P-NNN), matching the file's basename so the file a finding names is the event it names."
15
+ },
16
+ "title": { "type": "string", "description": "What this event did, in one line — navigation, never the fact." },
17
+ "decision": {
18
+ "$ref": "#/$defs/decisionRef",
19
+ "description": "REQUIRED — the Decisions entry that sanctioned this event (§3.3). A bulk re-taxonomy nobody signed is exactly the ungoverned drift the phoenix mechanism exists to replace, so the mapping cites its warrant like a registry minting does."
20
+ },
21
+ "applied": { "$ref": "#/$defs/isoDate", "description": "The day the event was applied, recorded by the steward." },
22
+ "scope": {
23
+ "$ref": "#/$defs/scope",
24
+ "description": "The subtree this event claims. Every leaf inside it must be accounted for by a row below — the completeness gate that makes a phoenix event total rather than partial."
25
+ },
26
+ "leaves": {
27
+ "type": "array",
28
+ "minItems": 1,
29
+ "items": { "$ref": "#/$defs/leafRow" },
30
+ "description": "The leaf-granular mapping: one row per leaf in scope. Order is the steward's; the engine keys by accession."
31
+ }
32
+ },
33
+ "$defs": {
34
+ "isoDate": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
35
+ "decisionRef": { "type": "string", "pattern": "^D-([0-9]+|[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9-]+)$" },
36
+ "accession": { "type": "string", "pattern": "^L-[0-9]{6}$" },
37
+ "facetValue": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*(/[a-z0-9]+(-[a-z0-9]+)*)*$" },
38
+ "scope": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "required": ["facet", "values"],
42
+ "properties": {
43
+ "facet": {
44
+ "enum": ["facets.domain", "facets.form", "facets.anchor", "facets.stage"],
45
+ "description": "Which facet this event re-taxonomizes. One facet per event: an event that moved two independent axes at once would be two reviews wearing one diff."
46
+ },
47
+ "values": {
48
+ "type": "array",
49
+ "minItems": 1,
50
+ "items": { "$ref": "#/$defs/facetValue" },
51
+ "description": "The OLD facet values this event claims. For a hierarchical facet a value claims its whole subtree, so listing a parent claims every descendant — which is what makes 'every leaf in scope' a question the engine can answer without the steward enumerating the tree."
52
+ }
53
+ }
54
+ },
55
+ "leafRow": {
56
+ "type": "object",
57
+ "additionalProperties": false,
58
+ "required": ["id"],
59
+ "properties": {
60
+ "id": {
61
+ "$ref": "#/$defs/accession",
62
+ "description": "The leaf this row governs. Identity is the accession and it does not change: this names the SAME leaf before and after, which is why no citation has to move."
63
+ },
64
+ "to": {
65
+ "$ref": "#/$defs/facetValue",
66
+ "description": "The new value for the scope's facet. Absent means CARRIED FORWARD — the leaf is in scope, was looked at, and deliberately keeps its current value. Carrying forward is not a rewrite, so it bumps no edition; it exists so that 'accounted for' can mean 'considered' rather than only 'moved'."
67
+ },
68
+ "why": {
69
+ "type": "string",
70
+ "pattern": "\\S",
71
+ "description": "Why this leaf went where it went. On a split this is the whole substance of the event — the class-level rule cannot say it, so the row must. REQUIRED WHENEVER `to` IS PRESENT: a moved leaf carries the reason it moved. That conditional is enforced by the phoenix command's gate (an `unexplained-move` finding) rather than here, because this document is interpreted by the engine's own validator, whose keyword subset does not include dependentRequired — and a rule stated in a keyword nothing enforces would be contract drift wearing the appearance of a check. Optional in the shape, so a carried-forward row (no `to`) may state a reason or not."
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:unknown-knowledge:schema:registry",
4
+ "title": "Governed vocabulary registry (_registries/<name>.yaml)",
5
+ "description": "A store-level registry: the closed vocabulary one facet draws its values from (PRD §3, UCS-1148). Registries are governed files, not schema enums — a value is MINTED into a registry by literary warrant (material exists that needs it) and every minting is a Decisions entry, so the vocabulary grows by steward review rather than by an engine release. Hierarchical registries (domain) mint each path segment as its own value and a child path is valid only when every segment above it is minted; the TOP level is open by construction — a new top-level class is a registry edit plus a Decisions entry, never a schema or engine change. A rejected value is SUPPRESSED rather than deleted (status: suppressed), so a vocabulary proposal that was considered and refused stays visible and cannot be silently re-minted. Membership of facet values in their registry is a structural-validator check (KK-05); this schema governs the registry file itself. Schema evolution is additive-only (§3.5, D-013).",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["schema-version", "store", "registry", "values"],
9
+ "properties": {
10
+ "schema-version": { "type": "integer", "minimum": 1 },
11
+ "store": { "enum": ["ontology", "knowledge", "decisions"] },
12
+ "registry": {
13
+ "type": "string",
14
+ "description": "The registry's name — must equal the file's basename, so the file a finding names is the registry it names (a structural-validator check)."
15
+ },
16
+ "hierarchical": {
17
+ "type": "boolean",
18
+ "description": "When true, values are path segments joined by '/' and a child path is valid only if every segment above it is itself minted. Absent means flat."
19
+ },
20
+ "values": {
21
+ "type": "array",
22
+ "items": { "$ref": "#/$defs/registryValue" },
23
+ "description": "The minted vocabulary. Order is the steward's; the engine compares as a set."
24
+ }
25
+ },
26
+ "$defs": {
27
+ "isoDate": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
28
+ "decisionRef": { "type": "string", "pattern": "^D-([0-9]+|[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9-]+)$" },
29
+ "registryValue": {
30
+ "type": "object",
31
+ "additionalProperties": false,
32
+ "required": ["value", "warrant", "decision"],
33
+ "properties": {
34
+ "value": {
35
+ "type": "string",
36
+ "pattern": "^[a-z0-9]+(-[a-z0-9]+)*(/[a-z0-9]+(-[a-z0-9]+)*)*$",
37
+ "description": "The minted term: lowercase kebab segments, '/'-joined for a hierarchical registry."
38
+ },
39
+ "gloss": { "type": "string", "description": "What the term means here — prose is navigation, never the fact." },
40
+ "warrant": {
41
+ "type": "string",
42
+ "pattern": "\\S",
43
+ "description": "The literary warrant: the material that exists and needs this value. A value minted without material to fill it is speculative shelving, which is what this field refuses — so it must carry actual text, not whitespace."
44
+ },
45
+ "status": {
46
+ "enum": ["minted", "suppressed"],
47
+ "description": "Absent means minted. A suppressed value was proposed and REJECTED — it stays listed so the refusal is durable and the term cannot be quietly re-minted; using it is a membership finding like any unminted value."
48
+ },
49
+ "decision": {
50
+ "$ref": "#/$defs/decisionRef",
51
+ "description": "REQUIRED — the Decisions entry recording this minting or suppression (§3.3). Every registry edit is a governed act with a written rationale, so a value that cites no decision is a vocabulary change nobody signed. The citation is resolved like any other cross-store ref: an id naming no decision is an unresolved-ref error."
52
+ },
53
+ "minted": { "$ref": "#/$defs/isoDate" }
54
+ }
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:unknown-knowledge:schema:rules",
4
+ "title": "Store rules (_rules.yaml)",
5
+ "description": "Second hop of the navigational grammar (PRD §3): per-store governance rules — id ranges per class, write gates, staleness policy. The rule item shape is bootstrap-generated per project and formalized additively by the taxonomy issues; v1 pins only the envelope so seeded files carry schema-version from day one (§3.5, seeded-once means conventions cannot be retrofitted).",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["schema-version", "store", "rules"],
9
+ "properties": {
10
+ "schema-version": { "type": "integer", "minimum": 1 },
11
+ "store": { "enum": ["ontology", "knowledge", "decisions"] },
12
+ "rules": { "type": "array" }
13
+ }
14
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:unknown-knowledge:schema:survey-scope",
4
+ "title": "Survey scope (PRD §4/§6)",
5
+ "description": "survey-scope.yaml — the human-confirmed include/exclude traversal boundary from the bootstrap scope+taxonomy gate, persisted at the client repo root. The honor-it contract: once this file exists, survey-map bounds its map to it, and audit/reflect sweeps never rescan excluded areas (widening happens via retrieval-miss findings, never re-litigation). Paths are repo-root-relative directory or file prefixes; exclude wins over include. Evolution is additive-only (§3.5, D-013).",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["schema-version", "include"],
9
+ "properties": {
10
+ "schema-version": { "type": "integer", "minimum": 1 },
11
+ "include": {
12
+ "type": "array",
13
+ "minItems": 1,
14
+ "items": { "type": "string" },
15
+ "description": "Root-relative path prefixes that ARE product surface. Trailing slashes are normalized away (src/ means src). The special prefix '.' covers root-level files only (package.json etc.), never subdirectories. An empty include would silently survey nothing — hence minItems 1; likewise an include matching zero tracked files is an engine failure, never a silent empty survey."
16
+ },
17
+ "exclude": {
18
+ "type": "array",
19
+ "items": { "type": "string" },
20
+ "description": "Root-relative path prefixes carved OUT of the includes (vendored/generated/infra). Exclude wins over include."
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,7 @@
1
+ # decisions/_catalog.yaml — navigational entry point for the decisions store
2
+ # (catalog -> entries/D-NNN files; decisions has no _rules.yaml, PRD §9.1).
3
+ # Empty seed: entries are appended through the gated decisions write path (§3.5).
4
+ # Shape: payload/schemas/catalog.schema.json. schema-version evolves additively.
5
+ schema-version: 1
6
+ store: decisions
7
+ entries: []
@@ -0,0 +1,42 @@
1
+ # Trust graduation category table (UCS-1155) — which change categories may ever
2
+ # graduate from full inspection to sampling, and which are permanently gated.
3
+ #
4
+ # Seeded EMPTY, like every other registry, and for the same reason plus one of
5
+ # its own. The shared reason: every row must cite a Decisions entry that
6
+ # resolves, and a seeded repo's decisions store is empty by design (D-001), so
7
+ # shipped rows would hand every client a broken ref.
8
+ #
9
+ # The reason particular to this table: a graduation-eligible row is a standing
10
+ # claim that a class of change is mechanical ENOUGH IN THIS PROJECT to be
11
+ # sampled rather than read. The kit cannot know that. Whether "alias additions"
12
+ # are mechanical depends on what this project's aliases do — in a store where an
13
+ # alias steers retrieval into regulated material, they are not mechanical at
14
+ # all. Shipping that judgment pre-made would be the kit deciding how much
15
+ # someone else's work gets read.
16
+ #
17
+ # So the vocabulary is yours to mint, and the shapes below are the guidance:
18
+ #
19
+ # ELIGIBLE — mechanical categories. The change is checkable by looking at it,
20
+ # and being right about it N times running is real evidence about the N+1th.
21
+ # The candidates named in the design: alias additions, verified bumps, paths
22
+ # edges, see-also links.
23
+ #
24
+ # GATED — judgment categories, permanently. New domain classes, contradicts
25
+ # and supersedes edges, authority assignments, and ANYTHING CITATION-BEARING.
26
+ # These stay gated however long the clean streak, because the streak is
27
+ # evidence about a different question than the one they ask: a correct
28
+ # authority assignment ten times over says the assigner has been careful, not
29
+ # that the eleventh source's trustworthiness can go unread.
30
+ #
31
+ # Every row needs a `warrant` — for a gated row, name the judgment the change
32
+ # requires that no streak removes. An `eligible` row needs a `threshold` (N
33
+ # consecutive approved-unmodified cycles); a `gated` row must not carry one.
34
+ #
35
+ # v1 DOES NOT COMPUTE THE COUNTS. The threshold is the bar a moderator judges
36
+ # the recorded approved-unmodified counts against by hand; the analytics are
37
+ # manual (docs/steward-guide.md). Citation spot-checks stay in the sampling plan
38
+ # at every trust level, including the most graduated.
39
+ schema-version: 1
40
+ store: decisions
41
+ table: graduation-categories
42
+ categories: []
@@ -0,0 +1,74 @@
1
+ # Decisions-entry template — a phoenix event (UCS-1154).
2
+ #
3
+ # A phoenix event is a governed bulk re-taxonomy: a drifted subtree's facets are
4
+ # rewritten from a leaf-granular mapping, every leaf the event moves has its
5
+ # `edition` bumped — the only thing that ever bumps it — and the whole thing
6
+ # lands as an ordinary PR. Copy this file to decisions/entries/<id>-<slug>.yaml,
7
+ # fill it, and open ONE PR carrying:
8
+ #
9
+ # - this entry,
10
+ # - the mapping, at knowledge/_phoenix/<event>.yaml,
11
+ # - the registry mintings the new values need (each with its own warrant),
12
+ # - the leaf rewrites, produced by the engine and never by hand:
13
+ # node payload/engine/phoenix.js <event> --root <dir> # dry run
14
+ # node payload/engine/phoenix.js <event> --root <dir> --apply # write
15
+ #
16
+ # The mapping file STAYS in the store after the event. It is what lets the
17
+ # structural validator confirm that every edition above 1 was sanctioned by an
18
+ # event, reading only the working tree — a governance rule checkable solely by
19
+ # reading git history is a rule that is not checked.
20
+ #
21
+ # The two rules this entry exists to evidence:
22
+ #
23
+ # THE MAPPING IS LEAF-GRANULAR. A class-level rename cannot express a SPLIT —
24
+ # when one class's material divides across two successors, only a per-leaf
25
+ # table can say which leaf went where, and the `why` on each row is the
26
+ # substance a reviewer reads.
27
+ #
28
+ # IDENTITY DOES NOT MOVE. Accession ids are untouched, so every citation into
29
+ # these leaves stays valid across the event. If a proposal requires renaming
30
+ # or reissuing an id, it is not a phoenix event.
31
+ #
32
+ # The `id` and `date` placeholders below are DELIBERATELY not valid, so this
33
+ # file fails validation until a steward fills them — pasting the template
34
+ # unedited must never produce a Decisions entry, or a bulk rewrite would end up
35
+ # carrying a rationale nobody wrote. Every other field is real: fill those two
36
+ # and the entry validates.
37
+ schema-version: 1
38
+ entries:
39
+ - id: D-YYYY-MM-DD-phoenix-example-split
40
+ title: "Phoenix: <what splits, merges or moves> (edition <n>)"
41
+ # `governance` — an event changes how the Store is filed, not how the engine
42
+ # works.
43
+ category: governance
44
+ status: proposed
45
+ date: "YYYY-MM-DD"
46
+ deciders: [<steward>]
47
+ # THE DRIFT. Name the material whose classification stopped matching it, and
48
+ # say how you noticed. "The tree would be tidier" is the case this refuses:
49
+ # a re-taxonomy costs every reader their memory of where things live, so the
50
+ # warrant is that the CURRENT shape actively misfiles material — two kinds of
51
+ # thing under one class that no longer share a reader, a class nobody looks
52
+ # in, a name that stopped meaning what it says.
53
+ context: >-
54
+ <Which leaves are filed where, and why that filing no longer serves the
55
+ people reading them.>
56
+ # What moves where, and — if this is a split — why no class-level rule could
57
+ # express it. Name the event id whose mapping carries the per-leaf rows.
58
+ decision: >-
59
+ <Split/merge/move <old> into <new>. Apply as phoenix event P-NNN, whose
60
+ mapping (knowledge/_phoenix/P-NNN.yaml) records where each leaf went and
61
+ why.>
62
+ # Say the edition bump out loud, and say what did NOT change: an event that
63
+ # quietly moved identity would break every citation into the subtree, and
64
+ # stating the invariant here is how a reviewer knows to check it.
65
+ consequences: >-
66
+ <Each moved leaf's edition goes <n-1> -> <n>. No accession id changes, so
67
+ every citation into these leaves stays valid and nothing that cites them
68
+ needs editing. Leaves carried forward keep their edition — they were
69
+ considered and deliberately left alone.>
70
+ supersedes: []
71
+ # The leaves this event touched. The same accessions are valid before AND
72
+ # after — that is the property being demonstrated, not a coincidence.
73
+ relates-to:
74
+ leaves: []
@@ -0,0 +1,100 @@
1
+ # Decisions-entry template — a reflect MINT PROPOSAL (UCS-1160).
2
+ #
3
+ # Reflect is where misses become tomorrow's deterministic edges. A corroborated
4
+ # cluster of residue or document-candidate findings is evidence that the store
5
+ # has no word for something the material keeps naming. Minting that word — a
6
+ # term, an alias, an operation, or a domain class — is a governed act, and this
7
+ # file is the shape of the rationale that sanctions it.
8
+ #
9
+ # Copy this file to decisions/entries/<id>-<slug>.yaml, fill it, and open ONE
10
+ # PR carrying the entry, the registry (or concept) edit that cites it, and the
11
+ # findings that supplied the warrant. Conduct in full:
12
+ # protocol/skills/knowledge-reflect.md (Minting conduct) and
13
+ # protocol/registry-warrant.md.
14
+ #
15
+ # Draft with a provisional date-suffixed id (D-YYYY-MM-DD-slug) and
16
+ # `status: proposed`; the steward assigns the final D-NNN at acceptance (§3.5).
17
+ # Agents draft; humans approve.
18
+ #
19
+ # The two rules this entry exists to evidence:
20
+ # ONE FINDING IS A DATA POINT, THREE ARE A PATTERN. `context` must name at
21
+ # least three DISTINCT fragments before a mint reaches the gate. "Distinct"
22
+ # is defined once, in protocol/skills/knowledge-reflect.md under Minting
23
+ # conduct ("What three distinct fragments means") — read it there rather
24
+ # than inferring it here. The short of it: it counts independent resolution
25
+ # events, not files, so three logs from ONE session are one data point.
26
+ # A VALUE IS MINTED ONLY ON LITERARY WARRANT. If `context` cannot name
27
+ # material that exists NOW, the value is not ready — corroboration says the
28
+ # word keeps coming up, warrant says there is something for it to hold.
29
+ #
30
+ # WHAT THE VALIDATOR CATCHES, AND WHAT ONLY A READER CATCHES.
31
+ #
32
+ # MACHINE-REFUSED — the `id` and `date` placeholders below are DELIBERATELY not
33
+ # valid (`YYYY` is not four digits), so pasting this file unedited fails
34
+ # validation and never produces a Decisions entry. (Same conduct as
35
+ # registry-minting.yaml and the audit's `K-XXX` drafts.)
36
+ #
37
+ # GREEN BUT STILL A PLACEHOLDER — filling those two makes the file VALIDATE,
38
+ # and these five fields still hold <angle-bracket> text that no validator
39
+ # judges, because they are free prose the schema deliberately leaves open:
40
+ #
41
+ # title "Mint <value> in the <registry> registry ..."
42
+ # deciders ["<steward>"]
43
+ # context "<Which material exists, and why no minted value fits it ...>"
44
+ # decision "Mint <value> in <registry>. ..."
45
+ # consequences "<What this obliges ...>"
46
+ #
47
+ # A green validation on this file means "the shape is right", NEVER "the
48
+ # rationale is written". Those five are caught by the human at the gate or not
49
+ # at all — which is the honest state of affairs, not an oversight: patterning
50
+ # them would constrain every real Decisions entry in the store, and a validator
51
+ # cannot tell a written warrant from a plausible-looking sentence anyway.
52
+ # Replace every <angle-bracket> before this entry goes to the gate.
53
+ schema-version: 1
54
+ entries:
55
+ - id: D-YYYY-MM-DD-mint-example-from-reflect
56
+ title: Mint <value> in the <registry> registry (reflect cycle <date>)
57
+ # `governance` — minting a vocabulary value changes what the Store may say,
58
+ # not how the engine works.
59
+ category: governance
60
+ status: proposed
61
+ date: "YYYY-MM-DD"
62
+ deciders: [<steward>]
63
+ # THE WARRANT, plus the CORROBORATION that raised it. Name the material that
64
+ # exists and needs this value, AND the findings that kept landing on it.
65
+ # Reflect's own recommendation list is not evidence — the fragments are.
66
+ # "We will need it later" is the case the warrant rule refuses; "it came up
67
+ # once" — and "it came up three times in one sitting" — are the cases the
68
+ # corroboration rule refuses.
69
+ context: >-
70
+ <Which material exists, and why no minted value fits it. Then: which
71
+ DISTINCT fragments corroborate it (name the paths), over which sessions
72
+ and dates — distinctness counts independent resolution events, not files
73
+ — and what resolved alongside the unresolved term (the findings'
74
+ `resolved-context`), which is what localizes the gap. For a document
75
+ candidate, name the section the
76
+ findings' `section` locators point at and say what reading it confirmed:
77
+ a candidate is a claim about the map until someone opens the source.>
78
+ # What is being minted, at which level, and in which vocabulary. For a
79
+ # hierarchical domain path, mint every segment: a child may not hang off an
80
+ # unminted parent.
81
+ decision: >-
82
+ Mint <value> in <registry>. <For an alias: name the concept it attaches to
83
+ and the surface form the findings kept using. For an operation: name the
84
+ verb and what it operates on. For a new top-level domain class: this is a
85
+ registry edit plus this entry — the top level is open, so no schema or
86
+ engine change is involved.>
87
+ # For a SUPPRESSION, keep the same shape and say what was refused and why.
88
+ # The value stays listed with `status: suppressed` rather than being
89
+ # deleted, so the refusal is durable and the term cannot be quietly
90
+ # re-minted — and the next reflect cycle that clusters the same residue sees
91
+ # that this term was already considered.
92
+ consequences: >-
93
+ <What this obliges: leaves to reclassify, siblings this now sits beside,
94
+ the residue this stops producing, or — on a suppression — where the
95
+ material should go instead.>
96
+ supersedes: []
97
+ # A re-minting REVERSES an earlier suppression: name that decision here and
98
+ # say in `context` why the refusal no longer holds.
99
+ relates-to:
100
+ leaves: []
@@ -0,0 +1,58 @@
1
+ # Decisions-entry template — minting or suppressing a registry value (UCS-1148).
2
+ #
3
+ # Every registry edit is a governed act with a written rationale. Copy this file
4
+ # to decisions/entries/<id>-<slug>.yaml, fill it, and open ONE PR carrying the
5
+ # entry, the registry edit that cites it, and the material that supplied the
6
+ # warrant. Conduct in full: protocol/registry-warrant.md.
7
+ #
8
+ # Draft with a provisional date-suffixed id (D-YYYY-MM-DD-slug) and
9
+ # `status: proposed`; the steward assigns the final D-NNN at acceptance (§3.5).
10
+ # Agents draft; humans approve.
11
+ #
12
+ # The one rule this entry exists to evidence:
13
+ # A VALUE IS MINTED ONLY WHEN MATERIAL EXISTS TO FILL IT (literary warrant).
14
+ # If `context` cannot name material that exists NOW, the value is not ready.
15
+ #
16
+ # The `id` and `date` placeholders below are DELIBERATELY not valid, so this
17
+ # file fails validation until a steward fills them — pasting the template
18
+ # unedited must never produce a Decisions entry, or a registry value would end
19
+ # up carrying a warrant nobody wrote. (Same conduct as the audit's `K-XXX`
20
+ # drafts.) Every other field is real: fill those two and the entry validates.
21
+ schema-version: 1
22
+ entries:
23
+ - id: D-YYYY-MM-DD-mint-example-domain
24
+ title: Mint <value> in the <registry> registry
25
+ # `governance` — a registry edit changes what the Store may say, not how the
26
+ # engine works.
27
+ category: governance
28
+ status: proposed
29
+ date: "YYYY-MM-DD"
30
+ deciders: [<steward>]
31
+ # THE WARRANT. Name the material that exists and needs this value: the
32
+ # leaves, documents, or body of work with nowhere to sit. "We will need it
33
+ # later" is the case the rule refuses — speculative shelving invites authors
34
+ # to file knowledge under a heading nobody chose deliberately.
35
+ context: >-
36
+ <Which material exists, and why no minted value fits it. For a
37
+ hierarchical domain, say why it belongs at this level rather than under an
38
+ existing class.>
39
+ # What is being minted, at which level, and in which registry. For a
40
+ # hierarchical path, mint every segment: a child may not hang off an
41
+ # unminted parent.
42
+ decision: >-
43
+ Mint <value> in <registry>. <For a new top-level domain class: this is a
44
+ registry edit plus this entry — the top level is open, so no schema or
45
+ engine change is involved.>
46
+ # For a SUPPRESSION, keep the same shape and say what was refused and why.
47
+ # The value stays listed with `status: suppressed` rather than being
48
+ # deleted, so the refusal is durable and the term cannot be quietly
49
+ # re-minted. Deleting it would lose the decision and invite the same
50
+ # proposal again with no memory of how it went.
51
+ consequences: >-
52
+ <What this obliges: leaves to reclassify, siblings this now sits beside,
53
+ or — on a suppression — where the material should go instead.>
54
+ supersedes: []
55
+ # A re-minting REVERSES an earlier suppression: name that decision here and
56
+ # say in `context` why the refusal no longer holds.
57
+ relates-to:
58
+ leaves: []