@stravica-ai/rcf-schemas 0.2.0

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 (82) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/LICENSE +202 -0
  3. package/README.md +165 -0
  4. package/docs/README.md +37 -0
  5. package/docs/adr.md +42 -0
  6. package/docs/build-sequence.md +44 -0
  7. package/docs/common.md +43 -0
  8. package/docs/fbs.md +75 -0
  9. package/docs/file-layout.md +62 -0
  10. package/docs/id-conventions.md +60 -0
  11. package/docs/manifest.md +70 -0
  12. package/docs/prd.md +64 -0
  13. package/docs/req.md +57 -0
  14. package/docs/tac.md +49 -0
  15. package/docs/tad.md +76 -0
  16. package/docs/test-suite.md +56 -0
  17. package/docs/user-story.md +61 -0
  18. package/fixtures/invalid/adr/adr-001-authoring-status.json +13 -0
  19. package/fixtures/invalid/adr/adr-002-supersededBy-bad-id.json +14 -0
  20. package/fixtures/invalid/adr/adr-003-missing-tadId.json +12 -0
  21. package/fixtures/invalid/build-sequence/bs-001-legacy-fbs-array.json +11 -0
  22. package/fixtures/invalid/build-sequence/bs-002-missing-prdId.json +7 -0
  23. package/fixtures/invalid/fbs/fbs-001-storyScope-wrapper.json +16 -0
  24. package/fixtures/invalid/fbs/fbs-002-empty-acIds.json +13 -0
  25. package/fixtures/invalid/fbs/fbs-003-authoring-status.json +13 -0
  26. package/fixtures/invalid/fbs/fbs-004-plain-int-acId.json +13 -0
  27. package/fixtures/invalid/fbs/fbs-005-missing-buildOrder.json +12 -0
  28. package/fixtures/invalid/fbs/fbs-006-buildOrder-zero.json +13 -0
  29. package/fixtures/invalid/manifest/manifest-001-userStories-array.json +10 -0
  30. package/fixtures/invalid/manifest/manifest-002-legacy-buildSequence.json +7 -0
  31. package/fixtures/invalid/manifest/manifest-003-wrong-version.json +7 -0
  32. package/fixtures/invalid/prd/prd-001-typoed-status.json +10 -0
  33. package/fixtures/invalid/prd/prd-002-legacy-requirementIds.json +11 -0
  34. package/fixtures/invalid/prd/prd-003-missing-objectives.json +9 -0
  35. package/fixtures/invalid/req/req-001-bad-prefix.json +13 -0
  36. package/fixtures/invalid/req/req-002-unknown-category.json +13 -0
  37. package/fixtures/invalid/req/req-003-missing-prdId.json +12 -0
  38. package/fixtures/invalid/tac/tac-001-empty-responsibilities.json +12 -0
  39. package/fixtures/invalid/tac/tac-002-bad-dependency-kind.json +15 -0
  40. package/fixtures/invalid/tac/tac-003-missing-tadId.json +11 -0
  41. package/fixtures/invalid/tad/tad-001-legacy-componentIds.json +16 -0
  42. package/fixtures/invalid/tad/tad-002-partial-deployment.json +17 -0
  43. package/fixtures/invalid/test-suite/ts-001-missing-usId.json +18 -0
  44. package/fixtures/invalid/test-suite/ts-002-empty-acIds.json +19 -0
  45. package/fixtures/invalid/test-suite/ts-003-bad-tc-id.json +19 -0
  46. package/fixtures/invalid/test-suite/ts-004-bad-tc-status.json +19 -0
  47. package/fixtures/invalid/test-suite/ts-005-bad-test-level.json +12 -0
  48. package/fixtures/invalid/user-story/us-001-empty-acs.json +14 -0
  49. package/fixtures/invalid/user-story/us-002-ac-missing-testable.json +19 -0
  50. package/fixtures/valid/adr/adr-001-minimal.json +13 -0
  51. package/fixtures/valid/adr/adr-002-comprehensive.json +27 -0
  52. package/fixtures/valid/adr/adr-003-draft-status.json +13 -0
  53. package/fixtures/valid/build-sequence/bs-001-minimal.json +8 -0
  54. package/fixtures/valid/build-sequence/bs-002-comprehensive.json +11 -0
  55. package/fixtures/valid/fbs/fbs-001-minimal.json +13 -0
  56. package/fixtures/valid/fbs/fbs-002-comprehensive.json +34 -0
  57. package/fixtures/valid/manifest/manifest-001-minimal.json +7 -0
  58. package/fixtures/valid/manifest/manifest-002-with-description.json +8 -0
  59. package/fixtures/valid/prd/prd-001-minimal.json +12 -0
  60. package/fixtures/valid/prd/prd-002-comprehensive.json +34 -0
  61. package/fixtures/valid/req/req-001-minimal.json +13 -0
  62. package/fixtures/valid/req/req-002-comprehensive.json +15 -0
  63. package/fixtures/valid/tac/tac-001-minimal.json +15 -0
  64. package/fixtures/valid/tac/tac-002-comprehensive.json +49 -0
  65. package/fixtures/valid/tad/tad-001-minimal.json +14 -0
  66. package/fixtures/valid/tad/tad-002-comprehensive.json +71 -0
  67. package/fixtures/valid/test-suite/ts-001-minimal.json +19 -0
  68. package/fixtures/valid/test-suite/ts-002-comprehensive.json +32 -0
  69. package/fixtures/valid/user-story/us-001-minimal.json +20 -0
  70. package/fixtures/valid/user-story/us-002-hierarchical-acs.json +40 -0
  71. package/package.json +44 -0
  72. package/schemas/adr.schema.json +58 -0
  73. package/schemas/build-sequence.schema.json +22 -0
  74. package/schemas/common.schema.json +103 -0
  75. package/schemas/fbs.schema.json +90 -0
  76. package/schemas/manifest.schema.json +17 -0
  77. package/schemas/prd.schema.json +49 -0
  78. package/schemas/req.schema.json +39 -0
  79. package/schemas/tac.schema.json +73 -0
  80. package/schemas/tad.schema.json +162 -0
  81. package/schemas/test-suite.schema.json +61 -0
  82. package/schemas/user-story.schema.json +56 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "reqId": "REQ-001",
