rcf-lite 0.16.0 → 0.18.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 (94) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/blueprints/application-api-rest/README.md +5 -1
  3. package/blueprints/application-api-rest/blueprint.json +1 -1
  4. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-006.json +4 -4
  5. package/blueprints/application-api-rest/contributions/tacs/tac-306-application-api-rest-operability.json +9 -8
  6. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2103.json +3 -3
  7. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2108.json +27 -27
  8. package/blueprints/application-api-rest/docs/topics.md +2 -2
  9. package/blueprints/application-api-rest/guide/application-api-rest.md +5 -1
  10. package/blueprints/application-spa/assets/tc-templates/e2e.md +85 -0
  11. package/blueprints/application-spa/blueprint.json +24 -2
  12. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1134.json +24 -0
  13. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1135.json +24 -0
  14. package/blueprints/application-spa/docs/topics.md +2 -2
  15. package/blueprints/delivery-ci-workflows/assets/ci-provider-examples/github-actions/pull-request-checks.yml +69 -0
  16. package/blueprints/delivery-ci-workflows/assets/ci-provider-examples/notes.md +18 -0
  17. package/blueprints/delivery-ci-workflows/blueprint.json +301 -60
  18. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6124.json +28 -0
  19. package/blueprints/delivery-ci-workflows/docs/topics.md +2 -2
  20. package/blueprints/deploy-cloudflare-workers/docs/topics.md +2 -2
  21. package/blueprints/email-smtp-resend/docs/topics.md +2 -2
  22. package/blueprints/observability-essentials/README.md +6 -2
  23. package/blueprints/observability-essentials/blueprint.json +133 -33
  24. package/blueprints/observability-essentials/contributions/adrs/adr-801-observability-essentials-health-probes.json +4 -4
  25. package/blueprints/observability-essentials/contributions/adrs/adr-802-observability-essentials-readiness-semantics.json +4 -4
  26. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +4 -4
  27. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +4 -4
  28. package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +10 -9
  29. package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +17 -11
  30. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +12 -3
  31. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7102.json +12 -3
  32. package/blueprints/observability-essentials/docs/topics.md +15 -8
  33. package/blueprints/observability-essentials/guide/observability-essentials.md +9 -3
  34. package/blueprints/observability-probe-endpoints/README.md +5 -1
  35. package/blueprints/observability-probe-endpoints/blueprint.json +116 -24
  36. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json +5 -5
  37. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +11 -2
  38. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14107.json +11 -2
  39. package/blueprints/observability-probe-endpoints/docs/topics.md +6 -6
  40. package/blueprints/observability-probe-endpoints/guide/observability-probe-endpoints.md +10 -0
  41. package/blueprints/persistence-data-d1/docs/topics.md +2 -2
  42. package/blueprints/persistence-data-sqlite/docs/topics.md +2 -2
  43. package/blueprints/security-auth-clerk/docs/topics.md +2 -2
  44. package/blueprints/security-auth-keycloak/docs/topics.md +2 -2
  45. package/blueprints/security-auth-magic-link/docs/topics.md +2 -2
  46. package/blueprints/security-auth-oauth2/docs/topics.md +2 -2
  47. package/blueprints/security-secrets-management/docs/topics.md +2 -2
  48. package/fixtures/canary-manifest.json +9 -9
  49. package/package.json +13 -1
  50. package/rcf/code-nodes/cn-070.json +12 -0
  51. package/rcf/code-nodes/cn-071.json +12 -0
  52. package/rcf/code-nodes/cn-072.json +12 -0
  53. package/rcf/code-nodes/cn-073.json +12 -0
  54. package/rcf/code-nodes/cn-074.json +19 -0
  55. package/rcf/code-nodes/cn-075.json +15 -0
  56. package/rcf/code-nodes/cn-076.json +14 -0
  57. package/rcf/fbs/fbs-020.json +18 -0
  58. package/rcf/fbs/fbs-021.json +18 -0
  59. package/rcf/fbs/fbs-022.json +18 -0
  60. package/rcf/fbs/fbs-023.json +18 -0
  61. package/rcf/fbs/fbs-024.json +24 -0
  62. package/rcf/fbs/fbs-025.json +25 -0
  63. package/rcf/fbs/fbs-026.json +27 -0
  64. package/rcf/fbs/fbs-027.json +25 -0
  65. package/rcf/prd.json +3 -2
  66. package/rcf/requirements/req-011.json +22 -0
  67. package/rcf/requirements/req-012.json +22 -0
  68. package/rcf/test-suites/ts-030.json +66 -0
  69. package/rcf/test-suites/ts-031.json +59 -0
  70. package/rcf/test-suites/ts-032.json +50 -0
  71. package/rcf/test-suites/ts-033.json +83 -0
  72. package/rcf/test-suites/ts-034.json +32 -0
  73. package/rcf/test-suites/ts-035.json +23 -0
  74. package/rcf/test-suites/ts-036.json +65 -0
  75. package/rcf/test-suites/ts-037.json +55 -0
  76. package/rcf/user-stories/us-1101.json +51 -0
  77. package/rcf/user-stories/us-1102.json +60 -0
  78. package/rcf/user-stories/us-1103.json +51 -0
  79. package/rcf/user-stories/us-1104.json +60 -0
  80. package/rcf/user-stories/us-1201.json +34 -0
  81. package/rcf/user-stories/us-1202.json +25 -0
  82. package/rcf/user-stories/us-1203.json +43 -0
  83. package/rcf/user-stories/us-1204.json +25 -0
  84. package/releases/releases.yaml +21 -1
  85. package/src/blueprint/index.js +1 -0
  86. package/src/blueprint/remove-resolution.js +104 -0
  87. package/src/blueprint/supersede.js +2 -2
  88. package/src/cli/blueprint.js +41 -0
  89. package/src/cli/doctor.js +257 -5
  90. package/src/cli/init.js +166 -0
  91. package/src/setup/playwright-checks.js +426 -0
  92. package/src/verify/cli/run.js +28 -0
  93. package/src/verify/engine/index.js +24 -4
  94. package/src/verify/engine/launcher.js +41 -10
@@ -1,4 +1,4 @@
1
- # Observability probe endpoints blueprint (v1.0.0)
1
+ # observability-probe-endpoints blueprint (v1.1.0)
2
2
 
