documentation-engine 0.3.1__tar.gz → 0.4.0__tar.gz

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 (128) hide show
  1. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/CHANGELOG.md +24 -1
  2. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/PKG-INFO +11 -1
  3. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/README.md +10 -0
  4. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/README.md +2 -0
  5. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/agent-contract.md +9 -0
  6. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/architecture.md +17 -0
  7. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/client-integration.md +18 -10
  8. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/mcp-adapter.md +3 -0
  9. documentation_engine-0.4.0/docs/provider-snapshots.md +175 -0
  10. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/setup-guide.md +5 -0
  11. documentation_engine-0.4.0/examples/provider-snapshots/.docsystem.toml +30 -0
  12. documentation_engine-0.4.0/examples/provider-snapshots/docs/README.md +8 -0
  13. documentation_engine-0.4.0/examples/provider-snapshots/docs/service-contract.md +17 -0
  14. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/scripts/installed_cli_smoke.sh +46 -0
  15. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/__init__.py +1 -1
  16. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/cli.py +153 -0
  17. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/config.py +31 -0
  18. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/federated_projection.py +2 -0
  19. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/projection.py +261 -5
  20. documentation_engine-0.4.0/src/docsystem/provider.py +449 -0
  21. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/sections.py +16 -5
  22. documentation_engine-0.4.0/tests/test_provider.py +614 -0
  23. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/ISSUE_TEMPLATE/adoption-finding.yml +0 -0
  24. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  25. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/ISSUE_TEMPLATE/core-bug.yml +0 -0
  26. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/ISSUE_TEMPLATE/docs-pattern-request.yml +0 -0
  27. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/ISSUE_TEMPLATE/runtime-report.yml +0 -0
  28. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  29. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/copilot-instructions.md +0 -0
  30. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/workflows/ci.yml +0 -0
  31. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.github/workflows/release.yml +0 -0
  32. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/.gitignore +0 -0
  33. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/AGENTS.md +0 -0
  34. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/CLAUDE.md +0 -0
  35. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/CONTRIBUTING.md +0 -0
  36. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/LICENSE +0 -0
  37. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/SECURITY.md +0 -0
  38. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/adopter-reporting.md +0 -0
  39. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/adoption.md +0 -0
  40. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/assets/context-reduction.svg +0 -0
  41. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/context-delivery.md +0 -0
  42. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/context-efficiency.md +0 -0
  43. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/delivery-traceability.md +0 -0
  44. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/document-profiles.md +0 -0
  45. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/execution-admission.md +0 -0
  46. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/execution-handoff.md +0 -0
  47. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/federation.md +0 -0
  48. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/graph-health.md +0 -0
  49. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/idea-intake.md +0 -0
  50. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/knowledge-promotion.md +0 -0
  51. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/local-state-safety.md +0 -0
  52. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/metadata-inventory.md +0 -0
  53. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/program-plans.md +0 -0
  54. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/releasing.md +0 -0
  55. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/workspace-sources.md +0 -0
  56. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/workstream-branching.md +0 -0
  57. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/workstream-evidence.md +0 -0
  58. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/docs/workstream-lifecycle.md +0 -0
  59. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/execution-admission-request.json +0 -0
  60. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/execution-result.json +0 -0
  61. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/generic-adopter/.docsystem.toml +0 -0
  62. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/generic-adopter/README.md +0 -0
  63. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/generic-adopter/plan/README.md +0 -0
  64. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/generic-adopter/plan/design.md +0 -0
  65. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/generic-adopter/plan/review.md +0 -0
  66. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/generic-adopter/plan/templates/document-template.md +0 -0
  67. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/idea-intake-request.json +0 -0
  68. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/workstream-branch-template.md +0 -0
  69. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/examples/workstream-record.json +0 -0
  70. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/pyproject.toml +0 -0
  71. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/__main__.py +0 -0
  72. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/admission.py +0 -0
  73. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/catalog.py +0 -0
  74. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/change_plan.py +0 -0
  75. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/delivery.py +0 -0
  76. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/execution.py +0 -0
  77. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/federation.py +0 -0
  78. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/graph.py +0 -0
  79. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/health.py +0 -0
  80. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/intake.py +0 -0
  81. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/inventory.py +0 -0
  82. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/journal.py +0 -0
  83. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/lifecycle.py +0 -0
  84. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/maintenance.py +0 -0
  85. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/mcp_server.py +0 -0
  86. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/metadata.py +0 -0
  87. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/migration.py +0 -0
  88. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/profiles.py +0 -0
  89. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/program_plan.py +0 -0
  90. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/promotion.py +0 -0
  91. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/readiness.py +0 -0
  92. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/shared_finish.py +0 -0
  93. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/workspace.py +0 -0
  94. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/src/docsystem/workstream.py +0 -0
  95. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_admission.py +0 -0
  96. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_catalog.py +0 -0
  97. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_change_plan.py +0 -0
  98. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_change_plan_cli.py +0 -0
  99. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_cli.py +0 -0
  100. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_cli_platform.py +0 -0
  101. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_config.py +0 -0
  102. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_context_cli.py +0 -0
  103. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_delivery.py +0 -0
  104. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_execution_handoff.py +0 -0
  105. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_federated_projection.py +0 -0
  106. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_federated_write.py +0 -0
  107. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_federation.py +0 -0
  108. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_graph.py +0 -0
  109. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_health.py +0 -0
  110. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_intake.py +0 -0
  111. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_inventory.py +0 -0
  112. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_journal.py +0 -0
  113. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_lifecycle.py +0 -0
  114. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_maintenance.py +0 -0
  115. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_mcp_adapter.py +0 -0
  116. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_metadata.py +0 -0
  117. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_migration.py +0 -0
  118. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_profiles.py +0 -0
  119. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_program_plan.py +0 -0
  120. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_promotion.py +0 -0
  121. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_readiness.py +0 -0
  122. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_references_cli.py +0 -0
  123. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_release_workflows.py +0 -0
  124. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_sections.py +0 -0
  125. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_vertical.py +0 -0
  126. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_workspace.py +0 -0
  127. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/tests/test_workstream.py +0 -0
  128. {documentation_engine-0.3.1 → documentation_engine-0.4.0}/uv.lock +0 -0
