@stravica-ai/rcf-schemas 0.4.5 → 0.5.1

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 (35) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +2 -2
  3. package/docs/adr.md +1 -1
  4. package/docs/build-sequence.md +1 -1
  5. package/docs/cn.md +1 -1
  6. package/docs/common.md +1 -1
  7. package/docs/fbs.md +1 -1
  8. package/docs/manifest.md +1 -1
  9. package/docs/prd.md +1 -1
  10. package/docs/req.md +1 -1
  11. package/docs/tac.md +1 -1
  12. package/docs/tad.md +1 -1
  13. package/docs/test-suite.md +6 -2
  14. package/docs/user-story.md +1 -1
  15. package/fixtures/invalid/manifest/manifest-022-library-prefix-bad-slug.json +16 -0
  16. package/fixtures/invalid/test-suite/ts-008-passing-tc-missing-testpointer.json +19 -0
  17. package/fixtures/invalid/test-suite/ts-009-failing-tc-missing-testpointer.json +19 -0
  18. package/fixtures/invalid/test-suite/ts-010-empty-testpointer.json +20 -0
  19. package/fixtures/valid/manifest/manifest-013-blueprint-library-prefix.json +25 -0
  20. package/fixtures/valid/test-suite/ts-003-runtime-provenance.json +1 -0
  21. package/fixtures/valid/test-suite/ts-004-widened-tsId.json +2 -0
  22. package/fixtures/valid/test-suite/ts-006-testpointer-conditional.json +46 -0
  23. package/package.json +6 -6
  24. package/schemas/adr.schema.json +10 -10
  25. package/schemas/build-sequence.schema.json +7 -7
  26. package/schemas/cn.schema.json +8 -8
  27. package/schemas/common.schema.json +1 -1
  28. package/schemas/fbs.schema.json +17 -17
  29. package/schemas/manifest.schema.json +56 -52
  30. package/schemas/prd.schema.json +6 -6
  31. package/schemas/req.schema.json +9 -9
  32. package/schemas/tac.schema.json +9 -9
  33. package/schemas/tad.schema.json +7 -7
  34. package/schemas/test-suite.schema.json +29 -12
  35. package/schemas/user-story.schema.json +13 -13
package/CHANGELOG.md CHANGED
@@ -4,6 +4,51 @@ All notable changes to `@stravica-ai/rcf-schemas` are documented in this file.
4
4
 
5
5
  The format roughly follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Pre-1.0 breaking changes are signalled by a minor bump per semver 0.x convention.
6
6
 
