@stravica-ai/rcf-schemas 0.4.2 → 0.4.3
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.
- package/CHANGELOG.md +28 -0
- package/docs/common.md +8 -6
- package/docs/id-conventions.md +18 -4
- package/docs/test-suite.md +3 -2
- package/docs/user-story.md +1 -0
- package/fixtures/invalid/fbs/fbs-012-uppercase-slug.json +13 -0
- package/fixtures/invalid/test-suite/ts-007-bad-tc-scope.json +20 -0
- package/fixtures/invalid/user-story/us-004-bad-ac-scope.json +21 -0
- package/fixtures/valid/adr/adr-004-slugged-id.json +14 -0
- package/fixtures/valid/cn/cn-003-slugged-id.json +10 -0
- package/fixtures/valid/fbs/fbs-006-slugged-id.json +13 -0
- package/fixtures/valid/tac/tac-003-slugged-id.json +18 -0
- package/fixtures/valid/test-suite/ts-004-widened-tsId.json +27 -0
- package/fixtures/valid/user-story/us-004-ac-scope-tags.json +33 -0
- package/package.json +1 -1
- package/schemas/common.schema.json +16 -12
- package/schemas/manifest.schema.json +6 -6
- package/schemas/test-suite.schema.json +6 -2
- package/schemas/user-story.schema.json +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,34 @@ 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.4.3 - 2026-08-12
|
|
8
|
+
|
|
9
|
+
Additive patch bump: car 1 of the `rcf-lite` 0.8.0 slug-train. Widens four id patterns to accept an optional kebab-case slug tail (per the slug design ratified on `w-2026-07-28-012`), widens the TS and TC id patterns to drop the 999 cap, adds a shared scope-tag vocabulary in `common.schema.json`, and exposes an optional `scope` field on ACs and TCs. Every change is additive; every existing id and every existing document continues to validate.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **`common.schema.json`**: new `$defs.scopeTag` enum (`library | runtime | deployed | unclassified`), shared between `user-story.acceptanceCriteria[].scope` and `test-suite.testCases[].scope`. `unclassified` is the migration state; the schema does not distinguish gate-passing values, ruleset-enforcing consumers do.
|
|
14
|
+
- **`user-story.schema.json`**: new optional `scope` on `$defs.acceptanceCriterion`, referencing `common.scopeTag`. Names the scope at which the AC is observable and governs which test scopes count as coverage.
|
|
15
|
+
- **`test-suite.schema.json`**: new optional `scope` on `$defs.testCase`, referencing `common.scopeTag`. Ruleset-enforcing consumers may require the TC scope to be equal to or wider than the covered AC's scope.
|
|
16
|
+
- Fixtures: `fixtures/valid/fbs/fbs-006-slugged-id.json`, `fixtures/valid/cn/cn-003-slugged-id.json`, `fixtures/valid/adr/adr-004-slugged-id.json`, `fixtures/valid/tac/tac-003-slugged-id.json`, `fixtures/valid/test-suite/ts-004-widened-tsId.json` (four-digit TS with two scope-tagged TCs), `fixtures/valid/user-story/us-004-ac-scope-tags.json` (three ACs, one per scope value). Invalid coverage: `fixtures/invalid/fbs/fbs-012-uppercase-slug.json`, `fixtures/invalid/test-suite/ts-007-bad-tc-scope.json`, `fixtures/invalid/user-story/us-004-bad-ac-scope.json`.
|
|
17
|
+
- Tests: slug-id cases added to `fbs.test.js`, `cn.test.js`, `adr.test.js`, `tac.test.js`; widened TS/TC id cases and TC scope cases added to `test-suite.test.js`; AC scope cases added to `user-story.test.js`; composite FBS-embedded id cases added to `manifest.test.js` (`reviewAudit.id`, `browserVerification.id`, `shipWithoutVerified.id`).
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **`common.schema.json`**: `fbsId`, `cnId`, `adrId`, `tacId` patterns widened to accept an optional kebab-case slug tail, `^<PREFIX>-\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$`. Numeric-only ids continue to validate unchanged. Slug segments must be lowercase alphanumeric joined by single hyphens; leading, trailing, and double hyphens are rejected. Kebab is enforced (well-formed) rather than the looser `[a-z0-9-]+` shape so downstream tools can round-trip slugs without normalisation.
|
|
22
|
+
- **`common.schema.json`**: `tsId` widened from `^TS-\d{3}$` to `^TS-\d{3,}$`; `tcId` widened from `^TC-\d{3}-[a-z0-9-]+$` to `^TC-\d{3,}-[a-z0-9-]+$`. Removes the 999 cap on both, and closes the silent-skip trap in downstream walkers that were coded against the three-digit-exact pattern. TC's slug portion keeps the looser `[a-z0-9-]+` shape (legacy compatibility).
|
|
23
|
+
- **`test-suite.schema.json`**: inline `testCase.id` pattern widened in lockstep with `common.tcId` (`^TC-\d{3,}-[a-z0-9-]+$`).
|
|
24
|
+
- **`manifest.schema.json`**: the three FBS-embedded composite id patterns widened to accept both numeric-only and slugged FBS ids: `reviewAudit.id` (`^ra-FBS-\d{3,}(?:-[a-z0-9]+(?:-[a-z0-9]+)*)?-\d+$`), `browserVerification.id` (`^bv-FBS-\d{3,}(?:-[a-z0-9]+(?:-[a-z0-9]+)*)?-\d+$`), and `shipWithoutVerified.id` (`^swv-FBS-\d{3,}(?:-[a-z0-9]+(?:-[a-z0-9]+)*)?-\d+$`). The trailing `-<n>` counter still parses cleanly against slugged FBS ids because the counter is required and anchored.
|
|
25
|
+
- **`docs/id-conventions.md`**, **`docs/common.md`**, **`docs/test-suite.md`**, **`docs/user-story.md`**: updated to reflect the widened patterns, the optional slug suffix, and the `scopeTag` vocabulary.
|
|
26
|
+
|
|
27
|
+
### Notes
|
|
28
|
+
|
|
29
|
+
- Additive-only: every 0.4.0-, 0.4.1-, and 0.4.2-valid document remains valid. Every numeric-only id continues to validate; every existing AC and TC without a `scope` field continues to validate.
|
|
30
|
+
- Canonical `$id` URLs stay at `v0.4.0`, following the patch-release precedent set at 0.2.1, 0.3.1, 0.4.1, and 0.4.2. Per the ratified umbrella exact-pin doctrine, the 0.8.0 slug-train's second and third cars (`rcf-lite-core`, `rcf-build-lite`) pin `@stravica-ai/rcf-schemas` to exactly `0.4.3` (no caret, no range) on merge; the pin review is recorded in the umbrella's release notes.
|
|
31
|
+
- Slug scope (FBS, CN, ADR, TAC) is the ratified set: BS is out of scope by design (Baz ruling 2026-07-28, `w-2026-07-28-012`), and PRD, REQ, US, TAD are per-project singletons where number collisions are not the problem the slug solves.
|
|
32
|
+
- Existing documents are NOT retro-slugged. The design is preferred-with-numeric-fallback; adopting slugs is opt-in per document at authoring time.
|
|
33
|
+
- Downstream landmines called out on `w-2026-07-28-012` (walker.js toUpperCase stem, writer.js nextFlatId parser, hardcoded `\d{3}` in walker.js:696-699, deriveSlug 'tc' leak) live in `rcf-lite` consumers, not in this repo. They are addressed by that repo's train cars, not here.
|
|
34
|
+
|
|
7
35
|
## 0.4.2 - 2026-07-31
|
|
8
36
|
|
|
9
37
|
Additive patch bump: closes the Track B N-5 review finding on the 0.7.0 train. The `testTheatreFinding` shape now expresses "not every finding kind anchors on a test suite" honestly instead of forcing a UI-drift finding to smuggle an FBS id through the `tsId` slot.
|
package/docs/common.md
CHANGED
|
@@ -15,19 +15,21 @@ Shared `$defs` referenced via `$ref` from every other RCF schema. ID patterns, s
|
|
|
15
15
|
| `usId` | string, `^US-\d{3,}$` | `user-story`, `test-suite` |
|
|
16
16
|
| `acId` | string, `^AC-\d{3,}(-\d+)?$` | `user-story.acceptanceCriteria[].id`, `fbs.acIds[]`, `test-suite.acId` |
|
|
17
17
|
| `tadId` | string, `^TAD-\d{3,}$` | `tad`, `tac`, `adr` |
|
|
18
|
-
| `tacId` | string, `^TAC-\d{3,}
|
|
19
|
-
| `adrId` | string, `^ADR-\d{3,}
|
|
18
|
+
| `tacId` | string, `^TAC-\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$` | `tac`, `fbs.contextRequirements.tacIds[]` |
|
|
19
|
+
| `adrId` | string, `^ADR-\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$` | `adr`, `fbs.contextRequirements.adrIds[]` |
|
|
20
20
|
| `bsId` | string, `^BS-\d{3,}$` | `build-sequence`, `fbs.bsId` |
|
|
21
|
-
| `fbsId` | string, `^FBS-\d{3,}
|
|
22
|
-
| `tsId` | string, `^TS-\d{3}$` | `test-suite.id` |
|
|
23
|
-
| `tcId` | string, `^TC-\d{3}-[a-z0-9-]+$` | `test-suite.testCases[].id` |
|
|
24
|
-
| `cnId` | string, `^CN-\d{3,}
|
|
21
|
+
| `fbsId` | string, `^FBS-\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$` | `fbs.fbsId`, `fbs.dependsOnFbsIds[]` |
|
|
22
|
+
| `tsId` | string, `^TS-\d{3,}$` | `test-suite.id` |
|
|
23
|
+
| `tcId` | string, `^TC-\d{3,}-[a-z0-9-]+$` | `test-suite.testCases[].id` |
|
|
24
|
+
| `cnId` | string, `^CN-\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$` | `cn.cnId`, `cn.dependencies[]` |
|
|
25
25
|
| `version` | string, `^\d+\.\d+\.\d+$` | every doc-type schema |
|
|
26
26
|
| `timestamp` | string, format `date-time` | every doc-type schema |
|
|
27
27
|
| `authoringStatus` | enum: `draft`, `review`, `needsRevision`, `approved`, `superseded` | PRD, REQ, US, TAD, TAC, BS |
|
|
28
28
|
| `adrStatus` | enum: `draft`, `proposed`, `accepted`, `superseded`, `deprecated` | ADR |
|
|
29
29
|
| `executionStatus` | enum: `notStarted`, `inProgress`, `complete`, `verified` | FBS doc + BS slot |
|
|
30
30
|
| `cnStatus` | enum: `draft`, `approved`, `deprecated` | CN |
|
|
31
|
+
| `attestationMode` | enum: `live`, `sandboxed`, `mocked`, `declaredMockOnly`, `notShipped` | `fbs.dependsOnServices[]`, manifest `preFlightConfig.servicesInScope[]` |
|
|
32
|
+
| `scopeTag` | enum: `library`, `runtime`, `deployed`, `unclassified` | `user-story.acceptanceCriteria[].scope`, `test-suite.testCases[].scope` |
|
|
31
33
|
| `docRef` | object `{ id, path }` | manifest `prd`, `tad`, `bs` |
|
|
32
34
|
|
|
33
35
|
## Why these are shared
|
package/docs/id-conventions.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ID conventions
|
|
2
2
|
|
|
3
|
-
The pattern, the prefix table, the AC sub-id form, and the file/nested asymmetry.
|
|
3
|
+
The pattern, the prefix table, the AC sub-id form, the optional slug suffix, and the file/nested asymmetry.
|
|
4
4
|
|
|
5
5
|
## The pattern
|
|
6
6
|
|
|
@@ -10,7 +10,21 @@ The pattern, the prefix table, the AC sub-id form, and the file/nested asymmetry
|
|
|
10
10
|
|
|
11
11
|
Three-digit minimum, unbounded above. `PRD-001` through `PRD-999` use the clean visual; `PRD-1000+` works without a schema migration. A single digit (`PRD-1`) is rejected.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
One family layers the same three-digit-minimum tail onto a slug: `TC-\d{3,}-<slug>` (TS-suffix, three-digit minimum, unbounded above, joined to a lowercase alphanumeric slug).
|
|
14
|
+
|
|
15
|
+
## Optional slug suffix (0.4.3)
|
|
16
|
+
|
|
17
|
+
Four families accept an optional kebab-case slug tail: `FBS`, `CN`, `ADR`, `TAC`. The full pattern is:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
^<PREFIX>-\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The slug is derived from the document title (kebab-case, lowercase alphanumeric segments joined by single hyphens). Leading hyphens, trailing hyphens, double hyphens, uppercase letters, and underscores are rejected.
|
|
24
|
+
|
|
25
|
+
Both forms remain valid: `FBS-004` and `FBS-004-user-login` both validate. Existing numeric-only ids continue to validate; there is no forcing function. Consumers that address documents by id treat the slug as part of the id string, not a separately parseable field.
|
|
26
|
+
|
|
27
|
+
Rationale: parallel authoring on branches can allocate the same number for different titles. The slug makes those distinct addresses at the filesystem and id layer, converting an add/add merge conflict into a clean co-existence. See the `rcf-lite` slug-train design for the full argument.
|
|
14
28
|
|
|
15
29
|
## Prefix table
|
|
16
30
|
|
|
@@ -42,11 +56,11 @@ Pick per project; the schema does not enforce either form. The published `Stravi
|
|
|
42
56
|
|
|
43
57
|
## TS ids
|
|
44
58
|
|
|
45
|
-
`^TS-\d{3}$`. Sequential, not parent-grouped: a US may have multiple TSs across levels (unit, integration, e2e, ...) and a parent-grouped id would collide. Recommended path: `rcf/test-suites/ts-001.json`.
|
|
59
|
+
`^TS-\d{3,}$`. Sequential, not parent-grouped: a US may have multiple TSs across levels (unit, integration, e2e, ...) and a parent-grouped id would collide. Recommended path: `rcf/test-suites/ts-001.json`.
|
|
46
60
|
|
|
47
61
|
## TC ids
|
|
48
62
|
|
|
49
|
-
`^TC-\d{3}-[a-z0-9-]+$`. TCs are nested in their parent TS's `testCases[]`. The pattern is `TC-<TS-suffix>-<slug>` where slug is a lowercase alphanumeric identifier chosen by the author (hyphens allowed). Examples: `TC-001-happy-path`, `TC-001-rejects-empty`, `TC-042-integration-boundary`. Slug uniqueness is within-TS, not global.
|
|
63
|
+
`^TC-\d{3,}-[a-z0-9-]+$`. TCs are nested in their parent TS's `testCases[]`. The pattern is `TC-<TS-suffix>-<slug>` where slug is a lowercase alphanumeric identifier chosen by the author (hyphens allowed). Examples: `TC-001-happy-path`, `TC-001-rejects-empty`, `TC-042-integration-boundary`. Slug uniqueness is within-TS, not global.
|
|
50
64
|
|
|
51
65
|
Rationale: sequential numbering for TCs is brittle if you renumber; slug-based ids give readable pointers in test-suite bodies and traceability queries.
|
|
52
66
|
|
package/docs/test-suite.md
CHANGED
|
@@ -20,7 +20,7 @@ Recommended path under the RCF tree: `rcf/test-suites/ts-001.json`. The schema v
|
|
|
20
20
|
|
|
21
21
|
| Field | Type | Notes |
|
|
22
22
|
|---|---|---|
|
|
23
|
-
| `id` | `^TS-\d{3}$` | Test Suite identifier. Sequential, not parent-grouped (a US can have multiple TSs across levels). |
|
|
23
|
+
| `id` | `^TS-\d{3,}$` | Test Suite identifier. Sequential, not parent-grouped (a US can have multiple TSs across levels). Three-digit minimum, unbounded above (widened in 0.4.3). |
|
|
24
24
|
| `usId` | `^US-\d{3,}$` | Parent User Story. Mandatory back-reference. |
|
|
25
25
|
| `title` | string, min 1 | Human-readable suite title. |
|
|
26
26
|
| `purpose` | string, min 1 | One-paragraph "what this suite is testing and why". |
|
|
@@ -36,11 +36,12 @@ Each entry in `testCases[]`:
|
|
|
36
36
|
|
|
37
37
|
| Field | Type | Required | Purpose |
|
|
38
38
|
|---|---|---|---|
|
|
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. |
|
|
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
42
|
| `testPointer` | string | no | Pointer to the executable test, `filePath::testName` format. |
|
|
43
43
|
| `status` | enum | yes | `pending`, `passing`, `failing`, `skipped`. Authored in 0.2.0; derived from real test runs in Phase 6+. |
|
|
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. |
|
|
44
45
|
|
|
45
46
|
## What changed in 0.2.0
|
|
46
47
|
|
package/docs/user-story.md
CHANGED
|
@@ -40,6 +40,7 @@ Each AC inside `acceptanceCriteria[]`:
|
|
|
40
40
|
| `when` | string | no | Trigger. |
|
|
41
41
|
| `then` | string | no | Observable outcome. |
|
|
42
42
|
| `testable` | boolean | yes | Author declares the AC is testable. |
|
|
43
|
+
| `scope` | `scopeTag` enum | no | `library`, `runtime`, `deployed`, `unclassified`. Optional at schema level (0.4.3). Names the scope at which the AC is observable; governs which test scopes count as coverage. |
|
|
43
44
|
|
|
44
45
|
The Given/When/Then triple is optional at the schema level so non-Gherkin teams aren't forced into it; the `testable` boolean is required to make authors stop and confirm the AC can actually be tested.
|
|
45
46
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fbsId": "FBS-004-UserLogin",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"bsId": "BS-001",
|
|
5
|
+
"buildOrder": 4,
|
|
6
|
+
"executionStatus": "notStarted",
|
|
7
|
+
"title": "x",
|
|
8
|
+
"summary": "y",
|
|
9
|
+
"acIds": ["AC-001"],
|
|
10
|
+
"dependsOnFbsIds": [],
|
|
11
|
+
"createdAt": "2026-08-12T09:00:00Z",
|
|
12
|
+
"updatedAt": "2026-08-12T09:00:00Z"
|
|
13
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "TS-001",
|
|
3
|
+
"usId": "US-001",
|
|
4
|
+
"title": "x",
|
|
5
|
+
"purpose": "y",
|
|
6
|
+
"testLevel": "unit",
|
|
7
|
+
"acIds": ["AC-001"],
|
|
8
|
+
"testCases": [
|
|
9
|
+
{
|
|
10
|
+
"id": "TC-001-a",
|
|
11
|
+
"acId": "AC-001",
|
|
12
|
+
"description": "TC scope is not one of the ratified vocabulary values.",
|
|
13
|
+
"status": "pending",
|
|
14
|
+
"scope": "production"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"status": "draft",
|
|
18
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
19
|
+
"updatedAt": "2026-01-01T00:00:00Z"
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-001",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-001",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "x",
|
|
8
|
+
"asA": "y",
|
|
9
|
+
"iWant": "z",
|
|
10
|
+
"soThat": "w",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-001",
|
|
14
|
+
"description": "AC scope is not one of the ratified vocabulary values.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "production"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
20
|
+
"updatedAt": "2026-01-01T00:00:00Z"
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-012-choose-postgres",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Choose PostgreSQL for the primary datastore",
|
|
8
|
+
"context": "The service needs a relational store with strong consistency and mature JSON support.",
|
|
9
|
+
"decision": "Adopt PostgreSQL 16 as the primary datastore.",
|
|
10
|
+
"consequences": "Introduces PostgreSQL as a runtime dependency; simplifies query semantics.",
|
|
11
|
+
"relatedAdrs": ["ADR-005-alignment-policy"],
|
|
12
|
+
"createdAt": "2026-08-12T09:00:00Z",
|
|
13
|
+
"updatedAt": "2026-08-12T09:00:00Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cnId": "CN-042-store-validator",
|
|
3
|
+
"path": "src/store/validator.js#getAjv",
|
|
4
|
+
"implementsAcIds": ["AC-102-1"],
|
|
5
|
+
"dependencies": ["CN-001", "CN-002-user-notifier"],
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"status": "draft",
|
|
8
|
+
"createdAt": "2026-08-12T09:00:00Z",
|
|
9
|
+
"updatedAt": "2026-08-12T09:00:00Z"
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fbsId": "FBS-004-user-login",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"bsId": "BS-001",
|
|
5
|
+
"buildOrder": 4,
|
|
6
|
+
"executionStatus": "notStarted",
|
|
7
|
+
"title": "User login",
|
|
8
|
+
"summary": "HTML login page and session cookie on submit.",
|
|
9
|
+
"acIds": ["AC-004-1"],
|
|
10
|
+
"dependsOnFbsIds": ["FBS-001", "FBS-002-persist-notes"],
|
|
11
|
+
"createdAt": "2026-08-12T09:00:00Z",
|
|
12
|
+
"updatedAt": "2026-08-12T09:00:00Z"
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-004-payment-gateway",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"name": "Payment gateway",
|
|
8
|
+
"purpose": "Server-side integration with the third-party payment provider.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Issue authorization requests",
|
|
11
|
+
"Reconcile capture events"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": [
|
|
14
|
+
{ "name": "Notes store", "kind": "tac", "tacId": "TAC-002-notes-store" }
|
|
15
|
+
],
|
|
16
|
+
"createdAt": "2026-08-12T09:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-12T09:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "TS-1000",
|
|
3
|
+
"usId": "US-1001",
|
|
4
|
+
"title": "Boot integration smoke",
|
|
5
|
+
"purpose": "Cover the boot-integration observable for AC-1001-1 on a real host.",
|
|
6
|
+
"testLevel": "integration",
|
|
7
|
+
"acIds": ["AC-1001-1"],
|
|
8
|
+
"testCases": [
|
|
9
|
+
{
|
|
10
|
+
"id": "TC-1000-startup-loads-config",
|
|
11
|
+
"acId": "AC-1001-1",
|
|
12
|
+
"description": "On boot, the config loader wires and dispatches the first tick.",
|
|
13
|
+
"status": "passing",
|
|
14
|
+
"scope": "runtime"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "TC-1000-deployed-smoke",
|
|
18
|
+
"acId": "AC-1001-1",
|
|
19
|
+
"description": "On the deployed instance, the first probe fires against a real target.",
|
|
20
|
+
"status": "passing",
|
|
21
|
+
"scope": "deployed"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"status": "approved",
|
|
25
|
+
"createdAt": "2026-08-12T09:00:00Z",
|
|
26
|
+
"updatedAt": "2026-08-12T09:00:00Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-1001",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "REQ-010",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Signed-in owner sees the dashboard on boot",
|
|
8
|
+
"asA": "signed-in owner",
|
|
9
|
+
"iWant": "to land on the dashboard after logging in",
|
|
10
|
+
"soThat": "I can see every monitor's status at a glance",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-1001-1",
|
|
14
|
+
"description": "on startup, the loader wires the config file and the first probe fires",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "runtime"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "AC-1001-2",
|
|
20
|
+
"description": "on the deployed instance, the first probe hits the real target within 60s of boot",
|
|
21
|
+
"testable": true,
|
|
22
|
+
"scope": "deployed"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "AC-1001-3",
|
|
26
|
+
"description": "parseConfig rejects an empty configuration document",
|
|
27
|
+
"testable": true,
|
|
28
|
+
"scope": "library"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"createdAt": "2026-08-12T09:00:00Z",
|
|
32
|
+
"updatedAt": "2026-08-12T09:00:00Z"
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
},
|
|
32
32
|
"tacId": {
|
|
33
33
|
"type": "string",
|
|
34
|
-
"pattern": "^TAC-\\d{3,}
|
|
35
|
-
"description": "Technical Architecture Component identifier."
|
|
34
|
+
"pattern": "^TAC-\\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$",
|
|
35
|
+
"description": "Technical Architecture Component identifier. Three-digit minimum, unbounded above. An optional kebab-case slug suffix (for example, TAC-004-payment-gateway) is permitted; existing numeric-only ids remain valid."
|
|
36
36
|
},
|
|
37
37
|
"adrId": {
|
|
38
38
|
"type": "string",
|
|
39
|
-
"pattern": "^ADR-\\d{3,}
|
|
40
|
-
"description": "Architectural Decision Record identifier."
|
|
39
|
+
"pattern": "^ADR-\\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$",
|
|
40
|
+
"description": "Architectural Decision Record identifier. Three-digit minimum, unbounded above. An optional kebab-case slug suffix (for example, ADR-012-choose-postgres) is permitted; existing numeric-only ids remain valid."
|
|
41
41
|
},
|
|
42
42
|
"bsId": {
|
|
43
43
|
"type": "string",
|
|
@@ -46,23 +46,23 @@
|
|
|
46
46
|
},
|
|
47
47
|
"fbsId": {
|
|
48
48
|
"type": "string",
|
|
49
|
-
"pattern": "^FBS-\\d{3,}
|
|
50
|
-
"description": "Functional Build Specification identifier."
|
|
49
|
+
"pattern": "^FBS-\\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$",
|
|
50
|
+
"description": "Functional Build Specification identifier. Three-digit minimum, unbounded above. An optional kebab-case slug suffix (for example, FBS-004-user-login) is permitted; existing numeric-only ids remain valid."
|
|
51
51
|
},
|
|
52
52
|
"tsId": {
|
|
53
53
|
"type": "string",
|
|
54
|
-
"pattern": "^TS-\\d{3}$",
|
|
55
|
-
"description": "Test Suite identifier."
|
|
54
|
+
"pattern": "^TS-\\d{3,}$",
|
|
55
|
+
"description": "Test Suite identifier. Three-digit minimum, unbounded above."
|
|
56
56
|
},
|
|
57
57
|
"tcId": {
|
|
58
58
|
"type": "string",
|
|
59
|
-
"pattern": "^TC-\\d{3}-[a-z0-9-]+$",
|
|
60
|
-
"description": "Test Case identifier. TS suffix (three
|
|
59
|
+
"pattern": "^TC-\\d{3,}-[a-z0-9-]+$",
|
|
60
|
+
"description": "Test Case identifier. TS suffix (three-digit minimum, unbounded above) joined to a lowercase alphanumeric slug."
|
|
61
61
|
},
|
|
62
62
|
"cnId": {
|
|
63
63
|
"type": "string",
|
|
64
|
-
"pattern": "^CN-\\d{3,}
|
|
65
|
-
"description": "Code Node identifier. Three-digit minimum, unbounded above."
|
|
64
|
+
"pattern": "^CN-\\d{3,}(-[a-z0-9]+(?:-[a-z0-9]+)*)?$",
|
|
65
|
+
"description": "Code Node identifier. Three-digit minimum, unbounded above. An optional kebab-case slug suffix (for example, CN-042-store-validator) is permitted; existing numeric-only ids remain valid."
|
|
66
66
|
},
|
|
67
67
|
"version": {
|
|
68
68
|
"type": "string",
|
|
@@ -94,6 +94,10 @@
|
|
|
94
94
|
"enum": ["live", "sandboxed", "mocked", "declaredMockOnly", "notShipped"],
|
|
95
95
|
"description": "How a third-party service dependency is attested by tests. Shared between fbs.dependsOnServices[] and manifest.preFlightConfig.servicesInScope[]. live: tests hit the live provider with real credentials. sandboxed: tests hit a provider-run sandbox. mocked: local fixtures or stubs; not ship-authoritative on its own. declaredMockOnly: operator has explicitly declared the FBS ships mock-only for this service. notShipped: the service is used only in local development."
|
|
96
96
|
},
|
|
97
|
+
"scopeTag": {
|
|
98
|
+
"enum": ["library", "runtime", "deployed", "unclassified"],
|
|
99
|
+
"description": "Scope tag classifying where a behaviour is observable. Shared between user-story.acceptanceCriteria[].scope and test-suite.testCases[].scope. library: observable in an isolated library or fixture. runtime: observable in the running product against local integration. deployed: observable on a booted artefact against real config and real network. unclassified: migration state for chains authored before the scope-tag vocabulary shipped; ruleset-enforcing consumers decide whether unclassified is currently accepted."
|
|
100
|
+
},
|
|
97
101
|
"docRef": {
|
|
98
102
|
"type": "object",
|
|
99
103
|
"additionalProperties": false,
|
|
@@ -154,8 +154,8 @@
|
|
|
154
154
|
"properties": {
|
|
155
155
|
"id": {
|
|
156
156
|
"type": "string",
|
|
157
|
-
"pattern": "^ra-FBS-\\d{3,}
|
|
158
|
-
"description": "Review-audit record id. Format: ra-<fbsId>-<n>; the trailing integer increments per re-audit of the same FBS."
|
|
157
|
+
"pattern": "^ra-FBS-\\d{3,}(?:-[a-z0-9]+(?:-[a-z0-9]+)*)?-\\d+$",
|
|
158
|
+
"description": "Review-audit record id. Format: ra-<fbsId>-<n>; the trailing integer increments per re-audit of the same FBS. Accepts both numeric-only and kebab-slug FBS ids."
|
|
159
159
|
},
|
|
160
160
|
"fbsId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/fbsId" },
|
|
161
161
|
"createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" },
|
|
@@ -389,8 +389,8 @@
|
|
|
389
389
|
"properties": {
|
|
390
390
|
"id": {
|
|
391
391
|
"type": "string",
|
|
392
|
-
"pattern": "^bv-FBS-\\d{3,}
|
|
393
|
-
"description": "Browser-verification record id. Format: bv-<fbsId>-<n>."
|
|
392
|
+
"pattern": "^bv-FBS-\\d{3,}(?:-[a-z0-9]+(?:-[a-z0-9]+)*)?-\\d+$",
|
|
393
|
+
"description": "Browser-verification record id. Format: bv-<fbsId>-<n>. Accepts both numeric-only and kebab-slug FBS ids."
|
|
394
394
|
},
|
|
395
395
|
"fbsId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/fbsId" },
|
|
396
396
|
"createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" },
|
|
@@ -730,8 +730,8 @@
|
|
|
730
730
|
"properties": {
|
|
731
731
|
"id": {
|
|
732
732
|
"type": "string",
|
|
733
|
-
"pattern": "^swv-FBS-\\d{3,}
|
|
734
|
-
"description": "Ship-without-verified acknowledgement id. Format: swv-<fbsId>-<n>; the trailing integer increments per acknowledgement of the same FBS."
|
|
733
|
+
"pattern": "^swv-FBS-\\d{3,}(?:-[a-z0-9]+(?:-[a-z0-9]+)*)?-\\d+$",
|
|
734
|
+
"description": "Ship-without-verified acknowledgement id. Format: swv-<fbsId>-<n>; the trailing integer increments per acknowledgement of the same FBS. Accepts both numeric-only and kebab-slug FBS ids."
|
|
735
735
|
},
|
|
736
736
|
"fbsId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/fbsId" },
|
|
737
737
|
"ackedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" },
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"properties": {
|
|
46
46
|
"id": {
|
|
47
47
|
"type": "string",
|
|
48
|
-
"pattern": "^TC-\\d{3}-[a-z0-9-]+$",
|
|
49
|
-
"description": "Test Case identifier. TS suffix (three
|
|
48
|
+
"pattern": "^TC-\\d{3,}-[a-z0-9-]+$",
|
|
49
|
+
"description": "Test Case identifier. TS suffix (three-digit minimum, unbounded above) joined to a lowercase alphanumeric slug (hyphens allowed)."
|
|
50
50
|
},
|
|
51
51
|
"acId": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/acId" },
|
|
52
52
|
"description": { "type": "string", "minLength": 1 },
|
|
@@ -55,6 +55,10 @@
|
|
|
55
55
|
"description": "Optional pointer to the executable test, format: filePath::testName."
|
|
56
56
|
},
|
|
57
57
|
"status": { "enum": ["pending", "passing", "failing", "skipped"] },
|
|
58
|
+
"scope": {
|
|
59
|
+
"$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/scopeTag",
|
|
60
|
+
"description": "Scope this test case exercises (library, runtime, deployed, unclassified). Optional at schema level; ruleset-enforcing consumers may require the TC scope to be equal to or wider than the covered AC's scope."
|
|
61
|
+
},
|
|
58
62
|
"runtimeProvenance": { "$ref": "#/$defs/runtimeProvenance" }
|
|
59
63
|
}
|
|
60
64
|
},
|
|
@@ -55,6 +55,10 @@
|
|
|
55
55
|
"when": { "type": "string" },
|
|
56
56
|
"then": { "type": "string" },
|
|
57
57
|
"testable": { "type": "boolean" },
|
|
58
|
+
"scope": {
|
|
59
|
+
"$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/scopeTag",
|
|
60
|
+
"description": "Scope at which this acceptance criterion is observable (library, runtime, deployed, unclassified). Optional at schema level; ruleset-enforcing consumers may require it. Governs which test scopes count as coverage for this AC."
|
|
61
|
+
},
|
|
58
62
|
"provenance": { "$ref": "#/$defs/acProvenance" }
|
|
59
63
|
}
|
|
60
64
|
},
|