3
3
  The tenth content blueprint on the rcf-build-lite blueprint mechanism, and the second in the `observability` category, sibling to the shipped `observability-essentials`. Scope: a health probe interface derived from an operator-declared target integration profile (`kubernetes`, `loadBalancer`, `uptimeMonitor`, `systemd`, `dockerHealthcheck`, `reverseProxy`, plus a `custom:<name>` slot). Each profile fixes the probe transport, path or command surface, response contract, and semantic distinction between liveness and readiness for the supervisor at hand. Kubernetes is the shipped default (HTTPGet `/live` and `/ready` on the request-traffic listener); every HTTP profile ships with a `probeListener.separatePort` opt-in for probe-traffic isolation from user traffic. Response contracts are minimal by construction; the profile validator refuses any override that would add a field beyond the enumerated set. Targeted at rcf-lite projects that must integrate with a specific EXTERNAL supervising system whose conventions drive the probe wire shape; not targeted at the self-supervised all-in-one observability case (observability-essentials owns that).
4
4
 
@@ -51,3 +51,7 @@ The probe surface always follows the operator-declared target integration profil
51
51
 
52
52
  - **Custom-profile contract adherence.** Projects that author a `custom:<name>` profile against the profile contract are expected to satisfy the same transport/paths/responseContract/semanticModel shape the shipped profiles do; the profile contract validator (TAC-1501) refuses a partial profile at boot, which is where the mechanism reach lands. What the validator cannot compel is that a project-authored custom profile's response shape is minimal in the AC-14105 and AC-14106 sense (a custom profile could in principle enumerate a rich field set the validator would accept as complete). Recorded here rather than smuggled in as an AC that would only apply to the shipped profiles. Promotion signal: a `custom-profile-shape-lint` addition to the profile contract validator that enforces the minimalism rule per field-set-size heuristic (harder than it sounds; some legitimate custom profiles do have wider fields); or a project-side grep gate. Project-side workaround until then: reviewers of a `custom:<name>` profile eyeball the enumerated field set against the pattern the shipped six carry.
