gcf-aif-ext 0.2.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.
- package/LICENSE +21 -0
- package/README.md +41 -0
- package/commands/gcf.js +173 -0
- package/extension.json +24 -0
- package/hooks/pre-commit.js +91 -0
- package/injections/commit-status.md +6 -0
- package/injections/plan-context.md +8 -0
- package/injections/review-pillars.md +7 -0
- package/lib/anchors.js +109 -0
- package/lib/audit-core.js +102 -0
- package/lib/context.js +77 -0
- package/lib/frontmatter.js +26 -0
- package/lib/gcf-paths.js +60 -0
- package/lib/git.js +19 -0
- package/lib/id.js +42 -0
- package/lib/index-gen.js +51 -0
- package/lib/linter.js +61 -0
- package/lib/playtest-list.js +13 -0
- package/lib/safe-path.js +71 -0
- package/lib/transitions.js +30 -0
- package/lib/validate-card.js +48 -0
- package/lib/verdict-fs.js +126 -0
- package/node_modules/cnlp-kit/CHANGELOG.md +625 -0
- package/node_modules/cnlp-kit/LICENSE +21 -0
- package/node_modules/cnlp-kit/README.md +242 -0
- package/node_modules/cnlp-kit/bin/cnlp.js +334 -0
- package/node_modules/cnlp-kit/cnlp-format.md +470 -0
- package/node_modules/cnlp-kit/package.json +40 -0
- package/node_modules/cnlp-kit/profiles/adr.md +129 -0
- package/node_modules/cnlp-kit/profiles/api.md +87 -0
- package/node_modules/cnlp-kit/profiles/concept.md +70 -0
- package/node_modules/cnlp-kit/profiles/docset.md +103 -0
- package/node_modules/cnlp-kit/profiles/guide.md +51 -0
- package/node_modules/cnlp-kit/profiles/profile.md +69 -0
- package/node_modules/cnlp-kit/profiles/reference.md +61 -0
- package/node_modules/cnlp-kit/profiles/skill.md +75 -0
- package/node_modules/cnlp-kit/profiles/task.md +65 -0
- package/node_modules/cnlp-kit/quality-rules.md +69 -0
- package/node_modules/cnlp-kit/skills/cnlp-docset/SKILL.md +73 -0
- package/node_modules/cnlp-kit/skills/cnlp-migrate/SKILL.md +64 -0
- package/node_modules/cnlp-kit/src/cnlp.js +534 -0
- package/node_modules/cnlp-kit/src/config.js +352 -0
- package/node_modules/yaml/LICENSE +13 -0
- package/node_modules/yaml/README.md +172 -0
- package/node_modules/yaml/bin.mjs +11 -0
- package/node_modules/yaml/browser/dist/compose/compose-collection.js +88 -0
- package/node_modules/yaml/browser/dist/compose/compose-doc.js +43 -0
- package/node_modules/yaml/browser/dist/compose/compose-node.js +109 -0
- package/node_modules/yaml/browser/dist/compose/compose-scalar.js +86 -0
- package/node_modules/yaml/browser/dist/compose/composer.js +219 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-map.js +115 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +49 -0
- package/node_modules/yaml/browser/dist/compose/resolve-end.js +37 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +207 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +226 -0
- package/node_modules/yaml/browser/dist/compose/resolve-props.js +146 -0
- package/node_modules/yaml/browser/dist/compose/util-contains-newline.js +34 -0
- package/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +26 -0
- package/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
- package/node_modules/yaml/browser/dist/compose/util-map-includes.js +13 -0
- package/node_modules/yaml/browser/dist/doc/Document.js +335 -0
- package/node_modules/yaml/browser/dist/doc/anchors.js +71 -0
- package/node_modules/yaml/browser/dist/doc/applyReviver.js +55 -0
- package/node_modules/yaml/browser/dist/doc/createNode.js +88 -0
- package/node_modules/yaml/browser/dist/doc/directives.js +176 -0
- package/node_modules/yaml/browser/dist/errors.js +57 -0
- package/node_modules/yaml/browser/dist/index.js +17 -0
- package/node_modules/yaml/browser/dist/log.js +11 -0
- package/node_modules/yaml/browser/dist/nodes/Alias.js +118 -0
- package/node_modules/yaml/browser/dist/nodes/Collection.js +147 -0
- package/node_modules/yaml/browser/dist/nodes/Node.js +38 -0
- package/node_modules/yaml/browser/dist/nodes/Pair.js +36 -0
- package/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
- package/node_modules/yaml/browser/dist/nodes/YAMLMap.js +144 -0
- package/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
- package/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +63 -0
- package/node_modules/yaml/browser/dist/nodes/identity.js +36 -0
- package/node_modules/yaml/browser/dist/nodes/toJS.js +37 -0
- package/node_modules/yaml/browser/dist/parse/cst-scalar.js +214 -0
- package/node_modules/yaml/browser/dist/parse/cst-stringify.js +61 -0
- package/node_modules/yaml/browser/dist/parse/cst-visit.js +97 -0
- package/node_modules/yaml/browser/dist/parse/cst.js +98 -0
- package/node_modules/yaml/browser/dist/parse/lexer.js +721 -0
- package/node_modules/yaml/browser/dist/parse/line-counter.js +39 -0
- package/node_modules/yaml/browser/dist/parse/parser.js +975 -0
- package/node_modules/yaml/browser/dist/public-api.js +102 -0
- package/node_modules/yaml/browser/dist/schema/Schema.js +37 -0
- package/node_modules/yaml/browser/dist/schema/common/map.js +17 -0
- package/node_modules/yaml/browser/dist/schema/common/null.js +15 -0
- package/node_modules/yaml/browser/dist/schema/common/seq.js +17 -0
- package/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
- package/node_modules/yaml/browser/dist/schema/core/bool.js +19 -0
- package/node_modules/yaml/browser/dist/schema/core/float.js +43 -0
- package/node_modules/yaml/browser/dist/schema/core/int.js +38 -0
- package/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
- package/node_modules/yaml/browser/dist/schema/json/schema.js +62 -0
- package/node_modules/yaml/browser/dist/schema/tags.js +96 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +58 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +67 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
- package/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
- package/node_modules/yaml/browser/dist/stringify/stringify.js +129 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +153 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyComment.js +20 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +25 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyPair.js +150 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyString.js +336 -0
- package/node_modules/yaml/browser/dist/util.js +11 -0
- package/node_modules/yaml/browser/dist/visit.js +233 -0
- package/node_modules/yaml/browser/index.js +5 -0
- package/node_modules/yaml/browser/package.json +3 -0
- package/node_modules/yaml/dist/cli.d.ts +8 -0
- package/node_modules/yaml/dist/cli.mjs +201 -0
- package/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
- package/node_modules/yaml/dist/compose/compose-collection.js +90 -0
- package/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
- package/node_modules/yaml/dist/compose/compose-doc.js +45 -0
- package/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
- package/node_modules/yaml/dist/compose/compose-node.js +112 -0
- package/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
- package/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
- package/node_modules/yaml/dist/compose/composer.d.ts +63 -0
- package/node_modules/yaml/dist/compose/composer.js +224 -0
- package/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
- package/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
- package/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
- package/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
- package/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-end.js +39 -0
- package/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
- package/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.js +228 -0
- package/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
- package/node_modules/yaml/dist/compose/resolve-props.js +148 -0
- package/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
- package/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
- package/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
- package/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
- package/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
- package/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
- package/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
- package/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
- package/node_modules/yaml/dist/doc/Document.d.ts +141 -0
- package/node_modules/yaml/dist/doc/Document.js +337 -0
- package/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
- package/node_modules/yaml/dist/doc/anchors.js +76 -0
- package/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
- package/node_modules/yaml/dist/doc/applyReviver.js +57 -0
- package/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
- package/node_modules/yaml/dist/doc/createNode.js +90 -0
- package/node_modules/yaml/dist/doc/directives.d.ts +49 -0
- package/node_modules/yaml/dist/doc/directives.js +178 -0
- package/node_modules/yaml/dist/errors.d.ts +21 -0
- package/node_modules/yaml/dist/errors.js +62 -0
- package/node_modules/yaml/dist/index.d.ts +25 -0
- package/node_modules/yaml/dist/index.js +50 -0
- package/node_modules/yaml/dist/log.d.ts +3 -0
- package/node_modules/yaml/dist/log.js +19 -0
- package/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
- package/node_modules/yaml/dist/nodes/Alias.js +120 -0
- package/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
- package/node_modules/yaml/dist/nodes/Collection.js +151 -0
- package/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
- package/node_modules/yaml/dist/nodes/Node.js +40 -0
- package/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
- package/node_modules/yaml/dist/nodes/Pair.js +39 -0
- package/node_modules/yaml/dist/nodes/Scalar.d.ts +47 -0
- package/node_modules/yaml/dist/nodes/Scalar.js +27 -0
- package/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
- package/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
- package/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
- package/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
- package/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
- package/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
- package/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
- package/node_modules/yaml/dist/nodes/identity.js +53 -0
- package/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
- package/node_modules/yaml/dist/nodes/toJS.js +39 -0
- package/node_modules/yaml/dist/options.d.ts +350 -0
- package/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
- package/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
- package/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
- package/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
- package/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
- package/node_modules/yaml/dist/parse/cst-visit.js +99 -0
- package/node_modules/yaml/dist/parse/cst.d.ts +109 -0
- package/node_modules/yaml/dist/parse/cst.js +112 -0
- package/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
- package/node_modules/yaml/dist/parse/lexer.js +723 -0
- package/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
- package/node_modules/yaml/dist/parse/line-counter.js +41 -0
- package/node_modules/yaml/dist/parse/parser.d.ts +84 -0
- package/node_modules/yaml/dist/parse/parser.js +980 -0
- package/node_modules/yaml/dist/public-api.d.ts +44 -0
- package/node_modules/yaml/dist/public-api.js +107 -0
- package/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
- package/node_modules/yaml/dist/schema/Schema.js +39 -0
- package/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/map.js +19 -0
- package/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
- package/node_modules/yaml/dist/schema/common/null.js +17 -0
- package/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/seq.js +19 -0
- package/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/string.js +16 -0
- package/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/bool.js +21 -0
- package/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/float.js +47 -0
- package/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/int.js +42 -0
- package/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
- package/node_modules/yaml/dist/schema/core/schema.js +25 -0
- package/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
- package/node_modules/yaml/dist/schema/json/schema.js +64 -0
- package/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
- package/node_modules/yaml/dist/schema/tags.d.ts +48 -0
- package/node_modules/yaml/dist/schema/tags.js +99 -0
- package/node_modules/yaml/dist/schema/types.d.ts +92 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/merge.js +71 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
- package/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
- package/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
- package/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
- package/node_modules/yaml/dist/stringify/stringify.js +132 -0
- package/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
- package/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
- package/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
- package/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
- package/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
- package/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
- package/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
- package/node_modules/yaml/dist/stringify/stringifyNumber.js +27 -0
- package/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
- package/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
- package/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
- package/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
- package/node_modules/yaml/dist/test-events.d.ts +4 -0
- package/node_modules/yaml/dist/test-events.js +134 -0
- package/node_modules/yaml/dist/util.d.ts +16 -0
- package/node_modules/yaml/dist/util.js +28 -0
- package/node_modules/yaml/dist/visit.d.ts +102 -0
- package/node_modules/yaml/dist/visit.js +236 -0
- package/node_modules/yaml/package.json +97 -0
- package/node_modules/yaml/util.js +2 -0
- package/package.json +54 -0
- package/profiles/card.md +65 -0
- package/profiles/pillars.md +31 -0
- package/profiles/system.md +56 -0
- package/schemas/card.schema.json +30 -0
- package/skills/gcf-adopt/SKILL.md +41 -0
- package/skills/gcf-audit/SKILL.md +27 -0
- package/skills/gcf-card/SKILL.md +35 -0
- package/skills/gcf-debate/SKILL.md +33 -0
- package/skills/gcf-ingest/SKILL.md +38 -0
- package/skills/gcf-init/SKILL.md +32 -0
- package/skills/gcf-verdict/SKILL.md +32 -0
- package/skills/gcf-vision/SKILL.md +33 -0
- package/templates/PILLARS.md +8 -0
- package/templates/backlog.md +4 -0
- package/templates/card.md +34 -0
- package/templates/cnlp.config.json +8 -0
- package/templates/config.yml +8 -0
- package/templates/system.md +22 -0
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
The format has its own version from here on. It used to be stamped with the release number of
|
|
4
|
+
an ADR extension, which made a breaking change to the format invisible inside that project's
|
|
5
|
+
patch release.
|
|
6
|
+
|
|
7
|
+
## 3.4.1
|
|
8
|
+
|
|
9
|
+
A record-list of multi-key records read as a wall. The only boundary between 2 records was a line
|
|
10
|
+
opening with `- ` rather than with 2 spaces, so finding where the third record ended meant scanning
|
|
11
|
+
forward for the next one. A blank line makes that boundary visible at the block level, and the old
|
|
12
|
+
boundary stays, so nothing that reads a document today reads it worse.
|
|
13
|
+
|
|
14
|
+
The parser was already indifferent: `itemsOf` drops a blank line and runs to the next top-level key,
|
|
15
|
+
so `readRecords` never sees one. Both spellings report the same issues, parse the same records, and
|
|
16
|
+
resolve the same references. What was missing was a sentence saying so.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **§3 states what a blank line does.** It separates records for a reader, carries no meaning, and
|
|
21
|
+
belongs between records that run to 2 lines or more; a list of one-line records stays tight. The
|
|
22
|
+
standard said nothing about blank lines anywhere, which left the behaviour undefined for the
|
|
23
|
+
second implementation `docs/BACKLOG.md` item 3 wants.
|
|
24
|
+
- **`renderBody` emits the separator**, so a scaffolded document is spelled the way a hand-written
|
|
25
|
+
one is.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **The corpus is reformatted** — 239 blank lines over 41 files: the 9 profiles, the 21 pages of the
|
|
30
|
+
2 worked docsets, and the Nano ID set outside this repository. Driven by the checker's own parser
|
|
31
|
+
rather than by a pattern over `- `, because a bullet-list item opens the same way and only the
|
|
32
|
+
profile says which blocks are record-lists. Content is unchanged: over `examples/`, 126 lines
|
|
33
|
+
added, 0 deleted, and 0 of the additions carry a character.
|
|
34
|
+
- **`docs/DOCSETS.md` measurements re-measured**, and 1 row had drifted before this change reached
|
|
35
|
+
it: `examples/dragonecs/index.md` was recorded at 10114 against a file of 9746. Nothing re-reads
|
|
36
|
+
those numbers, which is `docs/BACKLOG.md` item 8 arriving at the measurements instead of the pages.
|
|
37
|
+
|
|
38
|
+
## 3.4.0
|
|
39
|
+
|
|
40
|
+
Producing a document set and adopting one turned out to be 2 modes wearing 1 name, and only the
|
|
41
|
+
second was built. The first real run outside this repository wrote 12 documentation files and 13
|
|
42
|
+
files of project scaffolding around them — a `package.json`, a lockfile, a `node_modules`, a
|
|
43
|
+
`cnlp.config.json`, an empty profiles directory, and a copy of both packaged skills under 2 agent
|
|
44
|
+
directories. The operator asked for an output folder and got a project.
|
|
45
|
+
|
|
46
|
+
`skills/cnlp-docset/SKILL.md` prescribed every bit of it: `preconditions:` required `cnlp-kit` to be
|
|
47
|
+
a dependency of *this repository* and a `cnlp.config.json` to carry a `docsets` key. Exactly 1 piece
|
|
48
|
+
of that scaffolding did any work — the config, because `cnlp check` could not start without one and
|
|
49
|
+
`readConfig` takes its root from the directory a config sits in, so a config cannot be kept outside
|
|
50
|
+
the tree it describes.
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- **`cnlp check <dir>` reads a directory by path**, with no config file and no project around it. A
|
|
55
|
+
directory carrying an `index.md` is 1 set; a directory whose subdirectories carry one is the root
|
|
56
|
+
of several; anything else falls back to the layouts `cnlp init` already knows. `checkProject`
|
|
57
|
+
already took a plain object, so `configForPath` in `src/config.js` synthesizes one and no internal
|
|
58
|
+
changed.
|
|
59
|
+
- **`docsetCorpus(base)`** in `src/config.js` writes the 4 entries of a set once. `CANDIDATES` spelled
|
|
60
|
+
those globs literally for `docs/docsets` and now reuses it.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **`skills/cnlp-docset/SKILL.md` names an output directory**, not a project. `inputs:` takes
|
|
65
|
+
`output_directory` in place of `set_name`, `preconditions:` asks for neither a dependency nor a
|
|
66
|
+
config, and `scope:` states 2 rules that were missing: write nothing into that directory but the
|
|
67
|
+
set, and stop at authoring — a repository that will hold the set among its own documents runs
|
|
68
|
+
`cnlp init` and names it in `docsets:`, which is adoption and a second act by a second party.
|
|
69
|
+
- **A synthesized corpus drops an entry matching no file; a written one still refuses it.** Those
|
|
70
|
+
read as the same rule and are not: a glob a project typed and no file answers is a mistake, which
|
|
71
|
+
is what 2.6.0 added the refusal for, and a glob guessed from a directory names a folder a set
|
|
72
|
+
being written may not have yet. This also retires the friction the Nano ID run recorded, where
|
|
73
|
+
`cnlp check` on a freshly scaffolded index reported the empty `concepts/` glob rather than the
|
|
74
|
+
blocks the index still owed.
|
|
75
|
+
- **`README.md` splits producing from adopting** under "Document a library or a framework", and the
|
|
76
|
+
command table carries the path form.
|
|
77
|
+
|
|
78
|
+
### Added to the record
|
|
79
|
+
|
|
80
|
+
- **`docs/PROBE-nanoid.md`** — the first set built for a library nobody here had read, from prose
|
|
81
|
+
alone at weight 3, with the declarations withheld until it was finished and then compared. 1
|
|
82
|
+
capability of 8 was lost to prose, plus 6 contract-level losses, every one an omission and none an
|
|
83
|
+
invention: the 3.2.0 prohibition held. `docs/BACKLOG.md` item 9's criterion is met.
|
|
84
|
+
|
|
85
|
+
## 3.3.0
|
|
86
|
+
|
|
87
|
+
The mechanical half of authoring moved off the agent, and a docset stopped being a one-shot
|
|
88
|
+
artifact. Three commands' worth of work rested on one question — what does a document remember
|
|
89
|
+
about where it came from — and the answer turned out to be 1 optional key on a record rather than
|
|
90
|
+
the frontmatter reader `docs/BACKLOG.md` item 6 proposed. Drift is a property of a capability, and
|
|
91
|
+
a capability already had a record to carry it.
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
|
|
95
|
+
- **`cnlp scaffold <profile> <data.json>`** writes a document from data, in the blocks and the forms
|
|
96
|
+
the profile declares. It reads the profile and nothing else, so it branches on no document kind:
|
|
97
|
+
the same command emits a docset index and an ADR, frontmatter and headings included, and a
|
|
98
|
+
project's local profile shadows the packaged one here as everywhere else.
|
|
99
|
+
- **A block the data does not carry is left out, never filled.** A skeleton that conformed by
|
|
100
|
+
inventing content would claim a completeness nobody wrote. What `cnlp check` then reports as
|
|
101
|
+
missing is the list of what the author still owes — the same honesty `status: source` gives a
|
|
102
|
+
capability with no page.
|
|
103
|
+
- **`cnlp diff <profile> <document.md> <data.json>`** reports what moved between a document and a
|
|
104
|
+
fresh read of its sources: a record added, a record removed, a key whose value moved. Audit and
|
|
105
|
+
refresh are the same comparison, so this reports and the author decides which pages to rewrite.
|
|
106
|
+
A record the data can compare and the document cannot is reported rather than skipped: a run
|
|
107
|
+
covering fewer records than it claims is the failure the run exists to catch.
|
|
108
|
+
- **`fingerprint:` on a `catalog:` record**, the optional value that changes when the source does.
|
|
109
|
+
Without it a set can report a capability that appeared and one that vanished, and cannot report
|
|
110
|
+
one that stood still under a signature that moved.
|
|
111
|
+
- **`record_values:` on a `sections:` record** closes a record key to a vocabulary, written
|
|
112
|
+
`status = covered, source, avoid`. The checker holds every record of that block to it, in a
|
|
113
|
+
record-list and a keyed-block alike, and a key left out of it stays open.
|
|
114
|
+
|
|
115
|
+
### Fixed
|
|
116
|
+
|
|
117
|
+
- **`status:` no longer fails open.** A value outside `covered`, `source` and `avoid` read as
|
|
118
|
+
`covered`, which sent a reader to a `page:` that is not there, with nothing reporting it. It is
|
|
119
|
+
an error now. `relation:` is closed the same way on all 3 page profiles. Both were `note:` prose
|
|
120
|
+
that nothing read, and both are struck off `docs/BACKLOG.md` item 1 — which keeps the drivers
|
|
121
|
+
that are a line *shape* rather than a key *value*, and those still want `item_pattern:`.
|
|
122
|
+
- **3 documents named a check that now exists.** `profiles/docset.md` `enforcement:`, and 2 places
|
|
123
|
+
in `skills/cnlp-docset/SKILL.md`, said the vocabularies are caught by review.
|
|
124
|
+
|
|
125
|
+
## 3.2.0
|
|
126
|
+
|
|
127
|
+
The docset sub-tool stopped assuming one shape of input. `skills/cnlp-docset/SKILL.md` declared
|
|
128
|
+
`library_source` and `library_documentation` and its step 4 required the capability list to come
|
|
129
|
+
from the sources rather than from the existing documentation — which holds for a library you can
|
|
130
|
+
clone and holds for nothing else. A library arrives as a specification, as a documentation site with
|
|
131
|
+
no readable source, as a closed-source package, as a pile of markdown an operator collected by hand,
|
|
132
|
+
or as a vendor file written for an agent to swallow whole. Every one of those was outside the skill.
|
|
133
|
+
|
|
134
|
+
The generalization cost no change to the checker and no change to a profile, which is the criterion
|
|
135
|
+
`AGENTS.md` states for one: `identity:` already carried the optional `derived_from` key, added
|
|
136
|
+
because "a page written from prose carries less weight than one written from a signature".
|
|
137
|
+
|
|
138
|
+
### Added
|
|
139
|
+
|
|
140
|
+
- **A source weight, from 1 to 5, and the rule that a contract comes from the strongest source that
|
|
141
|
+
states it.** Declarations, then a specification written for a machine, then prose the library
|
|
142
|
+
publishes, then the examples and the tests it ships, then a file derived from a source nobody
|
|
143
|
+
read. The weights are `inputs:` of the skill, because they describe what the operator hands it.
|
|
144
|
+
- **`derived_from:` carries the sources and their weights**, filled in its own step, so a reader can
|
|
145
|
+
tell a set written from declarations from a set written from prose before trusting a signature on
|
|
146
|
+
any page of it.
|
|
147
|
+
- **A prohibition on promoting a claim past its source.** "Do not invent a signature" already
|
|
148
|
+
covered invention; it did not cover writing a prose claim as though a declaration stated it, which
|
|
149
|
+
is the failure a mixed pile of sources introduces and the one a reader cannot detect.
|
|
150
|
+
|
|
151
|
+
### Changed
|
|
152
|
+
|
|
153
|
+
- **`inputs:` is a source list**, replacing `library_source` and `library_documentation`, and
|
|
154
|
+
`invocation:` names `<sources>` in all 3 agent forms.
|
|
155
|
+
- **`preconditions:` binds every source to a fixed revision or a fixed version**, not the library
|
|
156
|
+
source alone. A set states what 1 release says whatever it read that release from.
|
|
157
|
+
- **Step 3 lists the sources and reports the strongest weight the list holds**, before any page is
|
|
158
|
+
written, because that weight bounds what every page below can claim.
|
|
159
|
+
- **Step 7 lets `read:` name a document and an anchor**, not a file alone: a capability left at
|
|
160
|
+
`status: source` in a set built from prose has no file to send the reader to.
|
|
161
|
+
- **`README.md` says the skill takes any mix of sources** and explains what each weight proves.
|
|
162
|
+
|
|
163
|
+
## 3.1.3
|
|
164
|
+
|
|
165
|
+
### Changed
|
|
166
|
+
|
|
167
|
+
- **The Node floor is `>=22.14`, where the APIs it rests on are stable.** The floor was `>=22`,
|
|
168
|
+
which is where `fs.promises.glob` first appeared — the function `src/config.js` expands the
|
|
169
|
+
corpus and finds document sets with. It stayed experimental until 22.14.0, and `fs.promises.cp`,
|
|
170
|
+
which `cnlp init` copies agent files with, until 22.3.0, so a run on a 22.0–22.13 runtime printed
|
|
171
|
+
an `ExperimentalWarning` the project cannot silence for its callers. The format, the profiles,
|
|
172
|
+
and the checker are unchanged.
|
|
173
|
+
|
|
174
|
+
## 3.1.2
|
|
175
|
+
|
|
176
|
+
First version published to the npm registry. `npm i -g cnlp-kit` replaces the GitHub tarball
|
|
177
|
+
install, so a consuming repository pins a semver range rather than a git ref. Nothing about the
|
|
178
|
+
format, the profiles, or the checker changes with it: the package has no build step and no runtime
|
|
179
|
+
dependency, and ships the same files it always did apart from `CHANGELOG.md`, which now travels
|
|
180
|
+
with the package so the npm page carries its own history. The source repository stays private —
|
|
181
|
+
what is public is the package, so the README carries no link to a place a reader cannot reach.
|
|
182
|
+
|
|
183
|
+
### Fixed
|
|
184
|
+
|
|
185
|
+
- **`cnlp --help` exits 0.** The usage text was printed with the exit code of a missing command,
|
|
186
|
+
so asking for help failed a shell that checks the status. A missing command still exits 1: an
|
|
187
|
+
invocation that names nothing is an error, and a request for the usage is not.
|
|
188
|
+
- **An API page stated a size the reference does not hold.** `entlong-unpack.md` claimed a handle
|
|
189
|
+
costs 8 bytes against 4 for an id and turned that into advice about loops; the claim is not in
|
|
190
|
+
the library's own documentation, and a worked example that ships as proof of the profiles states
|
|
191
|
+
only what its source states.
|
|
192
|
+
- **A pitfall named operations instead of the reason.** `concepts/component.md` listed a tag pool's
|
|
193
|
+
methods where the pitfall's own point is that a tag holds no value to read.
|
|
194
|
+
- **The broken fixture's description names the count it breaks.** It said 3 rules and breaks 2.
|
|
195
|
+
|
|
196
|
+
## 3.1.1
|
|
197
|
+
|
|
198
|
+
### Changed
|
|
199
|
+
|
|
200
|
+
- **the block `cnlp init` prints for an agent file is 3 lines, and was 5** — an installed skill
|
|
201
|
+
announces its own task through its `description:`, so the line naming the `cnlp-docset` and
|
|
202
|
+
`cnlp-migrate` skills stated what an agent already reads when a session starts. The
|
|
203
|
+
`profiles/<name>.md` line went with it: `npx cnlp print format`, which the line above it names,
|
|
204
|
+
is what delivers that. What is left is what no skill can carry, because a standing rule answers
|
|
205
|
+
to no task description.
|
|
206
|
+
|
|
207
|
+
## 3.1.0
|
|
208
|
+
|
|
209
|
+
A consistency pass: every rule the review found living outside `cnlp-format.md` moves in, and
|
|
210
|
+
`cnlp init` stops contradicting its own printed instructions.
|
|
211
|
+
|
|
212
|
+
### Changed
|
|
213
|
+
|
|
214
|
+
- **§7 states the `sections:` ordering rule.** "A record's `heading:` never names a heading
|
|
215
|
+
earlier than the heading of the record before it" was enforced by `test/profile.test.js` and
|
|
216
|
+
stated only in a `profiles/profile.md` note — a rule that escaped the standard. The note now
|
|
217
|
+
points at §7.
|
|
218
|
+
- **§5 records the `handle` split.** The deny-list row stands, but the checker's `DENY` pattern
|
|
219
|
+
does not read the word: the noun is an established domain term — an entity handle — that a
|
|
220
|
+
word-level pattern cannot tell from the verb, so the verb is left to review. The one verb use
|
|
221
|
+
in the example corpus is rewritten.
|
|
222
|
+
- **The docset enforcement line carries its condition everywhere.** `profiles/api.md`,
|
|
223
|
+
`concept.md` and `task.md` claimed reference resolution unconditionally; all three now state
|
|
224
|
+
"once the project declares `docsets:`", as `docset.md` already did.
|
|
225
|
+
|
|
226
|
+
### Fixed
|
|
227
|
+
|
|
228
|
+
- **`cnlp init` no longer recreates a deleted docsets directory.** It printed "a project
|
|
229
|
+
documenting no library deletes `docsets` and that directory", then recreated the directory on
|
|
230
|
+
the next run. An update run now creates it only when the config still carries the key.
|
|
231
|
+
- **A recorded empty agent choice repeats.** `"agents": []` read as "unrecorded", so a no-TTY
|
|
232
|
+
update run installed skills for every agent. An empty list is a choice and now repeats like
|
|
233
|
+
any other; only a missing config or key falls back to every agent.
|
|
234
|
+
- **The first-run message matches what the corpus can do.** When no known layout matched, `init`
|
|
235
|
+
wrote an example corpus and still printed "Next: run `cnlp check`" — a step that fails, since
|
|
236
|
+
the checker refuses a glob matching no file. The printed next step is now the edit.
|
|
237
|
+
- `AGENTS.md` step 4, `README.md` and `quality-rules.md` corrected where they misstated the
|
|
238
|
+
check's coverage, the adr block count, where the docset corpus entries go, and a byte-identity
|
|
239
|
+
test that never shipped.
|
|
240
|
+
|
|
241
|
+
## 3.0.0
|
|
242
|
+
|
|
243
|
+
Adoption is 1 command. 2.6.0 split it in 2 and got the default backwards: `cnlp skills` kept an
|
|
244
|
+
existing copy unless `--force` said otherwise, which made *stale* the normal outcome — and a skill
|
|
245
|
+
is versioned with the standard it teaches, so a copy from 2.6.0 instructs an agent in rules this
|
|
246
|
+
version changed. The skills also assumed 1 runtime, while both of them carry a Codex `invocation:`
|
|
247
|
+
line.
|
|
248
|
+
|
|
249
|
+
### Removed
|
|
250
|
+
|
|
251
|
+
- **`cnlp skills`.** Its work belongs to `cnlp init`, which is the breaking change this major
|
|
252
|
+
version is for. Nobody wants a config with no skills, or skills with no config.
|
|
253
|
+
|
|
254
|
+
### Added
|
|
255
|
+
|
|
256
|
+
- **`cnlp init` installs and updates.** It stops refusing when a config exists: on a second run it
|
|
257
|
+
rewrites the `agents` key it wrote itself, replaces every installed skill with the packaged one,
|
|
258
|
+
and leaves the corpus alone. Re-running it after an upgrade is what brings a project current.
|
|
259
|
+
- **A terminal menu of agent runtimes**, from `node:readline` and nothing else, ported from
|
|
260
|
+
`pure-typescript-reviewer`. Claude Code writes to `.claude/skills/`, Codex to `.agents/skills/`;
|
|
261
|
+
a runtime is 1 record in `AGENTS` in `src/config.js` and no branch anywhere else. The choice is
|
|
262
|
+
recorded in `cnlp.config.json`, so the next run is Enter.
|
|
263
|
+
- **A resolution order that never stops to ask when nothing can answer**: `--agents claude-code,codex`,
|
|
264
|
+
then the menu, then the recorded choice, then every agent. Git Bash under MinTTY reports no TTY
|
|
265
|
+
and neither does CI, so a run there repeats what the config holds rather than hanging on a menu
|
|
266
|
+
nothing can draw.
|
|
267
|
+
- **`cnlp check` reports skills an upgrade left behind**, reading the `.cnlp-version` stamp each
|
|
268
|
+
agent's skills directory carries. It reports and does not decide the exit code: a stale copy is
|
|
269
|
+
not a defect in a document the corpus names. The stamp is a sidecar file and never frontmatter —
|
|
270
|
+
`profiles/skill.md` declares the 2 fields a `SKILL.md` carries, and a third would fail the check
|
|
271
|
+
of any project whose corpus globs its own skills.
|
|
272
|
+
|
|
273
|
+
### Changed
|
|
274
|
+
|
|
275
|
+
- **`.claude/skills/*/SKILL.md` is no longer a corpus candidate.** With `init` writing this kit's
|
|
276
|
+
own skills there, proposing an entry over them would make a project check files it does not own
|
|
277
|
+
against its own local profile.
|
|
278
|
+
- **`README.md` states where the ownership line falls.** The package owns the skills and replaces
|
|
279
|
+
every copy; the project owns the config, its `custom_sections` and any local profile, and no
|
|
280
|
+
command here rewrites those. Without that sentence the new behaviour contradicts the rule.
|
|
281
|
+
|
|
282
|
+
## 2.6.0
|
|
283
|
+
|
|
284
|
+
Adoption stopped being a manual copy. 2.5.0 shipped 2 skills inside the package, where no agent
|
|
285
|
+
looks and no name resolves, and told the operator to copy them by hand — the same failure the zip
|
|
286
|
+
exporter had, arriving through a different door. `cnlp init` wrote a corpus naming files a project
|
|
287
|
+
may not have, so `cnlp check` failed on the first run and every adopter edited the config before
|
|
288
|
+
ever seeing it pass. And `cnlp-migrate` claimed to migrate a corpus while its body named skill
|
|
289
|
+
bodies in every block, so 8 of the 9 profiles had no skill at all.
|
|
290
|
+
|
|
291
|
+
### Added
|
|
292
|
+
|
|
293
|
+
- **`cnlp skills [--to <dir>] [--force]`** copies the packaged skills into `.claude/skills/`. It
|
|
294
|
+
keeps a copy already there unless `--force` says otherwise: the copy is the project's from the
|
|
295
|
+
moment it lands, and an upgrade of the package under it does not reach the operator's edits.
|
|
296
|
+
- **`cnlp init` reads the layout before it writes the corpus.** `proposeCorpus` in `src/config.js`
|
|
297
|
+
keeps the candidate entries that match a file — `AGENTS.md`, `CLAUDE.md`, `skills/*/SKILL.md`,
|
|
298
|
+
`docs/adr/*.md`, `docs/references/*.md`, the 4 docset globs — and names the count it found for
|
|
299
|
+
each. `checkProject` refuses a glob matching no file, so an entry no file answers is a config
|
|
300
|
+
that fails on its first run. Path convention only, never content: a decision record filed under
|
|
301
|
+
`docs/references/` reads as a reference until a human says otherwise.
|
|
302
|
+
|
|
303
|
+
### Changed
|
|
304
|
+
|
|
305
|
+
- **`cnlp-migrate` migrates any kind of document**, not a `SKILL.md`. Its body named skill bodies
|
|
306
|
+
in `purpose:`, `scope:` and every step, while §8's procedure is general and 8 other profiles
|
|
307
|
+
ship. It now groups documents by kind, reads the packaged profile nearest each kind, and writes
|
|
308
|
+
a new profile for a kind none of them fits — which is the profile contract's own promise that a
|
|
309
|
+
new kind of document costs 1 file and no code change.
|
|
310
|
+
- **`README.md` carries a guide**: install global against dev-dependency and when each one is
|
|
311
|
+
right, the 3 commands in order, the 2 scenarios end to end — convert what you have, document a
|
|
312
|
+
library — and a table of every command.
|
|
313
|
+
|
|
314
|
+
## 2.5.0
|
|
315
|
+
|
|
316
|
+
The kit stops serving 1 library. Everything since 2.1.0 was proven by hand-writing 21 pages for one
|
|
317
|
+
framework, and the rules that work produced reached the standard and the profiles in 2.4.0 — which
|
|
318
|
+
is what let the skill be written against the kit rather than against what its author remembered. A
|
|
319
|
+
docset skill written before that would have encoded the example.
|
|
320
|
+
|
|
321
|
+
### Added
|
|
322
|
+
|
|
323
|
+
- **`skills/cnlp-docset/SKILL.md`** — the skill that turns a library's sources and its existing
|
|
324
|
+
documentation into a conforming document set. It points at the standard and the 4 profiles rather
|
|
325
|
+
than restating their rules, and its order is the one the worked corpus was actually built in: the
|
|
326
|
+
closed catalog before any page, the running example's names before any example, `canonical_use:`
|
|
327
|
+
before the pages it routes to. No config or packaging change: `cnlp.config.json` already globs
|
|
328
|
+
`skills/*/SKILL.md` and `package.json` already ships `skills`.
|
|
329
|
+
- **`cnlp init` prints the block a project pastes into its agent file** — the lines pointing an
|
|
330
|
+
agent at `cnlp print format`, at `cnlp check` before a commit, at `cnlp docs`, and at the 2
|
|
331
|
+
skills. Printed and not written: `init` refuses to overwrite the config, and an agent file is the
|
|
332
|
+
same kind of file. This is the second half of backlog item 9, in its cheapest form.
|
|
333
|
+
- **`write` joins the canonical verb set in §5**, on the record as that section requires:
|
|
334
|
+
4 of the docset skill's steps open with it, and the set carried no verb for authoring a document.
|
|
335
|
+
|
|
336
|
+
### Changed
|
|
337
|
+
|
|
338
|
+
- **`test/profile.test.js` holds every packaged skill**, not 1 named one. A consumer's corpus checks
|
|
339
|
+
its own skills and never the ones inside `node_modules`, so this test is where a shipped skill
|
|
340
|
+
body is held.
|
|
341
|
+
- **`README.md`** gains both skills with what each one is for, and its install line pins the version
|
|
342
|
+
this entry ships. It pinned `v2.4.0` while no tag existed at all, so the documented install
|
|
343
|
+
command failed for every adopter.
|
|
344
|
+
|
|
345
|
+
## 2.4.1
|
|
346
|
+
|
|
347
|
+
The front door caught up. `README.md` had described the 2.0.0 package since 2.0.0: it pinned that
|
|
348
|
+
version in its install line, listed 5 shipped profiles where there are 9, named 4 commands without
|
|
349
|
+
`cnlp docs`, and said nothing about document sets — which is what every version since 2.1.0 added.
|
|
350
|
+
Merging that would have shipped a package contradicting its own contents. Documentation only; no
|
|
351
|
+
rule, profile or check changes.
|
|
352
|
+
|
|
353
|
+
### Changed
|
|
354
|
+
|
|
355
|
+
- **`README.md`** gains the 4 docset profiles in its table, a section on document sets naming the
|
|
356
|
+
`docsets` config key and `npx cnlp docs`, and a corrected account of its own corpus. Its "not here
|
|
357
|
+
yet" list now says `item_pattern:` carries 6 drivers rather than 2, and names the 3 rules of §9 a
|
|
358
|
+
review holds, so an unenforced rule reads as one without a trip to the backlog.
|
|
359
|
+
- **`cnlp init` writes a `docsets` key and creates the directory.** A key absent from the starter
|
|
360
|
+
reads as a capability that does not exist. `readConfig` rejects a `docsets` key naming a missing
|
|
361
|
+
directory, so writing one without the other would have produced a config that fails on first run.
|
|
362
|
+
- **`AGENTS.md` `read_first:` names `docs/DOCSETS.md`**, which has been the second working note an
|
|
363
|
+
editor of this repository needs since 2.1.0.
|
|
364
|
+
|
|
365
|
+
## 2.4.0
|
|
366
|
+
|
|
367
|
+
2.3.0 fixed a docset. It did not fix most of the rules that say how one is built: 5 of the 9 lessons
|
|
368
|
+
that work produced lived only as content under `examples/`, or only in `docs/DOCSETS.md`, which says
|
|
369
|
+
of itself that it is a working note. `examples/dragonecs/` had become the specification, which is
|
|
370
|
+
the failure this repository already rejected once when it dropped the zip exporter — a copy cannot
|
|
371
|
+
be upgraded, only overwritten. Nothing in `src/` or `examples/` changes: the corpus already obeyed
|
|
372
|
+
every rule written down here, which is the point. The rules were copied out of it.
|
|
373
|
+
|
|
374
|
+
### Added
|
|
375
|
+
|
|
376
|
+
- **§9 gains the rules a review holds**, beside the 4 a checker holds, the way §5 already splits the
|
|
377
|
+
enforced half of a limit from the reviewed half. A fact stated on one page of a set is not
|
|
378
|
+
restated on another, which is §6 reaching past the file it stops at. A set has 1 running example.
|
|
379
|
+
A name the entry document routes on reaches exactly 1 page. All 3 were found by reading a set: a
|
|
380
|
+
duplicated fact, 7 unrelated sets of type names, and 1 name routed to 3 pages.
|
|
381
|
+
- **`profiles/docset.md` says what `read_protocol:` has to contain** — the common case is written
|
|
382
|
+
from `canonical_use:`, a page opens for any call whose contract the reader lacks, and a step
|
|
383
|
+
telling the reader to stop reading is the defect. That sentence had to be deleted twice from a
|
|
384
|
+
written index and nothing had stopped it coming back.
|
|
385
|
+
- **`profiles/docset.md` says when a companion is loaded** — `when:` is "always" once the
|
|
386
|
+
companion's index carries `overrides:`, since a reader loading it on demand misses a correction to
|
|
387
|
+
a page it did not know was wrong.
|
|
388
|
+
- **The 3 page profiles require the set's names.** An `example:` is written in the names the set's
|
|
389
|
+
running example uses, so several pages compose into 1 program.
|
|
390
|
+
|
|
391
|
+
### Fixed
|
|
392
|
+
|
|
393
|
+
- **A deferred item restored.** The `status` vocabulary is review-only and fails open: an
|
|
394
|
+
unrecognised status reads as `covered` and sends a reader to a page that is absent. It was written
|
|
395
|
+
at 2.1.0 and lost when `docs/BACKLOG.md` was renumbered at 2.2.0. `docs/BACKLOG.md` item 1 now
|
|
396
|
+
carries it and the 3 other line-grammar rules the docset work added, so its 6 drivers are on the
|
|
397
|
+
record rather than implied.
|
|
398
|
+
- **`docs/DOCSETS.md` stops being the specification.** Every decision names the file that holds it
|
|
399
|
+
as a rule. A decision with no such pointer is now visible as a defect.
|
|
400
|
+
|
|
401
|
+
## 2.3.0
|
|
402
|
+
|
|
403
|
+
An index was a table of contents, which is enough for nothing. A reader holding one still had to
|
|
404
|
+
open most of the corpus before it knew the shape of a program, so the progression did not progress.
|
|
405
|
+
Breaking for a docset: an index without the 2 new blocks no longer conforms. Nothing else changes.
|
|
406
|
+
|
|
407
|
+
### Added
|
|
408
|
+
|
|
409
|
+
- **`canonical_use:` on the index** — 1 complete working use of the library, carrying every
|
|
410
|
+
load-bearing element. The common case is now written from the index alone. This is the block that
|
|
411
|
+
turns a routing document into a sufficient one.
|
|
412
|
+
- **`walkthrough:` on the index** — each part of that program and the page owning its detail. A
|
|
413
|
+
record-list and not comments inside the fence, because §3 makes a fence opaque, so a link written
|
|
414
|
+
there reaches no reader and no check.
|
|
415
|
+
- **`cnlp docs [<set>]`** — writes the index of every document set, the overridden set first.
|
|
416
|
+
Loading a companion stops being a second action anybody can forget, which is the failure the
|
|
417
|
+
`IEcsFixedRun` case showed costs a system that compiles, builds and never runs. A set is active
|
|
418
|
+
because it is present: a project vendors what it uses, so no second config key can disagree with
|
|
419
|
+
the files on disk.
|
|
420
|
+
- **`docsetsOf` and `readingOrder` in `src/config.js`.** `companions:` runs both ways and fixes no
|
|
421
|
+
order; `overrides:` does, so a set correcting another's pages is written after it.
|
|
422
|
+
|
|
423
|
+
### Changed
|
|
424
|
+
|
|
425
|
+
- **`read_protocol:` stops optimizing against reading.** It said "open the page the catalog names,
|
|
426
|
+
and open no other page" — a rule aimed at reading less, written when cost was still the goal. It
|
|
427
|
+
now says: write the common case from the index, open a page for any call whose contract you do not
|
|
428
|
+
hold, and **do not write a call whose contract you have not read**. An agent that stops reading too
|
|
429
|
+
early is the defect, not one that reads a second page.
|
|
430
|
+
- **`examples/dragonecs/api/pool-access.md` is merged into `api/pool-mutate.md`.** Reaching a pool
|
|
431
|
+
and changing a component through it is 1 flow, and the split had put the same fact in 2 files:
|
|
432
|
+
`concepts/component.md` and the deleted page both stated that `GetPool<T>` binds by marker
|
|
433
|
+
interface. §6 catches that inside a document and nothing catches it across one.
|
|
434
|
+
- **The catalog routes 1 symbol to 1 page.** `EcsPool<T>` had appeared in 3 records pointing at 3
|
|
435
|
+
pages, so an agent scanning for the most used type in the framework got 3 hits and no rule to
|
|
436
|
+
choose between them.
|
|
437
|
+
- **1 running example per docset.** Every fenced example is now a zoom into the program in
|
|
438
|
+
`canonical_use:`, with the same type and field names. They were 7 unrelated fragments that a
|
|
439
|
+
reader had to reconcile before writing anything.
|
|
440
|
+
- **`api/query.md` states the iteration hazard correctly.** It had claimed every structural change
|
|
441
|
+
invalidates an `EcsSpan`, which contradicts the framework's own examples. A span is a snapshot: a
|
|
442
|
+
change altering what the aspect matches is the hazard, and deleting entities is never safe.
|
|
443
|
+
|
|
444
|
+
## 2.2.0
|
|
445
|
+
|
|
446
|
+
§9, and the checker pass that holds it. The rules above were all about 1 document; this is the
|
|
447
|
+
first that needs a whole corpus at once. Additive: a project with no `docsets:` key in its
|
|
448
|
+
`cnlp.config.json` has no document set, and nothing about its run changes.
|
|
449
|
+
|
|
450
|
+
### Added
|
|
451
|
+
|
|
452
|
+
- **§9 page references.** A document set is a directory of documents that link to each other, a
|
|
453
|
+
page id is `<set>:<name>`, a bare name is local and a prefixed one crosses. `page:`, `by:` and
|
|
454
|
+
`docset:` are the only forms a reference takes: a name inside prose is a mention, and nothing
|
|
455
|
+
resolves it.
|
|
456
|
+
- **`pageRefs` in `src/cnlp.js`**, which reads references through the existing parser, so a `page:`
|
|
457
|
+
line inside a fenced example stays what §3 says it is — opaque content, not a link.
|
|
458
|
+
- **`linkIssues` and `pageIdOf` in `src/config.js`**, the corpus pass: every reference resolves,
|
|
459
|
+
every `docset:` names a set that exists, a `by:` value carries no prefix, and every page except a
|
|
460
|
+
set's `index` is reached by at least 1 reference. It runs over the files `checkProject` already
|
|
461
|
+
read, so it costs no second pass over the disk.
|
|
462
|
+
- **the `docsets` key in `cnlp.config.json`**, naming the directory whose immediate subdirectories
|
|
463
|
+
are 1 set each. Without it none of §9 applies, which is what keeps the change additive.
|
|
464
|
+
|
|
465
|
+
### Fixed
|
|
466
|
+
|
|
467
|
+
- **`examples/dragonecs/` routed a reader into a document set that does not exist.** The first run
|
|
468
|
+
of the new pass reported it: the index named DragonECS-AutoInjections under `companions:`, which
|
|
469
|
+
means "load this", while no docset covers that package. It moved to `excluded:`, which means "not
|
|
470
|
+
covered here, and this is where to look instead". The distinction only became visible once
|
|
471
|
+
something resolved the name.
|
|
472
|
+
|
|
473
|
+
## 2.1.0
|
|
474
|
+
|
|
475
|
+
4 profiles for library documentation an agent reads, and the first worked corpus written against
|
|
476
|
+
them. No rule changed and no branch entered the checker, which is what the profile contract
|
|
477
|
+
promised: a new kind of document costs 1 profile. A document conforming to 2.0.0 still conforms.
|
|
478
|
+
|
|
479
|
+
### Added
|
|
480
|
+
|
|
481
|
+
- **`profiles/docset.md`, `concept.md`, `api.md` and `task.md`** — the 4 page kinds of a docset,
|
|
482
|
+
which is the documentation of 1 library, written for an agent that loads a page at a time rather
|
|
483
|
+
than a file that holds everything.
|
|
484
|
+
- **`catalog:` on the index — the closed list of what a library offers.** Every capability carries a
|
|
485
|
+
record, and `read_protocol:` tells the reader that a symbol absent from it is a symbol the library
|
|
486
|
+
does not have. That is what the block is for: a reader who cannot tell absence from omission
|
|
487
|
+
invents the call it wanted.
|
|
488
|
+
- **`status:` on a catalog record**, one of `covered`, `source` or `avoid`. Trimming a library's
|
|
489
|
+
offering is marking, never deleting: a capability removed from the documentation gets invented
|
|
490
|
+
again or found in the source and used anyway, while one marked `avoid` carries an `instead:`
|
|
491
|
+
naming what to write. Nothing checks the vocabulary yet; `docs/BACKLOG.md` item 1 carries it.
|
|
492
|
+
- **`companions:` on the index**, naming another docset, when to load it, and what it owns. A
|
|
493
|
+
library that is engine-agnostic in its core and used through an integration package in practice
|
|
494
|
+
would otherwise leave a reader to write the integration from nothing.
|
|
495
|
+
- **`supersedes` in the `see_also` relations**, for the page of a companion docset that replaces a
|
|
496
|
+
page of the one it extends.
|
|
497
|
+
- **`overrides:` on the index**, which `examples/dragonecs-unity/` forced. `supersedes` sits on the
|
|
498
|
+
replacing page, and the reader who needs the correction most is the one who never opens that page:
|
|
499
|
+
a system written against the core pipeline page compiles, builds and never runs under Unity,
|
|
500
|
+
because that page states 1 run call and Unity needs 3. The correction has to sit in the index,
|
|
501
|
+
which is loaded whether or not the task looks engine-related.
|
|
502
|
+
- **`tasks:` on the index.** A catalog keyed on capability routes a reader holding a symbol. A
|
|
503
|
+
reader holding a goal had nowhere to start, and 1 task page in the first docset turned out to be
|
|
504
|
+
reachable from nothing at all.
|
|
505
|
+
- **`concepts:` and `tasks:` are record-lists**, so every link in a docset is a `page:` value. A
|
|
506
|
+
resolver picking page names out of backticks inside a bullet is guessing.
|
|
507
|
+
- **the page name rule**: a name crossing a docset carries the docset prefix and a bare name is
|
|
508
|
+
local, so an `overrides:` `page:` is always prefixed and its `by:` never is.
|
|
509
|
+
- **`excluded:` on the index**, for a whole region no page covers, with the reason.
|
|
510
|
+
- **`derived_from:` in `identity:`**, because a page written from prose documentation carries less
|
|
511
|
+
weight than one written from a signature, and a reader is entitled to know which it has.
|
|
512
|
+
- **`read_protocol:` on the index**, the block the rest rests on: it forbids inferring an overload,
|
|
513
|
+
a property or a default the pages do not state, and routes the reader to the source or to a
|
|
514
|
+
companion for everything the pages do not carry.
|
|
515
|
+
- **`choose:` on an API page**, the rule for picking 1 symbol out of a group. The worked corpus
|
|
516
|
+
needed it immediately — its subject declares 21 unpack calls that are 1 decision.
|
|
517
|
+
- **`see_also:` with a relation and a reason on every page**, so a reader decides whether to open a
|
|
518
|
+
page without opening it. Nothing resolves a page name to a file yet, so a broken link is caught by
|
|
519
|
+
review; `docs/BACKLOG.md` carries the item.
|
|
520
|
+
- **`examples/dragonecs/`**, 14 pages holding a real C# framework, and
|
|
521
|
+
**`examples/dragonecs-unity/`**, 8 pages holding the integration package that extends it. Both are
|
|
522
|
+
checked by the same `npx cnlp check` as everything else. The second one exists because a companion
|
|
523
|
+
package is where the design was wrong: `overrides:`, `tasks:` and the page name rule above all
|
|
524
|
+
came out of writing it, and none of the 3 was visible from the core docset alone. Neither corpus
|
|
525
|
+
ships — `files:` in `package.json` names neither.
|
|
526
|
+
|
|
527
|
+
### Fixed
|
|
528
|
+
|
|
529
|
+
- **a keyed-block declaring no `record_keys` is valid**, which `test/profile.test.js` rejected. §3
|
|
530
|
+
gives a keyed-block a second form — one verbatim fenced block, which carries no sub-keys — and the
|
|
531
|
+
standard's own `report_format:` example uses it. The checker always handled the form; no shipped
|
|
532
|
+
profile had used it, so the assertion outlived the rule it came from.
|
|
533
|
+
|
|
534
|
+
## 2.0.0
|
|
535
|
+
|
|
536
|
+
The §5 lexicon gains 4 rules, 2 of them mechanical. A document that conformed to 1.0.0 can fail
|
|
537
|
+
2.0.0, and that is what the major number is for: the format carries its own version so a change to
|
|
538
|
+
what conforms is visible from outside the project that ships it.
|
|
539
|
+
|
|
540
|
+
### Added
|
|
541
|
+
|
|
542
|
+
- **the active voice, in an imperative document only.** `mood:` was a register the checker never
|
|
543
|
+
read. It now gates 1 rule: a form of `be` with an `-ed` participle names no actor, and an imperative
|
|
544
|
+
body is addressed to whoever executes it. A `declarative` body is left alone, because the actor of
|
|
545
|
+
`a reference file is loaded by path` is genuinely nobody, and a participle naming a state —
|
|
546
|
+
`is required`, `is unchanged` — is exempt.
|
|
547
|
+
- **the light-verb construction.** `make a decision` is `decide` carrying 2 extra words and no verb of
|
|
548
|
+
its own. It is the shape prose keeps when a migration converts it a line at a time, so the rule
|
|
549
|
+
faces incoming documents rather than the corpus here, which never carried one.
|
|
550
|
+
- **one part of speech per term**, as a rule for review. `check the corpus` and `run the check` read
|
|
551
|
+
as 1 term and are 2. Telling a verb from a noun needs a parser and the checker is regular
|
|
552
|
+
expressions over lines, so §5 says so rather than implying the checker holds it. The first document
|
|
553
|
+
the rule caught was the standard itself — see Changed.
|
|
554
|
+
- **a growth policy for the canonical verbs**, and the 10 verbs the missing policy had cost. The set
|
|
555
|
+
was authored for 1 kind of document and this repository's own steps had already outrun it by `copy`,
|
|
556
|
+
`list`, `map`, `fill`, `pick`, `make`, `rewrite`, `tick`, `measure` and `repeat`. The set binds a
|
|
557
|
+
step's opening word, and nothing enforces it yet: the opener is an intra-block line grammar, which
|
|
558
|
+
is the `item_pattern:` item in `docs/BACKLOG.md` — now with a second driver.
|
|
559
|
+
|
|
560
|
+
### Changed
|
|
561
|
+
|
|
562
|
+
- the standard says `the checker` for the program everywhere: `the check` as a noun was the first
|
|
563
|
+
catch of the one-part-of-speech rule, in the file that added the rule. `npx cnlp check` stays
|
|
564
|
+
untouched — a quoted command is data. `the list` went the same way once `list` joined the canonical
|
|
565
|
+
verbs, so the collection those paragraphs name is `the set`.
|
|
566
|
+
- `skills/cnlp-migrate/SKILL.md` lost 2 bullets that restated a rule another block owns (§6): the
|
|
567
|
+
behaviour boundary lived in `scope:` and in `forbidden_behaviors:` at once, and the one-skill-first
|
|
568
|
+
order lived in `forbidden_behaviors:` and in `workflow:` step 8 at once.
|
|
569
|
+
- `lexiconIssues(lines, mood)` takes the register. `bodyIssues` passes `profile.mood`; a caller
|
|
570
|
+
reaching `lexiconIssues` directly and passing nothing gets every rule that holds in either register.
|
|
571
|
+
- §7 lists `mood` among the values the checker reads, and `profiles/profile.md` says the same in its
|
|
572
|
+
`note:`. Both used to state that the checker never reads it.
|
|
573
|
+
- `AGENTS.md` and `skills/cnlp-migrate/SKILL.md` lost 10 agentless passives, each a step or a
|
|
574
|
+
prohibition that now names who acts, plus the 2 bullets above — the 2 files together shrank by 172
|
|
575
|
+
characters, so the rules cost the documents they govern nothing to satisfy.
|
|
576
|
+
- the standard grew 59 lines: 4 rules with their reasons, 1 table of replacements, and the
|
|
577
|
+
participles the active-voice rule leaves to review.
|
|
578
|
+
|
|
579
|
+
## 1.0.0
|
|
580
|
+
|
|
581
|
+
First release as a standalone repository.
|
|
582
|
+
|
|
583
|
+
### Where it came from
|
|
584
|
+
|
|
585
|
+
- the standard, the checker, and the `profile`, `skill` and `adr` profiles —
|
|
586
|
+
`ai-factory-adr-extension` 2.2.0, where CNL-P was written
|
|
587
|
+
- the `guide` and `reference` profiles — `pure-typescript-reviewer`, which authored them on top
|
|
588
|
+
of the 1.18.0 export and proved the format extends without touching the checker
|
|
589
|
+
|
|
590
|
+
### Added
|
|
591
|
+
|
|
592
|
+
- `cnlp.config.json` and `cnlp check`. A project's corpus used to be constants at the top of a
|
|
593
|
+
test file the exporter overwrote, so every adopter edited a file it did not own.
|
|
594
|
+
- `cnlp print <doc> [--path]`, the runtime-neutral way to reach the standard from a project.
|
|
595
|
+
It replaces `ai-factory adr format`, which only existed inside one extension.
|
|
596
|
+
- `cnlp init`.
|
|
597
|
+
- local profile resolution: a profile in the directory `cnlp.config.json` names resolves before
|
|
598
|
+
the packaged one, so a project's `custom_sections` survive every upgrade.
|
|
599
|
+
|
|
600
|
+
### Changed
|
|
601
|
+
|
|
602
|
+
- `resolveDoc(name, { roots })` takes the roots to search. The zip exporter used to rewrite two
|
|
603
|
+
path expressions in the checker with `String.replace` to retarget it.
|
|
604
|
+
- `loadProfile` caches on the resolved path, not the name, so a local and a packaged profile of
|
|
605
|
+
the same name are 2 entries.
|
|
606
|
+
- the standard no longer names `ai-factory` anywhere: the profile roster, the enforcer path, the
|
|
607
|
+
`format:` paragraph and every example were project-bound.
|
|
608
|
+
- `profiles/adr.md` states its severity as a policy a project applies, not as one CLI.
|
|
609
|
+
- `profiles/skill.md`, `guide.md` and `reference.md` ship with `custom_sections: - none`.
|
|
610
|
+
- `quality-rules.md` dropped its `[adr]` markers; the 3 marked lines are now written generically.
|
|
611
|
+
|
|
612
|
+
### Fixed
|
|
613
|
+
|
|
614
|
+
- `profiles/profile.md` pointed at `docs/cnlp-format.md` and a test that the export never
|
|
615
|
+
carried, so in the one repository that adopted it the file named a directory that did not
|
|
616
|
+
exist while its 3 siblings named the right one.
|
|
617
|
+
- the `bullet-list` example in §3 of the standard had been blanked and showed nothing.
|
|
618
|
+
|
|
619
|
+
### Not carried over
|
|
620
|
+
|
|
621
|
+
- `transitions:` and `status_footer:` in the skill profile, and its 24 ADR `custom_sections` —
|
|
622
|
+
lifecycle conventions of the project the format came from.
|
|
623
|
+
- the ADR template sentinels in `profiles/adr.md`'s `enforcement:`, which belong to that
|
|
624
|
+
project's template rather than to the profile.
|
|
625
|
+
- the zip exporter and its conformance test. A package replaces both.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 VirtualMaestro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|