requirements-as-code 0.3.0__tar.gz → 0.4.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 (111) hide show
  1. {requirements_as_code-0.3.0/requirements_as_code.egg-info → requirements_as_code-0.4.2}/PKG-INFO +178 -14
  2. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/README.md +167 -12
  3. requirements_as_code-0.4.2/planning/adr/adr-001-markdown-first.md +21 -0
  4. requirements_as_code-0.4.2/planning/adr/adr-002-ai-optional.md +21 -0
  5. requirements_as_code-0.4.2/planning/adr/adr-003-structured-outputs-first.md +22 -0
  6. requirements_as_code-0.4.2/planning/adr/adr-004-artifact-model.md +24 -0
  7. requirements_as_code-0.4.2/planning/adr/adr-005-cli-first.md +30 -0
  8. requirements_as_code-0.4.2/planning/adr/adr-006-ingest-over-rewrite.md +20 -0
  9. requirements_as_code-0.4.2/planning/adr/adr-007-json-contract-stability.md +23 -0
  10. requirements_as_code-0.4.2/planning/adr/adr-008-agent-ready-architecture.md +40 -0
  11. requirements_as_code-0.4.2/planning/adr/adr-012-open-core-strategy.md +169 -0
  12. requirements_as_code-0.4.2/planning/adr/adr-013-leverage-existing-source-control-systems.md +201 -0
  13. requirements_as_code-0.4.2/planning/adr/adr-014-viewer-agnostic-knowledge-artifacts.md +181 -0
  14. requirements_as_code-0.4.2/planning/adr/adr-015-explorer-as-consumer.md +302 -0
  15. requirements_as_code-0.4.2/planning/adr/adr-016-rac-managed-knowledge-not-work.md +198 -0
  16. requirements_as_code-0.4.2/planning/roadmap/v0.3.1-formats.md +29 -0
  17. requirements_as_code-0.4.2/planning/roadmap/v0.4-inspect.md +43 -0
  18. requirements_as_code-0.4.2/planning/roadmap/v0.4.1-expansion.md +42 -0
  19. requirements_as_code-0.4.2/planning/roadmap/v0.4.1-inspect-expansion.md +355 -0
  20. requirements_as_code-0.4.2/planning/roadmap/v0.4.2-decision-metadata.md +298 -0
  21. requirements_as_code-0.4.2/planning/roadmap/v0.5.0-artifact-improvement.md +263 -0
  22. requirements_as_code-0.4.2/planning/roadmap/v0.5.1-guided-improvement.md +202 -0
  23. requirements_as_code-0.4.2/planning/roadmap/v0.8-explorer.md +392 -0
  24. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/pyproject.toml +16 -4
  25. requirements_as_code-0.4.2/rac/artifacts.py +89 -0
  26. requirements_as_code-0.4.2/rac/classification.py +102 -0
  27. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/cli.py +100 -12
  28. requirements_as_code-0.4.2/rac/fs.py +26 -0
  29. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/ingest.py +44 -5
  30. requirements_as_code-0.4.2/rac/inspect.py +158 -0
  31. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/models.py +5 -0
  32. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/outputs.py +136 -0
  33. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/parser.py +24 -2
  34. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/stats.py +78 -22
  35. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/validate.py +75 -0
  36. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2/requirements_as_code.egg-info}/PKG-INFO +178 -14
  37. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/requirements_as_code.egg-info/SOURCES.txt +31 -2
  38. requirements_as_code-0.4.2/requirements_as_code.egg-info/requires.txt +21 -0
  39. requirements_as_code-0.4.2/tests/fixtures/decision/bad_category.md +21 -0
  40. requirements_as_code-0.4.2/tests/fixtures/decision/bad_status.md +17 -0
  41. requirements_as_code-0.4.2/tests/fixtures/decision/minimal.md +13 -0
  42. requirements_as_code-0.4.2/tests/fixtures/decision/portfolio/01_accepted_arch.md +25 -0
  43. requirements_as_code-0.4.2/tests/fixtures/decision/portfolio/02_proposed_process.md +21 -0
  44. requirements_as_code-0.4.2/tests/fixtures/decision/portfolio/03_no_metadata.md +13 -0
  45. requirements_as_code-0.4.2/tests/fixtures/decision/with_metadata.md +26 -0
  46. requirements_as_code-0.4.2/tests/fixtures/inspect/ambiguous.md +9 -0
  47. requirements_as_code-0.4.2/tests/fixtures/inspect/decision.md +19 -0
  48. requirements_as_code-0.4.2/tests/fixtures/inspect/nested/another_requirement.md +9 -0
  49. requirements_as_code-0.4.2/tests/fixtures/inspect/requirement.md +14 -0
  50. requirements_as_code-0.4.2/tests/test_decision_metadata.py +188 -0
  51. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_ingest.py +86 -3
  52. requirements_as_code-0.4.2/tests/test_inspect.py +251 -0
  53. requirements_as_code-0.3.0/planning/adr/adr-001-markdown-first.md +0 -8
  54. requirements_as_code-0.3.0/planning/adr/adr-002-ai-optional.md +0 -7
  55. requirements_as_code-0.3.0/planning/adr/adr-003-structured-outputs-first.md +0 -9
  56. requirements_as_code-0.3.0/planning/adr/adr-004-artifact-model.md +0 -10
  57. requirements_as_code-0.3.0/planning/adr/adr-005-cli-first.md +0 -11
  58. requirements_as_code-0.3.0/planning/adr/adr-006-ingest-over-rewrite.md +0 -9
  59. requirements_as_code-0.3.0/planning/adr/adr-007-json-contract-stability.md +0 -17
  60. requirements_as_code-0.3.0/planning/adr/adr-008-agent-ready-architecture.md +0 -15
  61. requirements_as_code-0.3.0/planning/roadmap/v0.4-inspect.md +0 -34
  62. requirements_as_code-0.3.0/requirements_as_code.egg-info/requires.txt +0 -9
  63. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/.github/workflows/python-publish.yml +0 -0
  64. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/.gitignore +0 -0
  65. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/LICENSE +0 -0
  66. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/examples/example_dashboard_v1.md +0 -0
  67. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/examples/example_dashboard_v2.md +0 -0
  68. /requirements_as_code-0.3.0/planning/adr/adr-009-ai-assisted-development → /requirements_as_code-0.4.2/planning/adr/adr-009-ai-assisted-development.md +0 -0
  69. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/adr/adr-010-documents-are-not-artifacts.md +0 -0
  70. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/adr/adr-011-file-first-pipeline.md +0 -0
  71. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.0-workspace-analysis.md +0 -0
  72. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.1-review-engine.md +0 -0
  73. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.2-mcp-server.md +0 -0
  74. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.4-claude-skills.md +0 -0
  75. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.4-python-sdk.md +0 -0
  76. {requirements_as_code-0.3.0/planning/roadmap → requirements_as_code-0.4.2/planning/roadmap/archive}/v0.5-decisions.md +0 -0
  77. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/roadmap/v0.2-stats.md +0 -0
  78. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/roadmap/v0.3-ingest.md +0 -0
  79. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/roadmap/v0.6-roadmaps.md +0 -0
  80. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/roadmap/v0.7-prompts.md +0 -0
  81. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/__init__.py +0 -0
  82. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/diff.py +0 -0
  83. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/requirements_as_code.egg-info/dependency_links.txt +0 -0
  84. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/requirements_as_code.egg-info/entry_points.txt +0 -0
  85. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/requirements_as_code.egg-info/top_level.txt +0 -0
  86. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/setup.cfg +0 -0
  87. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/conftest.py +0 -0
  88. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/diff/new.md +0 -0
  89. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/diff/old.md +0 -0
  90. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/ingest/sample.md +0 -0
  91. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/duplicate_ids.md +0 -0
  92. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/empty_req_text.md +0 -0
  93. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/malformed_id.md +0 -0
  94. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/missing_id.md +0 -0
  95. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/missing_problem.md +0 -0
  96. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/missing_requirements.md +0 -0
  97. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/missing_title.md +0 -0
  98. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/multiple_titles.md +0 -0
  99. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/portfolio/broken.md +0 -0
  100. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/portfolio/feature_a.md +0 -0
  101. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/portfolio/feature_b.md +0 -0
  102. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/portfolio/sub/feature_c.md +0 -0
  103. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/valid/bullet_requirements.md +0 -0
  104. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/valid/feature.md +0 -0
  105. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/valid/minimal.md +0 -0
  106. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/valid/warnings.md +0 -0
  107. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_cli.py +0 -0
  108. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_diff.py +0 -0
  109. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_parser.py +0 -0
  110. {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_stats.py +0 -0
  111. {requirements_as_code-0.3.0 → requirements_as_code-0.4.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.3.0
3
+ Version: 0.4.2
4
4
  Summary: RAC — lint and diff product requirements written in Markdown.
5
5
  Author: tcballard
6
6
  License-Expression: MIT
@@ -23,10 +23,19 @@ License-File: LICENSE
23
23
  Requires-Dist: markdown-it-py>=3.0
24
24
  Provides-Extra: ingest
25
25
  Requires-Dist: markitdown[docx]; extra == "ingest"
26
+ Provides-Extra: ingest-pdf
27
+ Requires-Dist: markitdown[pdf]; extra == "ingest-pdf"
28
+ Provides-Extra: ingest-office
29
+ Requires-Dist: markitdown[pptx,xls,xlsx]; extra == "ingest-office"
30
+ Provides-Extra: ingest-all
31
+ Requires-Dist: markitdown[docx,pdf,pptx,xls,xlsx]; extra == "ingest-all"
26
32
  Provides-Extra: dev
27
33
  Requires-Dist: pytest>=7.0; extra == "dev"
28
- Requires-Dist: markitdown[docx]; extra == "dev"
34
+ Requires-Dist: markitdown[docx,pdf,pptx,xls,xlsx]; extra == "dev"
29
35
  Requires-Dist: python-docx; extra == "dev"
36
+ Requires-Dist: python-pptx; extra == "dev"
37
+ Requires-Dist: openpyxl; extra == "dev"
38
+ Requires-Dist: reportlab; extra == "dev"
30
39
  Dynamic: license-file
31
40
 
32
41
  # RAC (Requirements-as-Code)
@@ -410,14 +419,36 @@ Invalid Features (1)
410
419
  ./features/draft.md — missing-title, missing-requirements
411
420
  ```
412
421
 
413
- Counts span all parsed files; a feature with only *warnings* (e.g. no metrics)
414
- still counts as valid. Invalid files are listed at the end so they are never
415
- silently skipped.
422
+ Counts span all parsed requirement files; a feature with only *warnings* (e.g. no
423
+ metrics) still counts as valid. Invalid files are listed at the end so they are
424
+ never silently skipped.
416
425
 
417
- Add `--json` for machine-readable output. `stats` exits `0` when the directory
418
- has at least one valid feature, `1` if none are valid, and `2` if the path is
419
- not a directory. (A `--strict` flag for failing on *any* invalid file handy in
420
- CI — is planned.)
426
+ Decision artifacts are aggregated **separately** so they never distort the
427
+ requirement totals or averages. When a directory contains decisions, a
428
+ `Decisions` section reports the count plus a status and category breakdown:
429
+
430
+ ```text
431
+ Decisions
432
+ =========
433
+
434
+ Total: 17
435
+
436
+ Status
437
+ - Accepted: 12
438
+ - Proposed: 3
439
+ - Superseded: 2
440
+
441
+ Category
442
+ - Architecture: 8
443
+ - Product: 5
444
+ - Process: 4
445
+ ```
446
+
447
+ Add `--json` for machine-readable output (a `decisions` block is included only
448
+ when decisions are present). `stats` exits `0` when the directory has at least
449
+ one valid feature or decision, `1` if none, and `2` if the path is not a
450
+ directory. (A `--strict` flag for failing on *any* invalid file — handy in CI —
451
+ is planned.)
421
452
 
422
453
  ---
423
454
 
@@ -430,21 +461,32 @@ the result is a valid RAC artifact (that is the job of future `inspect` /
430
461
 
431
462
  ```bash
432
463
  rac ingest spec.docx # print converted Markdown (preview)
464
+ rac ingest spec.docx --stdout # same, explicit (handy in pipelines)
433
465
  rac ingest spec.docx -o spec.md # write it to a file
434
466
  rac ingest spec.docx -o spec.md --force # overwrite an existing file
435
467
  rac ingest spec.docx --json # { source, converter, output, markdown }
436
468
  ```
437
469
 
438
470
  Conversion is powered by [MarkItDown](https://github.com/microsoft/markitdown),
439
- installed via the optional `ingest` extra:
471
+ installed via optional extras — split by format so you only pull the readers you
472
+ need:
473
+
474
+ | Extra | Adds | Formats |
475
+ |-------|------|---------|
476
+ | `ingest` | `markitdown[docx]` | DOCX, HTML, Markdown |
477
+ | `ingest-pdf` | `markitdown[pdf]` | + PDF |
478
+ | `ingest-office` | `markitdown[pptx,xlsx,xls]` | + PPTX, XLSX, XLS |
479
+ | `ingest-all` | everything above | all supported formats |
440
480
 
441
481
  ```bash
442
- pip install "requirements-as-code[ingest]"
482
+ pip install "requirements-as-code[ingest]" # DOCX + HTML + Markdown
483
+ pip install "requirements-as-code[ingest-all]" # everything
443
484
  ```
444
485
 
445
- Supported today: **DOCX** and **Markdown** (pass-through). HTML and PDF are
446
- planned for v0.3.x. Converters live behind a `DocumentConverter` abstraction, so
447
- new sources can be added without changing the CLI.
486
+ HTML and Markdown need no extra (HTML is built into MarkItDown; Markdown is a
487
+ pass-through). If a file's reader isn't installed, `rac ingest` tells you exactly
488
+ which extra to install. Converters live behind a `DocumentConverter` abstraction,
489
+ so new sources can be added without changing the CLI.
448
490
 
449
491
  `ingest` exits `0` on success, `1` if a recognized document fails to convert, and
450
492
  `2` for usage errors (file not found, unsupported type, missing `ingest` extra,
@@ -452,6 +494,128 @@ or an existing output file without `--force`).
452
494
 
453
495
  ---
454
496
 
497
+ ## Inspect
498
+
499
+ Identify what kind of artifact a Markdown document is, and report which expected
500
+ sections are present or missing. Inspection is **read-only and observational** —
501
+ it answers *"what is this?"*, not *"how should I improve it?"* (that's a future
502
+ `improve` command).
503
+
504
+ ```bash
505
+ rac inspect bond-dashboard.md
506
+ rac inspect bond-dashboard.md --json
507
+ cat decision.md | rac inspect - # read from stdin
508
+ rac ingest prd.docx --stdout | rac inspect - # ingest then inspect
509
+ ```
510
+
511
+ Output:
512
+
513
+ ```text
514
+ Artifact Type: Requirement
515
+ Confidence: 71%
516
+
517
+ Present Sections:
518
+ ✓ Problem
519
+ ✓ Requirements
520
+ ✓ Success Metrics
521
+
522
+ Missing Sections:
523
+ ✗ Risks
524
+ ✗ Assumptions
525
+ ```
526
+
527
+ RAC classifies the document against known artifact schemas (no AI) and reports a
528
+ confidence score. v0.4 recognizes **Requirement** and **Decision** artifacts;
529
+ anything that doesn't fit well is reported as **Unknown** (a valid, successful
530
+ result — not an error). `--json` emits `{ type, confidence, present_sections,
531
+ missing_sections }`.
532
+
533
+ ### Inspect a directory
534
+
535
+ Point `inspect` at a directory to get a summary across many files (recursive by
536
+ default; `--top-level` limits it to the directory's own files):
537
+
538
+ ```bash
539
+ rac inspect planning/
540
+ rac inspect planning/ --top-level
541
+ rac inspect planning/ --json # versioned summary + per-file array
542
+ ```
543
+
544
+ ```text
545
+ Files Inspected: 23
546
+
547
+ Requirements: 7
548
+ Decisions: 3
549
+ Unknown: 13
550
+ ```
551
+
552
+ ### Explain a classification (`--verbose`)
553
+
554
+ ```bash
555
+ rac inspect bond-dashboard.md --verbose
556
+ ```
557
+
558
+ ```text
559
+ Artifact Type: Requirement
560
+ Confidence: 71%
561
+
562
+ Required Matches:
563
+ ✓ Problem
564
+ ✓ Requirements
565
+
566
+ Recommended Matches:
567
+ ✓ Success Metrics
568
+
569
+ Missing:
570
+ ✗ Risks
571
+ ✗ Assumptions
572
+
573
+ Score: 2 + 0.5 × 1 = 2.5 / 3.5 = 0.71
574
+ ```
575
+
576
+ ### Decision metadata
577
+
578
+ Decision artifacts (ADRs) may carry lightweight, optional metadata. When present,
579
+ `inspect` extracts it and `validate` checks the values:
580
+
581
+ ```markdown
582
+ ## Status
583
+
584
+ Accepted
585
+
586
+ ## Category
587
+
588
+ Architecture
589
+
590
+ ## Supersedes
591
+
592
+ ADR-012
593
+ ```
594
+
595
+ | Field | Supported values | Validated? |
596
+ |------------|--------------------------------------------------------------|------------|
597
+ | Status | Proposed, Accepted, Superseded, Deprecated | yes |
598
+ | Category | Architecture, Product, Process, Technical, Other | yes |
599
+ | Supersedes | any reference (free text) | no — metadata only |
600
+
601
+ `inspect` surfaces these under a **Decision Metadata** block (and in `--json` as
602
+ `status` / `category` / `supersedes`, present only when declared). Metadata is
603
+ **optional**: a decision without it is still valid. Only an *unsupported* Status
604
+ or Category value fails validation (`invalid-decision-status` /
605
+ `invalid-decision-category`); values are matched case-insensitively.
606
+
607
+ ### Synonyms
608
+
609
+ Common heading variants are recognized automatically (case-insensitive,
610
+ deterministic) — e.g. `Success Criteria` and `KPIs` both count as Success Metrics,
611
+ and `Alternatives` counts as Alternatives Considered.
612
+
613
+ `inspect` exits `0` for any completed inspection (including Unknown) and `2` for
614
+ usage errors (file not found, or a non-Markdown file — convert it with
615
+ `rac ingest` first).
616
+
617
+ ---
618
+
455
619
  ## Review (Planned)
456
620
 
457
621
  AI-assisted product review.
@@ -379,14 +379,36 @@ Invalid Features (1)
379
379
  ./features/draft.md — missing-title, missing-requirements
380
380
  ```
381
381
 
382
- Counts span all parsed files; a feature with only *warnings* (e.g. no metrics)
383
- still counts as valid. Invalid files are listed at the end so they are never
384
- silently skipped.
382
+ Counts span all parsed requirement files; a feature with only *warnings* (e.g. no
383
+ metrics) still counts as valid. Invalid files are listed at the end so they are
384
+ never silently skipped.
385
385
 
386
- Add `--json` for machine-readable output. `stats` exits `0` when the directory
387
- has at least one valid feature, `1` if none are valid, and `2` if the path is
388
- not a directory. (A `--strict` flag for failing on *any* invalid file handy in
389
- CI — is planned.)
386
+ Decision artifacts are aggregated **separately** so they never distort the
387
+ requirement totals or averages. When a directory contains decisions, a
388
+ `Decisions` section reports the count plus a status and category breakdown:
389
+
390
+ ```text
391
+ Decisions
392
+ =========
393
+
394
+ Total: 17
395
+
396
+ Status
397
+ - Accepted: 12
398
+ - Proposed: 3
399
+ - Superseded: 2
400
+
401
+ Category
402
+ - Architecture: 8
403
+ - Product: 5
404
+ - Process: 4
405
+ ```
406
+
407
+ Add `--json` for machine-readable output (a `decisions` block is included only
408
+ when decisions are present). `stats` exits `0` when the directory has at least
409
+ one valid feature or decision, `1` if none, and `2` if the path is not a
410
+ directory. (A `--strict` flag for failing on *any* invalid file — handy in CI —
411
+ is planned.)
390
412
 
391
413
  ---
392
414
 
@@ -399,21 +421,32 @@ the result is a valid RAC artifact (that is the job of future `inspect` /
399
421
 
400
422
  ```bash
401
423
  rac ingest spec.docx # print converted Markdown (preview)
424
+ rac ingest spec.docx --stdout # same, explicit (handy in pipelines)
402
425
  rac ingest spec.docx -o spec.md # write it to a file
403
426
  rac ingest spec.docx -o spec.md --force # overwrite an existing file
404
427
  rac ingest spec.docx --json # { source, converter, output, markdown }
405
428
  ```
406
429
 
407
430
  Conversion is powered by [MarkItDown](https://github.com/microsoft/markitdown),
408
- installed via the optional `ingest` extra:
431
+ installed via optional extras — split by format so you only pull the readers you
432
+ need:
433
+
434
+ | Extra | Adds | Formats |
435
+ |-------|------|---------|
436
+ | `ingest` | `markitdown[docx]` | DOCX, HTML, Markdown |
437
+ | `ingest-pdf` | `markitdown[pdf]` | + PDF |
438
+ | `ingest-office` | `markitdown[pptx,xlsx,xls]` | + PPTX, XLSX, XLS |
439
+ | `ingest-all` | everything above | all supported formats |
409
440
 
410
441
  ```bash
411
- pip install "requirements-as-code[ingest]"
442
+ pip install "requirements-as-code[ingest]" # DOCX + HTML + Markdown
443
+ pip install "requirements-as-code[ingest-all]" # everything
412
444
  ```
413
445
 
414
- Supported today: **DOCX** and **Markdown** (pass-through). HTML and PDF are
415
- planned for v0.3.x. Converters live behind a `DocumentConverter` abstraction, so
416
- new sources can be added without changing the CLI.
446
+ HTML and Markdown need no extra (HTML is built into MarkItDown; Markdown is a
447
+ pass-through). If a file's reader isn't installed, `rac ingest` tells you exactly
448
+ which extra to install. Converters live behind a `DocumentConverter` abstraction,
449
+ so new sources can be added without changing the CLI.
417
450
 
418
451
  `ingest` exits `0` on success, `1` if a recognized document fails to convert, and
419
452
  `2` for usage errors (file not found, unsupported type, missing `ingest` extra,
@@ -421,6 +454,128 @@ or an existing output file without `--force`).
421
454
 
422
455
  ---
423
456
 
457
+ ## Inspect
458
+
459
+ Identify what kind of artifact a Markdown document is, and report which expected
460
+ sections are present or missing. Inspection is **read-only and observational** —
461
+ it answers *"what is this?"*, not *"how should I improve it?"* (that's a future
462
+ `improve` command).
463
+
464
+ ```bash
465
+ rac inspect bond-dashboard.md
466
+ rac inspect bond-dashboard.md --json
467
+ cat decision.md | rac inspect - # read from stdin
468
+ rac ingest prd.docx --stdout | rac inspect - # ingest then inspect
469
+ ```
470
+
471
+ Output:
472
+
473
+ ```text
474
+ Artifact Type: Requirement
475
+ Confidence: 71%
476
+
477
+ Present Sections:
478
+ ✓ Problem
479
+ ✓ Requirements
480
+ ✓ Success Metrics
481
+
482
+ Missing Sections:
483
+ ✗ Risks
484
+ ✗ Assumptions
485
+ ```
486
+
487
+ RAC classifies the document against known artifact schemas (no AI) and reports a
488
+ confidence score. v0.4 recognizes **Requirement** and **Decision** artifacts;
489
+ anything that doesn't fit well is reported as **Unknown** (a valid, successful
490
+ result — not an error). `--json` emits `{ type, confidence, present_sections,
491
+ missing_sections }`.
492
+
493
+ ### Inspect a directory
494
+
495
+ Point `inspect` at a directory to get a summary across many files (recursive by
496
+ default; `--top-level` limits it to the directory's own files):
497
+
498
+ ```bash
499
+ rac inspect planning/
500
+ rac inspect planning/ --top-level
501
+ rac inspect planning/ --json # versioned summary + per-file array
502
+ ```
503
+
504
+ ```text
505
+ Files Inspected: 23
506
+
507
+ Requirements: 7
508
+ Decisions: 3
509
+ Unknown: 13
510
+ ```
511
+
512
+ ### Explain a classification (`--verbose`)
513
+
514
+ ```bash
515
+ rac inspect bond-dashboard.md --verbose
516
+ ```
517
+
518
+ ```text
519
+ Artifact Type: Requirement
520
+ Confidence: 71%
521
+
522
+ Required Matches:
523
+ ✓ Problem
524
+ ✓ Requirements
525
+
526
+ Recommended Matches:
527
+ ✓ Success Metrics
528
+
529
+ Missing:
530
+ ✗ Risks
531
+ ✗ Assumptions
532
+
533
+ Score: 2 + 0.5 × 1 = 2.5 / 3.5 = 0.71
534
+ ```
535
+
536
+ ### Decision metadata
537
+
538
+ Decision artifacts (ADRs) may carry lightweight, optional metadata. When present,
539
+ `inspect` extracts it and `validate` checks the values:
540
+
541
+ ```markdown
542
+ ## Status
543
+
544
+ Accepted
545
+
546
+ ## Category
547
+
548
+ Architecture
549
+
550
+ ## Supersedes
551
+
552
+ ADR-012
553
+ ```
554
+
555
+ | Field | Supported values | Validated? |
556
+ |------------|--------------------------------------------------------------|------------|
557
+ | Status | Proposed, Accepted, Superseded, Deprecated | yes |
558
+ | Category | Architecture, Product, Process, Technical, Other | yes |
559
+ | Supersedes | any reference (free text) | no — metadata only |
560
+
561
+ `inspect` surfaces these under a **Decision Metadata** block (and in `--json` as
562
+ `status` / `category` / `supersedes`, present only when declared). Metadata is
563
+ **optional**: a decision without it is still valid. Only an *unsupported* Status
564
+ or Category value fails validation (`invalid-decision-status` /
565
+ `invalid-decision-category`); values are matched case-insensitively.
566
+
567
+ ### Synonyms
568
+
569
+ Common heading variants are recognized automatically (case-insensitive,
570
+ deterministic) — e.g. `Success Criteria` and `KPIs` both count as Success Metrics,
571
+ and `Alternatives` counts as Alternatives Considered.
572
+
573
+ `inspect` exits `0` for any completed inspection (including Unknown) and `2` for
574
+ usage errors (file not found, or a non-Markdown file — convert it with
575
+ `rac ingest` first).
576
+
577
+ ---
578
+
424
579
  ## Review (Planned)
425
580
 
426
581
  AI-assisted product review.
@@ -0,0 +1,21 @@
1
+ # ADR-001 Markdown First
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ RAC needs a single canonical source format for requirements and other artifacts.
10
+
11
+ ## Decision
12
+
13
+ Markdown is the canonical source format.
14
+
15
+ ## Consequences
16
+
17
+ ### Positive
18
+
19
+ - Human-readable
20
+ - Git-friendly
21
+ - Tool-independent
@@ -0,0 +1,21 @@
1
+ # ADR-002 AI Optional
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ RAC should be useful on its own, with AI as an enhancement rather than a dependency.
10
+
11
+ ## Decision
12
+
13
+ RAC must provide value without AI.
14
+
15
+ ## Consequences
16
+
17
+ ### Positive
18
+
19
+ - Lower complexity
20
+ - Easier testing
21
+ - Works offline
@@ -0,0 +1,22 @@
1
+ # ADR-003 Structured Outputs First
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ RAC commands need to be consumable by scripts, SDKs, and future integrations — not just humans.
10
+
11
+ ## Decision
12
+
13
+ Every command returns typed result models.
14
+
15
+ ## Consequences
16
+
17
+ ### Positive
18
+
19
+ - JSON output becomes trivial
20
+ - SDK usage becomes trivial
21
+ - MCP integration becomes trivial
22
+ - CI integration becomes trivial
@@ -0,0 +1,24 @@
1
+ # ADR-004 Artifact Model
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ Not all documents are the same kind of knowledge. RAC needs a model that can grow beyond requirements.
10
+
11
+ ## Decision
12
+
13
+ RAC analyzes typed artifacts rather than generic documents. Planned artifact types include Requirement, Decision, Roadmap, Prompt, and Meeting.
14
+
15
+ ## Consequences
16
+
17
+ ### Positive
18
+
19
+ - Provides the bridge to v0.5+ artifact types
20
+ - Each artifact type can have its own structure and validation
21
+
22
+ ### Negative
23
+
24
+ - More modeling work as new artifact types are added
@@ -0,0 +1,30 @@
1
+ # ADR-005 CLI First
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ RAC needs a primary interface that ships quickly and automates well.
10
+
11
+ ## Decision
12
+
13
+ The CLI is the primary interface.
14
+
15
+ ## Alternatives Considered
16
+
17
+ ### Web app / SaaS / Browser extension
18
+
19
+ Cons:
20
+ - Slower path to value
21
+ - Harder to automate
22
+ - Heavier infrastructure
23
+
24
+ ## Consequences
25
+
26
+ ### Positive
27
+
28
+ - Fastest path to value
29
+ - Easy automation
30
+ - Easy AI integration later
@@ -0,0 +1,20 @@
1
+ # ADR-006 Ingestion Over Rewrite
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ People already have product knowledge in PDFs, Word docs, and Notion exports.
10
+
11
+ ## Decision
12
+
13
+ Users should not have to rewrite existing documents; RAC should adapt to them via ingestion.
14
+
15
+ ## Consequences
16
+
17
+ ### Positive
18
+
19
+ - Lower barrier to adoption
20
+ - RAC meets users where their knowledge already lives
@@ -0,0 +1,23 @@
1
+ # ADR-007 JSON Contract Stability
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ RAC's JSON output is consumed by scripts and will be consumed by future MCP integrations.
10
+
11
+ ## Decision
12
+
13
+ JSON outputs are treated as public APIs. Field names (for example `features`) will not change to alternatives (for example `feature_count`) without explicit versioning.
14
+
15
+ ## Consequences
16
+
17
+ ### Positive
18
+
19
+ - Stable contract for scripts and MCP integrations
20
+
21
+ ### Negative
22
+
23
+ - Schema changes require a versioning strategy
@@ -0,0 +1,40 @@
1
+ # ADR-008 Agent Ready Architecture
2
+
3
+ ## Status
4
+
5
+ Accepted
6
+
7
+ ## Context
8
+
9
+ Future versions of RAC may be used by Claude, Codex, Cursor, and other AI systems.
10
+
11
+ The architecture should avoid coupling business logic to the CLI.
12
+
13
+ ## Decision
14
+
15
+ All RAC capabilities will be implemented in reusable service layers.
16
+
17
+ The CLI will be a thin wrapper around those services.
18
+
19
+ ## Alternatives Considered
20
+
21
+ ### CLI-only Architecture
22
+
23
+ Pros:
24
+ - Simpler initially
25
+
26
+ Cons:
27
+ - Difficult to expose as SDK or MCP server
28
+
29
+ ## Consequences
30
+
31
+ ### Positive
32
+
33
+ - Easy MCP support
34
+ - Easy SDK support
35
+ - Easier testing
36
+
37
+ ### Negative
38
+
39
+ - Slightly more abstraction
40
+ - Additional project structure