53
53
  - **Kubernetes gRPC probe transport.** The `kubernetes` profile ships HTTPGet and TCPSocket transports (via TAC-1504's tcpAdapter selection) but not gRPC. A project on a gRPC-only mesh that wants the standard gRPC health protocol supersedes ADR-1503 with a project-level ADR selecting the gRPC transport, or authors a `custom:kubernetes-grpc` profile. Promotion signal: a shipped gRPC-transport handler in a v1.1 pass if enough rcf-lite projects reach for it. Project-side workaround: the `custom:<name>` slot is the mechanism escape hatch.
54
+
55
+ ## Optional startup path (v1.1.0)
56
+
57
+ The Kubernetes profile gains an optional third path `startup` (default `/startup`) from v1.1.0. It is BOUND only when the operator sets `probeInterface.options.kubernetes.startup.enabled: true`; unset or `false`, the profile resolves as before with the two-path set (`/live`, `/ready`). The startup handler follows the same generation rules as the other Kubernetes-profile handlers (same `{"status":"pass"|"fail"}` body, same auth-exempt list emission, same listener topology). See US-14102 AC-14102-4 and US-14107 AC-14107-4 for the acceptance criteria, and the composing section in `guide/observability-probe-endpoints.md` for how essentials and api-rest defer their path opinions to this blueprint.
@@ -1,28 +1,108 @@
1
1
  {
2
2
  "slug": "observability-probe-endpoints",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "category": "observability",
5
5
  "contributions": [
6
- { "id": "observability-probe-endpoints-REQ-001", "kind": "req", "path": "requirements/observability-probe-endpoints-req-001.json" },
7
- { "id": "observability-probe-endpoints-REQ-002", "kind": "req", "path": "requirements/observability-probe-endpoints-req-002.json" },
8
- { "id": "observability-probe-endpoints-REQ-003", "kind": "req", "path": "requirements/observability-probe-endpoints-req-003.json" },
9
- { "id": "observability-probe-endpoints-REQ-004", "kind": "req", "path": "requirements/observability-probe-endpoints-req-004.json" },
10
- { "id": "observability-probe-endpoints-REQ-005", "kind": "req", "path": "requirements/observability-probe-endpoints-req-005.json" },
11
- { "id": "observability-probe-endpoints-REQ-006", "kind": "req", "path": "requirements/observability-probe-endpoints-req-006.json" },
12
- { "id": "observability-probe-endpoints-REQ-007", "kind": "req", "path": "requirements/observability-probe-endpoints-req-007.json" },
13
- { "id": "observability-probe-endpoints-REQ-008", "kind": "req", "path": "requirements/observability-probe-endpoints-req-008.json" },
14
- { "id": "observability-probe-endpoints-US-14101", "kind": "us", "path": "user-stories/observability-probe-endpoints-us-14101.json" },
15
- { "id": "observability-probe-endpoints-US-14102", "kind": "us", "path": "user-stories/observability-probe-endpoints-us-14102.json" },
16
- { "id": "observability-probe-endpoints-US-14103", "kind": "us", "path": "user-stories/observability-probe-endpoints-us-14103.json" },
17
- { "id": "observability-probe-endpoints-US-14104", "kind": "us", "path": "user-stories/observability-probe-endpoints-us-14104.json" },
18
- { "id": "observability-probe-endpoints-US-14105", "kind": "us", "path": "user-stories/observability-probe-endpoints-us-14105.json" },
19
- { "id": "observability-probe-endpoints-US-14106", "kind": "us", "path": "user-stories/observability-probe-endpoints-us-14106.json" },
20
- { "id": "observability-probe-endpoints-US-14107", "kind": "us", "path": "user-stories/observability-probe-endpoints-us-14107.json" },
21
- { "id": "observability-probe-endpoints-US-14108", "kind": "us", "path": "user-stories/observability-probe-endpoints-us-14108.json" },
22
- { "id": "TAC-1501-observability-probe-endpoints-profile-resolver", "kind": "tac", "path": "tacs/tac-1501-observability-probe-endpoints-profile-resolver.json" },
23
- { "id": "TAC-1502-observability-probe-endpoints-handler-set", "kind": "tac", "path": "tacs/tac-1502-observability-probe-endpoints-handler-set.json" },
24
- { "id": "TAC-1503-observability-probe-endpoints-listener-topology", "kind": "tac", "path": "tacs/tac-1503-observability-probe-endpoints-listener-topology.json" },
25
- { "id": "TAC-1504-observability-probe-endpoints-non-http-adapters", "kind": "tac", "path": "tacs/tac-1504-observability-probe-endpoints-non-http-adapters.json" },
6
+ {
7
+ "id": "observability-probe-endpoints-REQ-001",
8
+ "kind": "req",
9
+ "path": "requirements/observability-probe-endpoints-req-001.json"
10
+ },
11
+ {
12
+ "id": "observability-probe-endpoints-REQ-002",
13
+ "kind": "req",
14
+ "path": "requirements/observability-probe-endpoints-req-002.json"
15
+ },
16
+ {
17
+ "id": "observability-probe-endpoints-REQ-003",
18
+ "kind": "req",
19
+ "path": "requirements/observability-probe-endpoints-req-003.json"
20
+ },
21
+ {
22
+ "id": "observability-probe-endpoints-REQ-004",
23
+ "kind": "req",
24
+ "path": "requirements/observability-probe-endpoints-req-004.json"
25
+ },
26
+ {
27
+ "id": "observability-probe-endpoints-REQ-005",
28
+ "kind": "req",
29
+ "path": "requirements/observability-probe-endpoints-req-005.json"
30
+ },
31
+ {
32
+ "id": "observability-probe-endpoints-REQ-006",
33
+ "kind": "req",
34
+ "path": "requirements/observability-probe-endpoints-req-006.json"
35
+ },
36
+ {
37
+ "id": "observability-probe-endpoints-REQ-007",
38
+ "kind": "req",
39
+ "path": "requirements/observability-probe-endpoints-req-007.json"
40
+ },
41
+ {
42
+ "id": "observability-probe-endpoints-REQ-008",
43
+ "kind": "req",
44
+ "path": "requirements/observability-probe-endpoints-req-008.json"
45
+ },
46
+ {
47
+ "id": "observability-probe-endpoints-US-14101",
48
+ "kind": "us",
49
+ "path": "user-stories/observability-probe-endpoints-us-14101.json"
50
+ },
51
+ {
52
+ "id": "observability-probe-endpoints-US-14102",
53
+ "kind": "us",
54
+ "path": "user-stories/observability-probe-endpoints-us-14102.json"
55
+ },
56
+ {
57
+ "id": "observability-probe-endpoints-US-14103",
58
+ "kind": "us",
59
+ "path": "user-stories/observability-probe-endpoints-us-14103.json"
60
+ },
61
+ {
62
+ "id": "observability-probe-endpoints-US-14104",
63
+ "kind": "us",
64
+ "path": "user-stories/observability-probe-endpoints-us-14104.json"
65
+ },
66
+ {
67
+ "id": "observability-probe-endpoints-US-14105",
68
+ "kind": "us",
69
+ "path": "user-stories/observability-probe-endpoints-us-14105.json"
70
+ },
71
+ {
72
+ "id": "observability-probe-endpoints-US-14106",
73
+ "kind": "us",
74
+ "path": "user-stories/observability-probe-endpoints-us-14106.json"
75
+ },
76
+ {
77
+ "id": "observability-probe-endpoints-US-14107",
78
+ "kind": "us",
79
+ "path": "user-stories/observability-probe-endpoints-us-14107.json"
80
+ },
81
+ {
82
+ "id": "observability-probe-endpoints-US-14108",
83
+ "kind": "us",
84
+ "path": "user-stories/observability-probe-endpoints-us-14108.json"
85
+ },
86
+ {
87
+ "id": "TAC-1501-observability-probe-endpoints-profile-resolver",
88
+ "kind": "tac",
89
+ "path": "tacs/tac-1501-observability-probe-endpoints-profile-resolver.json"
90
+ },
91
+ {
92
+ "id": "TAC-1502-observability-probe-endpoints-handler-set",
93
+ "kind": "tac",
94
+ "path": "tacs/tac-1502-observability-probe-endpoints-handler-set.json"
95
+ },
96
+ {
97
+ "id": "TAC-1503-observability-probe-endpoints-listener-topology",
98
+ "kind": "tac",
99
+ "path": "tacs/tac-1503-observability-probe-endpoints-listener-topology.json"
100
+ },
101
+ {
102
+ "id": "TAC-1504-observability-probe-endpoints-non-http-adapters",
103
+ "kind": "tac",
104
+ "path": "tacs/tac-1504-observability-probe-endpoints-non-http-adapters.json"
105
+ },
26
106
  {
27
107
  "id": "ADR-1501-observability-probe-endpoints-health-probes",
28
108
  "kind": "adr",
@@ -37,8 +117,20 @@
37
117
  "scope": "global",
38
118
  "topic": "readinessSemantics"
39
119
  },
40
- { "id": "ADR-1503-observability-probe-endpoints-kubernetes-default", "kind": "adr", "path": "adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json" },
41
- { "id": "ADR-1504-observability-probe-endpoints-separate-port-option", "kind": "adr", "path": "adrs/adr-1504-observability-probe-endpoints-separate-port-option.json" },
42
- { "id": "ADR-1505-observability-probe-endpoints-external-response-secrecy", "kind": "adr", "path": "adrs/adr-1505-observability-probe-endpoints-external-response-secrecy.json" }
120
+ {
121
+ "id": "ADR-1503-observability-probe-endpoints-kubernetes-default",
122
+ "kind": "adr",
123
+ "path": "adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json"
124
+ },
125
+ {
126
+ "id": "ADR-1504-observability-probe-endpoints-separate-port-option",
127
+ "kind": "adr",
128
+ "path": "adrs/adr-1504-observability-probe-endpoints-separate-port-option.json"
129
+ },
130
+ {
131
+ "id": "ADR-1505-observability-probe-endpoints-external-response-secrecy",
132
+ "kind": "adr",
133
+ "path": "adrs/adr-1505-observability-probe-endpoints-external-response-secrecy.json"
134
+ }
43
135
  ]
44
136
  }
@@ -2,12 +2,12 @@
2
2
  "adrId": "ADR-1503-observability-probe-endpoints-kubernetes-default",
3
3
  "prdId": "PRD-001",
4
4
  "tadId": "TAD-001",
5
- "version": "1.0.0",
5
+ "version": "1.1.0",
6
6
  "status": "accepted",
7
- "title": "Kubernetes is the shipped default target integration profile; HTTPGet /live and /ready on the request-traffic listener are its defaults",
7
+ "title": "Kubernetes is the shipped default target integration profile; HTTPGet /live and /ready on the request-traffic listener are its defaults, with an optional /startup path off by default",
8
8
  "context": "One of the shipped profiles has to be the default the process falls back on when the operator does not declare `probeInterface.profile` explicitly. The choice matters because the default is what a project on the shipped configuration exhibits before the operator has spent any time on the observability surface, and because the default shapes the reader's expectation of what the blueprint 'is about'. The round-2 canon selected Kubernetes as the default: `probe endpoints elicited per deployment type; k8s /live + /ready default; separate-port/separate-server option`.",
9
- "decision": "The `kubernetes` profile is the shipped default. When the operator does not declare `probeInterface.profile`, the resolver falls back to `kubernetes` with the default paths `/live` (liveness) and `/ready` (readiness), the default `httpGet` transport, the response contract `{\"status\":\"pass\"|\"fail\"}`, the fused listener topology (probes on the user-traffic listener), and the `strict-any-fail-over-declared-deps` readiness aggregation. The paths and the readiness aggregation are overridable at boot via `probeInterface.options.kubernetes.paths` and `probeInterface.options.kubernetes.readinessRule`. The default hits without operator configuration; overriding is a small config change on the same shape.",
10
- "consequences": "A project that applies this blueprint and nothing else immediately exhibits a Kubernetes-shaped probe surface at `/live` and `/ready`; the standard `livenessProbe` and `readinessProbe` of shape `httpGet: { path: /live, port: <containerPort> }` and `httpGet: { path: /ready, port: <containerPort> }` in a Kubernetes podspec work without further wiring. The default is scope-local because it is a preference not a contract: the ADR-1501 elicitation model is the global commitment and the Kubernetes profile is one instantiation of it. A project on Docker Compose or on a bare-metal load-balancer setup that runs the shipped default sees `/live` and `/ready` bound instead of `/health` and reads the disagreement as the signal to declare `probeInterface.profile: loadBalancer` at boot.",
9
+ "decision": "The `kubernetes` profile is the shipped default. When the operator does not declare `probeInterface.profile`, the resolver falls back to `kubernetes` with the default paths `/live` (liveness) and `/ready` (readiness), the default `httpGet` transport, the response contract `{\"status\":\"pass\"|\"fail\"}`, the fused listener topology (probes on the user-traffic listener), and the `strict-any-fail-over-declared-deps` readiness aggregation. An optional third path `startup` (default `/startup`) is available under `probeInterface.options.kubernetes.paths.startup`; it is BOUND only when the operator sets `probeInterface.options.kubernetes.startup.enabled: true`, and unset or `false` the profile resolves as before with the two-path set. The startup handler follows the same generation rules as the other Kubernetes-profile handlers: same `{\"status\":\"pass\"|\"fail\"}` body shape, same auth-exempt list emission (the resolved set includes `/startup` when the enable flag is set), same listener topology (fused with the user-traffic listener unless the separate-port option is chosen). The paths, the readiness aggregation, and the startup enablement are overridable at boot via `probeInterface.options.kubernetes.paths`, `probeInterface.options.kubernetes.readinessRule`, and `probeInterface.options.kubernetes.startup.enabled` respectively. The default hits without operator configuration; overriding is a small config change on the same shape.",
10
+ "consequences": "A project that applies this blueprint and nothing else immediately exhibits a Kubernetes-shaped probe surface at `/live` and `/ready`; the standard `livenessProbe` and `readinessProbe` of shape `httpGet: { path: /live, port: <containerPort> }` and `httpGet: { path: /ready, port: <containerPort> }` in a Kubernetes podspec work without further wiring. The default is scope-local because it is a preference not a contract: the ADR-1501 elicitation model is the global commitment and the Kubernetes profile is one instantiation of it. A project on Docker Compose or on a bare-metal load-balancer setup that runs the shipped default sees `/live` and `/ready` bound instead of `/health` and reads the disagreement as the signal to declare `probeInterface.profile: loadBalancer` at boot. The optional startup path lets a project that owns an initialisation-lifecycle predicate (config load, migrations, cache warm) surface it to the orchestrator without leaving the shipped default; a project without a startup-lifecycle predicate leaves the flag off and sees the two-path default it saw at v1.0.0. Enabling the startup path is a scope-local operator choice, not a shelf-wide contract change; the elicitation model itself (ADR-1501) is unchanged.",
11
11
  "alternativesConsidered": [
12
12
  {
13
13
  "name": "Load-balancer profile as the default",
@@ -26,5 +26,5 @@
26
26
  }
27
27
  ],
28
28
  "createdAt": "2026-08-30T00:00:00Z",
29
- "updatedAt": "2026-08-30T00:00:00Z"
29
+ "updatedAt": "2026-09-04T00:00:00Z"
30
30
  }
