documentation-engine 0.4.0__tar.gz → 0.5.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 (131) hide show
  1. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/workflows/ci.yml +2 -1
  2. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/CHANGELOG.md +20 -1
  3. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/PKG-INFO +9 -1
  4. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/README.md +8 -0
  5. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/README.md +2 -0
  6. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/agent-contract.md +8 -0
  7. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/architecture.md +10 -1
  8. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/client-integration.md +9 -0
  9. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/mcp-adapter.md +3 -0
  10. documentation_engine-0.5.0/docs/provider-artifacts.md +133 -0
  11. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/provider-snapshots.md +5 -0
  12. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/setup-guide.md +3 -0
  13. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/scripts/installed_cli_smoke.sh +24 -0
  14. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/__init__.py +1 -1
  15. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/cli.py +148 -1
  16. documentation_engine-0.5.0/src/docsystem/provider_artifact.py +752 -0
  17. documentation_engine-0.5.0/tests/test_provider_artifact.py +324 -0
  18. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/ISSUE_TEMPLATE/adoption-finding.yml +0 -0
  19. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  20. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/ISSUE_TEMPLATE/core-bug.yml +0 -0
  21. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/ISSUE_TEMPLATE/docs-pattern-request.yml +0 -0
  22. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/ISSUE_TEMPLATE/runtime-report.yml +0 -0
  23. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  24. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/copilot-instructions.md +0 -0
  25. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.github/workflows/release.yml +0 -0
  26. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/.gitignore +0 -0
  27. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/AGENTS.md +0 -0
  28. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/CLAUDE.md +0 -0
  29. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/CONTRIBUTING.md +0 -0
  30. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/LICENSE +0 -0
  31. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/SECURITY.md +0 -0
  32. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/adopter-reporting.md +0 -0
  33. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/adoption.md +0 -0
  34. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/assets/context-reduction.svg +0 -0
  35. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/context-delivery.md +0 -0
  36. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/context-efficiency.md +0 -0
  37. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/delivery-traceability.md +0 -0
  38. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/document-profiles.md +0 -0
  39. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/execution-admission.md +0 -0
  40. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/execution-handoff.md +0 -0
  41. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/federation.md +0 -0
  42. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/graph-health.md +0 -0
  43. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/idea-intake.md +0 -0
  44. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/knowledge-promotion.md +0 -0
  45. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/local-state-safety.md +0 -0
  46. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/metadata-inventory.md +0 -0
  47. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/program-plans.md +0 -0
  48. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/releasing.md +0 -0
  49. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/workspace-sources.md +0 -0
  50. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/workstream-branching.md +0 -0
  51. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/workstream-evidence.md +0 -0
  52. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/docs/workstream-lifecycle.md +0 -0
  53. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/execution-admission-request.json +0 -0
  54. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/execution-result.json +0 -0
  55. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/generic-adopter/.docsystem.toml +0 -0
  56. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/generic-adopter/README.md +0 -0
  57. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/generic-adopter/plan/README.md +0 -0
  58. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/generic-adopter/plan/design.md +0 -0
  59. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/generic-adopter/plan/review.md +0 -0
  60. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/generic-adopter/plan/templates/document-template.md +0 -0
  61. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/idea-intake-request.json +0 -0
  62. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/provider-snapshots/.docsystem.toml +0 -0
  63. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/provider-snapshots/docs/README.md +0 -0
  64. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/provider-snapshots/docs/service-contract.md +0 -0
  65. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/workstream-branch-template.md +0 -0
  66. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/examples/workstream-record.json +0 -0
  67. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/pyproject.toml +0 -0
  68. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/__main__.py +0 -0
  69. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/admission.py +0 -0
  70. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/catalog.py +0 -0
  71. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/change_plan.py +0 -0
  72. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/config.py +0 -0
  73. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/delivery.py +0 -0
  74. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/execution.py +0 -0
  75. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/federated_projection.py +0 -0
  76. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/federation.py +0 -0
  77. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/graph.py +0 -0
  78. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/health.py +0 -0
  79. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/intake.py +0 -0
  80. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/inventory.py +0 -0
  81. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/journal.py +0 -0
  82. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/lifecycle.py +0 -0
  83. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/maintenance.py +0 -0
  84. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/mcp_server.py +0 -0
  85. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/metadata.py +0 -0
  86. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/migration.py +0 -0
  87. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/profiles.py +0 -0
  88. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/program_plan.py +0 -0
  89. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/projection.py +0 -0
  90. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/promotion.py +0 -0
  91. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/provider.py +0 -0
  92. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/readiness.py +0 -0
  93. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/sections.py +0 -0
  94. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/shared_finish.py +0 -0
  95. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/workspace.py +0 -0
  96. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/src/docsystem/workstream.py +0 -0
  97. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_admission.py +0 -0
  98. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_catalog.py +0 -0
  99. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_change_plan.py +0 -0
  100. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_change_plan_cli.py +0 -0
  101. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_cli.py +0 -0
  102. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_cli_platform.py +0 -0
  103. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_config.py +0 -0
  104. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_context_cli.py +0 -0
  105. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_delivery.py +0 -0
  106. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_execution_handoff.py +0 -0
  107. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_federated_projection.py +0 -0
  108. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_federated_write.py +0 -0
  109. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_federation.py +0 -0
  110. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_graph.py +0 -0
  111. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_health.py +0 -0
  112. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_intake.py +0 -0
  113. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_inventory.py +0 -0
  114. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_journal.py +0 -0
  115. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_lifecycle.py +0 -0
  116. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_maintenance.py +0 -0
  117. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_mcp_adapter.py +0 -0
  118. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_metadata.py +0 -0
  119. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_migration.py +0 -0
  120. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_profiles.py +0 -0
  121. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_program_plan.py +0 -0
  122. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_promotion.py +0 -0
  123. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_provider.py +0 -0
  124. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_readiness.py +0 -0
  125. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_references_cli.py +0 -0
  126. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_release_workflows.py +0 -0
  127. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_sections.py +0 -0
  128. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_vertical.py +0 -0
  129. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_workspace.py +0 -0
  130. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/tests/test_workstream.py +0 -0
  131. {documentation_engine-0.4.0 → documentation_engine-0.5.0}/uv.lock +0 -0
