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.
- {requirements_as_code-0.3.0/requirements_as_code.egg-info → requirements_as_code-0.4.2}/PKG-INFO +178 -14
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/README.md +167 -12
- requirements_as_code-0.4.2/planning/adr/adr-001-markdown-first.md +21 -0
- requirements_as_code-0.4.2/planning/adr/adr-002-ai-optional.md +21 -0
- requirements_as_code-0.4.2/planning/adr/adr-003-structured-outputs-first.md +22 -0
- requirements_as_code-0.4.2/planning/adr/adr-004-artifact-model.md +24 -0
- requirements_as_code-0.4.2/planning/adr/adr-005-cli-first.md +30 -0
- requirements_as_code-0.4.2/planning/adr/adr-006-ingest-over-rewrite.md +20 -0
- requirements_as_code-0.4.2/planning/adr/adr-007-json-contract-stability.md +23 -0
- requirements_as_code-0.4.2/planning/adr/adr-008-agent-ready-architecture.md +40 -0
- requirements_as_code-0.4.2/planning/adr/adr-012-open-core-strategy.md +169 -0
- requirements_as_code-0.4.2/planning/adr/adr-013-leverage-existing-source-control-systems.md +201 -0
- requirements_as_code-0.4.2/planning/adr/adr-014-viewer-agnostic-knowledge-artifacts.md +181 -0
- requirements_as_code-0.4.2/planning/adr/adr-015-explorer-as-consumer.md +302 -0
- requirements_as_code-0.4.2/planning/adr/adr-016-rac-managed-knowledge-not-work.md +198 -0
- requirements_as_code-0.4.2/planning/roadmap/v0.3.1-formats.md +29 -0
- requirements_as_code-0.4.2/planning/roadmap/v0.4-inspect.md +43 -0
- requirements_as_code-0.4.2/planning/roadmap/v0.4.1-expansion.md +42 -0
- requirements_as_code-0.4.2/planning/roadmap/v0.4.1-inspect-expansion.md +355 -0
- requirements_as_code-0.4.2/planning/roadmap/v0.4.2-decision-metadata.md +298 -0
- requirements_as_code-0.4.2/planning/roadmap/v0.5.0-artifact-improvement.md +263 -0
- requirements_as_code-0.4.2/planning/roadmap/v0.5.1-guided-improvement.md +202 -0
- requirements_as_code-0.4.2/planning/roadmap/v0.8-explorer.md +392 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/pyproject.toml +16 -4
- requirements_as_code-0.4.2/rac/artifacts.py +89 -0
- requirements_as_code-0.4.2/rac/classification.py +102 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/cli.py +100 -12
- requirements_as_code-0.4.2/rac/fs.py +26 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/ingest.py +44 -5
- requirements_as_code-0.4.2/rac/inspect.py +158 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/models.py +5 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/outputs.py +136 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/parser.py +24 -2
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/stats.py +78 -22
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/validate.py +75 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2/requirements_as_code.egg-info}/PKG-INFO +178 -14
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/requirements_as_code.egg-info/SOURCES.txt +31 -2
- requirements_as_code-0.4.2/requirements_as_code.egg-info/requires.txt +21 -0
- requirements_as_code-0.4.2/tests/fixtures/decision/bad_category.md +21 -0
- requirements_as_code-0.4.2/tests/fixtures/decision/bad_status.md +17 -0
- requirements_as_code-0.4.2/tests/fixtures/decision/minimal.md +13 -0
- requirements_as_code-0.4.2/tests/fixtures/decision/portfolio/01_accepted_arch.md +25 -0
- requirements_as_code-0.4.2/tests/fixtures/decision/portfolio/02_proposed_process.md +21 -0
- requirements_as_code-0.4.2/tests/fixtures/decision/portfolio/03_no_metadata.md +13 -0
- requirements_as_code-0.4.2/tests/fixtures/decision/with_metadata.md +26 -0
- requirements_as_code-0.4.2/tests/fixtures/inspect/ambiguous.md +9 -0
- requirements_as_code-0.4.2/tests/fixtures/inspect/decision.md +19 -0
- requirements_as_code-0.4.2/tests/fixtures/inspect/nested/another_requirement.md +9 -0
- requirements_as_code-0.4.2/tests/fixtures/inspect/requirement.md +14 -0
- requirements_as_code-0.4.2/tests/test_decision_metadata.py +188 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_ingest.py +86 -3
- requirements_as_code-0.4.2/tests/test_inspect.py +251 -0
- requirements_as_code-0.3.0/planning/adr/adr-001-markdown-first.md +0 -8
- requirements_as_code-0.3.0/planning/adr/adr-002-ai-optional.md +0 -7
- requirements_as_code-0.3.0/planning/adr/adr-003-structured-outputs-first.md +0 -9
- requirements_as_code-0.3.0/planning/adr/adr-004-artifact-model.md +0 -10
- requirements_as_code-0.3.0/planning/adr/adr-005-cli-first.md +0 -11
- requirements_as_code-0.3.0/planning/adr/adr-006-ingest-over-rewrite.md +0 -9
- requirements_as_code-0.3.0/planning/adr/adr-007-json-contract-stability.md +0 -17
- requirements_as_code-0.3.0/planning/adr/adr-008-agent-ready-architecture.md +0 -15
- requirements_as_code-0.3.0/planning/roadmap/v0.4-inspect.md +0 -34
- requirements_as_code-0.3.0/requirements_as_code.egg-info/requires.txt +0 -9
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/.github/workflows/python-publish.yml +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/.gitignore +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/LICENSE +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/examples/example_dashboard_v1.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/examples/example_dashboard_v2.md +0 -0
- /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
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/adr/adr-010-documents-are-not-artifacts.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/adr/adr-011-file-first-pipeline.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.0-workspace-analysis.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.1-review-engine.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.2-mcp-server.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.4-claude-skills.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/future/v1.4-python-sdk.md +0 -0
- {requirements_as_code-0.3.0/planning/roadmap → requirements_as_code-0.4.2/planning/roadmap/archive}/v0.5-decisions.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/roadmap/v0.2-stats.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/roadmap/v0.3-ingest.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/roadmap/v0.6-roadmaps.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/planning/roadmap/v0.7-prompts.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/__init__.py +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/rac/diff.py +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/requirements_as_code.egg-info/dependency_links.txt +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/requirements_as_code.egg-info/entry_points.txt +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/requirements_as_code.egg-info/top_level.txt +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/setup.cfg +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/conftest.py +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/diff/new.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/diff/old.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/ingest/sample.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/duplicate_ids.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/empty_req_text.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/malformed_id.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/missing_id.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/missing_problem.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/missing_requirements.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/missing_title.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/invalid/multiple_titles.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/portfolio/broken.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/portfolio/feature_a.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/portfolio/feature_b.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/portfolio/sub/feature_c.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/valid/bullet_requirements.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/valid/feature.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/valid/minimal.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/fixtures/valid/warnings.md +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_cli.py +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_diff.py +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_parser.py +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_stats.py +0 -0
- {requirements_as_code-0.3.0 → requirements_as_code-0.4.2}/tests/test_validate.py +0 -0
{requirements_as_code-0.3.0/requirements_as_code.egg-info → requirements_as_code-0.4.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: requirements-as-code
|
|
3
|
-
Version: 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
|
|
414
|
-
still counts as valid. Invalid files are listed at the end so they are
|
|
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
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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
|
|
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
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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
|
|
383
|
-
still counts as valid. Invalid files are listed at the end so they are
|
|
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
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
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
|
|
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
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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
|