@@ -2,7 +2,7 @@
2
2
  "usId": "observability-probe-endpoints-US-14102",
3
3
  "prdId": "PRD-001",
4
4
  "reqId": "observability-probe-endpoints-REQ-002",
5
- "version": "1.0.0",
5
+ "version": "1.1.0",
6
6
  "status": "approved",
7
7
  "title": "A Kubernetes-supervised replica is probed at /live and /ready on the request-traffic listener with no operator configuration",
8
8
  "asA": "kubelet running a probing loop against a pod that applied the blueprint with no explicit configuration",
@@ -35,6 +35,15 @@
35
35
  "then": "the first response has status 200 and body `{\"status\":\"pass\"}`; the second response has status 503 and body `{\"status\":\"fail\"}`",
36
36
  "testable": true,
37
37
  "scope": "runtime"
38
+ },
39
+ {
40
+ "id": "AC-14102-4",
41
+ "description": "When the operator sets probeInterface.options.kubernetes.startup.enabled: true on the shipped Kubernetes profile, the resolver returns a three-path set including the startup path (default /startup) and the handler-set builder generates a startup handler that answers pass once the operator-declared startup predicate returns pass and fail otherwise.",
42
+ "given": "a process on the shipped kubernetes profile with probeInterface.options.kubernetes.startup.enabled set to true, a startup predicate wired against a stubbed initialisation state, and the paths option left at its default",
43
+ "when": "the resolver runs at boot, and then GETs are issued against /startup with the stubbed state first fail then pass",
44
+ "then": "the resolver returns { profile: kubernetes, paths: [/live, /ready, /startup] }; the first GET on /startup returns 503 with body {\"status\":\"fail\"}; the second GET on /startup returns 200 with body {\"status\":\"pass\"}; without the enable flag the resolver returns two paths and no /startup handler is registered",
45
+ "testable": true,
46
+ "scope": "runtime"
38
47
  }
39
48
  ],
40
49
  "tacIds": [
@@ -42,5 +51,5 @@
42
51
  "TAC-1503-observability-probe-endpoints-listener-topology"
43
52
  ],
44
53
  "createdAt": "2026-08-30T00:00:00Z",
45
- "updatedAt": "2026-08-30T00:00:00Z"
54
+ "updatedAt": "2026-09-04T00:00:00Z"
46
55
  }
@@ -2,7 +2,7 @@
2
2
  "usId": "observability-probe-endpoints-US-14107",
