requirements-as-code 0.7.0__tar.gz → 0.7.2__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 (167) hide show
  1. {requirements_as_code-0.7.0/requirements_as_code.egg-info → requirements_as_code-0.7.2}/PKG-INFO +73 -1
  2. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/README.md +72 -0
  3. requirements_as_code-0.7.2/planning/prompt/rac-agent-compression.md +12 -0
  4. requirements_as_code-0.7.2/planning/prompt/rac-agent-instructions.md +24 -0
  5. requirements_as_code-0.7.2/planning/prompt/rac-agent-release-gate-major.md +261 -0
  6. requirements_as_code-0.7.2/planning/prompt/rac-agent-release-gate-minor.md +23 -0
  7. requirements_as_code-0.7.2/planning/prompt/rac-agent-session-start.md +23 -0
  8. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/artifacts.py +11 -17
  9. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/cli.py +85 -2
  10. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/outputs.py +120 -0
  11. requirements_as_code-0.7.2/rac/relationships.py +440 -0
  12. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/stats.py +2 -2
  13. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2/requirements_as_code.egg-info}/PKG-INFO +73 -1
  14. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/SOURCES.txt +19 -0
  15. requirements_as_code-0.7.2/tests/fixtures/no_relationships/decision.md +22 -0
  16. requirements_as_code-0.7.2/tests/fixtures/no_relationships/requirement.md +17 -0
  17. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/ambiguous_target/adr-004-alt.md +13 -0
  18. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/ambiguous_target/adr-004.md +13 -0
  19. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/ambiguous_target/req-001.md +13 -0
  20. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/broken/search.md +13 -0
  21. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/duplicate/adr-004-alt.md +13 -0
  22. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/duplicate/adr-004.md +13 -0
  23. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/resolved/adr-004.md +17 -0
  24. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/resolved/req-001.md +13 -0
  25. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/resolved/roadmap-q3.md +17 -0
  26. requirements_as_code-0.7.2/tests/fixtures/relationship_validation/self_reference/adr-004.md +17 -0
  27. requirements_as_code-0.7.2/tests/test_relationship_validation.py +265 -0
  28. requirements_as_code-0.7.2/tests/test_relationships_cmd.py +233 -0
  29. requirements_as_code-0.7.0/rac/relationships.py +0 -86
  30. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/.github/workflows/python-publish.yml +0 -0
  31. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/.gitignore +0 -0
  32. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/LICENSE +0 -0
  33. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/examples/example_dashboard_v1.md +0 -0
  34. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/examples/example_dashboard_v2.md +0 -0
  35. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-001-markdown-first.md +0 -0
  36. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-002-ai-optional.md +0 -0
  37. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-003-structured-outputs-first.md +0 -0
  38. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-004-artifact-model.md +0 -0
  39. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-005-cli-first.md +0 -0
  40. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-006-ingest-over-rewrite.md +0 -0
  41. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-007-json-contract-stability.md +0 -0
  42. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-008-agent-ready-architecture.md +0 -0
  43. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-009-ai-assisted-development.md +0 -0
  44. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-010-documents-are-not-artifacts.md +0 -0
  45. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-011-file-first-pipeline.md +0 -0
  46. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-012-open-core-strategy.md +0 -0
  47. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-013-leverage-existing-source-control-systems.md +0 -0
  48. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-014-viewer-agnostic-knowledge-artifacts.md +0 -0
  49. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-015-explorer-as-consumer.md +0 -0
  50. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-016-relationships-as-structural-references.md +0 -0
  51. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-017-rac-managed-knowledge-not-work.md +0 -0
  52. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-command-surface.md +0 -0
  53. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-first-run-experience.md +0 -0
  54. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-health-model.md +0 -0
  55. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-import-workflow.md +0 -0
  56. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-knowledge-graph.md +0 -0
  57. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-visual-system.md +0 -0
  58. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.0-workspace-analysis.md +0 -0
  59. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.1-review-engine.md +0 -0
  60. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.2-mcp-server.md +0 -0
  61. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.4-claude-skills.md +0 -0
  62. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.4-python-sdk.md +0 -0
  63. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/archive/v0.5-decisions.md +0 -0
  64. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/archive/v0.7-prompts.md +0 -0
  65. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.2-stats.md +0 -0
  66. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.3-ingest.md +0 -0
  67. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.3.1-formats.md +0 -0
  68. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.4-inspect.md +0 -0
  69. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.4.1-expansion.md +0 -0
  70. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.4.1-inspect-expansion.md +0 -0
  71. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.4.2-decision-metadata.md +0 -0
  72. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.5.0-artifact-improvement.md +0 -0
  73. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.5.1-guided-improvement.md +0 -0
  74. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.5.2-schema.md +0 -0
  75. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.6.0-roadmap-artifacts.md +0 -0
  76. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.6.1-roadmap-improvement.md +0 -0
  77. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.6.2-prompt-artifact.md +0 -0
  78. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.6.3-design-artifacts.md +0 -0
  79. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.0-relationship-metadata.md +0 -0
  80. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.1-relationship-inspection.md +0 -0
  81. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.2-relationship-validation.md +0 -0
  82. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.3-repo-intelligence.md +0 -0
  83. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.4-repo-indexing.md +0 -0
  84. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.8.0-service-api.md +0 -0
  85. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.8.1-repository-model.md +0 -0
  86. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.8.2-interactive-runtime-readiness.md +0 -0
  87. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.8.3-integration-freeze.md +0 -0
  88. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.9.0-explorer-foundation.md +0 -0
  89. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.9.1-explorer-experience.md +0 -0
  90. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.9.2-knowledge-operations.md +0 -0
  91. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.9.3-intelligence-views.md +0 -0
  92. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/pyproject.toml +0 -0
  93. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/__init__.py +0 -0
  94. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/classification.py +0 -0
  95. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/diff.py +0 -0
  96. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/fs.py +0 -0
  97. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/improve.py +0 -0
  98. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/ingest.py +0 -0
  99. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/inspect.py +0 -0
  100. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/models.py +0 -0
  101. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/parser.py +0 -0
  102. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/schema.py +0 -0
  103. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/validate.py +0 -0
  104. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/dependency_links.txt +0 -0
  105. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/entry_points.txt +0 -0
  106. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/requires.txt +0 -0
  107. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/top_level.txt +0 -0
  108. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/setup.cfg +0 -0
  109. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/conftest.py +0 -0
  110. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/bad_category.md +0 -0
  111. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/bad_status.md +0 -0
  112. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/minimal.md +0 -0
  113. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/portfolio/01_accepted_arch.md +0 -0
  114. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/portfolio/02_proposed_process.md +0 -0
  115. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/portfolio/03_no_metadata.md +0 -0
  116. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/with_metadata.md +0 -0
  117. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/design/minimal.md +0 -0
  118. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/design/missing_constraints.md +0 -0
  119. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/design/valid.md +0 -0
  120. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/diff/new.md +0 -0
  121. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/diff/old.md +0 -0
  122. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/ingest/sample.md +0 -0
  123. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/inspect/ambiguous.md +0 -0
  124. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/inspect/decision.md +0 -0
  125. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/inspect/nested/another_requirement.md +0 -0
  126. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/inspect/requirement.md +0 -0
  127. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/duplicate_ids.md +0 -0
  128. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/empty_req_text.md +0 -0
  129. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/malformed_id.md +0 -0
  130. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/missing_id.md +0 -0
  131. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/missing_problem.md +0 -0
  132. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/missing_requirements.md +0 -0
  133. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/missing_title.md +0 -0
  134. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/multiple_titles.md +0 -0
  135. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/portfolio/broken.md +0 -0
  136. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/portfolio/feature_a.md +0 -0
  137. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/portfolio/feature_b.md +0 -0
  138. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/portfolio/sub/feature_c.md +0 -0
  139. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/prompt/minimal.md +0 -0
  140. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/prompt/missing_output.md +0 -0
  141. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/prompt/valid.md +0 -0
  142. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/decision_with_links.md +0 -0
  143. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/design_with_links.md +0 -0
  144. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/prompt_with_links.md +0 -0
  145. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/requirement_with_links.md +0 -0
  146. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/roadmap_with_links.md +0 -0
  147. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/roadmap/minimal.md +0 -0
  148. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/roadmap/missing_initiatives.md +0 -0
  149. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/roadmap/valid.md +0 -0
  150. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/valid/bullet_requirements.md +0 -0
  151. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/valid/feature.md +0 -0
  152. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/valid/minimal.md +0 -0
  153. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/valid/warnings.md +0 -0
  154. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_cli.py +0 -0
  155. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_decision_metadata.py +0 -0
  156. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_design.py +0 -0
  157. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_diff.py +0 -0
  158. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_improve.py +0 -0
  159. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_ingest.py +0 -0
  160. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_inspect.py +0 -0
  161. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_parser.py +0 -0
  162. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_prompt.py +0 -0
  163. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_relationships.py +0 -0
  164. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_roadmap.py +0 -0
  165. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_schema.py +0 -0
  166. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_stats.py +0 -0
  167. {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_validate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: requirements-as-code
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: RAC — lint and diff product requirements written in Markdown.
5
5
  Author: tcballard
6
6
  License-Expression: MIT
@@ -863,6 +863,78 @@ registered schemas are supported; custom schemas are out of scope.
863
863
 
864
864
  ---
865
865
 
866
+ ## Relationships
867
+
868
+ Inspect the explicit [relationship metadata](#relationship-metadata) declared
869
+ across a repository — a deterministic, read-only view of how artifacts reference
870
+ one another, without opening every file.
871
+
872
+ ```bash
873
+ rac relationships planning/
874
+ rac relationships planning/ --json
875
+ rac relationships planning/ --top-level # don't recurse into subdirectories
876
+ rac relationships requirements/search.md # a single file works too
877
+ ```
878
+
879
+ ```text
880
+ Relationships
881
+
882
+ Files Inspected: 24
883
+ Artifacts With Relationships: 8
884
+ Relationships Found: 14
885
+
886
+ By Type:
887
+ - Related Requirements: 4
888
+ - Related Decisions: 6
889
+ - Related Roadmaps: 2
890
+ - Related Prompts: 1
891
+ - Supersedes: 1
892
+
893
+ requirements/search.md
894
+ Related Decisions:
895
+ - ADR-004
896
+ ```
897
+
898
+ `--json` returns structured data for automation and future viewers (ADR-015 —
899
+ relationship intelligence lives in RAC Core, not the UI):
900
+
901
+ ```json
902
+ {
903
+ "directory": "planning",
904
+ "recursive": true,
905
+ "total_files": 24,
906
+ "artifacts_with_relationships": 8,
907
+ "relationship_count": 14,
908
+ "counts": { "related_decisions": 6, "related_requirements": 4 },
909
+ "artifacts": [
910
+ {
911
+ "path": "requirements/search.md",
912
+ "type": "requirement",
913
+ "relationships": { "related_decisions": ["ADR-004"] }
914
+ }
915
+ ]
916
+ }
917
+ ```
918
+
919
+ Notes:
920
+
921
+ - **Counts are individual references.** `relationship_count` equals
922
+ `sum(counts.values())`; an artifact listing two decisions contributes two.
923
+ - **`total_files`** counts every Markdown file considered — including files with
924
+ no relationships and Unknown artifacts.
925
+ - **Supersedes is a relationship here.** Unlike `rac inspect` (where `supersedes`
926
+ is a top-level scalar), this command reports it alongside the `related_*`
927
+ sections, in both `counts` and per-artifact `relationships`.
928
+ - **Spec-driven.** Extraction is keyed off each artifact type's declared sections.
929
+ Unknown artifacts are counted but contribute no relationships (and never appear
930
+ in `artifacts`); RAC does not scan arbitrary Markdown.
931
+ - **Read-only and exit `0`.** The command never modifies files and exits `0`
932
+ whether or not relationships are found (`2` only for a missing path or a
933
+ non-Markdown file). It does **not** resolve or validate targets — broken-link
934
+ detection is a later release.
935
+
936
+ ---
937
+
866
938
  ## Review (Planned)
867
939
 
868
940
  AI-assisted product review.
@@ -823,6 +823,78 @@ registered schemas are supported; custom schemas are out of scope.
823
823
 
824
824
  ---
825
825
 
826
+ ## Relationships
827
+
828
+ Inspect the explicit [relationship metadata](#relationship-metadata) declared
829
+ across a repository — a deterministic, read-only view of how artifacts reference
830
+ one another, without opening every file.
831
+
832
+ ```bash
833
+ rac relationships planning/
834
+ rac relationships planning/ --json
835
+ rac relationships planning/ --top-level # don't recurse into subdirectories
836
+ rac relationships requirements/search.md # a single file works too
837
+ ```
838
+
839
+ ```text
840
+ Relationships
841
+
842
+ Files Inspected: 24
843
+ Artifacts With Relationships: 8
844
+ Relationships Found: 14
845
+
846
+ By Type:
847
+ - Related Requirements: 4
848
+ - Related Decisions: 6
849
+ - Related Roadmaps: 2
850
+ - Related Prompts: 1
851
+ - Supersedes: 1
852
+
853
+ requirements/search.md
854
+ Related Decisions:
855
+ - ADR-004
856
+ ```
857
+
858
+ `--json` returns structured data for automation and future viewers (ADR-015 —
859
+ relationship intelligence lives in RAC Core, not the UI):
860
+
861
+ ```json
862
+ {
863
+ "directory": "planning",
864
+ "recursive": true,
865
+ "total_files": 24,
866
+ "artifacts_with_relationships": 8,
867
+ "relationship_count": 14,
868
+ "counts": { "related_decisions": 6, "related_requirements": 4 },
869
+ "artifacts": [
870
+ {
871
+ "path": "requirements/search.md",
872
+ "type": "requirement",
873
+ "relationships": { "related_decisions": ["ADR-004"] }
874
+ }
875
+ ]
876
+ }
877
+ ```
878
+
879
+ Notes:
880
+
881
+ - **Counts are individual references.** `relationship_count` equals
882
+ `sum(counts.values())`; an artifact listing two decisions contributes two.
883
+ - **`total_files`** counts every Markdown file considered — including files with
884
+ no relationships and Unknown artifacts.
885
+ - **Supersedes is a relationship here.** Unlike `rac inspect` (where `supersedes`
886
+ is a top-level scalar), this command reports it alongside the `related_*`
887
+ sections, in both `counts` and per-artifact `relationships`.
888
+ - **Spec-driven.** Extraction is keyed off each artifact type's declared sections.
889
+ Unknown artifacts are counted but contribute no relationships (and never appear
890
+ in `artifacts`); RAC does not scan arbitrary Markdown.
891
+ - **Read-only and exit `0`.** The command never modifies files and exits `0`
892
+ whether or not relationships are found (`2` only for a missing path or a
893
+ non-Markdown file). It does **not** resolve or validate targets — broken-link
894
+ detection is a later release.
895
+
896
+ ---
897
+
826
898
  ## Review (Planned)
827
899
 
828
900
  AI-assisted product review.
@@ -0,0 +1,12 @@
1
+ Create a compact handoff for a fresh coding session.
2
+
3
+ Include only:
4
+ - goal
5
+ - approved scope
6
+ - files changed or likely touched
7
+ - architecture constraints
8
+ - tests required
9
+ - commands to run
10
+ - unresolved questions
11
+
12
+ Do not include conversation history.
@@ -0,0 +1,24 @@
1
+ # RAC Agent Instructions
2
+
3
+ Before coding:
4
+ - Refresh from origin/main unless told otherwise.
5
+ - Read the target roadmap file and relevant ADRs.
6
+ - Produce a plan before implementation.
7
+ - Do not expand release scope beyond the roadmap.
8
+
9
+ Release discipline:
10
+ - Work on a feature branch, not main.
11
+ - Do not include Claude attribution in commits.
12
+ - After GitHub merge, refresh local main.
13
+ - Prune merged branches when asked.
14
+
15
+ Architecture:
16
+ - Prefer schema-driven artifact behavior.
17
+ - Do not add artifact-specific validation paths if a generic path can handle it.
18
+ - Keep classification separate from validation.
19
+ - Invalid but recognizable artifacts may still classify as their artifact type.
20
+
21
+ Testing:
22
+ - Add negative boundary tests for each new artifact type.
23
+ - Test that adjacent artifact types do not misclassify as each other.
24
+ - Run pytest before commit.
@@ -0,0 +1,261 @@
1
+ We are preparing a major release for RAC.
2
+
3
+ Your job is to run a release gate review, not to implement changes yet.
4
+
5
+ Context:
6
+ - RAC is a Markdown-first CLI for requirements-as-code.
7
+ - The system supports typed product artifacts such as Requirements, Decisions, Roadmaps, Designs, and related schema/template/improve/inspect/stats behavior.
8
+ - The product goal is deterministic artifact recognition, structural validation, useful CLI feedback, and stable JSON contracts.
9
+ - The release must not drift into project management, UI rendering, semantic scoring, AI interpretation, collaboration workflows, databases, accounts, or web-app behavior unless explicitly approved.
10
+
11
+ Review the current repository against these gates:
12
+
13
+ ## 1. Product scope gate
14
+
15
+ Identify anything in this release that exceeds the intended product boundary.
16
+
17
+ Check for:
18
+ - behavior that interprets artifact quality instead of validating structure
19
+ - workflow/project-management behavior
20
+ - semantic relationship analysis
21
+ - UI/design-token/rendering behavior
22
+ - hidden AI-like inference
23
+ - new concepts not documented in roadmap, ADRs, or release notes
24
+ - CLI behavior that surprises the user
25
+
26
+ Return:
27
+ - PASS / BLOCK
28
+ - exact files or commands involved
29
+ - required scope cuts before release
30
+
31
+ ## 2. Architecture consistency gate
32
+
33
+ Review whether the artifact model is still coherent.
34
+
35
+ Check:
36
+ - whether classification, validation, stats, schema, templates, inspect, and improve use shared artifact metadata where possible
37
+ - whether any artifact has special-case logic that should be generalized
38
+ - whether Roadmap, Design, Decision, and Requirement behavior follow the same architectural pattern
39
+ - whether new code duplicates existing artifact handling
40
+ - whether any module is becoming too large or too coupled
41
+ - whether public contracts are separated from implementation details
42
+
43
+ Return:
44
+ - PASS / BLOCK
45
+ - duplicated paths
46
+ - special cases that should be removed
47
+ - proposed simplification before release
48
+
49
+ ## 3. Duplication and deletion gate
50
+
51
+ This is a hard simplification review.
52
+
53
+ Answer these directly:
54
+
55
+ - What code became obsolete during this release?
56
+ - What can be deleted before release?
57
+ - What logic was copied instead of shared?
58
+ - Which artifact-specific branches can be collapsed into generic artifact-spec-driven behavior?
59
+ - Did any file grow past a size where it should be split?
60
+ - Are there old fixtures, examples, or docs that now contradict the current model?
61
+ - Are there stale branches, stale roadmap files, or stale TODOs that should be cleaned up?
62
+
63
+ Return:
64
+ - required deletions
65
+ - optional cleanup
66
+ - changes that should wait until after release
67
+
68
+ ## 4. CLI contract gate
69
+
70
+ Review every public command affected by this release.
71
+
72
+ Commands to check:
73
+ - rac validate
74
+ - rac diff
75
+ - rac stats
76
+ - rac inspect
77
+ - rac improve
78
+ - rac schema
79
+ - rac ingest, if touched
80
+
81
+ For each affected command, verify:
82
+ - human output is stable and understandable
83
+ - JSON output is stable and documented
84
+ - exit codes are intentional
85
+ - invalid input behavior is clear
86
+ - warnings vs errors are consistent
87
+ - unsupported artifact behavior is explicit
88
+ - examples in README/docs still work
89
+
90
+ Return a table:
91
+
92
+ Command | Changed? | Human output ok? | JSON ok? | Exit codes ok? | Docs ok? | Blockers
93
+
94
+ ## 5. Classification boundary gate
95
+
96
+ Review artifact classification behavior.
97
+
98
+ Check:
99
+ - Requirements do not classify as Design
100
+ - Designs do not classify as Requirements
101
+ - Roadmaps classify by approved structure, not loose title matching alone except where explicitly intended
102
+ - UI/design-themed titles alone do not classify as Design
103
+ - invalid but recognizable artifacts classify correctly, then fail validation separately
104
+ - incomplete artifacts behave according to the spec
105
+ - mixed documents do not produce surprising classifications
106
+ - negative fixtures exist for adjacent artifact types
107
+
108
+ Return:
109
+ - PASS / BLOCK
110
+ - missing boundary tests
111
+ - risky classification rules
112
+ - recommended fixture additions
113
+
114
+ ## 6. Validation and schema gate
115
+
116
+ Check that validation behavior and schema output agree.
117
+
118
+ Verify:
119
+ - required sections match the artifact specs
120
+ - recommended and optional sections are consistent across schema, templates, validation, and docs
121
+ - metadata vocabularies are enforced consistently
122
+ - missing required sections produce clear errors
123
+ - invalid metadata values produce clear errors
124
+ - schema JSON is stable and documented
125
+ - template output follows canonical section order
126
+
127
+ Return:
128
+ - mismatches
129
+ - missing tests
130
+ - release blockers
131
+
132
+ ## 7. Test and verification gate
133
+
134
+ Do not accept “tests pass” as enough.
135
+
136
+ Run or identify the exact commands needed to verify the release.
137
+
138
+ Check:
139
+ - unit tests for changed behavior
140
+ - CLI smoke tests
141
+ - classification boundary tests
142
+ - negative fixtures
143
+ - JSON output snapshots or equivalent assertions
144
+ - docs examples manually or automatically verified
145
+ - packaging/build check
146
+ - import check from a clean environment, if practical
147
+
148
+ Return:
149
+ - exact commands run
150
+ - exact commands still needed
151
+ - failures
152
+ - missing test files
153
+ - blockers
154
+
155
+ If tests are missing for new behavior, mark the release BLOCKED.
156
+
157
+ ## 8. Documentation gate
158
+
159
+ Review documentation from a new user’s point of view.
160
+
161
+ Check:
162
+ - README reflects current commands
163
+ - artifact docs match implementation
164
+ - examples use current output
165
+ - release notes or changelog entry exists
166
+ - ADRs are not contradicted
167
+ - roadmap item is updated or marked complete
168
+ - install/publish instructions are still accurate
169
+ - known limitations are explicit
170
+
171
+ Return:
172
+ - stale docs
173
+ - missing docs
174
+ - docs that overpromise behavior
175
+
176
+ ## 9. Release hygiene gate
177
+
178
+ Check repository and release state.
179
+
180
+ Verify:
181
+ - working tree is clean
182
+ - release branch is based on current origin/main
183
+ - merged branches are pruned or listed for pruning
184
+ - version number is updated consistently
185
+ - package metadata is correct
186
+ - no generated Claude attribution appears in commits, PR text, release notes, or docs
187
+ - CI is green
188
+ - build artifacts are not accidentally committed
189
+ - no credentials or local paths leaked
190
+
191
+ Return:
192
+ - PASS / BLOCK
193
+ - exact commands to confirm state
194
+ - required cleanup
195
+
196
+ ## 10. Backward compatibility and migration gate
197
+
198
+ Identify anything that could break existing users.
199
+
200
+ Check:
201
+ - command names
202
+ - arguments and flags
203
+ - JSON field names
204
+ - exit codes
205
+ - artifact classification behavior
206
+ - validation strictness
207
+ - package extras
208
+ - import paths
209
+ - documented examples
210
+
211
+ Return:
212
+ - breaking changes
213
+ - whether each breaking change is intentional
214
+ - migration note required
215
+ - release blocker if undocumented
216
+
217
+ ## Output format
218
+
219
+ Return the review in this structure:
220
+
221
+ # Major Release Gate Review
222
+
223
+ ## Decision
224
+ PASS or BLOCK
225
+
226
+ ## Release blockers
227
+ List only issues that must be fixed before release.
228
+
229
+ ## Required simplifications
230
+ List duplication, deletion, or extraction work required before release.
231
+
232
+ ## Test evidence
233
+ List commands run and results. If not run, say NOT RUN.
234
+
235
+ ## Product scope issues
236
+ List any behavior that exceeds the intended boundary.
237
+
238
+ ## Architecture issues
239
+ List duplicated or inconsistent implementation paths.
240
+
241
+ ## CLI contract issues
242
+ List command/output/JSON/exit-code problems.
243
+
244
+ ## Documentation issues
245
+ List stale, missing, or overpromising docs.
246
+
247
+ ## Release hygiene issues
248
+ List branch/version/CI/commit/publishing concerns.
249
+
250
+ ## Safe to defer
251
+ List cleanup that is real but not release-blocking.
252
+
253
+ ## Exact next actions
254
+ Give a short checklist of the next changes to make.
255
+
256
+ Important rules:
257
+ - Do not implement anything in this pass.
258
+ - Do not invent test results. If you did not run a command, mark it NOT RUN.
259
+ - Cite exact files and commands.
260
+ - Treat missing tests for new public behavior as a blocker.
261
+ - Treat duplicated artifact-specific
@@ -0,0 +1,23 @@
1
+ # Minor Release Gate
2
+
3
+ Before completing any 0.x.n release:
4
+
5
+ ## Duplication
6
+ - Did this release add artifact-specific classification logic?
7
+ - Did it duplicate validation, schema, template, stats, or improve behavior?
8
+ - Can new behavior be expressed through ArtifactSpec instead?
9
+ - Are there two sources of truth for sections, metadata, or guidance?
10
+
11
+ ## Simplification
12
+ - What code became obsolete?
13
+ - What branch or special case can be removed?
14
+ - Did any file grow past the agreed limit?
15
+ - Should a helper be extracted?
16
+ - Did this release increase the number of artifact-specific conditionals?
17
+
18
+ ## Verification
19
+ - Are there negative classification tests?
20
+ - Are adjacent artifact types tested against each other?
21
+ - Are incomplete-but-recognizable artifacts tested?
22
+ - Are CLI human and JSON outputs tested?
23
+ - Was pytest run before commit?
@@ -0,0 +1,23 @@
1
+ We are working on RAC, a Python CLI for requirements-as-code.
2
+
3
+ RAC models product-management Markdown artifacts as deterministic, typed artifacts.
4
+ Current artifact families include Requirements, Decisions, Roadmaps, Prompts, and Design.
5
+
6
+ Core principles:
7
+ - Markdown-first.
8
+ - Deterministic classification.
9
+ - Structural validation, not semantic scoring unless explicitly planned.
10
+ - CLI contracts matter: human output, JSON output, exit codes, and templates must be specified.
11
+ - Version numbers are scope fences.
12
+ - Prefer schema/artifact-spec-driven behavior over artifact-specific branches.
13
+ - Invalid but recognizable artifacts may still classify as their artifact type, then fail validation.
14
+
15
+ Before coding:
16
+ 1. Refresh from `origin/main`.
17
+ 2. Confirm branch state.
18
+ 3. Read the relevant roadmap item.
19
+ 4. Check against ADRs.
20
+ 5. Produce an implementation contract.
21
+ 6. Wait for approval.
22
+
23
+ Do not implement until I approve the plan.
@@ -50,6 +50,12 @@ class ArtifactSpec:
50
50
  # matching, so synonyms contribute to confidence. Matching is deterministic
51
51
  # (dict lookup) and case-insensitive (headings are normalized first).
52
52
  synonyms: dict[str, str] = field(default_factory=dict)
53
+ # Canonical-identifier section (v0.7.2 relationship validation): the normalized
54
+ # section name whose value is this artifact type's identifier, consulted by
55
+ # ``rac.relationships.artifact_identifier`` before falling back to the filename
56
+ # stem. A forward hook — no spec sets it today; relationship resolution works
57
+ # from the ``## ID`` section and filename stem until a type opts in.
58
+ id_field: str | None = None
53
59
 
54
60
  @property
55
61
  def expected(self) -> tuple[str, ...]:
@@ -68,23 +74,11 @@ class ArtifactSpec:
68
74
  # extracted, but never scored, never templated, never reported as missing
69
75
  # (REQ-002). v0.7.0 treats them as metadata only — RAC extracts and counts the
70
76
  # references but does not resolve, validate, or graph them.
71
-
72
- # The cross-artifact "Related X" sections. These populate the ``relationships``
73
- # dict in ``rac inspect`` output. ``related designs`` is included so every peer
74
- # artifact type can be referenced.
75
- RELATED_SECTIONS: tuple[str, ...] = (
76
- "related requirements",
77
- "related decisions",
78
- "related roadmaps",
79
- "related prompts",
80
- "related designs",
81
- )
82
-
83
- # The full relationship-section vocabulary, including ``supersedes``. ``stats``
84
- # counts presence across all of these. ``supersedes`` is the one exception that
85
- # does *not* appear in the inspect ``relationships`` dict: it remains a top-level
86
- # scalar field for backwards compatibility (see rac.inspect / ADR-007).
87
- RELATIONSHIP_SECTIONS: tuple[str, ...] = RELATED_SECTIONS + ("supersedes",)
77
+ #
78
+ # The relationship-section vocabulary and its canonical ordering live in
79
+ # :mod:`rac.relationships` (the module that owns relationship logic). This module
80
+ # only owns the human-facing ``descriptions`` for those sections, which the specs
81
+ # below consume.
88
82
 
89
83
  # One-line descriptions for every relationship section, surfaced by `rac schema`.
90
84
  # Relationship sections deliberately carry no ``guidance`` — guidance gates
@@ -8,11 +8,14 @@ Commands:
8
8
  rac inspect <file.md | -> [--json]
9
9
  rac improve <file.md | -> [--json | --template]
10
10
  rac schema [--list] [type] [--json | --template]
11
+ rac relationships <dir | file.md> [--validate] [--json] [--top-level]
11
12
 
12
13
  Exit codes:
13
- 0 success (incl. inspect/improve reporting Unknown)
14
+ 0 success (incl. inspect/improve reporting Unknown; relationships found or
15
+ not; --validate with all references resolved)
14
16
  1 validate: errors found; stats: no valid known artifacts; ingest:
15
- conversion failed
17
+ conversion failed; relationships --validate: broken/ambiguous/self
18
+ references or duplicate identifiers found
16
19
  2 usage / IO error (file not found, not a directory, unsupported type,
17
20
  refuse-to-overwrite)
18
21
  """
@@ -31,6 +34,12 @@ from .classification import score_artifacts
31
34
  from .improve import improve_product
32
35
  from .inspect import build_inspection, inspect_directory
33
36
  from .parser import parse, parse_file
37
+ from .relationships import (
38
+ build_relationship_report,
39
+ build_relationship_report_file,
40
+ validate_relationships,
41
+ validate_relationships_file,
42
+ )
34
43
  from .schema import available_schemas, schema_reference
35
44
  from .stats import collect_stats
36
45
  from .validate import has_errors, validate
@@ -236,6 +245,51 @@ def cmd_schema(args: argparse.Namespace) -> int:
236
245
  return EXIT_OK
237
246
 
238
247
 
248
+ def cmd_relationships(args: argparse.Namespace) -> int:
249
+ path = Path(args.path)
250
+ # --recursive is the default; --top-level disables it. If both are given,
251
+ # --top-level wins (mirrors `rac inspect`).
252
+ if path.is_dir():
253
+ is_dir = True
254
+ elif path.is_file():
255
+ if path.suffix.lower() not in (".md", ".markdown"):
256
+ print(
257
+ f"rac: relationships expects a Markdown file or directory; "
258
+ f"convert it first with: rac ingest {args.path}",
259
+ file=sys.stderr,
260
+ )
261
+ raise SystemExit(EXIT_USAGE)
262
+ is_dir = False
263
+ else:
264
+ print(f"rac: path not found: {args.path}", file=sys.stderr)
265
+ raise SystemExit(EXIT_USAGE)
266
+
267
+ if args.validate:
268
+ if is_dir:
269
+ report = validate_relationships(args.path, recursive=not args.top_level)
270
+ else:
271
+ report = validate_relationships_file(args.path)
272
+ if args.json:
273
+ print(outputs.render_relationship_validation_json(report))
274
+ else:
275
+ print(outputs.render_relationship_validation_human(report))
276
+ # Validation-style exit codes (REQ-007): 0 when everything resolves, 1 when
277
+ # any issue is found, 2 (above) for usage errors.
278
+ return EXIT_OK if report.ok else EXIT_VALIDATION_FAILED
279
+
280
+ if is_dir:
281
+ report = build_relationship_report(args.path, recursive=not args.top_level)
282
+ else:
283
+ report = build_relationship_report_file(args.path)
284
+ if args.json:
285
+ print(outputs.render_relationships_json(report))
286
+ else:
287
+ print(outputs.render_relationships_human(report))
288
+ # A completed inspection always succeeds — finding no relationships is a valid
289
+ # outcome, not an error (REQ-010).
290
+ return EXIT_OK
291
+
292
+
239
293
  def build_parser() -> argparse.ArgumentParser:
240
294
  version_str = f"rac {__version__}"
241
295
 
@@ -387,6 +441,35 @@ def build_parser() -> argparse.ArgumentParser:
387
441
  )
388
442
  p_schema.set_defaults(func=cmd_schema)
389
443
 
444
+ p_relationships = sub.add_parser(
445
+ "relationships",
446
+ help="Inspect explicit relationships across a directory (or single file).",
447
+ parents=[version_parent],
448
+ )
449
+ p_relationships.add_argument(
450
+ "path", help="A directory to scan, or a single Markdown file."
451
+ )
452
+ p_relationships.add_argument(
453
+ "--json", action="store_true", help="Emit JSON instead of human-readable text."
454
+ )
455
+ p_relationships.add_argument(
456
+ "--validate",
457
+ action="store_true",
458
+ help="Resolve references against discovered artifacts; exit 1 if any are "
459
+ "broken, ambiguous, self-referencing, or have duplicate identifiers.",
460
+ )
461
+ p_relationships.add_argument(
462
+ "--top-level",
463
+ action="store_true",
464
+ help="When inspecting a directory, only its top-level files (no recursion).",
465
+ )
466
+ p_relationships.add_argument(
467
+ "--recursive",
468
+ action="store_true",
469
+ help="Recurse into subdirectories (the default; accepted for clarity).",
470
+ )
471
+ p_relationships.set_defaults(func=cmd_relationships)
472
+
390
473
  return parser
391
474
 
392
475