7
+ ## 0.5.1 - 2026-08-31
8
+
9
+ Additive patch bump for the external-blueprint-library mechanism landing in `rcf-lite`. Adds one optional field on the applied-blueprint record so a project can durably record which registered library an apply resolved through, without the ownership fact having to be re-derived by string-matching `source`. Every change is additive: every 0.5.0-valid document remains valid, and every existing id continues to validate byte-for-byte.
10
+
11
+ ### Added
12
+
13
+ - **`manifest.schema.json`**: new optional `libraryPrefix` on `$defs.appliedBlueprintRecord`, referencing `common.$defs.blueprintSlug`. Stamped when an apply resolves through a registered external blueprint library (for example, an apply of `acme:spa` stamps `libraryPrefix: acme`); absent for shelf and path applies. Once stamped, the record's `libraryPrefix` is the ownership fact: the library registry may be renamed, re-pointed, or unregistered without orphaning previously applied records. Written by the library-resolving branch of `rcf blueprint add`; read by `rcf library remove`'s ownership check in preference to `source`-prefix matching.
14
+ - Fixtures (valid): `fixtures/valid/manifest/manifest-013-blueprint-library-prefix.json` (one library-applied blueprint with `libraryPrefix` stamped, alongside a shelf-applied blueprint with no `libraryPrefix`).
15
+ - Fixtures (invalid): `fixtures/invalid/manifest/manifest-022-library-prefix-bad-slug.json` (uppercase `libraryPrefix`, violates the `blueprintSlug` shape).
16
+ - Tests: `libraryPrefix` cases added to `manifest.test.js` covering the happy path (stamped alone, coexists with `namespace` and `contributions`), the shelf/path back-compat case (record without `libraryPrefix` still validates), a mixed library-and-shelf record, the two reject cases (uppercase, leading-hyphen), and a pre-0.5.1 back-compat case that keeps a `blueprints[]` record without `libraryPrefix` valid.
17
+
18
+ ### Notes
19
+
20
+ - Additive-only: every 0.5.0-valid document remains valid. `additionalProperties: false` on the record is preserved: `libraryPrefix` is the only new permitted property.
21
+ - Canonical `$id` URLs stay at `v0.5.0`, following the patch-release precedent set at 0.2.1, 0.3.1, 0.4.1, 0.4.2, 0.4.3, 0.4.4, and 0.4.5.
22
+ - Version choice: per repo precedent (every additive change since 0.2.0 has bumped as a patch), this bumps `0.5.0 -> 0.5.1`.
23
+
24
+ ## 0.5.0 - 2026-08-28
25
+
26
+ Minor bump for the `testPointer` conditional-by-status ruling (`w-2026-08-27-dave-001`, Baz ratified 2026-08-27). `testPointer` on a Test Case is now REQUIRED when the TC's `status` is `passing` or `failing`, and OPTIONAL when the TC's `status` is `pending` or `skipped`. This closes the "a passing verdict may point at nothing" hole the 0.4.x shape allowed and moves the durable landing point for the rule out of `rcf-lite`'s local strictness overlay (`w-2026-07-28-005`) into the shared schema, where every consumer inherits it uniformly.
27
+
28
+ ### Changed
29
+
30
+ - **`test-suite.schema.json`**: `$defs.testCase.testPointer` gains `minLength: 1` (a `testPointer` present at all must be non-empty; empty-string pointers were the same class of dishonest-coverage failure as absent pointers). A new `allOf` clause on `$defs.testCase` conditionally requires `testPointer` when `status` is `passing` or `failing`; other statuses may still omit it. The `additionalProperties: false` guarantee is preserved: nothing new is permitted; only the requiredness on one existing field is tightened for two of the four status values.
31
+ - **Canonical `$id`** URLs bumped from `https://schemas.stravica.io/rcf/v0.4.0/...` to `https://schemas.stravica.io/rcf/v0.5.0/...` on every schema, in lock-step with the bundle version. Matches the precedent set at 0.3.0 and 0.4.0 (patch releases keep the URL pinned; minor releases bump the URL). No consumer in the Stravica org hard-codes the URL literal (org-wide search 2026-08-28 hit only this repo's own files); `rcf-lite`, `rcf-build-lite`, `rcf-tools`, and every persona-run repo load schemas by file path and register with whatever `$id` the file declares.
32
+ - **Documentation URLs bumped in lock-step.** The `docs/*.md` canonical-`$id` references were stale on `v0.3.0` (never bumped at 0.4.0); this release syncs every doc page and the `README.md` code example to `v0.5.0`.
33
+
34
+ ### Added
35
+
36
+ - **Fixtures (valid)**: `fixtures/valid/test-suite/ts-006-testpointer-conditional.json` (a five-TC suite exercising every branch: passing+pointer, failing+pointer, pending without pointer, skipped without pointer, and pending with a declared-intent pointer).
37
+ - **Fixtures (invalid)**: `fixtures/invalid/test-suite/ts-008-passing-tc-missing-testpointer.json`, `fixtures/invalid/test-suite/ts-009-failing-tc-missing-testpointer.json` (the two directions of the new required rule), `fixtures/invalid/test-suite/ts-010-empty-testpointer.json` (the `minLength: 1` guard against empty-string pointers).
38
+ - **Tests**: `test/test-suite.test.js` gains the conditional-required cases (pending/skipped without pointer still valid; passing/failing without pointer rejected with an error referencing `testPointer`; passing/failing with pointer valid; pending/skipped may still carry a declared pointer; empty-string pointer rejected; mixed-status suite valid). Existing tests that constructed `status: passing` TCs without `testPointer` were updated to include a pointer so they exercise their originally intended assertion (id-slug pattern, scope tags, runtime provenance, and so on) rather than fail on the new rule.
39
+
40
+ ### Migration
41
+
42
+ - **Pre-0.5.0 docs with only `pending`/`skipped` TCs missing `testPointer`**: remain valid unchanged.
43
+ - **Pre-0.5.0 docs with `passing` or `failing` TCs missing `testPointer`**: were already dishonest coverage claims; validate against 0.5.0 by either (a) adding the real `testPointer` (the honest fix; the pointer is what the TC is asserting exists), or (b) downgrading the TC to `pending` or `skipped` if no executable landed. `rcf-lite`'s pre-0.5.0 strictness overlay already forced this in practice for tools that ran through the CLI; 0.5.0 makes the schema the single source of truth.
44
+ - **`rcf-lite` consumers**: the durable landing was called out in `rcf-lite`'s own overlay comment ("drop this block when that ships"). A follow-up `rcf-lite` release pins `@stravica-ai/rcf-schemas` to `0.5.0` and removes the local overlay so validation is inherited from the schema uniformly.
45
+
46
+ ### Notes
47
+
48
+ - Pre-1.0 semver convention (repo has followed this since 0.1.0): breaking-in-any-direction schema changes bump minor. This release breaks docs that authored dishonest `passing`/`failing`-without-pointer TCs; hence 0.5.0, not a patch.
49
+ - The rule is expressed as an `allOf` with an `if`/`then` conditional (the same pattern 0.4.2 used for per-kind `testTheatreFinding.tsId` requiredness). Ajv strict mode requires `testPointer` to be redeclared inside `then.properties`; the redeclaration mirrors the outer shape (`type: string, minLength: 1`) and is not an independent constraint.
50
+ - The 0.4.4 `back-compat-freeze.test.js` byte-for-byte pin is on a manifest fixture (`manifest-011-preblueprint-chain-frozen.json`) and is untouched by this release; it continues to pass on 0.5.0.
51
+
7
52
  ## 0.4.5 - 2026-08-19
8
53
 
9
54
  Additive patch bump for the blueprint conflict-resolution mechanism landing in `rcf-lite` Phase 3.5. Adds the schema seam the `rcf blueprint supersede` and `rcf blueprint add --resolve` verbs key to, so a project can record an operator ruling that resolves a cross-blueprint conflict on a scope:global ADR topic. Every change is additive: every 0.4.4-valid document remains valid, and every existing id continues to validate byte-for-byte.
package/README.md CHANGED
@@ -46,7 +46,7 @@ io.stravica.rcf:rcf-schemas:0.3.0
46
46
  Each schema is fetchable by its canonical `$id`:
47
47
 
48
48
  ```
49
- https://schemas.stravica.io/rcf/v0.3.0/<name>.schema.json
49
+ https://schemas.stravica.io/rcf/v0.5.0/<name>.schema.json
50
50
  ```
51
51
 
52
52
  ## Use
@@ -77,7 +77,7 @@ for (const name of names) {
77
77
  ajv.addSchema(schema);
78
78
  }
79
79
 
80
- const validatePrd = ajv.getSchema('https://schemas.stravica.io/rcf/v0.3.0/prd.schema.json');
80
+ const validatePrd = ajv.getSchema('https://schemas.stravica.io/rcf/v0.5.0/prd.schema.json');
81
81
  const ok = validatePrd(myPrdDoc);
82
82
  if (!ok) console.error(validatePrd.errors);
83
83
  ```
package/docs/adr.md CHANGED
@@ -4,7 +4,7 @@ Architectural Decision Record. One per decision, one file each. Follows the Nyga
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/adr.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/adr.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
@@ -4,7 +4,7 @@ Build Sequence. One per project. Pure planning shell. FBS files each carry the m
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/build-sequence.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/build-sequence.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
package/docs/cn.md CHANGED
@@ -4,7 +4,7 @@ Code Node. One file per node. Bridges the requirements graph to source code: ide
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/cn.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/cn.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
package/docs/common.md CHANGED
@@ -4,7 +4,7 @@ Shared `$defs` referenced via `$ref` from every other RCF schema. ID patterns, s
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/common.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/common.schema.json`
8
8
 
9
9
  ## What's in `$defs`
10
10
 
package/docs/fbs.md CHANGED
@@ -6,7 +6,7 @@ Structurally, each FBS carries the mandatory `bsId` back-reference plus `buildOr
6
6
 
7
7
  ## Canonical `$id`
8
8
 
9
- `https://schemas.stravica.io/rcf/v0.3.0/fbs.schema.json`
9
+ `https://schemas.stravica.io/rcf/v0.5.0/fbs.schema.json`
10
10
 
11
11
  ## Required fields
12
12
 
package/docs/manifest.md CHANGED
@@ -4,7 +4,7 @@ Project manifest. Roots-only shape: declares `prd`, `tad`, `bs`. Children are ow
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/manifest.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/manifest.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
package/docs/prd.md CHANGED
@@ -4,7 +4,7 @@ Product Requirements Document. One per project. Pure shell document; REQ bodies
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/prd.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/prd.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
package/docs/req.md CHANGED
@@ -4,7 +4,7 @@ Individual Requirement within a PRD. One file per REQ. Recommended path: `rcf/re
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/req.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/req.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
package/docs/tac.md CHANGED
@@ -4,7 +4,7 @@ Technical Architecture Component. One file per architectural component. Verbose
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/tac.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/tac.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
package/docs/tad.md CHANGED
@@ -4,7 +4,7 @@ Master Technical Architecture Document. One per project. Pure shell for cross-cu
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/tad.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/tad.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
@@ -4,7 +4,7 @@ Test Suite. One file per Test Suite. The JSON specification of what Test Cases e
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/test-suite.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/test-suite.schema.json`
8
8
 
9
9
  ## TS-as-JSON: what this schema is for
10
10
 
@@ -39,10 +39,14 @@ Each entry in `testCases[]`:
39
39
  | `id` | `^TC-\d{3,}-[a-z0-9-]+$` | yes | TC identifier. `TC-<TS-suffix>-<slug>`; slug is a lowercase alphanumeric identifier (hyphens allowed). Slug uniqueness is within-TS, not global. TS-suffix widened to three-digit minimum, unbounded above (0.4.3). |
40
40
  | `acId` | `^AC-\d{3,}(-\d+)?$` | yes | Which AC on the parent US this TC verifies. |
41
41
  | `description` | string, min 1 | yes | What the TC covers. |
42
- | `testPointer` | string | no | Pointer to the executable test, `filePath::testName` format. |
42
+ | `testPointer` | string, min 1 | conditional | Pointer to the executable test, `filePath::testName` format. **Required** when `status` is `passing` or `failing` (a passing or failing verdict claims coverage and must point at the test that produced the verdict). **Optional** when `status` is `pending` or `skipped` (no executable test has landed yet, and there is nothing honest to point at). Non-empty when present. Behaviour ratified 2026-08-27; landed in 0.5.0. |
43
43
  | `status` | enum | yes | `pending`, `passing`, `failing`, `skipped`. Authored in 0.2.0; derived from real test runs in Phase 6+. |
44
44
  | `scope` | `scopeTag` enum | no | `library`, `runtime`, `deployed`, `unclassified`. Optional at schema level (0.4.3). Ruleset-enforcing consumers may require the TC scope to be equal to or wider than the covered AC's scope. |
45
45
 
46
+ ## What changed in 0.5.0
47
+
48
+ `testPointer` moved from unconditionally-optional to conditionally-required by `status`. A TC with `status: passing` or `status: failing` MUST carry a non-empty `testPointer`; a TC with `status: pending` or `status: skipped` MAY omit it (and may still declare a planned pointer). The old shape (unconditionally optional) let a TC claim a passing verdict while pointing at nothing, which is dishonest coverage; 0.5.0 makes the schema express what the rcf-lite consumer already enforced as a local overlay (`w-2026-07-28-005`). Consumers on 0.4.x that shipped only `pending`/`skipped` TCs without `testPointer` remain valid; consumers that shipped `passing`/`failing` TCs without `testPointer` need to add pointers or downgrade the verdict.
49
+
46
50
  ## What changed in 0.2.0
47
51
 
48
52
  The 0.1.0 shape was per-AC (`acId` + `prdId` + `version` + `testCases[given/when/then]`). 0.2.0 makes the suite per-US-and-across-ACs, keeps the TS id in `common.schema.json` (`tsId`), and moves the Given/When/Then verbiage into the TC's `description` (specialised BDD-style step language belongs in the executable test, not the JSON spec).
@@ -4,7 +4,7 @@ User Story document. One file per US. Contains Acceptance Criteria inline as `ac
4
4
 
5
5
  ## Canonical `$id`
6
6
 
7
- `https://schemas.stravica.io/rcf/v0.3.0/user-story.schema.json`
7
+ `https://schemas.stravica.io/rcf/v0.5.0/user-story.schema.json`
8
8
 
9
9
  ## Required fields
10
10
 
@@ -0,0 +1,16 @@
1
+ {
2
+ "version": "2.0.0",
3
+ "projectName": "Invalid libraryPrefix (uppercase)",
4
+ "prd": { "id": "PRD-001", "path": "rcf/prd.json" },
5
+ "tad": { "id": "TAD-001", "path": "rcf/tad.json" },
6
+ "bs": { "id": "BS-001", "path": "rcf/build-sequence.json" },
7
+ "blueprints": [
8
+ {
9
+ "slug": "spa",
10
+ "version": "1.0.0",
11
+ "appliedAt": "2026-08-31T10:00:00Z",
12
+ "source": "acme:spa",
13
+ "libraryPrefix": "ACME"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "TS-201",
3
+ "usId": "US-201",
4
+ "title": "Passing TC missing required testPointer",
5
+ "purpose": "0.5.0 requires testPointer on passing TCs; this fixture omits it and must be rejected.",
6
+ "testLevel": "unit",
7
+ "acIds": ["AC-201-1"],
8
+ "testCases": [
9
+ {
10
+ "id": "TC-201-passing-no-pointer",
11
+ "acId": "AC-201-1",
12
+ "description": "Claims a passing verdict but points at nothing; the conditional-required rule rejects this shape.",
13
+ "status": "passing"
14
+ }
15
+ ],
16
+ "status": "draft",
17
+ "createdAt": "2026-08-28T00:00:00Z",
18
+ "updatedAt": "2026-08-28T00:00:00Z"
19
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "TS-202",
3
+ "usId": "US-202",
4
+ "title": "Failing TC missing required testPointer",
5
+ "purpose": "0.5.0 requires testPointer on failing TCs; this fixture omits it and must be rejected.",
6
+ "testLevel": "unit",
7
+ "acIds": ["AC-202-1"],
8
+ "testCases": [
9
+ {
10
+ "id": "TC-202-failing-no-pointer",
11
+ "acId": "AC-202-1",
12
+ "description": "Claims a failing verdict but points at nothing; the conditional-required rule rejects this shape.",
13
+ "status": "failing"
14
+ }
15
+ ],
16
+ "status": "draft",
17
+ "createdAt": "2026-08-28T00:00:00Z",
18
+ "updatedAt": "2026-08-28T00:00:00Z"
19
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "id": "TS-203",
3
+ "usId": "US-203",
4
+ "title": "Empty testPointer is rejected",
5
+ "purpose": "0.5.0 requires testPointer to be non-empty (minLength 1); an empty string is not a legitimate pointer.",
6
+ "testLevel": "unit",
7
+ "acIds": ["AC-203-1"],
8
+ "testCases": [
9
+ {
10
+ "id": "TC-203-empty-pointer",
11
+ "acId": "AC-203-1",
12
+ "description": "Empty pointer would let a TC claim coverage while pointing at nothing.",
13
+ "testPointer": "",
14
+ "status": "passing"
15
+ }
16
+ ],
17
+ "status": "draft",
18
+ "createdAt": "2026-08-28T00:00:00Z",
19
+ "updatedAt": "2026-08-28T00:00:00Z"
20
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "version": "2.0.0",
3
+ "projectName": "Project applying blueprints through a registered library",
4
+ "prd": { "id": "PRD-001", "path": "rcf/prd.json" },
5
+ "tad": { "id": "TAD-001", "path": "rcf/tad.json" },
6
+ "bs": { "id": "BS-001", "path": "rcf/build-sequence.json" },
7
+ "blueprints": [
8
+ {
9
+ "slug": "spa",
10
+ "version": "1.0.0",
11
+ "appliedAt": "2026-08-31T10:00:00Z",
12
+ "source": "acme:spa",
13
+ "libraryPrefix": "acme",
14
+ "contributions": [
15
+ { "id": "spa-REQ-001", "path": "rcf/requirements/spa-req-001.json", "kind": "req" }
16
+ ]
17
+ },
18
+ {
19
+ "slug": "rest",
20
+ "version": "1.0.0",
21
+ "appliedAt": "2026-08-31T10:00:05Z",
22
+ "source": "rcf/blueprints/rest"
23
+ }
24
+ ]
25
+ }
@@ -23,6 +23,7 @@
23
23
  "id": "TC-015-non-2xx",
24
24
  "acId": "AC-1001-2",
25
25
  "description": "non-2xx response surfaces to caller",
26
+ "testPointer": "test/email-dispatcher.test.ts::non-2xx surfaces",
26
27
  "status": "passing",
27
28
  "runtimeProvenance": {
28
29
  "profile": "mock",
@@ -10,6 +10,7 @@
10
10
  "id": "TC-1000-startup-loads-config",
11
11
  "acId": "AC-1001-1",
12
12
  "description": "On boot, the config loader wires and dispatches the first tick.",
13
+ "testPointer": "test/boot.test.ts::startup loads config",
13
14
  "status": "passing",
14
15
  "scope": "runtime"
15
16
  },
@@ -17,6 +18,7 @@
17
18
  "id": "TC-1000-deployed-smoke",
18
19
  "acId": "AC-1001-1",
19
20
  "description": "On the deployed instance, the first probe fires against a real target.",
21
+ "testPointer": "test/deploy.smoke.ts::deployed first probe",
20
22
  "status": "passing",
21
23
  "scope": "deployed"
22
24
  }
@@ -0,0 +1,46 @@
1
+ {
2
+ "id": "TS-200",
3
+ "usId": "US-200",
4
+ "title": "TC testPointer conditional-by-status coverage",
5
+ "purpose": "Prove the 0.5.0 rule: testPointer is required for passing/failing TCs and optional for pending/skipped TCs.",
6
+ "testLevel": "unit",
7
+ "acIds": ["AC-200-1"],
8
+ "testCases": [
9
+ {
10
+ "id": "TC-200-passing-with-pointer",
11
+ "acId": "AC-200-1",
12
+ "description": "Passing TC carries the executable pointer.",
13
+ "testPointer": "test/example.test.js::passing case",
14
+ "status": "passing"
15
+ },
16
+ {
17
+ "id": "TC-200-failing-with-pointer",
18
+ "acId": "AC-200-1",
19
+ "description": "Failing TC still points at the executable that produced the verdict.",
20
+ "testPointer": "test/example.test.js::failing case",
21
+ "status": "failing"
22
+ },
23
+ {
24
+ "id": "TC-200-pending-no-pointer",
25
+ "acId": "AC-200-1",
26
+ "description": "Pending TC has no landed executable yet, so no pointer.",
27
+ "status": "pending"
28
+ },
29
+ {
30
+ "id": "TC-200-skipped-no-pointer",
31
+ "acId": "AC-200-1",
32
+ "description": "Skipped TC also has no executable to point at.",
33
+ "status": "skipped"
34
+ },
35
+ {
36
+ "id": "TC-200-pending-with-pointer",
37
+ "acId": "AC-200-1",
38
+ "description": "A pending TC may still declare its intended pointer.",
39
+ "testPointer": "test/example.test.js::planned case",
40
+ "status": "pending"
41
+ }
42
+ ],
43
+ "status": "approved",
44
+ "createdAt": "2026-08-28T00:00:00Z",
45
+ "updatedAt": "2026-08-28T00:00:00Z"
46
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stravica-ai/rcf-schemas",
3
- "version": "0.4.5",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "description": "JSON Schemas for the Requirements Confidence Framework (RCF). Language-neutral. The contract every RCF tool keys to.",
6
6
  "license": "Apache-2.0",
@@ -19,9 +19,6 @@
19
19
  "LICENSE",
20
20
  "CHANGELOG.md"
21
21
  ],
22
- "scripts": {
23
- "test": "node --test test/*.test.js"
24
- },
25
22
  "devDependencies": {
26
23
  "ajv": "^8.17.1",
27
24
  "ajv-formats": "^3.0.1"
@@ -40,5 +37,8 @@
40
37
  "json-schema",
41
38
  "specifications",
42
39
  "traceability"
43
- ]
44
- }
40
+ ],
41
+ "scripts": {
42
+ "test": "node --test test/*.test.js"
43
+ }
44
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://schemas.stravica.io/rcf/v0.4.0/adr.schema.json",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.5.0/adr.schema.json",
4
4
  "title": "RCF Architectural Decision Record",