3
3
  "prdId": "PRD-001",
4
4
  "reqId": "observability-probe-endpoints-REQ-007",
5
- "version": "1.0.0",
5
+ "version": "1.1.0",
6
6
  "status": "approved",
7
7
  "title": "The probe paths sit on the project's auth-exempt list scoped exactly to the resolved set on the resolved listener",
8
8
  "asA": "operator running the service behind an auth middleware that rejects unauthenticated requests by default",
@@ -35,11 +35,20 @@
35
35
  "then": "the list contains exactly the strings `/live` and `/ready` and their exact-match matcher rule; any injected entry containing `*` or a trailing slash to imply a prefix causes the emitter to refuse with a stable-coded error",
36
36
  "testable": true,
37
37
  "scope": "runtime"
38
+ },
39
+ {
40
+ "id": "AC-14107-4",
41
+ "description": "When the optional startup path is enabled on the Kubernetes profile, the exemption list produced by the profile at boot enumerates exactly three exact-match entries /live, /ready and /startup on the resolved listener; a wildcard or prefix entry (a trailing slash implying prefix, an entry containing *) causes the emitter to refuse with the same stable-coded error as AC-14107-3.",
42
+ "given": "the exemption list produced by the profile resolver on the Kubernetes profile with probeInterface.options.kubernetes.startup.enabled set to true",
43
+ "when": "the exemption-list emitter runs and the produced entries are inspected, and separately an injected entry containing */ or * is presented",
44
+ "then": "the list contains exactly the three strings /live, /ready and /startup and their exact-match matcher rule; any wildcard-shaped entry is refused with a stable-coded error",
45
+ "testable": true,
46
+ "scope": "runtime"
38
47
  }
39
48
  ],
40
49
  "tacIds": [
41
50
  "TAC-1503-observability-probe-endpoints-listener-topology"
42
51
  ],
43
52
  "createdAt": "2026-08-30T00:00:00Z",
44
- "updatedAt": "2026-08-30T00:00:00Z"
53
+ "updatedAt": "2026-09-04T00:00:00Z"
45
54
  }
@@ -6,14 +6,14 @@ This file is the observability-probe-endpoints half of the cross-blueprint contr
6
6
 
7
7
  | Topic string | observability-probe-endpoints contribution | Origin | Composition note |
8
8
  |---|---|---|---|
9
- | `healthProbes` | ADR-1501-observability-probe-endpoints-health-probes | Reused from the observability-essentials vocabulary (observability-essentials contributes a self-supervised two-endpoint HTTP JSON contract on the request-traffic listener at the same topic string). This blueprint contributes an elicit-from-target-integration-profile model on the same topic string on purpose. | The one project-wide decision on the health probe interface. Composing this blueprint with observability-essentials fires a `globalAdrTopic` conflict by design because the two blueprints answer different questions: essentials commits to a self-supervised HTTP JSON floor; this blueprint commits to an elicit-and-adapt model whose shape follows the external supervisor. Expected resolution: one project-level ADR that either commits to the elicit-and-adapt model (external supervisor drives the shape) or the fused self-supervised model (project owns the shape) or an explicit hybrid with boundaries |
10
- | `readinessSemantics` | ADR-1502-observability-probe-endpoints-readiness-semantics | Reused from the observability-essentials vocabulary (observability-essentials contributes strict-any-fail-over-declared-deps as the project-wide readiness rule at the same topic string). This blueprint contributes per-profile readiness semantics on the same topic string on purpose. | The one project-wide readiness semantics decision. Composing with observability-essentials fires a `globalAdrTopic` conflict by design. Expected resolution: one project-level ADR that commits to one of the two rules or an explicit hybrid |
9
+ | `healthProbes` | ADR-1501-observability-probe-endpoints-health-probes | From essentials v2.0.0 this blueprint is the SOLE shelf-wide claimant of `healthProbes`. Round 2 canon: probes elicited from a target-integration profile; Kubernetes default `/live` + `/ready` on the request-traffic listener. Essentials v2.0.0 (see `projects/rcf-lite-wsd/specs/rcf-lite-probe-path-alignment-spec-2026-09-04.md` section 4) dropped its own scope:global claim on this topic. | Composing this blueprint with observability-essentials v2.0.0 or later fires NO `globalAdrTopic` conflict on `healthProbes`; the resolved profile path binds automatically for essentials on the same project. A composing blueprint that holds a different endpoint contract (a single `/health` endpoint, a gRPC health protocol, probes on a separate admin port) contributes its own scope:global ADR on this string and lets composition surface the pairing. Expected resolution: one project-level ADR that either adopts the composing blueprint or supersedes both |
10
+ | `readinessSemantics` | ADR-1502-observability-probe-endpoints-readiness-semantics | From essentials v2.0.0 this blueprint is the SOLE shelf-wide claimant of `readinessSemantics`. Round 2 canon: per-profile readiness semantics (Kubernetes profile default is strict-any-fail-over-declared-deps). Essentials v2.0.0 dropped its own scope:global claim on this topic (spec section 4). | Composing with observability-essentials v2.0.0 or later fires NO `globalAdrTopic` conflict on `readinessSemantics`. A composing blueprint that holds a different opinion (quorum aggregation, write-path-only readiness, graceful-degradation model) contributes its own scope:global ADR on this string and lets composition surface the pairing |
11
11
 
12
12
  The observability-probe-endpoints blueprint claims two global topics. Every other contribution is scope-local (ADR-1503 the Kubernetes default, ADR-1504 the separate-port option, and ADR-1505 the external-response secrecy rule do not contribute global topics; a composing blueprint that holds an opinion on the default profile, on probe-listener topology, or on response secrecy authors its own project-level ADR if it wants to override).
13
13
 
14
- Note on the deliberate conflict with observability-essentials: this blueprint is designed for the EXTERNAL-SYSTEM INTEGRATION case (orchestrators, load balancers, uptime monitors probing the service, with their conventions driving the wire shape). observability-essentials is designed for the SELF-SUPERVISED all-in-one case (probes plus public status page plus notification outcome sink for a project that designs its own observability floor). Both are legitimate; each is the right default for its case. The conflict is the mechanism telling the operator to pick one intentionally. Precedent for the vendor-sibling pattern: security-auth-clerk conflicts with security-auth-magic-link on `authModel` on purpose; persistence-data-d1 conflicts with persistence-data-sqlite on both `persistenceStore` and `migrationDiscipline` on purpose. This blueprint follows the same pattern on `healthProbes` and `readinessSemantics`.
14
+ Note on the delineation with observability-essentials from essentials v2.0.0: essentials contributes the body shape, dep registry, probe-secrecy rule, status page and notification sink; this blueprint contributes the path binding and profile elicitation. The two compose without a conflict on `healthProbes` or `readinessSemantics` from essentials v2.0.0 forward (this blueprint is the sole claimant on both). Precedent for the deliberate-conflict pattern still stands on other topic pairs: security-auth-clerk conflicts with security-auth-magic-link on `authModel` on purpose; persistence-data-d1 conflicts with persistence-data-sqlite on both `persistenceStore` and `migrationDiscipline` on purpose.
15
15
 