3
+ "prdId": "PRD-001",
4
+ "title": "Capture markdown notes",
5
+ "description": "The system must let a user write a markdown note and persist it.",
6
+ "category": "functional",
7
+ "domain": "capture",
8
+ "priority": "must",
9
+ "version": "0.1.0",
10
+ "status": "draft",
11
+ "createdAt": "2026-01-01T00:00:00Z",
12
+ "updatedAt": "2026-01-01T00:00:00Z"
13
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "reqId": "REQ-101",
3
+ "prdId": "PRD-100",
4
+ "title": "Offline-first sync",
5
+ "description": "The system must let users continue capturing and editing notes while offline; sync happens opportunistically when connectivity returns. Conflicts are resolved with a last-writer-wins policy and surfaced for manual review when content diverges.",
6
+ "category": "nonFunctional",
7
+ "domain": "sync",
8
+ "priority": "must",
9
+ "rationale": "Users in transit and in poor-connectivity environments must not lose work.",
10
+ "tags": ["sync", "offline", "conflict-resolution"],
11
+ "version": "1.0.0",
12
+ "status": "approved",
13
+ "createdAt": "2026-01-01T00:00:00Z",
14
+ "updatedAt": "2026-04-10T08:00:00Z"
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "tacId": "TAC-001",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "name": "Editor",
8
+ "purpose": "Browser-resident markdown editor.",
9
+ "responsibilities": [
10
+ "Render markdown",
11
+ "Capture user edits"
12
+ ],
13
+ "createdAt": "2026-01-01T00:00:00Z",
14
+ "updatedAt": "2026-01-01T00:00:00Z"
15
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "tacId": "TAC-100",
3
+ "prdId": "PRD-100",
4
+ "tadId": "TAD-100",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "name": "Sync Worker",
8
+ "purpose": "Cloudflare Worker that mediates between IndexedDB and R2 for note synchronisation.",
9
+ "responsibilities": [
10
+ "Accept pending deltas from clients",
11
+ "Reconcile against the authoritative version in R2",
12
+ "Surface conflicts back to the client"
13
+ ],
14
+ "internalStructure": "Single Worker entrypoint dispatching to /push, /pull, /conflict handlers. Internal modules: deltaParser, conflictDetector, r2Adapter.",
15
+ "interfaces": [
16
+ {
17
+ "name": "POST /sync/push",
18
+ "kind": "http-json",
19
+ "description": "Accepts a batch of pending deltas."
20
+ },
21
+ {
22
+ "name": "GET /sync/pull",
23
+ "kind": "http-json",
24
+ "description": "Returns deltas the client has not yet seen."
25
+ },
26
+ {
27
+ "name": "syncMetrics",
28
+ "kind": "internal-event-stream",
29
+ "description": "Per-batch latency and conflict count published to the metrics sink."
30
+ }
31
+ ],
32
+ "dependencies": [
33
+ {
34
+ "name": "Object store",
35
+ "kind": "tac",
36
+ "tacId": "TAC-101",
37
+ "description": "Persists note bodies."
38
+ },
39
+ {
40
+ "name": "Cloudflare R2",
41
+ "kind": "external",
42
+ "description": "Underlying blob backend."
43
+ }
44
+ ],
45
+ "tradeoffs": "Stateless Worker design simplifies failover but rules out long-lived in-memory caches; we accept the extra cold-start cost.",
46
+ "notes": "Watch the 50 ms CPU budget per request on the free tier.",
47
+ "createdAt": "2026-01-01T00:00:00Z",
48
+ "updatedAt": "2026-05-01T12:00:00Z"
49
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "tadId": "TAD-001",
3
+ "prdId": "PRD-001",
4
+ "version": "0.1.0",
5
+ "status": "draft",
6
+ "systemOverview": {
7
+ "executiveSummary": "Single-tenant note-taking web app, local-first.",
8
+ "systemPurpose": "Capture and retrieve personal notes.",
9
+ "architecturalApproach": "Monolithic frontend with a thin sync service.",
10
+ "keyCapabilities": ["Markdown editing", "Sync"]
11
+ },
12
+ "createdAt": "2026-01-01T00:00:00Z",
13
+ "updatedAt": "2026-01-01T00:00:00Z"
14
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "tadId": "TAD-100",
3
+ "prdId": "PRD-100",
4
+ "version": "1.0.0",
5
+ "status": "approved",
6
+ "systemOverview": {
7
+ "executiveSummary": "Markdown-first notebook with a thin sync layer over object storage, browser-resident editor, and a small set of edge-cached read APIs.",
8
+ "systemPurpose": "Capture and retrieve personal notes across devices with offline-first behaviour.",
9
+ "architecturalApproach": "Local-first PWA with CRDT-based sync to a serverless backend.",
10
+ "keyCapabilities": [
11
+ "Offline editing",
12
+ "Conflict resolution",
13
+ "Wiki-style linking",
14
+ "Full-text search"
15
+ ]
16
+ },
17
+ "architecturePrinciples": [
18
+ {
19
+ "name": "Local-first",
20
+ "description": "Every read and write succeeds offline; sync is a background concern.",
21
+ "rationale": "Users expect zero-latency local operation; network is unreliable."
22
+ },
23
+ {
24
+ "name": "Small surface",
25
+ "description": "Public APIs are small, versioned, and stable.",
26
+ "rationale": "Long-lived clients cannot churn on every backend change."
27
+ }
28
+ ],
29
+ "dataArchitecture": {
30
+ "dataStores": [
31
+ { "name": "IndexedDB (browser)", "kind": "embedded kv", "purpose": "Local note store and pending-sync queue" },
32
+ { "name": "Object storage (R2)", "kind": "blob store", "purpose": "Authoritative remote storage" }
33
+ ],
34
+ "coreEntities": [
35
+ { "name": "Note", "description": "Markdown document with id, title, body, timestamps." },
36
+ { "name": "Link", "description": "Directed edge between two notes." }
37
+ ],
38
+ "dataFlow": "Edits land in IndexedDB; background worker pushes deltas to R2 when online.",
39
+ "retention": "Indefinite; user-initiated delete only."
40
+ },
41
+ "integrationArchitecture": {
42
+ "apiDesign": "REST + JSON over HTTPS; idempotent writes keyed by client-generated UUID.",
43
+ "externalSystems": [
44
+ { "name": "Cloudflare R2", "purpose": "Authoritative blob store", "protocol": "HTTPS S3-compatible" }
45
+ ],
46
+ "eventModel": "Push notifications via WebPush for cross-device change signalling."
47
+ },
48
+ "securityArchitecture": {
49
+ "authenticationPattern": "Passwordless email magic link with rotating signed token.",
50
+ "authorizationModel": "User-scoped; all data is private to the authenticated user.",
51
+ "secretsManagement": "Cloudflare Workers Secrets; no plaintext in code.",
52
+ "threatModel": "STRIDE; primary concerns are token theft and replay.",
53
+ "complianceRequirements": ["GDPR data export and delete"]
54
+ },
55
+ "deploymentArchitecture": {
56
+ "targetEnvironment": "Cloudflare Pages + Workers + R2.",
57
+ "topology": "Edge-distributed; no origin region.",
58
+ "scaling": "Automatic per Cloudflare runtime.",
59
+ "cicd": "GitHub Actions; preview deploys per PR."
60
+ },
61
+ "operationalConcerns": {
62
+ "healthChecks": "Synthetic edge probe per region every 60 seconds.",
63
+ "logging": "Structured JSON logs shipped to Logflare.",
64
+ "metrics": "p50/p95 latency per Worker route; cache hit ratio per edge POP.",
65
+ "alerting": "PagerDuty on probe failure or error rate > 1%.",
66
+ "backup": "R2 versioning enabled with 30-day retention.",
67
+ "disasterRecovery": "Restore from R2 versioning; RPO 1 hour, RTO 4 hours."
68
+ },
69
+ "createdAt": "2026-01-01T00:00:00Z",
70
+ "updatedAt": "2026-05-01T12:00:00Z"
71
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "TS-001",
3
+ "usId": "US-001",
4
+ "title": "Note persistence smoke",
5
+ "purpose": "Cover the create-and-reopen round trip for a single note.",
6
+ "testLevel": "unit",
7
+ "acIds": ["AC-001"],
8
+ "testCases": [
9
+ {
10
+ "id": "TC-001-happy-path",
11
+ "acId": "AC-001",
12
+ "description": "Note survives close-and-reopen when saved in the default workspace.",
13
+ "status": "pending"
14
+ }
15
+ ],
16
+ "status": "draft",
17
+ "createdAt": "2026-01-01T00:00:00Z",
18
+ "updatedAt": "2026-01-01T00:00:00Z"
19
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "id": "TS-042",
3
+ "usId": "US-101",
4
+ "title": "Reconnect triggers automatic sync of pending edits",
5
+ "purpose": "Cover offline-edit persistence and the reconnect handshake against the Cloudflare emulator.",
6
+ "testLevel": "integration",
7
+ "acIds": ["AC-101-1", "AC-101-2"],
8
+ "testCases": [
9
+ {
10
+ "id": "TC-042-happy-path",
11
+ "acId": "AC-101-2",
12
+ "description": "The client is offline with three pending edits queued; on reconnect all three edits upload within 30 seconds and the queue drains.",
13
+ "testPointer": "packages/sync/test/reconnect.test.js::flushesQueueOnReconnect",
14
+ "status": "passing"
15
+ },
16
+ {
17
+ "id": "TC-042-no-net-when-idle",
18
+ "acId": "AC-101-2",
19
+ "description": "The client is online with no pending edits; the sync timer firing generates no network traffic.",
20
+ "status": "pending"
21
+ },
22
+ {
23
+ "id": "TC-042-survives-tab-close",
24
+ "acId": "AC-101-1",
25
+ "description": "The client is offline; a new note is created and the tab is closed. The pending edit survives the next session and uploads on reconnect.",
26
+ "status": "skipped"
27
+ }
28
+ ],
29
+ "status": "approved",
30
+ "createdAt": "2026-01-01T00:00:00Z",
31
+ "updatedAt": "2026-05-01T12:00:00Z"
32
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "usId": "US-001",
3
+ "prdId": "PRD-001",
4
+ "reqId": "REQ-001",
5
+ "version": "0.1.0",
6
+ "status": "draft",
7
+ "title": "Save a note",
8
+ "asA": "user",
9
+ "iWant": "to save a note I just wrote",
10
+ "soThat": "I can come back to it later",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-001",
14
+ "description": "Note persists after closing the app",
15
+ "testable": true
16
+ }
17
+ ],
18
+ "createdAt": "2026-01-01T00:00:00Z",
19
+ "updatedAt": "2026-01-01T00:00:00Z"
20
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "usId": "US-101",
3
+ "prdId": "PRD-100",
4
+ "reqId": "REQ-101",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "Edit a note while offline",
8
+ "description": "Cover the offline-edit + reconnect path end to end, including conflict surfacing.",
9
+ "asA": "user with intermittent connectivity",
10
+ "iWant": "to edit my notes while offline and have changes sync when I reconnect",
11
+ "soThat": "I can keep working on trains, planes, and behind firewalls",
12
+ "acceptanceCriteria": [
13
+ {
14
+ "id": "AC-101-1",
15
+ "description": "Editing a note while offline persists locally",
16
+ "given": "the device is offline and a note is loaded",
17
+ "when": "the user edits and saves the note",
18
+ "then": "the change is stored locally and visible in the note list",
19
+ "testable": true
20
+ },
21
+ {
22
+ "id": "AC-101-2",
23
+ "description": "Reconnect triggers automatic sync of pending edits",
24
+ "given": "pending offline edits exist",
25
+ "when": "connectivity is restored",
26
+ "then": "edits are uploaded within 30 seconds and remote reflects the new state",
27
+ "testable": true
28
+ },
29
+ {
30
+ "id": "AC-101-3",
31
+ "description": "Conflict surfaced when remote diverges from local",
32
+ "given": "the same note was edited locally offline and on another device",
33
+ "when": "sync runs after reconnect",
34
+ "then": "the conflict is surfaced in the UI with both versions visible",
35
+ "testable": true
36
+ }
37
+ ],
38
+ "createdAt": "2026-01-01T00:00:00Z",
39
+ "updatedAt": "2026-04-10T08:00:00Z"
40
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@stravica-ai/rcf-schemas",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "description": "JSON Schemas for the Requirements Confidence Framework (RCF). Language-neutral. The contract every RCF tool keys to.",
6
+ "license": "Apache-2.0",
7
+ "publishConfig": {
8
+ "registry": "https://registry.npmjs.org/",
9
+ "access": "public"
10
+ },
11
+ "engines": {
12
+ "node": ">=24.0.0"
13
+ },
14
+ "files": [
15
+ "schemas",
16
+ "docs",
17
+ "fixtures",
18
+ "README.md",
19
+ "LICENSE",
20
+ "CHANGELOG.md"
21
+ ],
22
+ "devDependencies": {
23
+ "ajv": "^8.17.1",
24
+ "ajv-formats": "^3.0.1"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/Stravica/rcf-schemas.git"
29
+ },
30
+ "homepage": "https://github.com/Stravica/rcf-schemas",
31
+ "bugs": {
32
+ "url": "https://github.com/Stravica/rcf-schemas/issues"
33
+ },
34
+ "keywords": [
35
+ "rcf",
36
+ "requirements-confidence-framework",
37
+ "json-schema",
38
+ "specifications",
39
+ "traceability"
40
+ ],
41
+ "scripts": {
42
+ "test": "node --test test/*.test.js"
43
+ }
44
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.2.0/adr.schema.json",
4
+ "title": "RCF Architectural Decision Record",
5
+ "description": "Architectural Decision Record. One per decision, one file each. Nygard / MADR convention.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "adrId",
10
+ "prdId",
11
+ "tadId",
12
+ "version",
13
+ "status",
14
+ "title",
15
+ "context",
16
+ "decision",
17
+ "consequences",
18
+ "createdAt",
19
+ "updatedAt"
20
+ ],
21
+ "properties": {
22
+ "adrId": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/adrId" },
23
+ "prdId": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/prdId" },
24
+ "tadId": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/tadId" },
25
+ "version": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/version" },
26
+ "status": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/adrStatus" },
27
+
28
+ "title": { "type": "string", "minLength": 1 },
29
+ "context": { "type": "string", "minLength": 1 },
30
+ "decision": { "type": "string", "minLength": 1 },
31
+ "consequences": { "type": "string", "minLength": 1 },
32
+ "alternativesConsidered": {
33
+ "type": "array",
34
+ "items": { "$ref": "#/$defs/alternative" }
35
+ },
36
+
37
+ "supersededBy": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/adrId" },
38
+ "relatedAdrs": {
39
+ "type": "array",
40
+ "items": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/adrId" }
41
+ },
42
+
43
+ "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/timestamp" },
44
+ "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/timestamp" }
45
+ },
46
+ "$defs": {
47
+ "alternative": {
48
+ "type": "object",
49
+ "additionalProperties": false,
50
+ "required": ["name", "summary"],
51
+ "properties": {
52
+ "name": { "type": "string", "minLength": 1 },
53
+ "summary": { "type": "string", "minLength": 1 },
54
+ "reasonNotChosen": { "type": "string" }
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.2.0/build-sequence.schema.json",
4
+ "title": "RCF Build Sequence",
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
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["bsId", "prdId", "version", "status", "createdAt", "updatedAt"],
9
+ "properties": {
10
+ "bsId": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/bsId" },
11
+ "prdId": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/prdId" },
12
+ "version": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/version" },
13
+ "status": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/authoringStatus" },
14
+ "title": { "type": "string" },
15
+ "buildPhilosophy": { "type": "string" },
16
+ "generationStrategy": {
17
+ "enum": ["verticalSlice", "dependencyFirst", "domainGrouped", "riskFrontLoaded"]
18
+ },
19
+ "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/timestamp" },
20
+ "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/timestamp" }
21
+ }
22
+ }
@@ -0,0 +1,103 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json",
4
+ "title": "RCF Shared Definitions",
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 10 doc-type schemas at validator init.",
6
+ "$defs": {
7
+ "prdId": {
8
+ "type": "string",
9
+ "pattern": "^PRD-\\d{3,}$",
10
+ "description": "PRD identifier. Three-digit minimum, unbounded above."
11
+ },
12
+ "reqId": {
13
+ "type": "string",
14
+ "pattern": "^REQ-\\d{3,}$",
15
+ "description": "Requirement identifier."
16
+ },
17
+ "usId": {
18
+ "type": "string",
19
+ "pattern": "^US-\\d{3,}$",
20
+ "description": "User Story identifier."
21
+ },
22
+ "acId": {
23
+ "type": "string",
24
+ "pattern": "^AC-\\d{3,}(-\\d+)?$",
25
+ "description": "Acceptance Criterion identifier. Supports hierarchical form (AC-101-1) and flat form (AC-201). Authors pick per project."
26
+ },
27
+ "tadId": {
28
+ "type": "string",
29
+ "pattern": "^TAD-\\d{3,}$",
30
+ "description": "Technical Architecture Document identifier."
31
+ },
32
+ "tacId": {
33
+ "type": "string",
34
+ "pattern": "^TAC-\\d{3,}$",
35
+ "description": "Technical Architecture Component identifier."
36
+ },
37
+ "adrId": {
38
+ "type": "string",
39
+ "pattern": "^ADR-\\d{3,}$",
40
+ "description": "Architectural Decision Record identifier."
41
+ },
42
+ "bsId": {
43
+ "type": "string",
44
+ "pattern": "^BS-\\d{3,}$",
45
+ "description": "Build Sequence identifier."
46
+ },
47
+ "fbsId": {
48
+ "type": "string",
49
+ "pattern": "^FBS-\\d{3,}$",
50
+ "description": "Functional Build Specification identifier."
51
+ },
52
+ "tsId": {
53
+ "type": "string",
54
+ "pattern": "^TS-\\d{3}$",
55
+ "description": "Test Suite identifier."
56
+ },
57
+ "tcId": {
58
+ "type": "string",
59
+ "pattern": "^TC-\\d{3}-[a-z0-9-]+$",
60
+ "description": "Test Case identifier. TS suffix (three digits) joined to a lowercase alphanumeric slug."
61
+ },
62
+ "version": {
63
+ "type": "string",
64
+ "pattern": "^\\d+\\.\\d+\\.\\d+$",
65
+ "description": "Semantic version string for individual RCF documents."
66
+ },
67
+ "timestamp": {
68
+ "type": "string",
69
+ "format": "date-time",
70
+ "description": "ISO 8601 / RFC 3339 date-time."
71
+ },
72
+ "authoringStatus": {
73
+ "enum": ["draft", "review", "needsRevision", "approved", "superseded"],
74
+ "description": "Authoring lifecycle status for PRD, REQ, US, TAD, TAC, BS."
75
+ },
76
+ "adrStatus": {
77
+ "enum": ["draft", "proposed", "accepted", "superseded", "deprecated"],
78
+ "description": "Nygard / MADR convention status for ADRs. Draft state prepended in 0.2.0."
79
+ },
80
+ "executionStatus": {
81
+ "enum": ["notStarted", "inProgress", "complete", "verified"],
82
+ "description": "Execution-state status for FBS documents and FBS slots within a Build Sequence."
83
+ },
84
+ "docRef": {
85
+ "type": "object",
86
+ "additionalProperties": false,
87
+ "required": ["id", "path"],
88
+ "properties": {
89
+ "id": {
90
+ "type": "string",
91
+ "minLength": 1,
92
+ "description": "Document id (matches the doc-type-specific id pattern)."
93
+ },
94
+ "path": {
95
+ "type": "string",
96
+ "minLength": 1,
97
+ "description": "Relative path to the document file."
98
+ }
99
+ },
100
+ "description": "Reference to a root document by id and file path. Used by the manifest."
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,90 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.2.0/fbs.schema.json",
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).",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "fbsId",
10
+ "prdId",
11
+ "bsId",
12
+ "buildOrder",
13
+ "executionStatus",
14
+ "title",
15
+ "summary",
16
+ "acIds",
17
+ "dependsOnFbsIds",
18
+ "createdAt",
19
+ "updatedAt"
20
+ ],
21
+ "properties": {
22
+ "fbsId": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/fbsId" },
23
+ "prdId": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/prdId" },
24
+ "bsId": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/bsId" },
25
+ "buildOrder": { "type": "integer", "minimum": 1 },
26
+ "executionStatus": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/executionStatus" },
27
+ "title": { "type": "string", "minLength": 1 },
28
+ "summary": { "type": "string", "minLength": 1 },
29
+ "approach": { "type": "string" },
30
+ "acIds": {
31
+ "type": "array",
32
+ "minItems": 1,
33
+ "items": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/acId" }
34
+ },
35
+ "dependsOnFbsIds": {
36
+ "type": "array",
37
+ "minItems": 0,
38
+ "items": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/fbsId" }
39
+ },
40
+ "contextRequirements": {
41
+ "type": "object",
42
+ "additionalProperties": false,
43
+ "properties": {
44
+ "prdSections": {
45
+ "type": "array",
46
+ "items": { "type": "string" }
47
+ },
48
+ "tadSections": {
49
+ "type": "array",
50
+ "items": { "type": "string" }
51
+ },
52
+ "tacIds": {
53
+ "type": "array",
54
+ "items": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/tacId" }
55
+ },
56
+ "adrIds": {
57
+ "type": "array",
58
+ "items": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/adrId" }
59
+ },
60
+ "existingModules": {
61
+ "type": "array",
62
+ "items": { "type": "string" }
63
+ },
64
+ "schemas": {
65
+ "type": "array",
66
+ "items": { "type": "string" }
67
+ },
68
+ "externalDocs": {
69
+ "type": "array",
70
+ "items": { "type": "string" }
71
+ },
72
+ "other": {
73
+ "type": "array",
74
+ "items": { "type": "string" }
75
+ }
76
+ }
77
+ },
78
+ "estimatedSize": { "enum": ["small", "medium", "large"] },
79
+ "estimatedHours": { "type": "number", "minimum": 0.5, "maximum": 16 },
80
+ "deliverables": {
81
+ "type": "array",
82
+ "items": { "type": "string" }
83
+ },
84
+ "riskLevel": { "enum": ["low", "medium", "high"] },
85
+ "domain": { "type": "string" },
86
+ "notes": { "type": "string" },
87
+ "createdAt": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/timestamp" },
88
+ "updatedAt": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/timestamp" }
89
+ }
90
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.stravica.io/rcf/v0.2.0/manifest.schema.json",
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.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["version", "projectName", "prd", "tad", "bs"],
9
+ "properties": {
10
+ "version": { "type": "string", "const": "2.0.0" },
11
+ "projectName": { "type": "string", "minLength": 1 },
12
+ "description": { "type": "string" },
13
+ "prd": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/docRef" },
14
+ "tad": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/docRef" },
15
+ "bs": { "$ref": "https://schemas.stravica.io/rcf/v0.2.0/common.schema.json#/$defs/docRef" }
16
+ }
17
+ }