@@ -4,6 +4,28 @@ All notable changes to Documentation Engine are documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.4.0] - 2026-08-09
8
+
9
+ ### Highlights
10
+
11
+ - External consumers can reconcile exact retained documentation generations
12
+ through a provider-neutral, privacy-safe contract without importing package
13
+ internals or reading generated projection files directly.
14
+ - Pinned comparison distinguishes content changes, relocation and genuine
15
+ entity absence while failing closed for unavailable, corrupt, unsupported or
16
+ incomplete provider evidence.
17
+
18
+ ### Added
19
+
20
+ - Opt-in, provider-neutral `provider snapshot` and `provider compare` commands
21
+ export bounded body-free observations from explicitly pinned immutable
22
+ generations and classify exact stable entities as relocated, changed,
23
+ missing or added.
24
+ - Projection schema 5 binds provider identity, visibility, advertised
25
+ capabilities, catalog completeness, coverage, document line counts and
26
+ explicit/generated anchor kind into the generation hash. Older generations
27
+ fail provider export as unsupported instead of receiving retroactive claims.
28
+
7
29
  ## [0.3.1] - 2026-07-19
8
30
 
9
31
  ### Fixed
@@ -197,7 +219,8 @@ documentation-engine` starts working only after the first successful release.
197
219
  - Measured context-reduction methodology and a reproducible consumer-install
198
220
  smoke test.
199
221
 
200
- [Unreleased]: https://github.com/Jafa7/DocumentationEngine/compare/v0.3.1...HEAD
222
+ [Unreleased]: https://github.com/Jafa7/DocumentationEngine/compare/v0.4.0...HEAD
223
+ [0.4.0]: https://github.com/Jafa7/DocumentationEngine/compare/v0.3.1...v0.4.0
201
224
  [0.3.1]: https://github.com/Jafa7/DocumentationEngine/compare/v0.3.0...v0.3.1
202
225
  [0.3.0]: https://github.com/Jafa7/DocumentationEngine/compare/v0.2.0...v0.3.0
203
226
  [0.2.0]: https://github.com/Jafa7/DocumentationEngine/compare/v0.1.2...v0.2.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: documentation-engine
3
- Version: 0.3.1
3
+ Version: 0.4.0
4
4
  Summary: Provider-neutral structured Markdown documentation engine.
5
5
  Project-URL: Repository, https://github.com/Jafa7/DocumentationEngine
6
6
  Project-URL: Documentation, https://github.com/Jafa7/DocumentationEngine/tree/main/docs
@@ -225,6 +225,7 @@ task rather than one mandatory process:
225
225
  | --- | --- | --- |
226
226
  | Core retrieval | Discover, read and inspect context/impact | Default for routine work |
227
227
  | Adoption | Connect or migrate an existing Markdown corpus | Setup and compatibility work |
228
+ | Provider reconciliation | Export or compare explicitly pinned, body-free generations | External consumers that retain stable documentation evidence |
228
229
  | Governed delivery | Roadmaps, admission, handoff and lifecycle evidence | Multi-stage, delegated or risk-bearing work |
229
230
  | Bounded mutation | Journaled managed-block synchronization and recovery | Explicitly approved mechanical writes |
230
231
  | Multi-source | Workspace selection and federation | Deliberate cross-project documentation queries |
@@ -342,6 +343,8 @@ docsystem migrate . --apply
342
343
  docsystem index . --write
343
344
  docsystem changes .
344
345
  docsystem changes . --json
346
+ docsystem provider snapshot GENERATION . --json
347
+ docsystem provider compare BEFORE AFTER . --json
345
348
  docsystem agent-instructions .
346
349
  docsystem agent-instructions . --json
347
350
  docsystem workspace list . --workspace /path/to/workspace
@@ -792,6 +795,13 @@ relations.
792
795
  hashed over both the derived content and a fingerprint of the projection-
793
796
  relevant configuration, then atomically selects the current generation.
794
797
  `index` checks freshness and `changes` reports changed documents and sections.
798
+ Projects that expose immutable documentation evidence to another consumer may
799
+ opt into `[provider]` identity and use `provider snapshot` or `provider compare`
800
+ with explicit retained generation hashes. These commands never select the
801
+ current pointer implicitly, never return Markdown bodies or absolute paths, and
802
+ distinguish unavailable/corrupt provider state from a genuinely missing
803
+ entity. See [pinned provider snapshots](docs/provider-snapshots.md) for the
804
+ versioned JSON, relocation and bounded-pagination contract.
795
805
  `read`, `context` and `impact` serve from the verified projection when it is
796
806
  current: verification re-hashes every included source byte-for-byte, checks the
797
807
  configuration fingerprint, and reconstructs the generation hash from the shards,
@@ -208,6 +208,7 @@ task rather than one mandatory process:
208
208
  | --- | --- | --- |
209
209
  | Core retrieval | Discover, read and inspect context/impact | Default for routine work |
210
210
  | Adoption | Connect or migrate an existing Markdown corpus | Setup and compatibility work |
211
+ | Provider reconciliation | Export or compare explicitly pinned, body-free generations | External consumers that retain stable documentation evidence |
211
212
  | Governed delivery | Roadmaps, admission, handoff and lifecycle evidence | Multi-stage, delegated or risk-bearing work |
212
213
  | Bounded mutation | Journaled managed-block synchronization and recovery | Explicitly approved mechanical writes |
213
214
  | Multi-source | Workspace selection and federation | Deliberate cross-project documentation queries |
@@ -325,6 +326,8 @@ docsystem migrate . --apply
325
326
  docsystem index . --write
326
327
  docsystem changes .
327
328
  docsystem changes . --json
329
+ docsystem provider snapshot GENERATION . --json
330
+ docsystem provider compare BEFORE AFTER . --json
328
331
  docsystem agent-instructions .
329
332
  docsystem agent-instructions . --json
330
333
  docsystem workspace list . --workspace /path/to/workspace
@@ -775,6 +778,13 @@ relations.
775
778
  hashed over both the derived content and a fingerprint of the projection-
776
779
  relevant configuration, then atomically selects the current generation.
777
780
  `index` checks freshness and `changes` reports changed documents and sections.
781
+ Projects that expose immutable documentation evidence to another consumer may
782
+ opt into `[provider]` identity and use `provider snapshot` or `provider compare`
783
+ with explicit retained generation hashes. These commands never select the
784
+ current pointer implicitly, never return Markdown bodies or absolute paths, and
785
+ distinguish unavailable/corrupt provider state from a genuinely missing
786
+ entity. See [pinned provider snapshots](docs/provider-snapshots.md) for the
787
+ versioned JSON, relocation and bounded-pagination contract.
778
788
  `read`, `context` and `impact` serve from the verified projection when it is
779
789
  current: verification re-hashes every included source byte-for-byte, checks the
780
790
  configuration fingerprint, and reconstructs the generation hash from the shards,
@@ -31,6 +31,8 @@ link to that owner rather than repeat commands or policy.
31
31
  recommendation, prerequisites and exact source-contract scope.
32
32
  - [Compact context delivery](context-delivery.md) — lossless range
33
33
  deduplication, inclusion reasons and diagnostics drill-down.
34
+ - [Pinned provider snapshots](provider-snapshots.md) — privacy-safe,
35
+ body-free export and comparison of explicit immutable generations.
34
36
  - [Bounded workstream evidence](workstream-evidence.md) — versioned completion
35
37
  criteria, corrective lineage and fail-closed finish evidence.
36
38
  - [Deterministic idea intake](idea-intake.md) — place an agent-interpreted idea
@@ -594,6 +594,15 @@ context the delta deliberately left out. `--since` and
594
594
  every rejected combination fails closed with no packet, so an agent never acts
595
595
  on a partially applied request.
596
596
 
597
+ When a separate consumer needs durable cross-process reconciliation rather
598
+ than a task packet, use `provider snapshot` or `provider compare` with explicit
599
+ retained generation hashes. Do not read `.docsystem/cache` directly and do not
600
+ interpret provider unavailability, corruption or incomplete coverage as a
601
+ missing document/section. Provider responses intentionally contain no Markdown
602
+ bodies; fetch authored content through `read` or `context` only when the task
603
+ requires it. The canonical contract is
604
+ [pinned provider snapshots](provider-snapshots.md).
605
+
597
606
  ## Report product issues without leaking adopter context
598
607
 
599
608
  When an agent finds a DocumentationEngine problem while working inside another
@@ -11,6 +11,7 @@ The core owns deterministic documentation retrieval mechanics:
11
11
  - inspectable context packets with explicit coverage and omissions;
12
12
  - impact and changed-section analysis;
13
13
  - versioned, sharded machine projections and diagnostics.
14
+ - body-free export and comparison of explicitly pinned provider generations.
14
15
 
15
16
  The package also ships optional extensions over that same core:
16
17
 
@@ -58,6 +59,7 @@ The capability groups are progressive, not an execution checklist:
58
59
  | --- | --- | --- |
59
60
  | Core discovery and retrieval | `readiness`, `catalog`, `validate`, `read`, `context`, `dependencies`, `references`, `impact`, `change-plan` | Default path for understanding and changing documentation-backed work |
60
61
  | Adoption and derived state | `migration-report`, `migrate`, `profile-check`, `index`, `changes`, `report` | Connecting an existing corpus, checking policy or refreshing disposable projections |
62
+ | Provider reconciliation | `provider snapshot`, `provider compare` | An external consumer needs exact body-free observations from one or two pinned generations |
61
63
  | Governed delivery | `roadmap`, `intake`, `admission`, `execution-handoff`, `execution-result`, `workstream`, `lifecycle`, `finish`, `promotion` | Genuinely multi-stage, delegated or risk-bearing work that requires bounded evidence |
62
64
  | Bounded mutation | `maintenance`, `maintenance-recover` | Explicitly approved mechanical synchronization with journal and recovery guarantees |
63
65
  | Multi-source operation | `workspace`, `federation` | A task that deliberately spans independently owned documentation sources |
@@ -94,6 +96,7 @@ Project policy may configure:
94
96
  - review policy;
95
97
  - graph-health advisory thresholds and required metadata fields;
96
98
  - projection retention;
99
+ - stable provider identity and exported visibility classification;
97
100
  - legacy path-relation migration and historical snapshot document types;
98
101
  - provider adapters.
99
102
 
@@ -179,6 +182,20 @@ direct Markdown with a visible diagnostic rather than serving mixed state.
179
182
  Coordinating multiple writers is a caller/orchestrator responsibility, not
180
183
  core engine behavior.
181
184
 
185
+ Provider reconciliation uses the same immutable generations but a different
186
+ verification mode from live reads. A provider generation binds stable provider
187
+ identity, visibility, supported capabilities, catalog completeness, coverage,
188
+ scope and body-free export boundaries into the manifest root. `provider
189
+ snapshot` and `provider compare` fully verify explicitly selected retained
190
+ generations without comparing them with live Markdown or using `current.json`;
191
+ historical drift is the evidence being requested. The provider model exposes
192
+ only IDs, canonical anchors, hashes, root-relative paths and line hints. Its
193
+ schema, deterministic cursor and byte/page bounds are independent from the
194
+ internal projection schema. See [pinned provider snapshots](provider-snapshots.md).
195
+ Portable comparison of complete exported snapshot artifacts is deliberately
196
+ deferred. Losing a retained operand requires an explicit full rebaseline; it
197
+ does not authorize heuristic reconstruction or an entity-absence conclusion.
198
+
182
199
  Retained generation manifests also drive two token-economy `context` modes
183
200
  that omit content only when omission is provably safe, never as a silent
184
201
  budget cut. `--assume-known ID@REV` is a client-declared cache: an agent
@@ -35,14 +35,16 @@ adoption-oriented, read-only commands:
35
35
  - `docsystem catalog PROJECT --explain --json`
36
36
  - `docsystem changes PROJECT --json`
37
37
  - `docsystem context DOCUMENT_ID PROJECT --json`
38
+ - `docsystem provider snapshot GENERATION PROJECT --json`
39
+ - `docsystem provider compare BEFORE AFTER PROJECT --json`
38
40
 
39
- Each prints one deterministic JSON object to stdout (sorted keys, stable
40
- field names) carrying the same diagnostics that the text form prints as
41
- human `ERROR`/`WARNING` lines on stderr. In `--json` mode those human
42
- stderr diagnostics may be suppressed since the JSON payload already carries
43
- the same information in structured form, so a wrapper does not need to read
44
- stderr to make a decision. Exit codes are unchanged by `--json`: `0` on
45
- success or a ready project, `1` otherwise.
41
+ Each successful command prints one deterministic JSON object to stdout (sorted
42
+ keys and stable field names). For the adoption/context commands, structured
43
+ diagnostics may replace duplicate human `ERROR`/`WARNING` lines. Provider
44
+ snapshot/compare instead fail closed with a stable error code on stderr and no
45
+ stdout, because an unavailable generation must never resemble an entity result.
46
+ Exit codes are unchanged by `--json`: `0` on success or a ready project, `1`
47
+ otherwise.
46
48
 
47
49
  Every `--json` root is an object with a `"schema_version": 1` field; it is
48
50
  bumped only on a breaking change to an existing field, while new fields may
@@ -101,9 +103,15 @@ hash before comparison. `--since` and
101
103
  `--assume-known` are mutually exclusive, and neither combines with
102
104
  `--outline`; a rejected combination exits `1` with no stdout.
103
105
 
104
- A wrapper that speaks MCP can skip the CLI entirely and use
105
- [the MCP adapter](mcp-adapter.md), which exposes these same read-only
106
- commands as typed tools over the identical JSON contract.
106
+ A wrapper that speaks MCP can use [the MCP adapter](mcp-adapter.md) for its
107
+ document, context, graph and governance tools over the same core contracts.
108
+
109
+ Provider snapshot/compare responses use their own versioned, body-free schema
110
+ and bounded cursor contract. They require explicit retained generations and
111
+ never infer either operand from current Markdown or `current.json`. These two
112
+ commands are currently CLI-only. A wrapper must distinguish
113
+ provider/generation failures on stderr from `missing` inside a successful
114
+ comparison; see [pinned provider snapshots](provider-snapshots.md).
107
115
 
108
116
  `docsystem readiness PROJECT --json` is the entry point for an adoption
109
117
  sequence: its `next_command` field names the single safe next command for
@@ -60,6 +60,9 @@ The adapter is deliberately a wrapper, not a second implementation:
60
60
  `maintenance-recover`) intentionally have no tools and stay
61
61
  with the human or calling system, matching
62
62
  [the agent contract](agent-contract.md);
63
+ - pinned `provider snapshot` and `provider compare` are currently CLI-only.
64
+ An MCP wrapper may be added later only as a thin transport over the same
65
+ bounded, body-free contract; clients must not inspect projection files;
63
66
  - a non-zero CLI exit becomes a tool error carrying the CLI's stderr
64
67
  diagnostics, so a client never mistakes a failure for data. The one
65
68
  exception is `readiness`, whose "not ready" state is a legitimate answer:
@@ -0,0 +1,175 @@
1
+ # Pinned provider snapshots
2
+
3
+ Pinned provider snapshots let an external consumer reconcile two exact states
4
+ of a Documentation Engine catalog without importing package internals or
5
+ reading `.docsystem/cache` directly. The surface is read-only, body-free and
6
+ provider-neutral.
7
+
8
+ This contract answers a different question from `docsystem changes`:
9
+
10
+ - `changes` compares live Markdown with the generation selected by
11
+ `current.json`;
12
+ - `provider snapshot` exports observations from one explicitly named immutable
13
+ generation;
14
+ - `provider compare` compares two explicitly named immutable generations and
15
+ does not substitute the current pointer for either operand.
16
+
17
+ ## Opt-in provider identity
18
+
19
+ Configure a stable identity before building generations intended for external
20
+ reconciliation:
21
+
22
+ ```toml
23
+ [provider]
24
+ id = "example-docs"
25
+ visibility = "private"
26
+
27
+ [projection]
28
+ format = "sharded-json"
29
+ keep_generations = 4
30
+ ```
31
+
32
+ `provider.id` accepts 1–128 lowercase letters, digits, `.`, `_` and `-`.
33
+ `visibility` is `private` by default and may be set to `public`; it is an
34
+ exported classification, not an access-control mechanism. Filesystem,
35
+ sandbox, service and transport policy still control who can invoke the CLI.
36
+
37
+ Provider configuration is optional for all existing commands. The provider
38
+ commands fail closed with `provider-not-configured` when the ID is absent.
39
+ Never derive the ID from an absolute path, host name or repository remote.
40
+
41
+ Run `docsystem index PROJECT --write` after configuring the provider. Each new
42
+ projection generation binds the provider ID, visibility, capabilities,
43
+ catalog-completeness evidence, coverage and fixed export boundaries into its
44
+ content hash. Generations created by older projection schemas do not acquire
45
+ those claims retroactively and are reported as `generation-unsupported`.
46
+
47
+ ## Export one pinned generation
48
+
49
+ ```bash
50
+ docsystem provider snapshot GENERATION PROJECT --json
51
+ docsystem provider snapshot GENERATION PROJECT --json \
52
+ --page-size 100 --cursor CURSOR
53
+ ```
54
+
55
+ `GENERATION` is a full retained generation hash or an unambiguous prefix of at
56
+ least twelve characters. It is required; the command never selects
57
+ `current.json` implicitly.
58
+
59
+ The versioned response identifies the provider and generation, advertises
60
+ capabilities, states coverage/scope/boundaries, and returns a page of stable
61
+ document and section observations. Each observation contains only:
62
+
63
+ - `document_id` and canonical `anchor` (`null` for a document);
64
+ - `anchor_kind` (`explicit` or `generated`) for a section;
65
+ - exact content hash;
66
+ - documentation-root-relative POSIX path;
67
+ - one-based inclusive line hints;
68
+ - configured visibility.
69
+
70
+ Markdown bodies, titles, metadata values, relations, excluded paths, absolute
71
+ paths and projection locations are not exported. Explicit anchors provide the
72
+ strongest stable section identity. A generated anchor remains canonical for
73
+ that generation, but changing its heading may produce a missing/added pair
74
+ rather than an inferred match; the engine does not use title similarity.
75
+
76
+ ## Compare two pinned generations
77
+
78
+ ```bash
79
+ docsystem provider compare BEFORE AFTER PROJECT --json
80
+ docsystem provider compare BEFORE AFTER PROJECT --json \
81
+ --page-size 100 --cursor CURSOR
82
+ ```
83
+
84
+ Both operands are verified independently and may be retained historical
85
+ generations. They do not need to match live Markdown or the current pointer.
86
+ They must belong to the configured provider and advertise the same supported
87
+ capability.
88
+
89
+ The comparison uses the exact key `(kind, document_id, canonical_anchor)`:
90
+
91
+ | Classification | Meaning |
92
+ | --- | --- |
93
+ | `relocated` | Identity and content hash are unchanged, but path or line hints changed |
94
+ | `changed` | Identity exists on both sides and its content hash changed |
95
+ | `missing` | Identity exists only in `BEFORE` |
96
+ | `added` | Identity exists only in `AFTER` |
97
+
98
+ Every change carries the exact body-free `before` and `after` observation when
99
+ that side exists. A content change takes precedence over relocation, while the
100
+ two observations still expose any simultaneous location change. The summary
101
+ also counts unchanged entities. Valid Documentation Engine catalogs prevent
102
+ duplicate stable keys; ambiguity is never used to disguise corruption or an
103
+ incomplete catalog.
104
+
105
+ ## Integrity and availability
106
+
107
+ Pinned export verifies the selector, projection schema, manifest-to-generation
108
+ hash, provider capability descriptor, completeness evidence, document coverage
109
+ and every stored document/reverse/reference shard hash. It deliberately does
110
+ not compare historical source hashes with live Markdown: a retained generation
111
+ is immutable historical evidence and is expected to differ from current files.
112
+
113
+ Failures return exit code `1`, write no stdout, and use a stable code in stderr,
114
+ for example `ERROR [generation-corrupt]: ...`. Important distinctions include:
115
+
116
+ - `provider-unavailable`: generation storage cannot be read;
117
+ - `generation-unknown`: the requested retained generation does not exist;
118
+ - `generation-selector-ambiguous`: a prefix selects more than one generation;
119
+ - `generation-corrupt`: bound manifest or shard evidence is invalid;
120
+ - `generation-unsupported`: the generation lacks this versioned capability;
121
+ - `generation-incomplete`: catalog or coverage completeness cannot be proved;
122
+ - `provider-mismatch`: generation identity differs from configured identity;
123
+ - `page-invalid` / `page-too-large`: pagination evidence is invalid or cannot
124
+ fit the bounded response.
125
+
126
+ Provider unavailability and corrupt/incomplete snapshots are never represented
127
+ as missing entities.
128
+
129
+ ## Pagination and deterministic bytes
130
+
131
+ Pages default to 100 entities, accept 1–500, and never exceed 262,144 UTF-8
132
+ bytes. The response may return fewer than the requested count to respect the
133
+ byte limit. If one observation cannot fit, the command fails instead of
134
+ truncating a field. `next_cursor` is bound to the response kind and exact
135
+ generation operand(s); using it for another query fails closed.
136
+
137
+ Following `next_cursor` until `null` reconstructs the complete ordered result
138
+ without loss or duplication. Repeating the same pinned request produces the
139
+ same sorted JSON bytes with one trailing newline.
140
+
141
+ Retention controls availability. Set `projection.keep_generations` high enough
142
+ for the consumer's reconciliation window, or archive the body-free exported
143
+ responses in the consumer. If either comparison generation has been evicted,
144
+ the provider fails with `generation-unknown`/unavailable. The consumer must
145
+ perform an explicit full rebaseline from a newly selected complete generation
146
+ and record that the earlier delta chain ended. Retention loss is never evidence
147
+ that an entity was removed, and the engine does not reconstruct the missing
148
+ operand heuristically.
149
+
150
+ ## Deferred follow-up: portable snapshot artifacts
151
+
152
+ Portable comparison after provider retention expiry is a named follow-up, not
153
+ part of the first contract. A future command may accept complete exported
154
+ snapshot artifacts as operands, but must bind and verify their schema, provider
155
+ and generation identity, query/scope, coverage/completeness, complete ordered
156
+ observations and canonical artifact digest before applying the same comparison
157
+ semantics. It must reject partial page sets, mixed-query pages, tampering,
158
+ unsupported schemas and incompatible providers. Persisted pages from this
159
+ version are evidence for a consumer; they are not yet accepted back as
160
+ Documentation Engine comparison operands.
161
+
162
+ For v1, entity identity is exactly `(kind, document_id, canonical_anchor)`.
163
+ Moving the same document ID to another provider-relative path can be
164
+ `relocated`. Moving a section across document IDs is `missing` plus `added`,
165
+ even when its anchor and content match; cross-document similarity is not safe
166
+ structural identity and is not inferred.
167
+
168
+ The first contract is CLI-only. A service or MCP adapter may wrap these exact
169
+ read-only commands later, but it must preserve their integrity, privacy,
170
+ pagination and failure semantics rather than inspect projection files itself.
171
+
172
+ [`examples/provider-snapshots/`](../examples/provider-snapshots/) is a public
173
+ synthetic corpus with explicit anchors and an opt-in provider profile. Copy it
174
+ to a temporary directory, run `index --write`, make one source change and write
175
+ a second generation to exercise the commands without exposing adopter data.
@@ -177,6 +177,11 @@ format = "sharded-json"
177
177
  keep_generations = 2
178
178
  ```