16
- Note on the delineation from observability-essentials's `statusPageContract` topic: this blueprint does not contribute an opinion on the public status page. A project that wants the probe surface from this blueprint AND the public status page and notification outcome sink from observability-essentials resolves the two `healthProbes` and `readinessSemantics` conflicts with project-level ADRs and keeps `statusPageContract` on the essentials-supplied side; the blueprints then compose without further conflict.
16
+ Note on the delineation from observability-essentials's `statusPageContract` topic: this blueprint does not contribute an opinion on the public status page. A project that wants the probe surface from this blueprint AND the public status page and notification outcome sink from observability-essentials composes the two cleanly from essentials v2.0.0 forward; `statusPageContract` stays on the essentials-supplied side and no probe-path or readiness-semantics conflict fires.
17
17
 
18
18
  Rules for new topics (inherited from the application-spa, application-api-rest, security-auth-magic-link, persistence-data-sqlite, delivery-ci-workflows, observability-essentials, security-secrets-management, security-auth-clerk, email-smtp-resend, and deploy-cloudflare-workers vocabularies, restated as law): lower camel case, one concept per topic, no version suffixes. A topic names the decision area, not the chosen answer. Do not mint variants of existing strings (`probeInterface`, `probeSurface`, `probes`, `livenessReadiness`, `probeTransport` are all wrong when `healthProbes` already exists; `readinessAggregation`, `readyPolicy`, `readinessRule` are all wrong when `readinessSemantics` already exists).
19
19
 
@@ -32,14 +32,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
32
32
  | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
33
33
  | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
34
34
  | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
35
- | observability-essentials | 7101-7899 | 8xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics`, `statusPageContract` |
35
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
36
36
  | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.0 | `secretsSource` |
37
37
  | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
38
38
  | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
39
39
  | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
40
40
  | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
41
41
  | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
42
- | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics` |
42
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
43
43
 
44
44
  US 14101-14108 sit at the LOW end of the 14101-14899 band on purpose. A project-side story that mechanically derives from an observability-probe-endpoints REQ id into the number `14108` would collide against observability-probe-endpoints-US-14108 in this package; the band leaves headroom at the HIGH end (US 14181-14899) so a project's own stories anchored to observability-probe-endpoints REQs can allocate without conflict. The watchpost run4 lesson applies here too. Band spacing between the previous HQ-lane row (persistence-data-d1, 13101-13899, 14xx) and this one (14101-14899, 15xx) reflects the four-digit widening pattern opened by security-auth-clerk at 10xx and continued through the round-2 HQ lane.
45
45
 
@@ -81,3 +81,13 @@ A project applies the observability-probe-endpoints blueprint on a fresh tree, d
81
81
  ## Cost-honesty paragraph
82
82
 
83
83
  Shipping this doc set costs the project the following. Every process pays the profile-resolver step at boot and one indirection through the frozen profile object at each probe binding site; the cost is small but real. A project that wants hot-reload of the profile selection restarts the process gracefully; the blueprint declines to support live rebinding. The separate-port topology opens a second HTTP listener when in effect; the extra port is a small memory cost and one more thing to think about in the deployment substrate. The profile-swap-is-config invariant costs the project a small amount of author discipline: per-profile branching in the boot path outside the resolver call site would defeat the invariant, and the AC scan catches the drift only if the project wires it into its own CI. The response-minimalism-by-construction rule costs the project any richer probe body it may have wanted for its own consumption (that surface belongs to observability-essentials, to an authenticated dashboard, or to a project-side triage endpoint outside the probe path set). The blueprint says nothing about the public status page, the notification outcome sink, metrics export, distributed tracing, or the auth model itself; a project that needs any of those spends its own build cycles on them and this blueprint does not save it any work there.
84
+
85
+ ## Composing with observability-essentials and application-api-rest
86
+
87
+ From v1.1.0 this blueprint is the single owner of probe-path binding on the core shelf. The composition is documented in the ratified rcf-lite probe-path alignment spec (`projects/rcf-lite-wsd/specs/rcf-lite-probe-path-alignment-spec-2026-09-04.md`) and verified by the compose test at `packages/rcf-lite/test/blueprint/probe-path-alignment.test.js`.
88
+
89
+ - observability-essentials (v2.0.0 and up) contributes body shape, dep registry, probe-secrecy, status page, and notification sink; it defers path binding to this blueprint when composed, and reads `probeInterface.paths` from project configuration when it is applied alone. Its `healthProbes` and `readinessSemantics` global claims were dropped in v2.0.0; this blueprint is now the sole `scope: global` claimant on both topics.
90
+ - application-api-rest (v2.0.0 and up) contributes the request pipeline, auth middleware, error envelope, versioning, logging, migrations and meta endpoint; it defers probe paths to this blueprint (including the optional startup path). Its auth-middleware installer consumes the exempt path set this blueprint emits and no other; adjacent routes never fall under the same exemption.
91
+ - The three-way compose test at `packages/rcf-lite/test/blueprint/probe-path-alignment.test.js` is the ratified truth for this shelf-alignment surface. Every ordering of the three blueprints applies cleanly; there is exactly one `scope: global` ADR per topic in the resulting manifest; no literal `/healthz`, `/readyz`, `/healthz/live`, `/healthz/ready` or `/healthz/startup` string appears outside this blueprint's own README and guide prose.
92
+
93
+ Enabling the optional startup path costs one line of configuration: `probeInterface.options.kubernetes.startup.enabled: true`. The resolver emits a three-path set (`/live`, `/ready`, `/startup`) and the handler-set builder generates a startup handler that answers pass once the operator-declared startup predicate returns pass. api-rest projects that own an initialisation-lifecycle predicate (config load, migrations, cache warm) wire it here; projects that do not, leave the flag off and see the two-path default.
@@ -30,14 +30,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
30
30
  | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
31
31
  | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
32
32
  | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
