@stravica-ai/rcf-schemas 0.6.3 → 0.7.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.
- package/CHANGELOG.md +59 -0
- package/docs/fbs.md +1 -0
- package/docs/manifest.md +14 -0
- package/fixtures/invalid/fbs/fbs-014-journey-step-ids-non-string.json +14 -0
- package/fixtures/invalid/fbs/fbs-015-journey-step-ids-duplicate.json +14 -0
- package/fixtures/invalid/fbs/fbs-016-journey-step-ids-empty-string.json +14 -0
- package/fixtures/invalid/user-story/us-009-ac-probe-unknown-property.json +24 -0
- package/fixtures/invalid/user-story/us-010-ac-probe-expect-body-both.json +27 -0
- package/fixtures/invalid/user-story/us-011-ac-probe-expect-status-600.json +24 -0
- package/fixtures/invalid/user-story/us-012-ac-probe-expect-header-missing-match.json +26 -0
- package/fixtures/invalid/user-story/us-013-ac-probe-missing-path.json +24 -0
- package/fixtures/valid/fbs/fbs-008-journey-step-ids.json +14 -0
- package/fixtures/valid/manifest/manifest-017-review-audit-journey-stub.json +29 -0
- package/fixtures/valid/user-story/us-007-ac-probe-minimal.json +24 -0
- package/fixtures/valid/user-story/us-008-ac-probe-full.json +39 -0
- package/package.json +1 -1
- package/schemas/fbs.schema.json +7 -1
- package/schemas/manifest.schema.json +9 -3
- package/schemas/user-story.schema.json +74 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,65 @@ 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.7.1 - 2026-10-16
|
|
8
|
+
|
|
9
|
+
Patch bump for rcf-lite issue 349 (per-AC probe catalog resolved by deterministic verify, rcf-lite TAC-4150 and FBS-218). Adds an additive, optional `probe` object on the inline `$defs.acceptanceCriterion` of the user story, so an acceptance criterion can carry a structured, deterministic probe that `rcf verify run --mode deterministic` resolves to pass, fail or skipped with evidence. An AC without a probe stays critique-only. Every change is additive: every 0.7.0-valid document keeps validating.
|
|
10
|
+
|
|
11
|
+
Patch semver convention: URLs pinned at `v0.6.0`. No breaking change; every 0.7.0-valid document keeps validating. rcf-lite TAC-4150 calls this change "the rcf-schemas minor"; under this repo's rule (`CONTRIBUTING.md` and the `README.md` Versioning section: additive changes are a patch bump, breaking changes a minor) an optional property on a closed object is additive, the same call 0.6.2 made for `ownerRef`, `disposition` and `vendorCitation` on the same record, so the release is `0.7.1`.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`user-story.schema.json`**: new optional `probe` on the inline `$defs.acceptanceCriterion`, `$defs.acProbe`. Object, `additionalProperties: false`, only `path` required. Fields: `method` (string enum `GET | HEAD | POST | PUT | PATCH | DELETE | OPTIONS`; absence means GET, documented in the `description` rather than a JSON Schema `default`, since no schema in this repo uses `default`), `path` (min-length-1 string, a URL path relative to the run's `--url`), `expectStatus` (integer, 100..599), `expectHeader` (`$defs.acProbeExpectHeader`), `expectBody` (`$defs.acProbeExpectBody`), `selector` (min-length-1 string, a DOM selector that must be present), `parityEnv` (min-length-1 string, paired by the resolver with `rcf verify run --parity-env`). Shape follows the Probe record in rcf-lite TAC-4150.
|
|
16
|
+
- **`user-story.schema.json`**: new `$defs.acProbeExpectHeader`. Object with required `name` and `match` (both min-length-1 strings), `additionalProperties: false`. Match semantics belong to the consuming resolver; the schema constrains shape only.
|
|
17
|
+
- **`user-story.schema.json`**: new `$defs.acProbeExpectBody`. Object with optional `contains` (min-length-1 string, literal text) and `matches` (min-length-1 string, a regular expression source), `additionalProperties: false`, `minProperties: 1` and `maxProperties: 1`, so exactly one of the two is present.
|
|
18
|
+
- **Fixtures (valid)**: `fixtures/valid/user-story/us-007-ac-probe-minimal.json` (a probe with only `path`), `fixtures/valid/user-story/us-008-ac-probe-full.json` (a probe carrying every field, `expectBody.matches`).
|
|
19
|
+
- **Fixtures (invalid)**: `fixtures/invalid/user-story/us-009-ac-probe-unknown-property.json` (unknown `timeoutMs` on the probe), `fixtures/invalid/user-story/us-010-ac-probe-expect-body-both.json` (`expectBody` with both `contains` and `matches`), `fixtures/invalid/user-story/us-011-ac-probe-expect-status-600.json` (`expectStatus` 600), `fixtures/invalid/user-story/us-012-ac-probe-expect-header-missing-match.json` (`expectHeader` without `match`), `fixtures/invalid/user-story/us-013-ac-probe-missing-path.json` (probe without the required `path`). Each fails on exactly one ajv error.
|
|
20
|
+
- **Tests**: `test/user-story.test.js` gains 23 cases for `probe` (back-compat absent, minimal path-only, full shape, `expectBody.contains`, every method enum value, lowercase method rejected, missing and empty `path` rejected, unknown probe property rejected, bare-string probe rejected, `expectBody` with both, neither, an unknown property or an empty `contains` rejected, `expectStatus` 600, 99, 200.5 and "200" rejected, bounds 100 and 599 accepted, `expectHeader` missing `match`, missing `name` or carrying an unknown property rejected, empty `selector` and empty `parityEnv` rejected, probe alongside `scope`, `determinism`, `ownerRef`, `disposition` and `provenance`). Total suite grows from 379 to 402.
|
|
21
|
+
|
|
22
|
+
### Migration
|
|
23
|
+
|
|
24
|
+
- **Existing chains on 0.7.0**: bump `@stravica-ai/rcf-schemas` to `0.7.1`. Every existing document keeps validating; `probe` is optional and unknown to pre-0.7.1 callers.
|
|
25
|
+
- **To adopt a probe on an AC**: add `probe: { path }` plus whichever expectations the criterion needs (`expectStatus`, `expectHeader`, `expectBody`, `selector`, `parityEnv`). An AC with no probe stays critique-only; the rcf-lite catalog file `rcf/verify-catalog.json` remains an alternative carrier, and an AC-level probe wins over a catalog entry (rcf-lite TAC-4150).
|
|
26
|
+
- **Consumers to bump**: `rcf-lite` (its `packages/rcf-lite/package.json` pins the schemas package exact, at `0.7.0` on `main` at this release). The pin bump to `0.7.1` is FBS-218's job: the build spec cannot merge until the pin lands. This repo does not touch rcf-lite.
|
|
27
|
+
|
|
28
|
+
### Notes
|
|
29
|
+
|
|
30
|
+
- `expectBody` uses `minProperties` / `maxProperties` on a closed object rather than a `oneOf` of `required` arms: ajv strict mode (`strictRequired`, which this repo's test loader runs under) refuses a `required` keyword in an arm that does not declare the property locally, and the closed-object count expresses "exactly one of `contains` or `matches`" in one place with a direct error message.
|
|
31
|
+
- Scripted back-compat pass at authoring time: every 0.7.0 fixture at main `e721930` (65 valid + 90 invalid = 155 total) validates to the same outcome against the 0.7.1 schemas with zero drift.
|
|
32
|
+
- `docs/user-story.md` does not yet describe `probe`; this release was scoped to the schema, fixtures, tests, version and changelog, and the doc page catches up in a follow-up.
|
|
33
|
+
- `back-compat-freeze.test.js` continues to pass.
|
|
34
|
+
|
|
35
|
+
## 0.7.0 - 2026-10-11
|
|
36
|
+
|
|
37
|
+
Minor bump for the discovery-UX gate: adds an optional `journeyStepIds[]` carrier on the FBS schema and a new `journeyStub` review-finding kind on `reviewAudit[].testTheatreFindings[].kind`. Both additions are additive at the shape level; every 0.6.3-valid document keeps validating. The bump is a minor (not a patch) because the review-kind enum is a shared vocabulary and the enum extension is a vocabulary change consumers may want to switch on, following the project's pre-1.0 convention. Canonical `$id` URLs are kept at `v0.6.0` on this release: no schema's `$id` or cross-file `$ref` changes, so every validator keyed to the `v0.6.0` URLs picks up the additions by file bytes alone. Rolling the URLs to `v0.7.0` is deferred to HQ at publish time if the convention calls for it.
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- **`fbs.schema.json`**: new optional top-level `journeyStepIds` property. Shape: `array` with items `{ type: "string", minLength: 1 }` and `uniqueItems: true`. Carries discovery journey step ids (shape `JNY-nnn-nnn`, owned by the discovery journey record at `rcf/discovery/journey.json`, minted by the discovery binder as `JNY-nnn-nnn` under their parent `JNY-nnn` journey) that the build unit delivers. Written at Define; read by the build-review surface so a UI-bearing FBS that leaves a journey step unbound, or a discovery step with no FBS binding, raises the new `journeyStub` finding kind. Pre-0.7.0 FBSes stay valid: the field is optional and no existing property changes.
|
|
42
|
+
- **`manifest.schema.json`**: `reviewAudit[].testTheatreFindings[].kind` enum gains `journeyStub` (appended between `uiBaselineDrift` and `otherDeclared`, nothing reordered). The `allOf` conditional that lets `uiBaselineDrift` findings omit `tsId` is widened via `anyOf` so `journeyStub` findings also omit `tsId`: they anchor on an FBS id or a `JNY-nnn-nnn` step id via `anchorId`, same pattern as `uiBaselineDrift`. Every other kind still requires `tsId`; the back-compat allOf arm is unchanged for them.
|
|
43
|
+
- **`manifest.schema.json`**: top-level `description` extended to name the new `journeyStub` kind, following the "From 0.X.Y the manifest additionally carries..." precedent set at 0.4.1, 0.4.4, 0.4.5, 0.5.1 and 0.6.3.
|
|
44
|
+
- **Fixtures (valid)**: `fixtures/valid/fbs/fbs-008-journey-step-ids.json` (FBS-215 carrying three `JNY-nnn-nnn` ids), `fixtures/valid/manifest/manifest-017-review-audit-journey-stub.json` (one `reviewAudit` with two `journeyStub` findings: one anchored on an FBS id, one anchored on a `JNY-nnn-nnn` step id).
|
|
45
|
+
- **Fixtures (invalid)**: `fixtures/invalid/fbs/fbs-014-journey-step-ids-non-string.json` (numeric item), `fixtures/invalid/fbs/fbs-015-journey-step-ids-duplicate.json` (two identical entries, `uniqueItems`), `fixtures/invalid/fbs/fbs-016-journey-step-ids-empty-string.json` (empty-string item, items `minLength` 1).
|
|
46
|
+
- **Tests**: `test/fbs.test.js` gains 9 cases for `journeyStepIds` (back-compat absent, populated, empty array, free-form ids, non-string rejected, empty-string rejected, duplicate rejected, non-array rejected, alongside `contextRequirements.standardIds`). `test/manifest.test.js` gains 5 cases for the `journeyStub` kind (anchor on FBS id, anchor on `JNY-nnn-nnn` step id, finding without `tsId` validates, bad severity rejected, non-exempt kind still requires `tsId`). Total suite grows from 365 to 379.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- No `$id` URL roll on this minor bump: the schemas remain keyed to `https://schemas.stravica.io/rcf/v0.6.0/...`. Deviates from the 0.3.0 / 0.4.0 / 0.5.0 / 0.6.0 precedent of rolling the URL on a minor; retained here because the scope is strictly additive and rolling the URL is itself a consumer-visible change that would be larger than the schema delta. Final call on URL rolling at publish time; nothing on this PR precommits it.
|
|
51
|
+
|
|
52
|
+
### Migration
|
|
53
|
+
|
|
54
|
+
- **Existing chains on 0.6.3**: bump `@stravica-ai/rcf-schemas` to `0.7.0`. Every existing document keeps validating; both additions are optional and unknown to pre-0.7.0 callers.
|
|
55
|
+
- **To adopt `journeyStepIds` on an FBS**: list the discovery journey step ids the build unit delivers; the discovery record is the source of truth for the ids. The field is optional and may be left absent until the FBS is bound.
|
|
56
|
+
- **To emit a `journeyStub` finding from the review surface**: switch the current `otherDeclared` + `kindDescription: "journeyStub: ..."` path to `kind: "journeyStub"`, anchored on the relevant FBS id or `JNY-nnn-nnn` step id via `anchorId`.
|
|
57
|
+
- **Consumers to bump**: `rcf-lite` (its `packages/rcf-lite/package.json` pins the schemas package exact; the discovery-UX-gate train bumps it to `0.7.0`).
|
|
58
|
+
|
|
59
|
+
### Notes
|
|
60
|
+
|
|
61
|
+
- Review-kind enum additive-safety was verified in-tree: `rcf-lite` carries only a JSDoc `TestTheatreFindingKind` typedef and non-exhaustive consumption of the `kind` string. No exhaustive `switch` on the enum surfaced in a repository walk at relay time.
|
|
62
|
+
- The `allOf` widening uses the same `if`/`then` conditional pattern the schema already uses for `uiBaselineDrift` (0.4.2) and `applicable` (0.6.3), with the `if` moved into an `anyOf` so both exempt kinds share one arm. The `else` arm is byte-identical to the pre-0.7.0 clause; every pre-0.7.0 finding keeps hitting the same requiredness.
|
|
63
|
+
- `back-compat-freeze.test.js` continues to pass: the frozen pre-0.4.4 manifest fixture is unaffected by the enum addition or the allOf widening.
|
|
64
|
+
- Scripted back-compat pass at authoring time: every 0.6.3 fixture at main `990875b4` (63 valid + 87 invalid = 150 total) validates to the same outcome against the 0.7.0 schemas with zero drift.
|
|
65
|
+
|
|
7
66
|
## 0.6.3 - 2026-09-17
|
|
8
67
|
|
|
9
68
|
Patch bump for the last two schema-shaped claims on the rcf-lite 0.28.0 referee-guarantees train (docs claims C-33 and C-38). Adds an additive, optional `shipWithoutEval[]` carrier on the manifest (sister of `shipWithoutVerified`, written by `rcf finalise --ship-without-eval`), and an additive, optional `applicable` boolean on `browserVerificationProbePackCheck` (mirrors the pack-level `applicable`, so a check whose own `appliesTo` predicate returned false records `applicable: false` at the check level without a stray verdict or severity). Every change is additive: every 0.6.2-valid manifest keeps validating.
|
package/docs/fbs.md
CHANGED
|
@@ -36,6 +36,7 @@ Structurally, each FBS carries the mandatory `bsId` back-reference plus `buildOr
|
|
|
36
36
|
| `domain` | string | Free-form domain label. |
|
|
37
37
|
| `notes` | string | FBS-specific gotchas. |
|
|
38
38
|
| `noCodeNodes` | boolean | Declares this build spec produces no traceable code (docs-only or config-only). `rcf build --mark complete` records it via `--no-code-nodes` and the CodeNode gate skips the spec. Added in 0.3.1. |
|
|
39
|
+
| `journeyStepIds` | array of non-empty strings, `uniqueItems: true` | Discovery journey step ids (shape `JNY-nnn-nnn`, owned by the discovery journey record at `rcf/discovery/journey.json`) that this build unit delivers. Written at Define; read by the build-review surface so a UI-bearing FBS that leaves a journey step unbound, or a discovery step with no FBS binding, raises a `journeyStub` review finding. Optional; pre-0.7.0 FBSes keep validating. Added in 0.7.0. |
|
|
39
40
|
|
|
40
41
|
## `contextRequirements` shape
|
|
41
42
|
|
package/docs/manifest.md
CHANGED
|
@@ -59,6 +59,20 @@ SSoT discipline. Every parent-child edge is encoded exactly once, on the child,
|
|
|
59
59
|
|
|
60
60
|
Enumerating children in the manifest as well would create two sources of truth; pick one. The child owns the reference. The manifest stays small (~8 properties) and a new US / TAC / ADR / FBS / REQ / TS never requires a manifest edit.
|
|
61
61
|
|
|
62
|
+
## `reviewAudit[].testTheatreFindings[].kind` vocabulary
|
|
63
|
+
|
|
64
|
+
Review findings on a `reviewAudit` record carry a `kind` from a fixed enum. The vocabulary grows additively; a consumer that switches on the enum should treat an unknown value as "unrecognised" rather than fail-closed.
|
|
65
|
+
|
|
66
|
+
| Kind | Introduced | Anchor | Notes |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `mockOnlyIntegrationClaim` | 0.4.0 | `tsId` required | Test suite claims an integration level but the runtime profile is mock. |
|
|
69
|
+
| `testPointerBroken` | 0.4.0 | `tsId` required | The TS/TC pointer resolves to no code node. |
|
|
70
|
+
| `assertionStrengthWeak` | 0.4.0 | `tsId` required | Assertion found too weak for the AC it attests. |
|
|
71
|
+
| `acIdsCoverageDrift` | 0.4.0 | `tsId` required | AC coverage drifted between declared and attested. |
|
|
72
|
+
| `uiBaselineDrift` | 0.4.2 | `anchorId` (FBS id or file path) | UI implementation contradicts a declared uiBaseline default. Exempt from the `tsId` requirement. |
|
|
73
|
+
| `journeyStub` | 0.7.0 | `anchorId` (FBS id or discovery `JNY-nnn-nnn` step id) | Build-review surface flag: a UI-bearing FBS whose `journeyStepIds[]` is empty, or a discovery step with no FBS binding. Exempt from the `tsId` requirement; the sibling pattern of `uiBaselineDrift`. |
|
|
74
|
+
| `otherDeclared` | 0.4.0 | `tsId` required; `kindDescription` required in practice | Catch-all; carries free-text `kindDescription`. |
|
|
75
|
+
|
|
62
76
|
## Example
|
|
63
77
|
|
|
64
78
|
```json
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fbsId": "FBS-215",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"bsId": "BS-001",
|
|
5
|
+
"buildOrder": 15,
|
|
6
|
+
"executionStatus": "notStarted",
|
|
7
|
+
"title": "journeyStepIds non-string item",
|
|
8
|
+
"summary": "journeyStepIds carries a numeric entry; the schema requires string items.",
|
|
9
|
+
"acIds": ["AC-001"],
|
|
10
|
+
"dependsOnFbsIds": [],
|
|
11
|
+
"journeyStepIds": ["JNY-001-001", 2],
|
|
12
|
+
"createdAt": "2026-10-11T00:00:00Z",
|
|
13
|
+
"updatedAt": "2026-10-11T00:00:00Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fbsId": "FBS-215",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"bsId": "BS-001",
|
|
5
|
+
"buildOrder": 15,
|
|
6
|
+
"executionStatus": "notStarted",
|
|
7
|
+
"title": "journeyStepIds duplicate items",
|
|
8
|
+
"summary": "journeyStepIds carries two identical entries; uniqueItems is enforced.",
|
|
9
|
+
"acIds": ["AC-001"],
|
|
10
|
+
"dependsOnFbsIds": [],
|
|
11
|
+
"journeyStepIds": ["JNY-001-001", "JNY-001-001"],
|
|
12
|
+
"createdAt": "2026-10-11T00:00:00Z",
|
|
13
|
+
"updatedAt": "2026-10-11T00:00:00Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fbsId": "FBS-215",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"bsId": "BS-001",
|
|
5
|
+
"buildOrder": 15,
|
|
6
|
+
"executionStatus": "notStarted",
|
|
7
|
+
"title": "journeyStepIds empty-string entry",
|
|
8
|
+
"summary": "journeyStepIds carries an empty-string entry; items have minLength 1.",
|
|
9
|
+
"acIds": ["AC-001"],
|
|
10
|
+
"dependsOnFbsIds": [],
|
|
11
|
+
"journeyStepIds": ["JNY-001-001", ""],
|
|
12
|
+
"createdAt": "2026-10-11T00:00:00Z",
|
|
13
|
+
"updatedAt": "2026-10-11T00:00:00Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-301",
|
|
3
|
+
"prdId": "PRD-100",
|
|
4
|
+
"reqId": "REQ-301",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "Probe with an unknown property is rejected",
|
|
8
|
+
"asA": "author",
|
|
9
|
+
"iWant": "the probe object to stay closed",
|
|
10
|
+
"soThat": "a typo in a probe field is a validation error, not a silent no-op",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-301-1",
|
|
14
|
+
"description": "Probe carries an unknown timeoutMs field.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"probe": {
|
|
17
|
+
"path": "/healthz",
|
|
18
|
+
"timeoutMs": 500
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
23
|
+
"updatedAt": "2026-10-16T00:00:00Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-301",
|
|
3
|
+
"prdId": "PRD-100",
|
|
4
|
+
"reqId": "REQ-301",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "Probe expectBody with both contains and matches is rejected",
|
|
8
|
+
"asA": "author",
|
|
9
|
+
"iWant": "expectBody to carry exactly one assertion",
|
|
10
|
+
"soThat": "the resolver never has to pick between two body checks",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-301-1",
|
|
14
|
+
"description": "expectBody carries both contains and matches.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"probe": {
|
|
17
|
+
"path": "/api/notes",
|
|
18
|
+
"expectBody": {
|
|
19
|
+
"contains": "notes",
|
|
20
|
+
"matches": "^\\{"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
26
|
+
"updatedAt": "2026-10-16T00:00:00Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-301",
|
|
3
|
+
"prdId": "PRD-100",
|
|
4
|
+
"reqId": "REQ-301",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "Probe expectStatus outside 100..599 is rejected",
|
|
8
|
+
"asA": "author",
|
|
9
|
+
"iWant": "expectStatus to be a real HTTP status code",
|
|
10
|
+
"soThat": "a typo in the expected status is caught at authoring time",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-301-1",
|
|
14
|
+
"description": "expectStatus is 600.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"probe": {
|
|
17
|
+
"path": "/healthz",
|
|
18
|
+
"expectStatus": 600
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
23
|
+
"updatedAt": "2026-10-16T00:00:00Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-301",
|
|
3
|
+
"prdId": "PRD-100",
|
|
4
|
+
"reqId": "REQ-301",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "Probe expectHeader without match is rejected",
|
|
8
|
+
"asA": "author",
|
|
9
|
+
"iWant": "a header assertion to name both the header and the value",
|
|
10
|
+
"soThat": "a header probe always asserts something",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-301-1",
|
|
14
|
+
"description": "expectHeader names the header but omits match.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"probe": {
|
|
17
|
+
"path": "/healthz",
|
|
18
|
+
"expectHeader": {
|
|
19
|
+
"name": "content-type"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
25
|
+
"updatedAt": "2026-10-16T00:00:00Z"
|
|
26
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-301",
|
|
3
|
+
"prdId": "PRD-100",
|
|
4
|
+
"reqId": "REQ-301",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "draft",
|
|
7
|
+
"title": "Probe without path is rejected",
|
|
8
|
+
"asA": "author",
|
|
9
|
+
"iWant": "every probe to name the path it requests",
|
|
10
|
+
"soThat": "the resolver always knows what to fetch",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-301-1",
|
|
14
|
+
"description": "Probe omits the required path.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"probe": {
|
|
17
|
+
"method": "GET",
|
|
18
|
+
"expectStatus": 200
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
23
|
+
"updatedAt": "2026-10-16T00:00:00Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fbsId": "FBS-215",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"bsId": "BS-001",
|
|
5
|
+
"buildOrder": 15,
|
|
6
|
+
"executionStatus": "notStarted",
|
|
7
|
+
"title": "Discovery UX gate: journeyStub review-kind binding",
|
|
8
|
+
"summary": "Bind the FBS to the discovery journey steps it delivers so build review can detect unbound steps and unbound UI-bearing specs.",
|
|
9
|
+
"acIds": ["AC-215-1", "AC-215-2"],
|
|
10
|
+
"dependsOnFbsIds": ["FBS-210"],
|
|
11
|
+
"journeyStepIds": ["JNY-001-001", "JNY-001-002", "JNY-002-001"],
|
|
12
|
+
"createdAt": "2026-10-11T00:00:00Z",
|
|
13
|
+
"updatedAt": "2026-10-11T00:00:00Z"
|
|
14
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"projectName": "journeyStub review-kind coverage",
|
|
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
|
+
"reviewAudit": [
|
|
8
|
+
{
|
|
9
|
+
"id": "ra-FBS-215-1",
|
|
10
|
+
"fbsId": "FBS-215",
|
|
11
|
+
"createdAt": "2026-10-11T15:30:00Z",
|
|
12
|
+
"testTheatreFindings": [
|
|
13
|
+
{
|
|
14
|
+
"anchorId": "FBS-215",
|
|
15
|
+
"kind": "journeyStub",
|
|
16
|
+
"detail": "FBS-215 is UI-bearing (uiBearing: true) but journeyStepIds[] is empty; the discovery journey record binds no step to this build.",
|
|
17
|
+
"severity": "block"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"anchorId": "JNY-001-003",
|
|
21
|
+
"kind": "journeyStub",
|
|
22
|
+
"detail": "Discovery step JNY-001-003 has no FBS binding; no FBS lists it in journeyStepIds[].",
|
|
23
|
+
"severity": "warn"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"verdict": "block"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-301",
|
|
3
|
+
"prdId": "PRD-100",
|
|
4
|
+
"reqId": "REQ-301",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Health endpoint answers on the deployed URL",
|
|
8
|
+
"asA": "operator running deterministic verify",
|
|
9
|
+
"iWant": "an acceptance criterion to carry the smallest possible probe",
|
|
10
|
+
"soThat": "rcf verify run resolves it without a critique pass",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-301-1",
|
|
14
|
+
"description": "The health endpoint answers on the deployed URL.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "deployed",
|
|
17
|
+
"probe": {
|
|
18
|
+
"path": "/healthz"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
23
|
+
"updatedAt": "2026-10-16T00:00:00Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "US-301",
|
|
3
|
+
"prdId": "PRD-100",
|
|
4
|
+
"reqId": "REQ-301",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Notes API returns JSON and the notes list renders",
|
|
8
|
+
"asA": "operator running deterministic verify",
|
|
9
|
+
"iWant": "an acceptance criterion to carry a probe exercising every field",
|
|
10
|
+
"soThat": "rcf verify run resolves status, header, body, selector and environment in one pass",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-301-1",
|
|
14
|
+
"description": "Listing notes returns a JSON notes array, and the notes page renders its list.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"given": "a deployed notes service",
|
|
17
|
+
"when": "the client lists notes",
|
|
18
|
+
"then": "the response is JSON and the list renders",
|
|
19
|
+
"scope": "deployed",
|
|
20
|
+
"determinism": "deterministic",
|
|
21
|
+
"probe": {
|
|
22
|
+
"method": "GET",
|
|
23
|
+
"path": "/api/notes?limit=1",
|
|
24
|
+
"expectStatus": 200,
|
|
25
|
+
"expectHeader": {
|
|
26
|
+
"name": "content-type",
|
|
27
|
+
"match": "application/json"
|
|
28
|
+
},
|
|
29
|
+
"expectBody": {
|
|
30
|
+
"matches": "^\\{\"notes\":\\["
|
|
31
|
+
},
|
|
32
|
+
"selector": "[data-testid=\"notes-list\"]",
|
|
33
|
+
"parityEnv": "preview"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"createdAt": "2026-01-01T00:00:00Z",
|
|
38
|
+
"updatedAt": "2026-10-16T00:00:00Z"
|
|
39
|
+
}
|
package/package.json
CHANGED
package/schemas/fbs.schema.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://schemas.stravica.io/rcf/v0.6.0/fbs.schema.json",
|
|
4
4
|
"title": "RCF Functional Build Spec",
|
|
5
|
-
"description": "Functional Build Specification. One per build session. Carries the mandatory bsId parent reference plus buildOrder and executionStatus. Owns its acIds[] scope (Acceptance Criteria delivered by this FBS) and its dependsOnFbsIds[] graph edge (other FBSs this one depends on). From 0.4.4 the contextRequirements block carries an optional standardIds[] array. It is the host for the bundle assembler's selective-retrieval step: the assembler analyses the FBS work text against the manifest.standards[] tag vocabulary and populates standardIds for that bundle only, or honours an operator override authored on the FBS. Every added field is optional; pre-0.4.4 FBSes remain valid.",
|
|
5
|
+
"description": "Functional Build Specification. One per build session. Carries the mandatory bsId parent reference plus buildOrder and executionStatus. Owns its acIds[] scope (Acceptance Criteria delivered by this FBS) and its dependsOnFbsIds[] graph edge (other FBSs this one depends on). From 0.4.4 the contextRequirements block carries an optional standardIds[] array. It is the host for the bundle assembler's selective-retrieval step: the assembler analyses the FBS work text against the manifest.standards[] tag vocabulary and populates standardIds for that bundle only, or honours an operator override authored on the FBS. From 0.7.0 the FBS additionally carries an optional journeyStepIds[] array: discovery journey step ids (JNY-nnn-nnn) owned by the discovery journey record that this build unit delivers, so the build-review surface can detect unbound discovery steps and unbound UI-bearing build specs. Every added field is optional; pre-0.4.4 FBSes remain valid.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": [
|
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
"minItems": 0,
|
|
38
38
|
"items": { "$ref": "https://schemas.stravica.io/rcf/v0.6.0/common.schema.json#/$defs/fbsId" }
|
|
39
39
|
},
|
|
40
|
+
"journeyStepIds": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"items": { "type": "string", "minLength": 1 },
|
|
43
|
+
"uniqueItems": true,
|
|
44
|
+
"description": "Discovery journey step ids (shape JNY-nnn-nnn, owned by the discovery journey record at rcf/discovery/journey.json) that this build unit delivers. Written at Define by the author or the discovery binder; read by the build-review surface so a UI-bearing FBS that leaves a journey step unbound, or a discovery step with no FBS binding, raises a journeyStub review finding. Optional; pre-0.7.0 FBSes keep validating with no journeyStepIds field present."
|
|
45
|
+
},
|
|
40
46
|
"contextRequirements": {
|
|
41
47
|
"type": "object",
|
|
42
48
|
"additionalProperties": false,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://schemas.stravica.io/rcf/v0.6.0/manifest.schema.json",
|
|
4
4
|
"title": "RCF Project Manifest",
|
|
5
|
-
"description": "Project manifest. Roots-only shape: declares prd, tad, bs. Children are owned by their parents and discovered by walking from the roots. From 0.4.0 the manifest also carries optional records for pre-flight configuration, review audits, UI baselines, browser verification, baseline-AC opt-outs, intake classification, register-regression canaries, and the review-surface state. From 0.4.1 the manifest additionally carries optional shipWithoutVerified acknowledgements written by rcf finalise --ship-without-verified. From 0.4.2 the testTheatreFinding shape carries an optional anchorId and drops tsId from its required list when kind is uiBaselineDrift (the drift finding is not anchored on a test suite); every other kind still requires tsId, and any 0.4.0- or 0.4.1-valid record remains valid. From 0.4.4 the manifest carries two optional additive sections that host the blueprint-library mechanism: blueprints[] (applied-blueprints registry written by rcf blueprint add / remove / upgrade) and standards[] (standards-pack registry written at rcf init and rcf standards add). From 0.4.5 the manifest additionally carries an optional resolutions[] section: one entry per operator-authored resolution of a cross-blueprint conflict, keyed at first by the globalAdrTopic conflict class (two applied blueprints each contributing a scope:global ADR on the same topic, resolved by a project-level ADR that supersedes both). Written by rcf blueprint supersede and by rcf blueprint add --resolve; read by the conflict detector so the resolved conflict is honoured and both blueprint ADRs may co-reside as superseded history. From 0.5.1 the appliedBlueprintRecord carries an optional libraryPrefix (blueprintSlug), stamped when an apply resolves through a registered external blueprint library so the library-registered ownership is durable on the record itself rather than derived by string-matching source; absent for shelf or path applies. From 0.6.3 the manifest additionally carries an optional shipWithoutEval[] section written by rcf finalise --ship-without-eval (sister of shipWithoutVerified; acknowledges EVAL-MISSING or EVAL-BELOW-THRESHOLD per-AC verdicts on the verify report and carries the operator's reason string); and the browserVerificationProbePackCheck item accepts an optional applicable:boolean flag, letting a check-level appliesTo predicate record applicable:false without a verdict or severity (aggregate verdict treats such a check as neither pass nor fail). Every added field is optional; pre-0.4.0 manifests remain valid.",
|
|
5
|
+
"description": "Project manifest. Roots-only shape: declares prd, tad, bs. Children are owned by their parents and discovered by walking from the roots. From 0.4.0 the manifest also carries optional records for pre-flight configuration, review audits, UI baselines, browser verification, baseline-AC opt-outs, intake classification, register-regression canaries, and the review-surface state. From 0.4.1 the manifest additionally carries optional shipWithoutVerified acknowledgements written by rcf finalise --ship-without-verified. From 0.4.2 the testTheatreFinding shape carries an optional anchorId and drops tsId from its required list when kind is uiBaselineDrift (the drift finding is not anchored on a test suite); every other kind still requires tsId, and any 0.4.0- or 0.4.1-valid record remains valid. From 0.4.4 the manifest carries two optional additive sections that host the blueprint-library mechanism: blueprints[] (applied-blueprints registry written by rcf blueprint add / remove / upgrade) and standards[] (standards-pack registry written at rcf init and rcf standards add). From 0.4.5 the manifest additionally carries an optional resolutions[] section: one entry per operator-authored resolution of a cross-blueprint conflict, keyed at first by the globalAdrTopic conflict class (two applied blueprints each contributing a scope:global ADR on the same topic, resolved by a project-level ADR that supersedes both). Written by rcf blueprint supersede and by rcf blueprint add --resolve; read by the conflict detector so the resolved conflict is honoured and both blueprint ADRs may co-reside as superseded history. From 0.5.1 the appliedBlueprintRecord carries an optional libraryPrefix (blueprintSlug), stamped when an apply resolves through a registered external blueprint library so the library-registered ownership is durable on the record itself rather than derived by string-matching source; absent for shelf or path applies. From 0.6.3 the manifest additionally carries an optional shipWithoutEval[] section written by rcf finalise --ship-without-eval (sister of shipWithoutVerified; acknowledges EVAL-MISSING or EVAL-BELOW-THRESHOLD per-AC verdicts on the verify report and carries the operator's reason string); and the browserVerificationProbePackCheck item accepts an optional applicable:boolean flag, letting a check-level appliesTo predicate record applicable:false without a verdict or severity (aggregate verdict treats such a check as neither pass nor fail). From 0.7.0 the testTheatreFinding kind enum additionally accepts journeyStub (sibling of uiBaselineDrift), carried by the build-review surface when the FBS-to-discovery-journey binding is incomplete; the enum extension is additive, every 0.6.3-valid finding keeps validating. Every added field is optional; pre-0.4.0 manifests remain valid.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": ["version", "projectName", "prd", "tad", "bs"],
|
|
@@ -214,9 +214,10 @@
|
|
|
214
214
|
"assertionStrengthWeak",
|
|
215
215
|
"acIdsCoverageDrift",
|
|
216
216
|
"uiBaselineDrift",
|
|
217
|
+
"journeyStub",
|
|
217
218
|
"otherDeclared"
|
|
218
219
|
],
|
|
219
|
-
"description": "Category of the finding. uiBaselineDrift is added by the UI-design-gate track for FBS implementations that contradict a uiBaseline default. otherDeclared requires a kindDescription."
|
|
220
|
+
"description": "Category of the finding. uiBaselineDrift is added by the UI-design-gate track for FBS implementations that contradict a uiBaseline default. journeyStub (added 0.7.0) is raised by the build-review surface when the FBS-to-journey binding (fbs.journeyStepIds[] against the discovery journey record) is incomplete: a discovery step with no FBS binding, or a UI-bearing FBS whose journeyStepIds[] is empty. Previously these cases went out as otherDeclared with a `journeyStub:` detail prefix; the dedicated kind lets consumers key on it without parsing the detail string. otherDeclared requires a kindDescription."
|
|
220
221
|
},
|
|
221
222
|
"kindDescription": {
|
|
222
223
|
"type": "string",
|
|
@@ -235,7 +236,12 @@
|
|
|
235
236
|
},
|
|
236
237
|
"allOf": [
|
|
237
238
|
{
|
|
238
|
-
"if": {
|
|
239
|
+
"if": {
|
|
240
|
+
"anyOf": [
|
|
241
|
+
{ "properties": { "kind": { "const": "uiBaselineDrift" } }, "required": ["kind"] },
|
|
242
|
+
{ "properties": { "kind": { "const": "journeyStub" } }, "required": ["kind"] }
|
|
243
|
+
]
|
|
244
|
+
},
|
|
239
245
|
"then": {},
|
|
240
246
|
"else": {
|
|
241
247
|
"properties": {
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"ownerRef": { "$ref": "#/$defs/acOwnerRef" },
|
|
72
72
|
"disposition": { "$ref": "#/$defs/acDisposition" },
|
|
73
73
|
"vendorCitation": { "$ref": "#/$defs/acVendorCitation" },
|
|
74
|
+
"probe": { "$ref": "#/$defs/acProbe" },
|
|
74
75
|
"provenance": { "$ref": "#/$defs/acProvenance" }
|
|
75
76
|
}
|
|
76
77
|
},
|
|
@@ -111,6 +112,79 @@
|
|
|
111
112
|
},
|
|
112
113
|
"description": "Vendor citation for an acceptance criterion whose truth rests on a third-party platform fact. Optional at schema level; consumer rulesets may require it on any AC that asserts a vendor fact (for example, a platform migration keyword or a rate-limit value)."
|
|
113
114
|
},
|
|
115
|
+
"acProbe": {
|
|
116
|
+
"type": "object",
|
|
117
|
+
"additionalProperties": false,
|
|
118
|
+
"required": ["path"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"method": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"enum": ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
|
|
123
|
+
"description": "HTTP method of the probe request. Optional; absence means GET."
|
|
124
|
+
},
|
|
125
|
+
"path": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"minLength": 1,
|
|
128
|
+
"description": "URL path the probe requests, relative to the run's --url (for example /healthz or /api/notes?limit=1). The only required field."
|
|
129
|
+
},
|
|
130
|
+
"expectStatus": {
|
|
131
|
+
"type": "integer",
|
|
132
|
+
"minimum": 100,
|
|
133
|
+
"maximum": 599,
|
|
134
|
+
"description": "HTTP status code the response must carry."
|
|
135
|
+
},
|
|
136
|
+
"expectHeader": { "$ref": "#/$defs/acProbeExpectHeader" },
|
|
137
|
+
"expectBody": { "$ref": "#/$defs/acProbeExpectBody" },
|
|
138
|
+
"selector": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"minLength": 1,
|
|
141
|
+
"description": "DOM selector that must be present in the rendered response."
|
|
142
|
+
},
|
|
143
|
+
"parityEnv": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"minLength": 1,
|
|
146
|
+
"description": "Target environment the probe is scoped to; the consuming resolver pairs it with rcf verify run --parity-env."
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"description": "Deterministic per-AC probe resolved by rcf verify run (rcf-lite issue 349). Absent means the criterion stays critique-only. Shape follows the Probe record in rcf-lite TAC-4150; the schema constrains shape only and the resolution semantics belong to the consumer."
|
|
150
|
+
},
|
|
151
|
+
"acProbeExpectHeader": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"additionalProperties": false,
|
|
154
|
+
"required": ["name", "match"],
|
|
155
|
+
"properties": {
|
|
156
|
+
"name": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"minLength": 1,
|
|
159
|
+
"description": "Response header name."
|
|
160
|
+
},
|
|
161
|
+
"match": {
|
|
162
|
+
"type": "string",
|
|
163
|
+
"minLength": 1,
|
|
164
|
+
"description": "Value the named header must match. Match semantics belong to the consuming resolver."
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"description": "Response header assertion on an acceptance-criterion probe. Both name and match are required."
|
|
168
|
+
},
|
|
169
|
+
"acProbeExpectBody": {
|
|
170
|
+
"type": "object",
|
|
171
|
+
"additionalProperties": false,
|
|
172
|
+
"properties": {
|
|
173
|
+
"contains": {
|
|
174
|
+
"type": "string",
|
|
175
|
+
"minLength": 1,
|
|
176
|
+
"description": "Literal text the response body must contain."
|
|
177
|
+
},
|
|
178
|
+
"matches": {
|
|
179
|
+
"type": "string",
|
|
180
|
+
"minLength": 1,
|
|
181
|
+
"description": "Regular expression source the response body must match."
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
"minProperties": 1,
|
|
185
|
+
"maxProperties": 1,
|
|
186
|
+
"description": "Response body assertion on an acceptance-criterion probe. Exactly one of contains or matches: the object is closed to those two properties and carries exactly one of them."
|
|
187
|
+
},
|
|
114
188
|
"acProvenance": {
|
|
115
189
|
"type": "object",
|
|
116
190
|
"additionalProperties": false,
|