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.
- {requirements_as_code-0.7.0/requirements_as_code.egg-info → requirements_as_code-0.7.2}/PKG-INFO +73 -1
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/README.md +72 -0
- requirements_as_code-0.7.2/planning/prompt/rac-agent-compression.md +12 -0
- requirements_as_code-0.7.2/planning/prompt/rac-agent-instructions.md +24 -0
- requirements_as_code-0.7.2/planning/prompt/rac-agent-release-gate-major.md +261 -0
- requirements_as_code-0.7.2/planning/prompt/rac-agent-release-gate-minor.md +23 -0
- requirements_as_code-0.7.2/planning/prompt/rac-agent-session-start.md +23 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/artifacts.py +11 -17
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/cli.py +85 -2
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/outputs.py +120 -0
- requirements_as_code-0.7.2/rac/relationships.py +440 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/stats.py +2 -2
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2/requirements_as_code.egg-info}/PKG-INFO +73 -1
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/SOURCES.txt +19 -0
- requirements_as_code-0.7.2/tests/fixtures/no_relationships/decision.md +22 -0
- requirements_as_code-0.7.2/tests/fixtures/no_relationships/requirement.md +17 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/ambiguous_target/adr-004-alt.md +13 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/ambiguous_target/adr-004.md +13 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/ambiguous_target/req-001.md +13 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/broken/search.md +13 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/duplicate/adr-004-alt.md +13 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/duplicate/adr-004.md +13 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/resolved/adr-004.md +17 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/resolved/req-001.md +13 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/resolved/roadmap-q3.md +17 -0
- requirements_as_code-0.7.2/tests/fixtures/relationship_validation/self_reference/adr-004.md +17 -0
- requirements_as_code-0.7.2/tests/test_relationship_validation.py +265 -0
- requirements_as_code-0.7.2/tests/test_relationships_cmd.py +233 -0
- requirements_as_code-0.7.0/rac/relationships.py +0 -86
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/.github/workflows/python-publish.yml +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/.gitignore +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/LICENSE +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/examples/example_dashboard_v1.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/examples/example_dashboard_v2.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-001-markdown-first.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-002-ai-optional.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-003-structured-outputs-first.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-004-artifact-model.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-005-cli-first.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-006-ingest-over-rewrite.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-007-json-contract-stability.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-008-agent-ready-architecture.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-009-ai-assisted-development.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-010-documents-are-not-artifacts.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-011-file-first-pipeline.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-012-open-core-strategy.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-013-leverage-existing-source-control-systems.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-014-viewer-agnostic-knowledge-artifacts.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-015-explorer-as-consumer.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-016-relationships-as-structural-references.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/adr/adr-017-rac-managed-knowledge-not-work.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-command-surface.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-first-run-experience.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-health-model.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-import-workflow.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-knowledge-graph.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/designs/explorer-visual-system.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.0-workspace-analysis.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.1-review-engine.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.2-mcp-server.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.4-claude-skills.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/future/v1.4-python-sdk.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/archive/v0.5-decisions.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/archive/v0.7-prompts.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.2-stats.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.3-ingest.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.3.1-formats.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.4-inspect.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.4.1-expansion.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.4.1-inspect-expansion.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.4.2-decision-metadata.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.5.0-artifact-improvement.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.5.1-guided-improvement.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.5.2-schema.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.6.0-roadmap-artifacts.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.6.1-roadmap-improvement.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.6.2-prompt-artifact.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.6.3-design-artifacts.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.0-relationship-metadata.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.1-relationship-inspection.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.2-relationship-validation.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.3-repo-intelligence.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.7.4-repo-indexing.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.8.0-service-api.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.8.1-repository-model.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.8.2-interactive-runtime-readiness.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.8.3-integration-freeze.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.9.0-explorer-foundation.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.9.1-explorer-experience.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.9.2-knowledge-operations.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/planning/roadmap/v0.9.3-intelligence-views.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/pyproject.toml +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/__init__.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/classification.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/diff.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/fs.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/improve.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/ingest.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/inspect.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/models.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/parser.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/schema.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/rac/validate.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/dependency_links.txt +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/entry_points.txt +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/requires.txt +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/requirements_as_code.egg-info/top_level.txt +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/setup.cfg +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/conftest.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/bad_category.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/bad_status.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/minimal.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/portfolio/01_accepted_arch.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/portfolio/02_proposed_process.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/portfolio/03_no_metadata.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/decision/with_metadata.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/design/minimal.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/design/missing_constraints.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/design/valid.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/diff/new.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/diff/old.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/ingest/sample.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/inspect/ambiguous.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/inspect/decision.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/inspect/nested/another_requirement.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/inspect/requirement.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/duplicate_ids.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/empty_req_text.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/malformed_id.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/missing_id.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/missing_problem.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/missing_requirements.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/missing_title.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/invalid/multiple_titles.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/portfolio/broken.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/portfolio/feature_a.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/portfolio/feature_b.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/portfolio/sub/feature_c.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/prompt/minimal.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/prompt/missing_output.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/prompt/valid.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/decision_with_links.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/design_with_links.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/prompt_with_links.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/requirement_with_links.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/relationships/roadmap_with_links.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/roadmap/minimal.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/roadmap/missing_initiatives.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/roadmap/valid.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/valid/bullet_requirements.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/valid/feature.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/valid/minimal.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/fixtures/valid/warnings.md +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_cli.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_decision_metadata.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_design.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_diff.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_improve.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_ingest.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_inspect.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_parser.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_prompt.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_relationships.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_roadmap.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_schema.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_stats.py +0 -0
- {requirements_as_code-0.7.0 → requirements_as_code-0.7.2}/tests/test_validate.py +0 -0
{requirements_as_code-0.7.0/requirements_as_code.egg-info → requirements_as_code-0.7.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: requirements-as-code
|
|
3
|
-
Version: 0.7.
|
|
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
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
|
|
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
|
|