agent-doc-system 1.0.0 → 1.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.
package/docs/MIGRATION.md CHANGED
@@ -41,6 +41,7 @@ independently:
41
41
  "counts": { "CONFIRMED": 4, "DERIVED": 38 },
42
42
  "contradictions": [ ... ],
43
43
  "documentationContradictions": [ ... ],
44
+ "normative": { "sections": [ { "path", "section", "heading", "sha256", "coveredBy" } ], "uncovered": [ ... ], "requirements": [ ... ] },
44
45
  "reviewedAmbiguity": [ ... ],
45
46
  "documentation": { "orphanDocs", "undocumentedComponents", "unverifiedComponents" },
46
47
  "contracts": { "inventory", "unclaimed" },
@@ -77,6 +78,64 @@ be checked at all.
77
78
  The rule for extending this: only check vocabulary the graph owns. A check that
78
79
  guesses is a check that cries wolf.
79
80
 
81
+ **These are the only automatic documentation checks.** The audit does not read
82
+ prose for meaning, so it does not find where an arbitrary sentence contradicts
83
+ the code. A specification saying "the verifier runtime is installed on the
84
+ production host" is invisible to it until someone turns that sentence into a
85
+ requirement — which is what the next section makes mandatory.
86
+
87
+ ### Normative requirements
88
+
89
+ A specification that is linked to a component is *routed*; that says nothing
90
+ about whether anyone checked the implementation against it. List the documents
91
+ that state obligations in `docs.normative`:
92
+
93
+ ```yaml
94
+ docs:
95
+ normative:
96
+ - specs/**
97
+ - verification_layer/*_PROFILE.md
98
+ ```
99
+
100
+ Every level-2 (`##`) section of those documents is then pinned by digest and
101
+ must be accounted for in one of two ways:
102
+
103
+ - **a requirement** on the component that must fulfil it, citing the section:
104
+
105
+ ```yaml
106
+ # provisioning/agentdoc.yaml
107
+ spec:
108
+ requirements:
109
+ - id: verification-runtime-on-host
110
+ key: requirement.provides.verification-runtime
111
+ value: provided
112
+ source:
113
+ path: specs/EXECUTION_LAYER_SPEC.md
114
+ section: 13-host-configuration
115
+ sha256: <digest from `agentdoc audit` → normative.sections>
116
+ satisfiedBy: [ansible]
117
+ expects:
118
+ installs: /var/lib/agent-platform-runtime/verification-python-v1
119
+ ```
120
+
121
+ - **an attestation** in `normativeCoverage` that the section carries no
122
+ implementation obligation (`disposition: no-implementation-obligation` or
123
+ `informative`), with a reason and a review condition.
124
+
125
+ A section that is neither raises `AGENTDOC_NORMATIVE_UNCOVERED`. A requirement
126
+ is an `AUTHORED` fact that can only be *corroborated*: until implementation
127
+ evidence on the same key agrees with it — a `DERIVED` fact from an adapter
128
+ named in `satisfiedBy` that finds what `expects` names (see `ADAPTERS.md`,
129
+ `ansible`), or a
130
+ `requirement-satisfaction` reviewed override citing the implementation — it is
131
+ `UNRESOLVED` and raises `AGENTDOC_REQUIREMENT_UNVERIFIED`, naming the adapter in
132
+ `satisfiedBy` that is missing. Implementation evidence that disagrees is a
133
+ conflict no authority rule may settle (see `AUTHORITY.md`). Editing a cited
134
+ section invalidates its requirement or attestation
135
+ (`AGENTDOC_NORMATIVE_SOURCE_STALE`): the review has to be redone.
136
+
137
+ A missing adapter lowers coverage; it never makes an obligation disappear.
138
+
80
139
  ### Reviewed ambiguity
81
140
 
82
141
  The list a human must work through:
@@ -88,6 +147,8 @@ The list a human must work through:
88
147
  | `UNCLAIMED_CONTRACT` | which API owns this contract, or is it dead? |
89
148
  | `REVIEWED_OVERRIDE` | is this interpretation still true? |