33
- | observability-essentials | 7101-7899 | 8xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics`, `statusPageContract` |
33
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
34
34
  | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.0 | `secretsSource` |
35
35
  | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
36
36
  | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
37
37
  | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
38
38
  | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
39
39
  | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
40
- | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics` |
40
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
41
41
 
42
42
  US 13101-13107 sit at the LOW end of the 13101-13899 band on purpose. A project-side story that mechanically derives from a persistence-data-d1 REQ id into the number `13107` would collide against persistence-data-d1-US-13107 in this package; the band leaves headroom at the HIGH end (US 13181-13899) so a project's own stories anchored to persistence-data-d1 REQs can allocate without conflict. The watchpost run4 lesson applies here too.
43
43
 
@@ -30,14 +30,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
30
30
  | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
31
31
  | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
32
32
  | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
33
- | observability-essentials | 7101-7899 | 8xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics`, `statusPageContract` |
33
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
34
34
  | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.0 | `secretsSource` |
35
35
  | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
36
36
  | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
37
37
  | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
38
38
  | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
39
39
  | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
40
- | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics` |
40
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
41
41
 
42
42
  US 5101-5111 sit at the LOW end of the 5101-5899 band on purpose. A project-side story that mechanically derives from `persistence-data-sqlite-REQ-011` into the number `5111` would collide against persistence-data-sqlite-US-5111 in this package; the band leaves headroom at the HIGH end (US 5181-5899) so a project's own stories anchored to persistence-data-sqlite REQs can allocate without conflict. The watchpost run4 lesson applies here too.
43
43
 
@@ -27,14 +27,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
27
27
  | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
28
28
  | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
29
29
  | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
30
- | observability-essentials | 7101-7899 | 8xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics`, `statusPageContract` |
30
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
31
31
  | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.0 | `secretsSource` |
32
32
  | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
33
33
  | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
34
34
  | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
35
35
  | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
36
36
  | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
37
- | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics` |
37
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
38
38
 
39
39
  US 9101-9110 sit at the LOW end of the 9101-9899 band on purpose. A project-side story that mechanically derives from a security-auth-clerk REQ id into the number `9110` would collide against security-auth-clerk-US-9110 in this package; the band leaves headroom at the HIGH end (US 9181-9899) so a project's own stories anchored to security-auth-clerk REQs can allocate without conflict. The watchpost run4 lesson applies here too.
40
40
 
@@ -38,14 +38,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
38
38
  | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
39
39
  | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
40
40
  | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
41
- | observability-essentials | 7101-7899 | 8xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics`, `statusPageContract` |
41
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
42
42
  | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.0 | `secretsSource` |
43
43
  | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
44
44
  | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
45
45
  | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
46
46
  | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
47
47
  | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
48
- | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics` |
48
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
49
49
 
50
50
  US 11101-11113 sit at the LOW end of the 11101-11899 band on purpose. A project-side story that mechanically derives from a security-auth-keycloak REQ id into the number `11113` would collide against security-auth-keycloak-US-11113 in this package; the band leaves headroom at the HIGH end (US 11181-11899) so a project's own stories anchored to security-auth-keycloak REQs can allocate without conflict. The watchpost run4 lesson applies here too.
51
51
 
@@ -27,14 +27,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
27
27
  | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
28
28
  | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
29
29
  | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
30
- | observability-essentials | 7101-7899 | 8xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics`, `statusPageContract` |
30
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
31
31
  | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.0 | `secretsSource` |
32
32
  | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
33
33
  | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
34
34
  | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
35
35
  | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
36
36
  | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
37
- | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics` |
37
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
38
38
 
39
39
  US 3101-3111 sit at the LOW end of the 3101-3899 band on purpose. A project-side story that mechanically derives from `security-auth-magic-link-REQ-011` into the number `3111` would collide against security-auth-magic-link-US-3111 in this package; the band leaves headroom at the HIGH end (US 3181-3899) so a project's own stories anchored to security-auth-magic-link REQs can allocate without conflict.
40
40
 
@@ -38,14 +38,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
38
38
  | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
39
39
  | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
40
40
  | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
41
- | observability-essentials | 7101-7899 | 8xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics`, `statusPageContract` |
41
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
42
42
  | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.0 | `secretsSource` |
43
43
  | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
44
44
  | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
45
45
  | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
46
46
  | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
47
47
  | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
48
- | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics` |
48
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
49
49
 
50
50
  US 10101-10111 sit at the LOW end of the 10101-10899 band on purpose. A project-side story that mechanically derives from a security-auth-oauth2 REQ id into the number `10111` would collide against security-auth-oauth2-US-10111 in this package; the band leaves headroom at the HIGH end (US 10181-10899) so a project's own stories anchored to security-auth-oauth2 REQs can allocate without conflict. The watchpost run4 lesson applies here too.
51
51
 
@@ -27,14 +27,14 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
27
27
  | hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
28
28
  | persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
29
29
  | delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