5
5
  "description": "Architectural Decision Record. One per decision, one file each. Nygard / MADR convention.",
6
6
  "type": "object",
@@ -19,11 +19,11 @@
19
19
  "updatedAt"
20
20
  ],
21
21
  "properties": {
22
- "adrId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/adrId" },
23
- "prdId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/prdId" },
24
- "tadId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/tadId" },
25
- "version": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/version" },
26
- "status": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/adrStatus" },
22
+ "adrId": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/adrId" },
23
+ "prdId": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/prdId" },
24
+ "tadId": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/tadId" },
25
+ "version": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/version" },
26
+ "status": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/adrStatus" },
27
27
 
28
28
  "title": { "type": "string", "minLength": 1 },
29
29
  "context": { "type": "string", "minLength": 1 },
@@ -34,14 +34,14 @@
34
34
  "items": { "$ref": "#/$defs/alternative" }
35
35
  },
36
36
 
37
- "supersededBy": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/adrId" },
37
+ "supersededBy": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/adrId" },
38
38
  "relatedAdrs": {
39
39
  "type": "array",
40
- "items": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/adrId" }
40
+ "items": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/adrId" }
41
41
  },
42
42
 
43
- "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" },
44
- "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" }
43
+ "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/timestamp" },
44
+ "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/timestamp" }
45
45
  },
