@stravica-ai/rcf-schemas 0.4.4 → 0.4.5
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 +18 -0
- package/fixtures/invalid/manifest/manifest-020-resolution-bad-id.json +20 -0
- package/fixtures/invalid/manifest/manifest-021-resolution-single-supersedes.json +19 -0
- package/fixtures/valid/manifest/manifest-012-blueprint-topic-resolution.json +41 -0
- package/package.json +1 -1
- package/schemas/manifest.schema.json +59 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ 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.5 - 2026-08-19
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **`manifest.schema.json`**: new optional `resolutions[]` at top level, items `$defs.blueprintConflictResolution`. One entry per operator-authored resolution of a cross-blueprint conflict. Fields: `id` (`^res-YYYY-MM-DD-NNN$`), `createdAt`, `kind` (single-valued enum `globalAdrTopic`; the enum is deliberately single-valued so later minor bumps can add further resolution classes additively without breaking existing consumers), `topic` (the topic key the resolution applies to, matching both superseded blueprint ADRs), `resolvedByAdrId` (the project-level ADR id that supersedes the blueprint ADRs), `supersedes[]` (min 2 items, each `{ slug: blueprintSlug, adrId: string }`), and optional `reason` (operator note). Written by `rcf blueprint supersede` and `rcf blueprint add --resolve`; read by the conflict detector so a would-be conflict on a resolved topic is honoured and both blueprint ADRs may co-reside as superseded history.
|
|
14
|
+
- Fixtures (valid): `fixtures/valid/manifest/manifest-012-blueprint-topic-resolution.json` (two applied blueprints whose global auth ADRs collide, resolved by a project-level ADR that supersedes both).
|
|
15
|
+
- Fixtures (invalid): `fixtures/invalid/manifest/manifest-020-resolution-bad-id.json` (resolution id in the wrong shape), `fixtures/invalid/manifest/manifest-021-resolution-single-supersedes.json` (supersedes[] with a single entry, violating minItems 2).
|
|
16
|
+
- Tests: `resolutions[]` cases added to `manifest.test.js` covering the happy path (required fields, with reason, three superseded ADRs, additive composition alongside `blueprints[]` and `standards[]`), the reject-cases (bad id shape, missing required fields, unknown kind, `supersedes[]` minItems 2, uppercase slug in a `supersedes[]` entry, missing `adrId`, and an unrecognised additional property under `additionalProperties: false`), plus a pre-0.4.5 back-compat case that keeps a `blueprints[]`+`standards[]` manifest with no `resolutions[]` valid.
|
|
17
|
+
|
|
18
|
+
### Notes
|
|
19
|
+
|
|
20
|
+
- Additive-only: every 0.4.4-valid document remains valid. The prior `blueprints[]` + `standards[]` shape is untouched.
|
|
21
|
+
- `back-compat-freeze.test.js` (added in 0.4.4) continues to assert the frozen pre-0.4.3 chain snapshot validates byte-for-byte; the 0.4.5 additions are new-fields-only and cannot affect existing document bytes.
|
|
22
|
+
- Canonical `$id` URLs stay at `v0.4.0`, following the patch-release precedent set at 0.2.1, 0.3.1, 0.4.1, 0.4.2, 0.4.3, and 0.4.4.
|
|
23
|
+
- Version choice: additive change, no existing document invalidated, no shape widened destructively — per repo precedent this bumps `0.4.4 -> 0.4.5` as a patch.
|
|
24
|
+
|
|
7
25
|
## 0.4.4 - 2026-08-18
|
|
8
26
|
|
|
9
27
|
Additive patch bump for the blueprint-library mechanism landing in `rcf-build-lite`. Unblocks Phase 1 of the blueprint programme (`w-2026-08-18-016`) by adding the schema seams the mechanism keys to. Every change is additive: every 0.4.3-valid document remains valid, and every existing id continues to validate byte-for-byte.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"projectName": "Bad resolution id",
|
|
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
|
+
"resolutions": [
|
|
8
|
+
{
|
|
9
|
+
"id": "resolution-1",
|
|
10
|
+
"createdAt": "2026-08-19T10:15:00Z",
|
|
11
|
+
"kind": "globalAdrTopic",
|
|
12
|
+
"topic": "auth",
|
|
13
|
+
"resolvedByAdrId": "ADR-042",
|
|
14
|
+
"supersedes": [
|
|
15
|
+
{ "slug": "spa", "adrId": "ADR-005-spa" },
|
|
16
|
+
{ "slug": "rest", "adrId": "ADR-003-rest" }
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"projectName": "Resolution with a single supersedes entry (minItems 2 violation)",
|
|
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
|
+
"resolutions": [
|
|
8
|
+
{
|
|
9
|
+
"id": "res-2026-08-19-001",
|
|
10
|
+
"createdAt": "2026-08-19T10:15:00Z",
|
|
11
|
+
"kind": "globalAdrTopic",
|
|
12
|
+
"topic": "auth",
|
|
13
|
+
"resolvedByAdrId": "ADR-042",
|
|
14
|
+
"supersedes": [
|
|
15
|
+
{ "slug": "spa", "adrId": "ADR-005-spa" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"projectName": "Composed SPA + REST project with a resolved auth conflict",
|
|
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-19T10:00:00Z",
|
|
12
|
+
"source": "@stravica-ai/rcf-blueprint-spa@1.0.0",
|
|
13
|
+
"contributions": [
|
|
14
|
+
{ "id": "ADR-005-spa", "path": "rcf/adrs/adr-005-spa.json", "kind": "adr", "scope": "global", "topic": "auth" }
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"slug": "rest",
|
|
19
|
+
"version": "1.0.0",
|
|
20
|
+
"appliedAt": "2026-08-19T10:00:05Z",
|
|
21
|
+
"source": "@stravica-ai/rcf-blueprint-rest@1.0.0",
|
|
22
|
+
"contributions": [
|
|
23
|
+
{ "id": "ADR-003-rest", "path": "rcf/adrs/adr-003-rest.json", "kind": "adr", "scope": "global", "topic": "auth" }
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"resolutions": [
|
|
28
|
+
{
|
|
29
|
+
"id": "res-2026-08-19-001",
|
|
30
|
+
"createdAt": "2026-08-19T10:15:00Z",
|
|
31
|
+
"kind": "globalAdrTopic",
|
|
32
|
+
"topic": "auth",
|
|
33
|
+
"resolvedByAdrId": "ADR-042",
|
|
34
|
+
"supersedes": [
|
|
35
|
+
{ "slug": "spa", "adrId": "ADR-005-spa" },
|
|
36
|
+
{ "slug": "rest", "adrId": "ADR-003-rest" }
|
|
37
|
+
],
|
|
38
|
+
"reason": "Project auth model is documented in ADR-042; both blueprint auth ADRs remain on disk as superseded history."
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
package/package.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.4.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). 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. 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"],
|
|
@@ -65,6 +65,11 @@
|
|
|
65
65
|
"type": "array",
|
|
66
66
|
"items": { "$ref": "#/$defs/standardsPackRecord" },
|
|
67
67
|
"description": "Standards-pack registry. One entry per standards folder registered at rcf init (or later via rcf standards add). Records the pack's id, slug, source path, optional copy path (present only when the source lived outside the project root and was copied into rcf/standards/<slug>/ for portability), tag vocabulary, testsProvidedBy classification, and provenance. Read by the bundle assembler's selective-retrieval step when populating fbs.contextRequirements.standardIds. Optional; projects that register no standards have no entries."
|
|
68
|
+
},
|
|
69
|
+
"resolutions": {
|
|
70
|
+
"type": "array",
|
|
71
|
+
"items": { "$ref": "#/$defs/blueprintConflictResolution" },
|
|
72
|
+
"description": "Operator-authored resolutions of cross-blueprint conflicts. One entry per resolved conflict. Written by rcf blueprint supersede (which also scaffolds the project-level ADR that supersedes both blueprint ADRs) and by rcf blueprint add --resolve (which records the resolution declaratively on the add itself). Read by the conflict detector at rcf blueprint add: a resolution whose kind and key match a would-be conflict causes the detector to honour the resolution and let both blueprint ADRs co-reside as superseded history. Optional; projects with no cross-blueprint conflicts have no entries."
|
|
68
73
|
}
|
|
69
74
|
},
|
|
70
75
|
"$defs": {
|
|
@@ -870,6 +875,59 @@
|
|
|
870
875
|
}
|
|
871
876
|
},
|
|
872
877
|
"description": "One standards-pack registration. Written by rcf init (during standards prompting) and rcf standards add; read by the bundle assembler's selective-retrieval step."
|
|
878
|
+
},
|
|
879
|
+
"blueprintConflictResolution": {
|
|
880
|
+
"type": "object",
|
|
881
|
+
"additionalProperties": false,
|
|
882
|
+
"required": ["id", "createdAt", "kind", "topic", "resolvedByAdrId", "supersedes"],
|
|
883
|
+
"properties": {
|
|
884
|
+
"id": {
|
|
885
|
+
"type": "string",
|
|
886
|
+
"pattern": "^res-\\d{4}-\\d{2}-\\d{2}-\\d{3}$",
|
|
887
|
+
"description": "Blueprint-conflict-resolution record id. Format: res-YYYY-MM-DD-NNN. Monotonic per project."
|
|
888
|
+
},
|
|
889
|
+
"createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/timestamp" },
|
|
890
|
+
"kind": {
|
|
891
|
+
"enum": ["globalAdrTopic"],
|
|
892
|
+
"description": "Which conflict class this record resolves. Currently the only kind is globalAdrTopic (two applied blueprints each contributing a scope:global ADR on the same topic). The enum is single-valued so a later minor bump can add further resolution classes additively without breaking existing consumers."
|
|
893
|
+
},
|
|
894
|
+
"topic": {
|
|
895
|
+
"type": "string",
|
|
896
|
+
"minLength": 1,
|
|
897
|
+
"description": "The topic key the resolution applies to (for example, 'auth', 'versioning', 'errorEnvelope'). Matches the topic on both superseded blueprint ADRs. Required for kind=globalAdrTopic; the conflict detector reads this to know which would-be conflict the record honours."
|
|
898
|
+
},
|
|
899
|
+
"resolvedByAdrId": {
|
|
900
|
+
"type": "string",
|
|
901
|
+
"minLength": 1,
|
|
902
|
+
"description": "The project-level ADR id that supersedes the blueprint ADRs (for example, ADR-042). Its file lives outside any applied blueprint's namespace and is authored at rcf blueprint supersede time. Provenance for the resolution; the conflict detector does not currently re-read the referenced ADR."
|
|
903
|
+
},
|
|
904
|
+
"supersedes": {
|
|
905
|
+
"type": "array",
|
|
906
|
+
"minItems": 2,
|
|
907
|
+
"items": { "$ref": "#/$defs/blueprintConflictResolutionSupersededAdr" },
|
|
908
|
+
"description": "The blueprint ADRs this resolution supersedes. Two entries at minimum: the two applied blueprints whose global ADRs collided on topic. Both blueprint ADRs co-reside on disk as superseded history; the resolvedByAdrId is the live decision."
|
|
909
|
+
},
|
|
910
|
+
"reason": {
|
|
911
|
+
"type": "string",
|
|
912
|
+
"minLength": 1,
|
|
913
|
+
"description": "Optional operator note recording why this resolution was chosen. Free text; the schema does not enforce a minimum floor here so the operator can record a terse one-liner when the resolvedByAdrId itself carries the reasoning."
|
|
914
|
+
}
|
|
915
|
+
},
|
|
916
|
+
"description": "One blueprint-conflict resolution. Written by rcf blueprint supersede (scaffolds the resolvedByAdrId and appends the record) and by rcf blueprint add --resolve (appends the record without scaffolding a new ADR). Read by the conflict detector to skip a would-be conflict when a resolution matches."
|
|
917
|
+
},
|
|
918
|
+
"blueprintConflictResolutionSupersededAdr": {
|
|
919
|
+
"type": "object",
|
|
920
|
+
"additionalProperties": false,
|
|
921
|
+
"required": ["slug", "adrId"],
|
|
922
|
+
"properties": {
|
|
923
|
+
"slug": { "$ref": "https://schemas.stravica.io/rcf/v0.4.0/common.schema.json#/$defs/blueprintSlug" },
|
|
924
|
+
"adrId": {
|
|
925
|
+
"type": "string",
|
|
926
|
+
"minLength": 1,
|
|
927
|
+
"description": "The blueprint-owned ADR id that is superseded (for example, spa-ADR-005 or ADR-005-spa). Kept as a free-string minLength: 1 so the shape does not have to encode the mixed prefix/suffix namespacing grammar."
|
|
928
|
+
}
|
|
929
|
+
},
|
|
930
|
+
"description": "One superseded blueprint ADR: the applied blueprint's slug plus the ADR id inside that blueprint's contribution set."
|
|
873
931
|
}
|
|
874
932
|
}
|
|
875
933
|
}
|