90
149
  | `NEGATED_COMPONENT`, `PORT_MISMATCH`, `UNLINKED_PORT_CLAIM` | which source is right? |
150
+ | `NORMATIVE_UNCOVERED` | what does this section oblige, and which component must do it? |
151
+ | `REQUIREMENT_UNVERIFIED` | where is the implementation — or is this a gap to fix before release? |
91
152
 
92
153
  ## CREATE
93
154
 
@@ -132,9 +193,12 @@ agentdoc audit > migration-report.json
132
193
 
133
194
  Then, in order:
134
195
 
135
- 1. **Source-of-truth mapping.** For each major claim, record which of the four
136
- inventories supports it. Anything supported by none goes to
137
- `reviewedAmbiguity`.
196
+ 1. **Source-of-truth mapping.** Configure `docs.normative`, then work
197
+ `normative.uncovered`: every section of every normative document becomes a
198
+ component requirement or a reviewed attestation. Prove each requirement
199
+ with implementation evidence, or leave it `REQUIREMENT_UNVERIFIED` for a
200
+ human. For other major claims, record which of the four inventories
201
+ supports them; anything supported by none goes to `reviewedAmbiguity`.
138
202
  2. **Contradiction detection.** Work `contradictions` and
139
203
  `documentationContradictions`. Each one needs a human decision: fix the
140
204
  documentation, fix the code, or record an authority rule saying which class
@@ -152,7 +216,11 @@ Then, in order:
152
216
  from a human everywhere else.
153
217
  7. **Catalog proposal.** `scaffold` lists what it would write.
154
218
  8. **Migration.** `scaffold --write`, then review every generated file.
155
- 9. **Validation.** `validate` → `compile` → `check`.
219
+ 9. **Validation.** `validate` → `compile` → `check --strict`. The strict gate
220
+ fails on every warning not accepted with pinned evidence, so a migration
221
+ cannot finish with an unreviewed normative section or an unproven
222
+ requirement. A known gap is accepted explicitly (`warningAcceptances`) and
223
+ stays `UNRESOLVED` in the audit.
156
224
 
157
225
  ### Do not trust the documentation
158
226
 
@@ -21,7 +21,7 @@ jobs:
21
21
  with: { node-version: '24' }
22
22
  - name: Install the agentdoc CLI
23
23
  # Unpinned tracks main. For CI reproducibility pin a tag or commit:
24
- # github:lbframe/agent-doc-system#v1.0.0
24
+ # github:lbframe/agent-doc-system#v1.1.0
25
25
  # A compiler upgrade intentionally invalidates committed graphs.
26
26
  run: npm install -g github:lbframe/agent-doc-system
27
27
  - name: Validate and compile
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-doc-system",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "Portable documentation and software-catalog system with an explicit authority model, for AI coding agents",
6
6
  "keywords": [
@@ -66,6 +66,46 @@
66
66
  }
67
67
  }
68
68
  },