@@ -83,7 +83,8 @@ jobs:
83
83
  $env:TMP = $env:RUNNER_TEMP
84
84
  $env:TEMP = $env:RUNNER_TEMP
85
85
  uv run pytest tests/test_cli.py tests/test_cli_platform.py `
86
- tests/test_context_cli.py tests/test_mcp_adapter.py tests/test_readiness.py
86
+ tests/test_context_cli.py tests/test_mcp_adapter.py tests/test_readiness.py `
87
+ tests/test_provider_artifact.py
87
88
 
88
89
  - name: Installed CLI UTF-8 PowerShell smoke
89
90
  shell: pwsh
@@ -4,6 +4,24 @@ All notable changes to Documentation Engine are documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.5.0] - 2026-08-09
8
+
9
+ ### Highlights
10
+
11
+ - Adopters can consume one complete, immutable and body-free provider artifact
12
+ without implementing Documentation Engine pagination or importing package
13
+ internals.
14
+ - Standalone verification binds provider identity, exact retained generations,
15
+ scope, completeness, ordered entity evidence and a deterministic digest while
16
+ rejecting corrupt, partial or incompatible artifacts fail closed.
17
+
18
+ ### Added
19
+
20
+ - Complete `traceability-provider-v1` snapshot and comparison artifacts hide
21
+ provider pagination from adopters, bind deterministic digests and can be
22
+ verified without project state while preserving the retained-generation
23
+ boundary of the paged provider contract.
24
+
7
25
  ## [0.4.0] - 2026-08-09
8
26
 
9
27
  ### Highlights