179
179
 
180
+ Projects that expose immutable body-free observations to another consumer may
181
+ also configure an explicit `[provider]` identity. This is optional for ordinary
182
+ local use; see [pinned provider snapshots](provider-snapshots.md). Do not infer
183
+ the identity from a private filesystem path.
184
+
180
185
  Whole-graph smell policy is optional and should reflect the adopting project,
181
186
  not copied thresholds. With no thresholds, `graph-health` still reports the
182
187
  complete deterministic inventory and emits only intrinsic dead-link evidence:
@@ -0,0 +1,30 @@
1
+ version = 1
2
+
3
+ [documentation]
4
+ root = "docs"
5
+ language = "en"
6
+
7
+ [areas]
8
+ workspace = "."
9
+
10
+ [identifiers]
11
+ document = "DOC"
12
+
13
+ [catalog]
14
+ exclude = []
15
+
16
+ [navigation]
17
+ extend_through = []
18
+
19
+ [provider]
20
+ id = "example-docs"
21
+ visibility = "public"
22
+
23
+ [relations]
24
+ legacy_paths = "strict"
25
+ snapshot_types = []
26
+ snapshot_rules = []
27
+
28
+ [projection]
29
+ format = "sharded-json"
30
+ keep_generations = 4
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: DOC-001
3
+ revision: 1
4
+ ---
5
+
6
+ # Example documentation index
7
+
8
+ - [Service contract](service-contract.md)
@@ -0,0 +1,17 @@
1
+ ---
2
+ id: DOC-002
3
+ revision: 1
4
+ ---
5
+
6
+ # Service contract
7
+
8
+ <a id="purpose"></a>
9
+ ## Purpose
10
+
11
+ Define one synthetic service boundary.
12
+
13
+ <a id="constraints"></a>
14
+ ## Constraints
15
+
16
+ - Preserve stable identities across file relocation.
17
+ - Report unavailable provider evidence separately from missing entities.
@@ -130,6 +130,52 @@ run_cli_checks() {
130
130
  env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" init .
131
131
  env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" doctor .
132
132
  env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" show-config .
133
+
134
+ sed -i '/^\[provider\]$/a id = "installed-smoke"' .docsystem.toml
135
+ mkdir -p plan/foundation
136
+ cat > plan/foundation/README.md <<'MARKDOWN'
137
+ ---
138
+ id: DOC-001
139
+ revision: 1
140
+ ---
141
+ # Installed consumer fixture
142
+
143
+ <a id="contract"></a>
144
+ ## Contract
145
+
146
+ Original private-like fixture text that must not appear in provider output.
147
+ MARKDOWN
148
+ first_generation="$(
149
+ env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" index . --write \
150
+ | sed -n 's/^Projection generation written: //p'
151
+ )"
152
+ if [[ -z "${first_generation}" ]]; then
153
+ echo "error: installed provider smoke did not create the first generation" >&2
154
+ exit 1
155
+ fi
156
+ printf '\nA changed line.\n' >> plan/foundation/README.md
157
+ second_generation="$(
158
+ env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" index . --write \
159
+ | sed -n 's/^Projection generation written: //p'
160
+ )"
161
+ env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" provider snapshot \
162
+ "${first_generation}" . --json > provider-snapshot.json
163
+ env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" provider compare \
164
+ "${first_generation}" "${second_generation}" . --json \
165
+ > provider-compare.json
166
+ env -u PYTHONPATH -u PYTHONHOME "${venv_python}" - <<'PY'
167
+ import json
168
+ from pathlib import Path
169
+
170
+ snapshot_text = Path("provider-snapshot.json").read_text(encoding="utf-8")
171
+ comparison = json.loads(Path("provider-compare.json").read_text(encoding="utf-8"))
172
+ snapshot = json.loads(snapshot_text)
173
+ assert snapshot["kind"] == "provider-snapshot"
174
+ assert snapshot["snapshot"]["provider_id"] == "installed-smoke"
175
+ assert "Original private-like fixture text" not in snapshot_text
176
+ assert comparison["kind"] == "provider-compare"
177
+ assert comparison["summary"]["changed"] >= 1
178
+ PY
133
179
  )
134
180
  }
135
181
 
@@ -9,7 +9,7 @@ from docsystem.catalog import (
9
9
  from docsystem.metadata import DocumentMetadata, MetadataReference
10
10
  from docsystem.sections import MarkdownSection
11
11
 
12
- __version__ = "0.3.1"
12
+ __version__ = "0.4.0"
13
13
 
14
14
  __all__ = [
15
15
  "CatalogMembership",