69
+ "normativeCitation": {
70
+ "description": "One section of a configured normative document, pinned by the digest it had when it was reviewed. `agentdoc audit` lists every section with its current digest.",
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": ["path", "section", "sha256"],
74
+ "properties": {
75
+ "path": { "$ref": "#/$defs/repoPath" },
76
+ "section": { "type": "string", "minLength": 1, "maxLength": 200, "pattern": "^\\S+$" },
77
+ "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
78
+ }
79
+ },
80
+ "requirementKey": { "type": "string", "maxLength": 80, "pattern": "^requirement\\.[a-z0-9]+(?:[.-][a-z0-9]+)*$" },
81
+ "requirementValue": { "type": "string", "maxLength": 80, "pattern": "^[a-z0-9]+(?:[.-][a-z0-9]+)*$" },
82
+ "requirement": {
83
+ "description": "An implementation obligation a normative document places on this component. It is an AUTHORED fact that must be corroborated by implementation evidence on the same key; it never stands on its own word.",
84
+ "type": "object",
85
+ "additionalProperties": false,
86
+ "required": ["id", "key", "value", "source"],
87
+ "properties": {
88
+ "id": { "$ref": "#/$defs/name" },
89
+ "key": { "$ref": "#/$defs/requirementKey" },
90
+ "value": { "$ref": "#/$defs/requirementValue" },
91
+ "source": { "$ref": "#/$defs/normativeCitation" },
92
+ "satisfiedBy": {
93
+ "description": "Adapters able to derive the implementation side of this requirement. Named so a missing extractor is reported as such instead of as silence.",
94
+ "type": "array", "minItems": 1, "maxItems": 12, "uniqueItems": true,
95
+ "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" }
96
+ },
97
+ "expects": {
98
+ "description": "What an adapter in satisfiedBy must find for the requirement to be provided: a host path installed, or a service managed. Without it an adapter has nothing deterministic to compare.",
99
+ "type": "object",
100
+ "additionalProperties": false,
101
+ "oneOf": [{ "required": ["installs"] }, { "required": ["service"] }],
102
+ "properties": {
103
+ "installs": { "type": "string", "maxLength": 400, "pattern": "^/[^\\s{}]*[^\\s{}/]$" },
104
+ "service": { "type": "string", "maxLength": 200, "pattern": "^[A-Za-z0-9@._-]+$" }
105
+ }
106
+ }
107
+ }
108
+ },
69
109
  "warningAcceptance": {
70
110
  "type": "object",
71
111
  "additionalProperties": false,
@@ -27,7 +27,11 @@
27
27
  "description": "Published artifacts or remotes this component is consumed through.",
28
28
  "items": { "$ref": "common.json#/$defs/repoPath" }
29
29
  },
30
- "context": { "$ref": "common.json#/$defs/context" }
30
+ "context": { "$ref": "common.json#/$defs/context" },
31
+ "requirements": {
32
+ "type": "array", "minItems": 1, "maxItems": 64,
33
+ "items": { "$ref": "common.json#/$defs/requirement" }
34
+ }
31
35
  },
32
36
  "oneOf": [
33
37
  { "required": ["system"], "not": { "anyOf": [{ "required": ["domain"] }, { "required": ["placementRationale"] }] } },
@@ -358,7 +358,8 @@
358
358
  "capability",
359
359
  "component-placement",
360
360
  "event-producer",
361
- "event-consumer"
361
+ "event-consumer",
362
+ "requirement-satisfaction"
362
363
  ]
363
364
  },
364
365
  "subject": {
@@ -416,6 +417,12 @@
416
417
  "minLength": 1,
417
418
  "maxLength": 200
418
419
  },
420
+ "key": {
421
+ "$ref": "common.json#/$defs/requirementKey"
422
+ },
423
+ "value": {
424
+ "$ref": "common.json#/$defs/requirementValue"
425
+ },
419
426
  "reason": {
420
427
  "$ref": "common.json#/$defs/rationale"
421
428
  },
@@ -633,6 +640,59 @@
633
640
  ]
634
641
  }
635
642
  }
643
+ },
644
+ {
645
+ "if": {
646
+ "properties": {
647
+ "fact": {
648
+ "const": "requirement-satisfaction"
649
+ }
650
+ },
651
+ "required": [
652
+ "fact"
653
+ ]
654
+ },
655
+ "then": {
656
+ "required": [
657
+ "key",
658
+ "value"
659
+ ],
660
+ "not": {
661
+ "anyOf": [
662
+ {
663
+ "required": [
664
+ "target"
665
+ ]
666
+ },
667
+ {
668
+ "required": [
669
+ "transport"
670
+ ]
671
+ },
672
+ {
673
+ "required": [
674
+ "role"
675
+ ]
676
+ }
677
+ ]
678
+ }
679
+ },
680
+ "else": {
681
+ "not": {
682
+ "anyOf": [
683
+ {
684
+ "required": [
685
+ "key"
686
+ ]
687
+ },
688
+ {
689
+ "required": [
690
+ "value"
691
+ ]
692
+ }
693
+ ]
694
+ }
695
+ }
636
696
  }
637
697
  ]