@@ -219,7 +237,8 @@ documentation-engine` starts working only after the first successful release.
219
237
  - Measured context-reduction methodology and a reproducible consumer-install
220
238
  smoke test.
221
239
 
222
- [Unreleased]: https://github.com/Jafa7/DocumentationEngine/compare/v0.4.0...HEAD
240
+ [Unreleased]: https://github.com/Jafa7/DocumentationEngine/compare/v0.5.0...HEAD
241
+ [0.5.0]: https://github.com/Jafa7/DocumentationEngine/compare/v0.4.0...v0.5.0
223
242
  [0.4.0]: https://github.com/Jafa7/DocumentationEngine/compare/v0.3.1...v0.4.0
224
243
  [0.3.1]: https://github.com/Jafa7/DocumentationEngine/compare/v0.3.0...v0.3.1
225
244
  [0.3.0]: https://github.com/Jafa7/DocumentationEngine/compare/v0.2.0...v0.3.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: documentation-engine
3
- Version: 0.4.0
3
+ Version: 0.5.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
@@ -345,6 +345,9 @@ docsystem changes .
345
345
  docsystem changes . --json
346
346
  docsystem provider snapshot GENERATION . --json
347
347
  docsystem provider compare BEFORE AFTER . --json
348
+ docsystem provider export snapshot GENERATION . --output snapshot.json
349
+ docsystem provider export compare BEFORE AFTER . --output comparison.json
350
+ docsystem provider artifact verify snapshot.json --json
348
351
  docsystem agent-instructions .
349
352
  docsystem agent-instructions . --json
350
353
  docsystem workspace list . --workspace /path/to/workspace
@@ -802,6 +805,11 @@ current pointer implicitly, never return Markdown bodies or absolute paths, and
802
805
  distinguish unavailable/corrupt provider state from a genuinely missing
803
806
  entity. See [pinned provider snapshots](docs/provider-snapshots.md) for the
804
807
  versioned JSON, relocation and bounded-pagination contract.
808
+ For a durable process boundary, `provider export` assembles those pages into
809
+ one complete immutable artifact and `provider artifact verify` checks it
810
+ without project state. See
811
+ [complete provider artifacts](docs/provider-artifacts.md). Artifact verification
812
+ does not compare exported files or extend the configured retention window.
805
813
  `read`, `context` and `impact` serve from the verified projection when it is
806
814
  current: verification re-hashes every included source byte-for-byte, checks the
807
815
  configuration fingerprint, and reconstructs the generation hash from the shards,
@@ -328,6 +328,9 @@ docsystem changes .
328
328
  docsystem changes . --json
329
329
  docsystem provider snapshot GENERATION . --json
330
330
  docsystem provider compare BEFORE AFTER . --json
331
+ docsystem provider export snapshot GENERATION . --output snapshot.json
332
+ docsystem provider export compare BEFORE AFTER . --output comparison.json
333
+ docsystem provider artifact verify snapshot.json --json
331
334
  docsystem agent-instructions .
332
335
  docsystem agent-instructions . --json
333
336
  docsystem workspace list . --workspace /path/to/workspace
@@ -785,6 +788,11 @@ current pointer implicitly, never return Markdown bodies or absolute paths, and
785
788
  distinguish unavailable/corrupt provider state from a genuinely missing
786
789
  entity. See [pinned provider snapshots](docs/provider-snapshots.md) for the
787
790
  versioned JSON, relocation and bounded-pagination contract.
791
+ For a durable process boundary, `provider export` assembles those pages into
792
+ one complete immutable artifact and `provider artifact verify` checks it
793
+ without project state. See
794
+ [complete provider artifacts](docs/provider-artifacts.md). Artifact verification
795
+ does not compare exported files or extend the configured retention window.
788
796
  `read`, `context` and `impact` serve from the verified projection when it is
789
797
  current: verification re-hashes every included source byte-for-byte, checks the
790
798
  configuration fingerprint, and reconstructs the generation hash from the shards,
@@ -33,6 +33,8 @@ link to that owner rather than repeat commands or policy.
33
33
  deduplication, inclusion reasons and diagnostics drill-down.
34
34
  - [Pinned provider snapshots](provider-snapshots.md) — privacy-safe,
35
35
  body-free export and comparison of explicit immutable generations.
36
+ - [Complete provider artifacts](provider-artifacts.md) — transport-neutral,
37
+ self-verifying snapshot and comparison files for external consumers.
36
38
  - [Bounded workstream evidence](workstream-evidence.md) — versioned completion
37
39
  criteria, corrective lineage and fail-closed finish evidence.
38
40
  - [Deterministic idea intake](idea-intake.md) — place an agent-interpreted idea
@@ -603,6 +603,14 @@ bodies; fetch authored content through `read` or `context` only when the task
603
603
  requires it. The canonical contract is
604
604
  [pinned provider snapshots](provider-snapshots.md).
605
605
 
606
+ When another process needs durable provider evidence, prefer
607
+ `provider export snapshot` or `provider export compare` over implementing a
608
+ cursor loop in the adopter. Run `provider artifact verify FILE --json` before
609
+ import and bind the consumer record to the returned provider, generations and
610
+ digest. Verification does not require project state and does not authorize
611
+ comparison of exported files. See
612
+ [complete provider artifacts](provider-artifacts.md).
613
+
606
614
  ## Report product issues without leaking adopter context
607
615
 
608
616
  When an agent finds a DocumentationEngine problem while working inside another
@@ -59,7 +59,7 @@ The capability groups are progressive, not an execution checklist:
59
59
  | --- | --- | --- |
60
60
  | Core discovery and retrieval | `readiness`, `catalog`, `validate`, `read`, `context`, `dependencies`, `references`, `impact`, `change-plan` | Default path for understanding and changing documentation-backed work |
61
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 |
62
+ | Provider reconciliation | `provider snapshot`, `provider compare`, `provider export`, `provider artifact verify` | An external consumer needs exact body-free observations or one complete transport artifact from pinned generations |
63
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 |
64
64
  | Bounded mutation | `maintenance`, `maintenance-recover` | Explicitly approved mechanical synchronization with journal and recovery guarantees |
65
65
  | Multi-source operation | `workspace`, `federation` | A task that deliberately spans independently owned documentation sources |
@@ -196,6 +196,15 @@ Portable comparison of complete exported snapshot artifacts is deliberately
196
196
  deferred. Losing a retained operand requires an explicit full rebaseline; it
197
197
  does not authorize heuristic reconstruction or an entity-absence conclusion.
198
198
 
199
+ The `traceability-provider-v1` boundary adds complete snapshot and comparison
200
+ artifacts without exposing pagination mechanics to adopters. Export walks and
201
+ validates bounded pages internally, seals the complete ordered result with a
202
+ deterministic digest and writes it atomically. Standalone artifact verification
203
+ needs no project configuration or cache. It validates transport evidence only;
204
+ consumer-owned semantic relations, reconciliation and impact remain outside
205
+ Documentation Engine. See
206
+ [complete provider artifacts](provider-artifacts.md).
207
+
199
208
  Retained generation manifests also drive two token-economy `context` modes
200
209
  that omit content only when omission is provably safe, never as a silent
201
210
  budget cut. `--assume-known ID@REV` is a client-declared cache: an agent
@@ -37,6 +37,7 @@ adoption-oriented, read-only commands:
37
37
  - `docsystem context DOCUMENT_ID PROJECT --json`
38
38
  - `docsystem provider snapshot GENERATION PROJECT --json`
39
39
  - `docsystem provider compare BEFORE AFTER PROJECT --json`
40
+ - `docsystem provider artifact verify FILE --json`
40
41
 
41
42
  Each successful command prints one deterministic JSON object to stdout (sorted
42
43
  keys and stable field names). For the adoption/context commands, structured
@@ -113,6 +114,14 @@ commands are currently CLI-only. A wrapper must distinguish
113
114
  provider/generation failures on stderr from `missing` inside a successful
114
115
  comparison; see [pinned provider snapshots](provider-snapshots.md).
115
116
 
117
+ Do not reproduce provider pagination in an adopter when the integration needs
118
+ one durable import unit. Use `provider export snapshot` or
119
+ `provider export compare`; Documentation Engine assembles all pages and writes
120
+ a complete digest-bound artifact. The standalone verifier is the compatibility
121
+ gate, so a consumer checks protocol/schema/capability rather than tracking
122
+ package minor versions. See
123
+ [complete provider artifacts](provider-artifacts.md).
124
+
116
125
  `docsystem readiness PROJECT --json` is the entry point for an adoption
117
126
  sequence: its `next_command` field names the single safe next command for
118
127
  the project's current state (`init`, `doctor`, `migrate`, `index --write`, or
@@ -63,6 +63,9 @@ The adapter is deliberately a wrapper, not a second implementation:
63
63
  - pinned `provider snapshot` and `provider compare` are currently CLI-only.
64
64
  An MCP wrapper may be added later only as a thin transport over the same
65
65
  bounded, body-free contract; clients must not inspect projection files;
66
+ - complete `provider export` and standalone `provider artifact verify` are also
67
+ CLI-only. They form the transport-neutral file boundary for consumers that
68
+ should not own provider pagination mechanics;
66
69
  - a non-zero CLI exit becomes a tool error carrying the CLI's stderr
67
70
  diagnostics, so a client never mistakes a failure for data. The one
68
71
  exception is `readiness`, whose "not ready" state is a legitimate answer:
@@ -0,0 +1,133 @@
1
+ # Complete provider artifacts
2
+
3
+ Complete provider artifacts are the transport-neutral boundary between
4
+ Documentation Engine and an external traceability consumer. They remove the
5
+ need for an adopter to invoke paged commands repeatedly, validate cursors or
6
+ understand projection files. Documentation Engine owns that mechanical work;
7
+ the consumer receives one complete, body-free JSON artifact.
8
+
9
+ The capability name is `traceability-provider-v1`. It is generic: the
10
+ artifact describes documentation entities and changes only. Product logic,
11
+ code/test relations, reconciliation policy, attention queues and impact
12
+ semantics remain consumer responsibilities.
13
+
14
+ ## Export complete evidence
15
+
16
+ Build and retain the required projection generations first, then export them
17
+ explicitly:
18
+
19
+ ```bash
20
+ docsystem provider export snapshot GENERATION PROJECT \
21
+ --output snapshot.json
22
+
23
+ docsystem provider export compare BEFORE AFTER PROJECT \
24
+ --output comparison.json
25
+ ```
26
+
27
+ Both commands fully verify the selected retained generation or generations,
28
+ walk the existing bounded provider pages internally and require the pages to
29
+ reconstruct one complete ordered result. The output is written through a
30
+ temporary file and atomically selected only after assembly and self-
31
+ verification. An existing output path is never replaced.
32
+
33
+ Export remains subject to provider retention. An evicted generation fails as
34
+ unknown or unavailable and requires an explicit rebaseline. The command never
35
+ reconstructs an operand from current Markdown and never interprets provider
36
+ unavailability as entity absence.
37
+
38
+ ## Verify without project state
39
+
40
+ Any process with the artifact file can validate its integrity and supported
41
+ contract without a Documentation Engine project, provider cache or Python API:
42
+
43
+ ```bash
44
+ docsystem provider artifact verify snapshot.json --json
45
+ docsystem provider artifact verify comparison.json --json
46
+ ```
47
+
48
+ A valid artifact returns deterministic JSON with `valid: true`, its kind,
49
+ provider ID, pinned generation IDs, digest and item counts. Failure exits `1`,
50
+ writes no stdout and emits a stable code on stderr.
51
+
52
+ Important failure classes include:
53
+
54
+ - `artifact-corrupt`: malformed content, invalid entity evidence or digest
55
+ mismatch;
56
+ - `artifact-incomplete`: missing observations, changes, coverage or count
57
+ evidence;
58
+ - `artifact-mixed-provider`: inconsistent provider identities;
59
+ - `artifact-mixed-query`: incompatible scopes inside one comparison;
60
+ - `artifact-schema-unsupported`: unsupported artifact schema;
61
+ - `artifact-incompatible`: unsupported protocol, capability, kind or assembly
62
+ policy;
63
+ - `artifact-output-exists`: export refused to replace existing evidence;
64
+ - `artifact-write-failed`: the destination filesystem could not provide the
65
+ required atomic create operation.
66
+
67
+ The SHA-256 digest detects accidental or unauthorized content changes when the
68
+ expected digest is retained separately. It is not a digital signature and
69
+ does not establish who created the artifact. Transport authentication and
70
+ artifact provenance remain deployment responsibilities.
71
+
72
+ ## Artifact contract
73
+
74
+ Every artifact contains:
75
+
76
+ - `schema_version`: version of the JSON artifact layout;
77
+ - `artifact_kind`: snapshot or comparison artifact;
78
+ - `protocol`: `traceability-provider`, version `1`, with capability
79
+ `traceability-provider-v1`;
80
+ - `provider`: stable provider ID, provider contract version, visibility and
81
+ generation-advertised capabilities;
82
+ - `query`: exact pinned generation and scope identity;
83
+ - `completeness`: `complete: true`, coverage, boundaries and exact counts;
84
+ - `policy`: bounded-page assembly, complete-or-fail behavior, ordering and
85
+ body-omission policy;
86
+ - complete ordered `observations` or `changes`;
87
+ - `content_digest`: SHA-256 over canonical content excluding the digest field.
88
+
89
+ Snapshot observations contain stable kind/document/anchor identity, content
90
+ hash, provider-relative POSIX path, inclusive line hints, anchor kind and
91
+ visibility. Comparison changes contain `relocated`, `changed`, `missing` or
92
+ `added` plus exact before/after observations. Markdown bodies, headings,
93
+ metadata values, relations, absolute paths and projection locations are never
94
+ included.
95
+
96
+ The entity identity and change semantics are identical to the paged
97
+ [pinned provider contract](provider-snapshots.md). A consumer should store the
98
+ complete artifact as immutable evidence and import only fields it understands.
99
+
100
+ ## Compatibility policy
101
+
102
+ Consumers must negotiate the artifact, not the installed package release:
103
+
104
+ 1. Require protocol name `traceability-provider` and version `1`.
105
+ 2. Require capability `traceability-provider-v1`.
106
+ 3. Require a supported artifact `schema_version` and `artifact_kind`.
107
+ 4. Run `provider artifact verify` before import.
108
+ 5. Bind imported state to `provider.id`, exact generation IDs, query scope and
109
+ `content_digest`.
110
+
111
+ Within protocol version 1, Documentation Engine may add optional fields or
112
+ additional capabilities. Consumers must ignore unknown optional fields while
113
+ continuing to validate the required v1 fields. Existing field meanings,
114
+ identity rules, classifications and completeness semantics do not change
115
+ within v1. A breaking change requires a new protocol/schema version or a new
116
+ capability, so an adopter does not need to track Documentation Engine patch or
117
+ minor releases merely to decide whether an artifact is importable.
118
+
119
+ The paged `provider snapshot` and `provider compare` commands remain supported
120
+ for streaming clients. New adopters that need a durable process boundary
121
+ should prefer complete artifacts and should not read `.docsystem/cache`, shard
122
+ files or internal Python modules.
123
+
124
+ ## Deliberate boundary
125
+
126
+ Artifact verification does not enable Documentation Engine to compare two
127
+ previously exported files. `provider export compare` still selects two retained
128
+ provider generations and exports their verified comparison. Portable
129
+ comparison after provider retention expiry remains a separate future
130
+ capability; consumers must not infer it from `traceability-provider-v1`.
131
+
132
+ See [`examples/provider-snapshots/`](../examples/provider-snapshots/) for a
133
+ public synthetic provider fixture suitable for black-box integration tests.
@@ -169,6 +169,11 @@ The first contract is CLI-only. A service or MCP adapter may wrap these exact
169
169
  read-only commands later, but it must preserve their integrity, privacy,
170
170
  pagination and failure semantics rather than inspect projection files itself.
171
171
 
172
+ Adopters that need one durable process-boundary file instead of paged wire
173
+ responses should use [complete provider artifacts](provider-artifacts.md).
174
+ Documentation Engine assembles and verifies all pages internally while keeping
175
+ these paged commands backward compatible.
176
+
172
177
  [`examples/provider-snapshots/`](../examples/provider-snapshots/) is a public
173
178
  synthetic corpus with explicit anchors and an opt-in provider profile. Copy it
174
179
  to a temporary directory, run `index --write`, make one source change and write
@@ -181,6 +181,9 @@ Projects that expose immutable body-free observations to another consumer may
181
181
  also configure an explicit `[provider]` identity. This is optional for ordinary
182
182
  local use; see [pinned provider snapshots](provider-snapshots.md). Do not infer
183
183
  the identity from a private filesystem path.
184
+ External processes that need one durable import unit should use
185
+ [complete provider artifacts](provider-artifacts.md) instead of reproducing the
186
+ paged provider protocol.
184
187
 
185
188
  Whole-graph smell policy is optional and should reflect the adopting project,
186
189
  not copied thresholds. With no thresholds, `graph-health` still reports the
@@ -163,18 +163,42 @@ MARKDOWN
163
163
  env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" provider compare \
164
164
  "${first_generation}" "${second_generation}" . --json \
165
165
  > provider-compare.json
166
+ env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" provider export snapshot \
167
+ "${first_generation}" . --output provider-snapshot-artifact.json
168
+ env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" provider export compare \
169
+ "${first_generation}" "${second_generation}" . \
170
+ --output provider-compare-artifact.json
171
+ (
172
+ cd "${work_dir}"
173
+ env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" provider artifact verify \
174
+ "${project_dir}/provider-snapshot-artifact.json" --json \
175
+ > "${project_dir}/provider-snapshot-verification.json"
176
+ env -u PYTHONPATH -u PYTHONHOME "${docsystem_bin}" provider artifact verify \
177
+ "${project_dir}/provider-compare-artifact.json" --json \
178
+ > "${project_dir}/provider-compare-verification.json"
179
+ )
166
180
  env -u PYTHONPATH -u PYTHONHOME "${venv_python}" - <<'PY'
167
181
  import json
168
182
  from pathlib import Path
169
183
 
170
184
  snapshot_text = Path("provider-snapshot.json").read_text(encoding="utf-8")
171
185
  comparison = json.loads(Path("provider-compare.json").read_text(encoding="utf-8"))
186
+ snapshot_artifact_text = Path("provider-snapshot-artifact.json").read_text(encoding="utf-8")
187
+ compare_artifact_text = Path("provider-compare-artifact.json").read_text(encoding="utf-8")
172
188
  snapshot = json.loads(snapshot_text)
173
189
  assert snapshot["kind"] == "provider-snapshot"
174
190
  assert snapshot["snapshot"]["provider_id"] == "installed-smoke"
175
191
  assert "Original private-like fixture text" not in snapshot_text
176
192
  assert comparison["kind"] == "provider-compare"
177
193
  assert comparison["summary"]["changed"] >= 1
194
+ assert "Original private-like fixture text" not in snapshot_artifact_text
195
+ assert "Original private-like fixture text" not in compare_artifact_text
196
+ for name in ("snapshot", "compare"):
197
+ verification = json.loads(
198
+ Path(f"provider-{name}-verification.json").read_text(encoding="utf-8")
199
+ )
200
+ assert verification["kind"] == "provider-artifact-verification"
201
+ assert verification["valid"] is True
178
202
  PY
179
203
  )
180
204
  }
@@ -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.4.0"
12
+ __version__ = "0.5.0"
13
13
 
14
14
  __all__ = [
15
15
  "CatalogMembership",
@@ -196,6 +196,14 @@ from docsystem.provider import (
196
196
  encode_response,
197
197
  snapshot_response,
198
198
  )
199
+ from docsystem.provider_artifact import (
200
+ ProviderArtifactError,
201
+ compare_artifact,
202
+ encode_artifact,
203
+ load_and_verify_artifact,
204
+ snapshot_artifact,
205
+ write_artifact,
206
+ )
199
207
  from docsystem.readiness import evaluate_readiness
200
208
  from docsystem.sections import MarkdownSection, extract_navigation, extract_section
201
209
  from docsystem.shared_finish import SharedFinishError, load_shared_finish_record
@@ -4376,7 +4384,9 @@ def changes(project_root: Path, *, json_output: bool = False) -> int:
4376
4384
  return 1
4377
4385
 
4378
4386
 
4379
- def _provider_error(error: PinnedGenerationError | ProviderContractError) -> int:
4387
+ def _provider_error(
4388
+ error: PinnedGenerationError | ProviderContractError | ProviderArtifactError,
4389
+ ) -> int:
4380
4390
  print(f"ERROR [{error.code}]: {error}", file=sys.stderr)
4381
4391
  return 1
4382
4392
 
@@ -4450,6 +4460,73 @@ def provider_compare(
4450
4460
  return 1
4451
4461
 
4452
4462
 
4463
+ def provider_export_snapshot(
4464
+ project_root: Path, generation: str, *, output: Path
4465
+ ) -> int:
4466
+ """Write one complete immutable snapshot artifact from a pinned generation."""
4467
+
4468
+ try:
4469
+ config = load_config(project_root)
4470
+ if config.provider_id is None:
4471
+ raise ProviderContractError(
4472
+ "provider-not-configured",
4473
+ "provider.id is required for provider artifact export",
4474
+ )
4475
+ snapshot = load_pinned_projection(config, generation)
4476
+ write_artifact(output, snapshot_artifact(snapshot))
4477
+ print(f"Provider snapshot artifact written: {output}")
4478
+ return 0
4479
+ except (OSError, ValueError) as error:
4480
+ if isinstance(
4481
+ error,
4482
+ (PinnedGenerationError, ProviderContractError, ProviderArtifactError),
4483
+ ):
4484
+ return _provider_error(error)
4485
+ print(f"ERROR: {error}", file=sys.stderr)
4486
+ return 1
4487
+
4488
+
4489
+ def provider_export_compare(
4490
+ project_root: Path,
4491
+ before_generation: str,
4492
+ after_generation: str,
4493
+ *,
4494
+ output: Path,
4495
+ ) -> int:
4496
+ """Write one complete immutable comparison artifact from pinned generations."""
4497
+
4498
+ try:
4499
+ config = load_config(project_root)
4500
+ if config.provider_id is None:
4501
+ raise ProviderContractError(
4502
+ "provider-not-configured",
4503
+ "provider.id is required for provider artifact export",
4504
+ )
4505
+ before = load_pinned_projection(config, before_generation)
4506
+ after = load_pinned_projection(config, after_generation)
4507
+ write_artifact(output, compare_artifact(before, after))
4508
+ print(f"Provider compare artifact written: {output}")
4509
+ return 0
4510
+ except (OSError, ValueError) as error:
4511
+ if isinstance(
4512
+ error,
4513
+ (PinnedGenerationError, ProviderContractError, ProviderArtifactError),
4514
+ ):
4515
+ return _provider_error(error)
4516
+ print(f"ERROR: {error}", file=sys.stderr)
4517
+ return 1
4518
+
4519
+
4520
+ def provider_artifact_verify(path: Path) -> int:
4521
+ """Verify one complete artifact without loading project or provider state."""
4522
+
4523
+ try:
4524
+ sys.stdout.write(encode_artifact(load_and_verify_artifact(path)))
4525
+ return 0
4526
+ except ProviderArtifactError as error:
4527
+ return _provider_error(error)
4528
+
4529
+
4453
4530
  def _validation_summary(issues: tuple[ValidationIssue, ...]) -> dict[str, int]:
4454
4531
  summary = {
4455
4532
  "errors": 0,
@@ -8773,6 +8850,52 @@ def build_parser() -> argparse.ArgumentParser:
8773
8850
  )
8774
8851
  add_provider_page(provider_compare_parser)
8775
8852
 
8853
+ provider_export_parser = provider_subparsers.add_parser(
8854
+ "export", help="Assemble one complete immutable provider artifact."
8855
+ )
8856
+ provider_export_subparsers = provider_export_parser.add_subparsers(
8857
+ dest="provider_export_command", required=True
8858
+ )
8859
+ provider_export_snapshot_parser = provider_export_subparsers.add_parser(
8860
+ "snapshot", help="Export one complete pinned snapshot artifact."
8861
+ )
8862
+ provider_export_snapshot_parser.add_argument("generation")
8863
+ provider_export_snapshot_parser.add_argument(
8864
+ "project", nargs="?", type=Path, default=Path.cwd()
8865
+ )
8866
+ provider_export_snapshot_parser.add_argument(
8867
+ "--output", required=True, type=Path, metavar="FILE"
8868
+ )
8869
+ provider_export_compare_parser = provider_export_subparsers.add_parser(
8870
+ "compare", help="Export one complete pinned comparison artifact."
8871
+ )
8872
+ provider_export_compare_parser.add_argument("before_generation")
8873
+ provider_export_compare_parser.add_argument("after_generation")
8874
+ provider_export_compare_parser.add_argument(
8875
+ "project", nargs="?", type=Path, default=Path.cwd()
8876
+ )
8877
+ provider_export_compare_parser.add_argument(
8878
+ "--output", required=True, type=Path, metavar="FILE"
8879
+ )
8880
+
8881
+ provider_artifact_parser = provider_subparsers.add_parser(
8882
+ "artifact", help="Inspect a transport-neutral provider artifact."
8883
+ )
8884
+ provider_artifact_subparsers = provider_artifact_parser.add_subparsers(
8885
+ dest="provider_artifact_command", required=True
8886
+ )
8887
+ provider_artifact_verify_parser = provider_artifact_subparsers.add_parser(
8888
+ "verify", help="Verify artifact integrity and compatibility."
8889
+ )
8890
+ provider_artifact_verify_parser.add_argument("file", type=Path)
8891
+ provider_artifact_verify_parser.add_argument(
8892
+ "--json",
8893
+ action="store_true",
8894
+ required=True,
8895
+ dest="json_output",
8896
+ help="Print a deterministic verification result.",
8897
+ )
8898
+
8776
8899
  finish_parser = subparsers.add_parser(
8777
8900
  "finish",
8778
8901
  help="Build a compact handoff packet for returning work to a parent context.",
@@ -9054,6 +9177,8 @@ def build_parser() -> argparse.ArgumentParser:
9054
9177
  changes_parser,
9055
9178
  provider_snapshot_parser,
9056
9179
  provider_compare_parser,
9180
+ provider_export_snapshot_parser,
9181
+ provider_export_compare_parser,
9057
9182
  finish_parser,
9058
9183
  agent_instructions_parser,
9059
9184
  ):
@@ -9147,6 +9272,13 @@ def main() -> int:
9147
9272
  f"unknown federation command: {args.federation_command}"
9148
9273
  )
9149
9274
 
9275
+ if args.command == "provider" and args.provider_command == "artifact":
9276
+ if args.provider_artifact_command == "verify":
9277
+ return provider_artifact_verify(args.file)
9278
+ raise AssertionError(
9279
+ f"unknown provider artifact command: {args.provider_artifact_command}"
9280
+ )
9281
+
9150
9282
  selection = _resolve_selection(args)
9151
9283
  if selection is None:
9152
9284
  return 1
@@ -9337,6 +9469,21 @@ def main() -> int:
9337
9469
  cursor=args.cursor,
9338
9470
  page_size=args.page_size,
9339
9471
  )
9472
+ if args.provider_command == "export":
9473
+ if args.provider_export_command == "snapshot":
9474
+ return provider_export_snapshot(
9475
+ project, args.generation, output=args.output
9476
+ )
9477
+ if args.provider_export_command == "compare":
9478
+ return provider_export_compare(
9479
+ project,
9480
+ args.before_generation,
9481
+ args.after_generation,
9482
+ output=args.output,
9483
+ )
9484
+ raise AssertionError(
9485
+ f"unknown provider export command: {args.provider_export_command}"
9486
+ )
9340
9487
  raise AssertionError(f"unknown provider command: {args.provider_command}")
9341
9488
  if args.command == "finish":
9342
9489
  return finish(