46
46
  "$defs": {
47
47
  "alternative": {
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://schemas.stravica.io/rcf/v0.4.0/build-sequence.schema.json",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.5.0/build-sequence.schema.json",
4
4
  "title": "RCF Build Sequence",
5
5
  "description": "One per project. Pure planning shell. FBSs each carry the mandatory bsId parent reference plus buildOrder; the ordered FBS list is computed by loading every FBS under rcf/fbs/, filtering by bsId, and sorting by buildOrder. Duplicate buildOrder within one BS is a validation error at load time.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": ["bsId", "prdId", "version", "status", "createdAt", "updatedAt"],
9
9
  "properties": {
10
- "bsId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/bsId" },
11
- "prdId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/prdId" },
12
- "version": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/version" },
13
- "status": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/authoringStatus" },
10
+ "bsId": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/bsId" },
11
+ "prdId": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/prdId" },
12
+ "version": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/version" },
13
+ "status": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/authoringStatus" },
14
14
  "title": { "type": "string" },
15
15
  "buildPhilosophy": { "type": "string" },
16
16
  "generationStrategy": {
17
17
  "enum": ["verticalSlice", "dependencyFirst", "domainGrouped", "riskFrontLoaded"]
18
18
  },
19
- "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" },
20
- "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" }
19
+ "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/timestamp" },
20
+ "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/timestamp" }
21
21
  }