638
698
  }
@@ -644,6 +704,51 @@
644
704
  "$ref": "common.json#/$defs/warningAcceptance"
645
705
  }
646
706
  },
707
+ "normativeCoverage": {
708
+ "description": "Reviewed attestations that a normative section carries no implementation obligation. Pinned by the section digest; a changed section invalidates its attestation and forces a fresh review.",
709
+ "type": "array",
710
+ "maxItems": 2048,
711
+ "items": {
712
+ "type": "object",
713
+ "additionalProperties": false,
714
+ "required": [
715
+ "path",
716
+ "section",
717
+ "sha256",
718
+ "disposition",
719
+ "reason",
720
+ "reviewWhen"
721
+ ],
722
+ "properties": {
723
+ "path": {
724
+ "$ref": "common.json#/$defs/repoPath"
725
+ },
726
+ "section": {
727
+ "type": "string",
728
+ "minLength": 1,
729
+ "maxLength": 200,
730
+ "pattern": "^\\S+$"
731
+ },
732
+ "sha256": {
733
+ "type": "string",
734
+ "pattern": "^[0-9a-f]{64}$"
735
+ },
736
+ "disposition": {
737
+ "enum": [
738
+ "no-implementation-obligation",
739
+ "informative"
740
+ ]
741
+ },
742
+ "reason": {
743
+ "$ref": "common.json#/$defs/rationale"
744
+ },
745
+ "reviewWhen": {
746
+ "type": "string",
747
+ "minLength": 12
748
+ }
749
+ }
750
+ }
751
+ },
647
752
  "output": {
648
753
  "type": "object",
649
754
  "additionalProperties": false,
@@ -678,6 +783,17 @@
678
783
  },
679
784
  "runbookDir": {
680
785
  "$ref": "common.json#/$defs/repoPath"
786
+ },
787
+ "normative": {
788
+ "description": "Globs of normative documents (specifications, technical profiles). Every level-2 section of a matched Markdown document must be cited by a component requirement or attested in normativeCoverage; otherwise AGENTDOC_NORMATIVE_UNCOVERED.",
789
+ "type": "array",
790
+ "minItems": 1,
791
+ "maxItems": 64,
792
+ "uniqueItems": true,
793
+ "items": {
794
+ "type": "string",
795
+ "minLength": 1
796
+ }
681
797
  }
682
798
  }
683
799
  }
@@ -96,7 +96,11 @@ not work around it: run `agentdoc compile`, review the diff, commit the graph.
96
96
  - **Never hand-edit `.agentdoc/graph.json`.** The gate rejects it, and it would
97
97
  be wrong anyway.
98
98
  - **Do not trust existing documentation.** In MIGRATE it is evidence of what
99
- someone once believed; the audit says where that belief contradicts the code.
99
+ someone once believed. The audit flags only a narrow set of contradictions
100
+ automatically (negated components, port claims); it does not read prose for
101
+ meaning. Obligations in specifications are checked only once declared:
102
+ configure `docs.normative`, turn every section into a component requirement
103
+ or a reviewed attestation, and finish with `agentdoc check --strict`.
100
104
 
101
105
  ## Deeper references
102
106
 
@@ -5,13 +5,18 @@ operates on a catalog can be run from any subdirectory of the repository: the
5
5
  configuration is found by walking up to `agentdoc/agentdoc.config.yaml`. No
6
6
  command ever needs the agentdoc source tree or a path to it.
7
7
 
8
- Exit codes: `0` ok, `1` failure, `2` usage.
8
+ Exit codes: `0` ok, `1` failure, `2` usage. Flags are declared per command:
9
+ an unknown or misspelled flag is a usage error (`2`), with a suggestion when
10
+ one is close — it is never silently ignored, so `check --strcit` cannot pass
11
+ for `check --strict`. `agentdoc <command> --help` lists exactly what a command
12
+ accepts.
9
13
 
10
14
  ## Meta
11
15
 