30
- | observability-essentials | 7101-7899 | 8xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics`, `statusPageContract` |
30
+ | observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
31
31
  | security-secrets-management | 8101-8899 | 9xx | shipped v1.0.0 | `secretsSource` |
32
32
  | security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
33
33
  | security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
34
34
  | security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
35
35
  | deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
36
36
  | persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
37
- | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.0.0 | `healthProbes`, `readinessSemantics` |
37
+ | observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
38
38
 
39
39
  US 8101-8110 sit at the LOW end of the 8101-8899 band on purpose. A project-side story that mechanically derives from a security-secrets-management REQ id into the number `8110` would collide against security-secrets-management-US-8110 in this package; the band leaves headroom at the HIGH end (US 8181-8899) so a project's own stories anchored to security-secrets-management REQs can allocate without conflict. The watchpost run4 lesson applies here too.
40
40
 
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "registerCanary": [
3
3
  {
4
- "id": "rc-2026-09-03-001",
5
- "createdAt": "2026-09-03T13:16:14.200Z",
6
- "buildVersion": "0.16.0-mockdriver",
4
+ "id": "rc-2026-09-04-001",
5
+ "createdAt": "2026-09-04T12:13:52.789Z",
6
+ "buildVersion": "0.18.0-mockdriver",
7
7
  "fixturePromptId": "canary-prompt-01",
8
8
  "responseWordCount": 55,
9
9
  "grades": {
@@ -34,9 +34,9 @@
34
34
  "shipDespiteFailReason": "mock canary driver used; no real subagent was dispatched. This record verifies canary infrastructure only, not the register itself."
35
35
  },
36
36
  {
37
- "id": "rc-2026-09-03-002",
38
- "createdAt": "2026-09-03T13:16:14.200Z",
39
- "buildVersion": "0.16.0-mockdriver",
37
+ "id": "rc-2026-09-04-002",
38
+ "createdAt": "2026-09-04T12:13:52.790Z",
39
+ "buildVersion": "0.18.0-mockdriver",
40
40
  "fixturePromptId": "canary-prompt-02",
41
41
  "responseWordCount": 55,
42
42
  "grades": {
@@ -67,9 +67,9 @@
67
67
  "shipDespiteFailReason": "mock canary driver used; no real subagent was dispatched. This record verifies canary infrastructure only, not the register itself."
68
68
  },
69
69
  {
70
- "id": "rc-2026-09-03-003",
71
- "createdAt": "2026-09-03T13:16:14.201Z",
72
- "buildVersion": "0.16.0-mockdriver",
70
+ "id": "rc-2026-09-04-003",
71
+ "createdAt": "2026-09-04T12:13:52.790Z",
72
+ "buildVersion": "0.18.0-mockdriver",
73
73
  "fixturePromptId": "canary-prompt-03",
74
74
  "responseWordCount": 55,
75
75
  "grades": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rcf-lite",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "type": "module",
5
5
  "description": "One-install tooling for the Requirements Confidence Framework (RCF): the unified `rcf` CLI grouped into the five RCF tool groups (discover, define, build, verify, audit) plus a small core set (init, doctor, guidance, mcp), an MCP server, the live tree viewer and the fresh-context adversarial ship-gate verifier. Consumes @stravica-ai/rcf-schemas.",
6
6
  "license": "Apache-2.0",
@@ -69,6 +69,18 @@
69
69
  "js-yaml": "^4.1.0",
70
70
  "mermaid": "11.6.0"
71
71
  },
72
+ "peerDependencies": {
73
+ "@playwright/mcp": ">=0.0.40",
74
+ "playwright": ">=1.50.0"
75
+ },
76
+ "peerDependenciesMeta": {
77
+ "@playwright/mcp": {
78
+ "optional": true
79
+ },
80
+ "playwright": {
81
+ "optional": true
82
+ }
83
+ },
72
84
  "scripts": {
73
85
  "test": "node --test --test-concurrency=1 'test/**/*.test.js'",
74
86
  "vendor": "node scripts/vendor-mermaid.mjs",
@@ -0,0 +1,12 @@
1
+ {
2
+ "cnId": "CN-070",
3
+ "path": "src/verify/engine/launcher.js#PLAYWRIGHT_MCP_VERSION",
4
+ "title": "Pinned Playwright MCP version + composer",
5
+ "description": "Exports the PLAYWRIGHT_MCP_VERSION constant, the playwrightMcpConfig(version) composer, and the isSemverString(value) guard the CLI's override uses. DEFAULT_MCP_CONFIG is composed from PLAYWRIGHT_MCP_VERSION so nothing in the module surfaces @playwright/mcp@latest. The exported constant + composer are what src/verify/cli/run.js reuses when --playwright-mcp-version fires, and what src/verify/engine/index.js reads when it threads the effective pin into report.run.runStats.playwrightMcpVersion.",
6
+ "implementsAcIds": ["AC-1101-1", "AC-1101-2", "AC-1101-3", "AC-1101-4"],
7
+ "dependencies": [],
8
+ "version": "0.1.0",
9
+ "status": "draft",
10
+ "createdAt": "2026-09-03T17:00:00Z",
11
+ "updatedAt": "2026-09-03T17:00:00Z"
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "cnId": "CN-071",
3
+ "path": "test/blueprint/apply-spa-v1-4-0-schema.test.js",
4
+ "title": "Application-spa v1.4.0 browserSurface + browser-facing user stories + e2e template",
5
+ "description": "The SPA blueprint at 1.4.0 declares the top-level browserSurface object and contributes application-spa-US-1134 (icon on the home route) and application-spa-US-1135 (unauthenticated protected route lands on sign-in) as browser-facing acceptance criteria. blueprints/application-spa/assets/tc-templates/e2e.md ships as the paste-in test-case template naming rcf verify browser as the driver seam. blueprints/delivery-ci-workflows/blueprint.json bumps to 2.2.0 with US-6124 binding AC-6124-1 on the elicited e2e check, plus the illustrative e2e job in pull-request-checks.yml and the alternate-provider notes. The applied SPA v1.4.0 manifest still validates against rcf-schemas 0.5.1 (test/blueprint/apply-spa-v1-4-0-schema.test.js) with no browserSurface field on the applied blueprint record; doctor and any future workflow-materialiser read browserSurface off the applied record's source reference.",
6
+ "implementsAcIds": ["AC-1102-1", "AC-1102-2", "AC-1102-3", "AC-1102-4", "AC-1102-5"],
7
+ "dependencies": [],
8
+ "version": "0.1.0",
9
+ "status": "draft",
10
+ "createdAt": "2026-09-03T17:00:00Z",
11
+ "updatedAt": "2026-09-03T17:00:00Z"
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "cnId": "CN-072",
3
+ "path": "src/setup/playwright-checks.js#loadBrowserFacingSources",
4
+ "title": "Doctor's browser-facing projection + four Playwright checks",
5
+ "description": "loadBrowserFacingSources(projectRoot) walks manifest.blueprints[].source, reads each blueprint.json, and returns { browserFacing, sources[] } (spec 3.1). checkPlaywrightPresent(projectRoot) uses require.resolve('playwright'); checkBrowserPresent() probes PATH for chrome/chromium then ~/.cache/ms-playwright then `npx --no-install @playwright/mcp browser-status --json`; checkPlaywrightMcpReachable() spawns `npx --no-install @playwright/mcp --help` with a 15-second diagnostic ceiling. hasPlaywrightSignature + findProjectPlaywrightKey are the shared signature detectors doctor's redundant-entry check and init's project-scope probe consume. FIX_LINES exports the spec-verbatim fix lines; SKIP_LINE_NON_BROWSER_FACING is the single skip line for non-browser-facing projects. src/cli/doctor.js wires the four checks into KNOWN_CHECKS, honours the --check filter override on API-only projects (spec 3.5), and prints the skip line before the summary (spec 3.4).",
6
+ "implementsAcIds": ["AC-1103-1", "AC-1103-2", "AC-1103-3", "AC-1103-4"],
7
+ "dependencies": [],
8
+ "version": "0.1.0",
9
+ "status": "draft",
10
+ "createdAt": "2026-09-03T17:00:00Z",
11
+ "updatedAt": "2026-09-03T17:00:00Z"
12
+ }