22
22
  }
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://schemas.stravica.io/rcf/v0.4.0/cn.schema.json",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.5.0/cn.schema.json",
4
4
  "title": "RCF Code Node",
5
5
  "description": "Code Node document. One file per node. Identity is a working-tree path, optionally #symbol-suffixed; granularity (file vs symbol) is derived from the presence of '#', never stored. Bridges the spec graph to source: implementsAcIds anchors the node into the AC layer, dependencies declares CN-to-CN edges.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": ["cnId", "path", "implementsAcIds", "version", "status", "createdAt", "updatedAt"],
9
9
  "properties": {
10
- "cnId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/cnId" },
10
+ "cnId": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/cnId" },
11
11
  "path": {
12
12
  "type": "string",
13
13
  "minLength": 1,
@@ -18,19 +18,19 @@
18
18
  "description": { "type": "string" },
19
19
  "implementsAcIds": {
20
20
  "type": "array",
21
- "items": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/acId" },
21
+ "items": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/acId" },
22
22
  "minItems": 0,
23
23
  "description": "Acceptance criteria this code node satisfies. May be empty: an orphan CN (utilities, glue, wiring) is a legitimate state."
24
24
  },
25
25
  "dependencies": {
26
26
  "type": "array",
27
- "items": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/cnId" },
27
+ "items": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/cnId" },
28
28
  "minItems": 0,
29
29
  "description": "Code nodes this node depends on (CN-to-CN edges). Hand-declared in v1."
30
30
  },
31
- "version": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/version" },
32
- "status": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/cnStatus" },
33
- "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" },
34
- "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" }
31
+ "version": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/version" },
32
+ "status": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/cnStatus" },
33
+ "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/timestamp" },
34
+ "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json#/$defs/timestamp" }
35
35
  }
36
36
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.5.0/common.schema.json",
4
4
  "title": "RCF Shared Definitions",
5
5
  "description": "Shared $defs referenced via $ref from every other RCF schema. ID patterns, status enums, version string, timestamp format, and the docRef shape. This file is not a document schema; consumers register it alongside the 11 doc-type schemas at validator init. From 0.4.4 the reqId/usId/prdId/bsId/tadId/tsId patterns accept an optional lowercase kebab-slug prefix (for example, spa-REQ-001) so blueprint mechanisms can contribute namespaced doc ids without colliding with project-authored ids. Existing numeric-only ids remain valid. The adrId/tacId/fbsId/cnId patterns already carry an optional kebab-slug SUFFIX (0.4.3) and are intentionally left untouched: id grammar is mixed across types for tonight (prefix for REQ/US/PRD/BS/TAD/TS; suffix for ADR/TAC/FBS/CN); unifying is a schemas follow-up.",
6
6
  "$defs": {