12
16
  ```bash
13
17
  agentdoc --version # installed version
14
- agentdoc --help # command list (also: agentdoc <command> --help)
18
+ agentdoc --help # command list
19
+ agentdoc <command> --help # every flag of one command (also: agentdoc help <command>)
15
20
  agentdoc doctor # machine check: is this CLI install healthy
16
21
  agentdoc doctor --project # the same, plus the current project's catalog health
17
22
  ```
@@ -42,13 +47,16 @@ failures as part of its output.
42
47
  ```bash
43
48
  agentdoc validate # sources + schemas + semantic checks
44
49
  agentdoc compile [--require-clean] # deterministic graph build, atomic write
45
- agentdoc check [--require-clean] [--allow-stale-observations]
50
+ agentdoc check [--strict] [--require-clean] [--allow-stale-observations]
46
51
  ```
47
52
 
48
53
  `compile` writes `.agentdoc/graph.json` (or the path in `output.graph`).
49
54
  `check` is the gate: it fails on a stale or hand-edited graph, a compiler or
50
55
  schema version mismatch, an observation past its declared `maxAgeDays`, and —
51
- with `--require-clean` — catalog inputs that differ from `HEAD`.
56
+ with `--require-clean` — catalog inputs that differ from `HEAD`. With
57
+ `--strict` it also fails on every warning not accepted in `warningAcceptances`
58
+ — the gate that ends a MIGRATE (unreviewed normative sections, unproven
59
+ requirements, orphan documents).
52
60
 
53
61
  ## Query and impact
54
62
 
@@ -81,8 +81,14 @@ agentdoc audit > migration-report.json
81
81
 
82
82
  Then, in order:
83
83
 
84
- 1. **Source-of-truth mapping.** For each major claim, record which inventory
85
- supports it. Anything supported by none goes to `reviewedAmbiguity`.
84
+ 1. **Source-of-truth mapping.** Set `docs.normative` to the specifications and
85
+ profiles, then empty `normative.uncovered`: each section becomes a
86
+ `spec.requirements` entry on the component that must fulfil it, or a
87
+ `normativeCoverage` attestation that it obliges nothing. Prove each
88
+ requirement (adapter evidence or a `requirement-satisfaction` override);
89
+ an unproven one stays `REQUIREMENT_UNVERIFIED`. For other major claims,
90
+ record which inventory supports them; anything supported by none goes to
91
+ `reviewedAmbiguity`.
86
92
  2. **Contradictions.** Work `contradictions` and `documentationContradictions`.
87
93
  Each needs a human decision: fix the docs, fix the code, or add an authority
88
94
  rule saying which class wins for that key.
@@ -91,7 +97,13 @@ Then, in order:
91
97
  5. **Stale contracts.** Point the API descriptor at the current contract file.
92
98
  6. **Ownership.** Placement from code where unambiguous, from a human elsewhere.
93
99
  7. **Catalog.** `scaffold --write`, review every generated file.
94
- 8. **Gate.** `validate` → `compile` → `check`, then install CI.
100
+ 8. **Gate.** `validate` → `compile` → `check --strict`, then install CI. Strict
101
+ fails on any unaccepted warning: an unreviewed section or an unproven
102
+ requirement cannot ship in a "complete" migration.
103
+
104
+ **The audit does not read prose for meaning.** It checks only negated
105
+ components and port claims automatically; every other documented obligation is
106
+ caught only if it is declared as a requirement.
95
107
 
96
108
  **Do not trust existing documentation.** The single most common migration
97
109
  failure is copying existing prose into descriptions. If you cannot write a
package/templates/ci.yml CHANGED
@@ -17,7 +17,7 @@ jobs:
17
17
  with: { node-version: '24' }
18
18
  - name: Install the agentdoc CLI
19
19
  # Unpinned tracks main. For CI reproducibility pin a tag or commit:
20
- # github:lbframe/agent-doc-system#v1.0.0
20
+ # github:lbframe/agent-doc-system#v1.1.0
21
21
  # A compiler upgrade intentionally invalidates committed graphs.
22
22
  run: npm install -g github:lbframe/agent-doc-system
23
23
  - name: Validate and compile