rcf-lite 0.17.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 (62) hide show
  1. package/CHANGELOG.md +22 -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/docs/topics.md +2 -2
  11. package/blueprints/delivery-ci-workflows/docs/topics.md +2 -2
  12. package/blueprints/deploy-cloudflare-workers/docs/topics.md +2 -2
  13. package/blueprints/email-smtp-resend/docs/topics.md +2 -2
  14. package/blueprints/observability-essentials/README.md +6 -2
  15. package/blueprints/observability-essentials/blueprint.json +133 -33
  16. package/blueprints/observability-essentials/contributions/adrs/adr-801-observability-essentials-health-probes.json +4 -4
  17. package/blueprints/observability-essentials/contributions/adrs/adr-802-observability-essentials-readiness-semantics.json +4 -4
  18. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +4 -4
  19. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +4 -4
  20. package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +10 -9
  21. package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +17 -11
  22. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +12 -3
  23. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7102.json +12 -3
  24. package/blueprints/observability-essentials/docs/topics.md +15 -8
  25. package/blueprints/observability-essentials/guide/observability-essentials.md +9 -3
  26. package/blueprints/observability-probe-endpoints/README.md +5 -1
  27. package/blueprints/observability-probe-endpoints/blueprint.json +116 -24
  28. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json +5 -5
  29. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +11 -2
  30. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14107.json +11 -2
  31. package/blueprints/observability-probe-endpoints/docs/topics.md +6 -6
  32. package/blueprints/observability-probe-endpoints/guide/observability-probe-endpoints.md +10 -0
  33. package/blueprints/persistence-data-d1/docs/topics.md +2 -2
  34. package/blueprints/persistence-data-sqlite/docs/topics.md +2 -2
  35. package/blueprints/security-auth-clerk/docs/topics.md +2 -2
  36. package/blueprints/security-auth-keycloak/docs/topics.md +2 -2
  37. package/blueprints/security-auth-magic-link/docs/topics.md +2 -2
  38. package/blueprints/security-auth-oauth2/docs/topics.md +2 -2
  39. package/blueprints/security-secrets-management/docs/topics.md +2 -2
  40. package/fixtures/canary-manifest.json +6 -6
  41. package/package.json +1 -1
  42. package/rcf/code-nodes/cn-074.json +19 -0
  43. package/rcf/code-nodes/cn-075.json +15 -0
  44. package/rcf/code-nodes/cn-076.json +14 -0
  45. package/rcf/fbs/fbs-024.json +24 -0
  46. package/rcf/fbs/fbs-025.json +25 -0
  47. package/rcf/fbs/fbs-026.json +27 -0
  48. package/rcf/fbs/fbs-027.json +25 -0
  49. package/rcf/requirements/req-012.json +22 -0
  50. package/rcf/test-suites/ts-034.json +32 -0
  51. package/rcf/test-suites/ts-035.json +23 -0
  52. package/rcf/test-suites/ts-036.json +65 -0
  53. package/rcf/test-suites/ts-037.json +55 -0
  54. package/rcf/user-stories/us-1201.json +34 -0
  55. package/rcf/user-stories/us-1202.json +25 -0
  56. package/rcf/user-stories/us-1203.json +43 -0
  57. package/rcf/user-stories/us-1204.json +25 -0
  58. package/releases/releases.yaml +11 -1
  59. package/src/blueprint/index.js +1 -0
  60. package/src/blueprint/remove-resolution.js +104 -0
  61. package/src/cli/blueprint.js +41 -0
  62. package/src/cli/doctor.js +76 -1
@@ -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
 
@@ -2,8 +2,8 @@
2
2
  "registerCanary": [
3
3
  {
4
4
  "id": "rc-2026-09-04-001",
5
- "createdAt": "2026-09-04T09:05:34.919Z",
6
- "buildVersion": "0.17.0-mockdriver",
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": {
@@ -35,8 +35,8 @@
35
35
  },
36
36
  {
37
37
  "id": "rc-2026-09-04-002",
38
- "createdAt": "2026-09-04T09:05:34.920Z",
39
- "buildVersion": "0.17.0-mockdriver",
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": {
@@ -68,8 +68,8 @@
68
68
  },
69
69
  {
70
70
  "id": "rc-2026-09-04-003",
71
- "createdAt": "2026-09-04T09:05:34.920Z",
72
- "buildVersion": "0.17.0-mockdriver",
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.17.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",
@@ -0,0 +1,19 @@
1
+ {
2
+ "cnId": "CN-074",
3
+ "path": "test/blueprint/probe-path-alignment.test.js",
4
+ "title": "Three-way probe-path compose test (nine assertions across essentials v2.0.0, probe-endpoints v1.1.0, api-rest v2.0.0)",
5
+ "description": "The compose test file covers the nine assertions ratified in spec section 7 as document-level mechanism invariants over the shipped blueprint contributions and the applied rcf/ tree. Six static-named permutation tests for assertion 1 (the AC-1201-1 test pointer resolves to the first permutation), then one assertion each for one-owner-per-topic in the manifest, no-literal-path in the applied tree with Historical-ADR skip, bare compose defaults + optional startup + loadBalancer /health, essentials-alone required-config + PROBE_INTERFACE_PATHS_MISSING, auth-exempt-list agreement, TAC path-required-no-default, startup binding when enabled, and no dual handler registration. Runs in one process under the shipped node --test runner.",
6
+ "implementsAcIds": [
7
+ "AC-1201-1",
8
+ "AC-1201-2",
9
+ "AC-1202-1",
10
+ "AC-1203-1",
11
+ "AC-1203-2",
12
+ "AC-1203-3"
13
+ ],
14
+ "dependencies": [],
15
+ "version": "0.1.0",
16
+ "status": "draft",
17
+ "createdAt": "2026-09-04T00:00:00Z",
18
+ "updatedAt": "2026-09-04T00:00:00Z"
19
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "cnId": "CN-075",
3
+ "path": "src/cli/doctor.js#runProbePathOwnerCheck",
4
+ "title": "probe-path-owner doctor check",
5
+ "description": "Reads rcf/manifest.json, counts scope:global claimants on healthProbes and readinessSemantics; drift on more than one claimant per topic (names the applied blueprints and the remedy line naming the one that would have to drop its opinion, spec section 9). Also flags redundant historical resolutions[] entries on either topic when the current claimant count is <= 1 (a project that resolved the v1.x designed-in conflicts and re-applied to essentials v2.0.0 sees the resolution flagged as redundant, with the rcf define blueprint remove-resolution hint). Added to KNOWN_CHECKS; help text lists the new check. Not gated on browser-facing.",
6
+ "implementsAcIds": [
7
+ "AC-1203-2",
8
+ "AC-1203-3"
9
+ ],
10
+ "dependencies": [],
11
+ "version": "0.1.0",
12
+ "status": "draft",
13
+ "createdAt": "2026-09-04T00:00:00Z",
14
+ "updatedAt": "2026-09-04T00:00:00Z"
15
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "cnId": "CN-076",
3
+ "path": "src/blueprint/remove-resolution.js#removeResolution",
4
+ "title": "`rcf define blueprint remove-resolution` verb implementation",
5
+ "description": "removeResolution({ projectRoot, tree, resolvedByAdrId }) matches the argument against tree.manifest.resolutions[].resolvedByAdrId and drops the single matching entry via updateManifest (validates + tmp-write + rename); no other section of the manifest is touched, and the project-level ADR file at rcf/adrs/<adr-id>.json is left in place as historical context. Refuses with a usage rcfError (mapped to exit 2 at the CLI edge) when the id is malformed against ^ADR-\\d{3,}(-<kebab-tail>)?$ or when it is well-formed but names no ADR on tree.byId and is not on resolutions[]. When the id is well-formed and names an ADR present on the tree but is not on resolutions[], returns `{ removed: false, alreadyAbsent: true }` so the CLI edge prints the 'nothing to remove' line and exits 0 (the second-pass idempotency semantics ratified in spec A2). The verb is dispatched from src/cli/blueprint.js's main() and advertised in the HELP block; the doctor's probe-path-owner check names it verbatim as the remedy line for a redundant historical resolution.",
6
+ "implementsAcIds": [
7
+ "AC-1204-1"
8
+ ],
9
+ "dependencies": [],
10
+ "version": "0.1.0",
11
+ "status": "draft",
12
+ "createdAt": "2026-09-04T00:00:00Z",
13
+ "updatedAt": "2026-09-04T00:00:00Z"
14
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "fbsId": "FBS-024",
3
+ "prdId": "PRD-001",
4
+ "bsId": "BS-001",
5
+ "buildOrder": 24,
6
+ "executionStatus": "verified",
7
+ "title": "Three-way compose test asserting no globalAdrTopic conflict on healthProbes or readinessSemantics across every ordering",
8
+ "summary": "Add packages/rcf-lite/test/blueprint/probe-path-alignment.test.js: six per-permutation tests (assertion 1) covering AC-1201-1 and one applied-manifest walker (assertion 2) covering AC-1201-2. Uses the shipped applyBlueprint + walkTree + initProject seams; runs in one process under the shipped node --test runner.",
9
+ "acIds": [
10
+ "AC-1201-1",
11
+ "AC-1201-2"
12
+ ],
13
+ "dependsOnFbsIds": [],
14
+ "contextRequirements": {
15
+ "tacIds": [],
16
+ "adrIds": []
17
+ },
18
+ "domain": "blueprints",
19
+ "estimatedSize": "small",
20
+ "riskLevel": "low",
21
+ "notes": "Part of the ratified 2026-09-04 probe-path alignment train (w-2026-09-03-dave-021). Covers US-1201 on REQ-012.",
22
+ "createdAt": "2026-09-04T00:00:00Z",
23
+ "updatedAt": "2026-09-04T00:00:00Z"
24
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "fbsId": "FBS-025",
3
+ "prdId": "PRD-001",
4
+ "bsId": "BS-001",
5
+ "buildOrder": 25,
6
+ "executionStatus": "verified",
7
+ "title": "Compose test assertion 3: greppable no-literal-path invariant on the applied rcf/ tree",
8
+ "summary": "Add the assertion 3 block to packages/rcf-lite/test/blueprint/probe-path-alignment.test.js: applies the three amended blueprints, walks the resulting rcf/ tree, greps for the five literal probe-path strings, and skips ADR contribution files whose title begins \"Historical:\" (per spec section 4) or whose adrId names probe-secrecy (context-only ADR).",
9
+ "acIds": [
10
+ "AC-1202-1"
11
+ ],
12
+ "dependsOnFbsIds": [
13
+ "FBS-024"
14
+ ],
15
+ "contextRequirements": {
16
+ "tacIds": [],
17
+ "adrIds": []
18
+ },
19
+ "domain": "blueprints",
20
+ "estimatedSize": "small",
21
+ "riskLevel": "low",
22
+ "notes": "Part of the ratified 2026-09-04 probe-path alignment train (w-2026-09-03-dave-021). Covers US-1202 on REQ-012.",
23
+ "createdAt": "2026-09-04T00:00:00Z",
24
+ "updatedAt": "2026-09-04T00:00:00Z"
25
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "fbsId": "FBS-026",
3
+ "prdId": "PRD-001",
4
+ "bsId": "BS-001",
5
+ "buildOrder": 26,
6
+ "executionStatus": "verified",
7
+ "title": "Compose test assertions 4-9 covering the per-blueprint ratified alignment facts and the probe-path-owner doctor check",
8
+ "summary": "Add the assertion 4-9 block to packages/rcf-lite/test/blueprint/probe-path-alignment.test.js covering probe-endpoints optional startup + composing section (assertion 4, 8), essentials PROBE_INTERFACE_PATHS_MISSING refuse-boot + no-shipped-default TACs + no-dual-handler (assertions 5, 7, 9), api-rest deferral of the probe paths and auth-exempt-list binding (assertion 6). Add the probe-path-owner check to KNOWN_CHECKS in packages/rcf-lite/src/cli/doctor.js with the runProbePathOwnerCheck implementation reading manifest.blueprints[].contributions[] for scope:global topic multi-claim drift and manifest.resolutions[] for redundant resolutions on healthProbes/readinessSemantics after the alignment.",
9
+ "acIds": [
10
+ "AC-1203-1",
11
+ "AC-1203-2",
12
+ "AC-1203-3"
13
+ ],
14
+ "dependsOnFbsIds": [
15
+ "FBS-025"
16
+ ],
17
+ "contextRequirements": {
18
+ "tacIds": [],
19
+ "adrIds": []
20
+ },
21
+ "domain": "blueprints",
22
+ "estimatedSize": "medium",
23
+ "riskLevel": "low",
24
+ "notes": "Part of the ratified 2026-09-04 probe-path alignment train (w-2026-09-03-dave-021). Covers US-1203 on REQ-012.",
25
+ "createdAt": "2026-09-04T00:00:00Z",
26
+ "updatedAt": "2026-09-04T00:00:00Z"
27
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "fbsId": "FBS-027",
3
+ "prdId": "PRD-001",
4
+ "bsId": "BS-001",
5
+ "buildOrder": 27,
6
+ "executionStatus": "verified",
7
+ "title": "`rcf define blueprint remove-resolution <adr-id>` verb (drops one manifest.resolutions[] entry; idempotent; refuses exit 2 on malformed or unknown id)",
8
+ "summary": "Add packages/rcf-lite/src/blueprint/remove-resolution.js implementing removeResolution({ projectRoot, tree, resolvedByAdrId }) with the three ratified behaviours (remove + idempotent + refuse), export it from packages/rcf-lite/src/blueprint/index.js, wire the `remove-resolution` verb into packages/rcf-lite/src/cli/blueprint.js's HELP block and dispatch, and cover the surface with packages/rcf-lite/test/blueprint/remove-resolution.test.js (module) and remove-resolution cases appended to packages/rcf-lite/test/blueprint/cli.test.js (CLI edge). No changes to the doctor hint text (it names the verb already); no changes to project ADR files (the verb is scoped to manifest.resolutions[]).",
9
+ "acIds": [
10
+ "AC-1204-1"
11
+ ],
12
+ "dependsOnFbsIds": [
13
+ "FBS-026"
14
+ ],
15
+ "contextRequirements": {
16
+ "tacIds": [],
17
+ "adrIds": []
18
+ },
19
+ "domain": "blueprints",
20
+ "estimatedSize": "small",
21
+ "riskLevel": "low",
22
+ "notes": "Part of the ratified 2026-09-04 probe-path alignment train (w-2026-09-03-dave-021). Covers US-1204 on REQ-012. Spec amendment A2, added under the envelope 2026-09-04 after gate d-2026-09-04-016 finding 1 (the doctor and spec section 9 named the verb before it existed).",
23
+ "createdAt": "2026-09-04T00:00:00Z",
24
+ "updatedAt": "2026-09-04T00:00:00Z"
25
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "reqId": "REQ-012",
3
+ "prdId": "PRD-001",
4
+ "title": "Core shelf: probe-path binding has one owner (observability-probe-endpoints), essentials and api-rest defer",
5
+ "description": "The shipped observability-essentials, observability-probe-endpoints, and application-api-rest blueprints compose on one project without a `globalAdrTopic` conflict on the `healthProbes` or `readinessSemantics` topics; observability-probe-endpoints is the sole shelf-wide `scope: global` claimant on both topics. observability-essentials v2.0.0 drops those claims and restates its two probe REQs and TACs path-neutral, refusing boot with the stable-coded error `PROBE_INTERFACE_PATHS_MISSING` when `probeInterface.paths.liveness` or `probeInterface.paths.readiness` is absent and probe-endpoints is not composed. application-api-rest v2.0.0 drops the literal `/healthz/live`, `/healthz/ready`, and `/healthz/startup` bindings from REQ-006, US-2108 (all eight ACs), TAC-306 and US-2103, deferring to the resolved probe path set (probe-endpoints Kubernetes profile default `/live` and `/ready`, optional `/startup`; loadBalancer profile `/health`; or project-supplied `probeInterface.paths` in the essentials-alone case). observability-probe-endpoints v1.1.0 adds the optional third Kubernetes-profile path `startup` (default `/startup`), off by default and enabled by `probeInterface.options.kubernetes.startup.enabled: true`, with paired ACs on US-14102 and US-14107 and a composing section in its guide. The three-way alignment is verified by the compose test at `packages/rcf-lite/test/blueprint/probe-path-alignment.test.js` and is the ratified truth for the shelf.",
6
+ "category": "functional",
7
+ "domain": "blueprints",
8
+ "priority": "must",
9
+ "rationale": "The shipped shelf carried three literal probe-path opinions before this alignment (essentials /healthz + /readyz, probe-endpoints /live + /ready, api-rest /healthz/live + /healthz/ready + /healthz/startup). Composing any two of the three on one project either fired a designed-in `globalAdrTopic` conflict on healthProbes/readinessSemantics or silently shipped three disagreeing probe bindings. WSD-012 mandates /live and /ready, which is the probe-endpoints Kubernetes default; Dex's A4 wsd-service-anatomy binds those two paths as a parameter and required this item as its dependency. Aligning ownership to one blueprint (probe-endpoints) and making the other two defer is the smallest change that closes both the conflict-by-design surface and the silent-disagreement surface without inventing a new composer primitive. Ratified spec: `projects/rcf-lite-wsd/specs/rcf-lite-probe-path-alignment-spec-2026-09-04.md` (sections 1 through 11).",
10
+ "tags": [
11
+ "blueprints",
12
+ "observability",
13
+ "probe-endpoints",
14
+ "essentials",
15
+ "api-rest",
16
+ "alignment"
17
+ ],
18
+ "version": "0.1.0",
19
+ "status": "draft",
20
+ "createdAt": "2026-09-04T00:00:00Z",
21
+ "updatedAt": "2026-09-04T00:00:00Z"
22
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "id": "TS-034",
3
+ "usId": "US-1201",
4
+ "title": "Three amended blueprints apply cleanly in every ordering with one-owner-per-topic in the manifest",
5
+ "purpose": "Cover the two ACs on US-1201: no globalAdrTopic conflict on healthProbes/readinessSemantics during apply in any of the six permutations, and one-and-only-one probe-endpoints scope:global claimant per topic in the resulting manifest.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-1201-1",
9
+ "AC-1201-2"
10
+ ],
11
+ "testCases": [
12
+ {
13
+ "id": "TC-034-permutations-no-globaladr-conflict",
14
+ "acId": "AC-1201-1",
15
+ "description": "The first of six orderings (essentials -> probe-endpoints -> api-rest) is exercised here as the resolved test-point representative of the parameterised assertion; the other five permutations run in the same suite file (assertion 1 (apply cleanly in every ordering): ...) and share this AC.",
16
+ "testPointer": "test/blueprint/probe-path-alignment.test.js::assertion 1 (apply cleanly in every ordering): observability-essentials -> observability-probe-endpoints -> application-api-rest",
17
+ "status": "pending",
18
+ "scope": "library"
19
+ },
20
+ {
21
+ "id": "TC-034-one-owner-per-topic",
22
+ "acId": "AC-1201-2",
23
+ "description": "After applying all three blueprints into a fresh project tree, exactly one scope:global ADR on healthProbes and one on readinessSemantics are present in the manifest, both owned by observability-probe-endpoints",
24
+ "testPointer": "test/blueprint/probe-path-alignment.test.js::assertion 2: one owner per topic across the applied manifest",
25
+ "status": "pending",
26
+ "scope": "library"
27
+ }
28
+ ],
29
+ "status": "draft",
30
+ "createdAt": "2026-09-04T00:00:00Z",
31
+ "updatedAt": "2026-09-04T00:00:00Z"
32
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "id": "TS-035",
3
+ "usId": "US-1202",
4
+ "title": "Applied tree carries no literal /healthz or /readyz path outside probe-endpoints prose",
5
+ "purpose": "Cover the one AC on US-1202: greppable proof that /healthz, /readyz, /healthz/live, /healthz/ready and /healthz/startup do not appear in the applied rcf/ contribution JSON tree after re-applying all three amended blueprints.",
6
+ "testLevel": "integration",
7
+ "acIds": [
8
+ "AC-1202-1"
9
+ ],
10
+ "testCases": [
11
+ {
12
+ "id": "TC-035-no-literal-path-in-applied-tree",
13
+ "acId": "AC-1202-1",
14
+ "description": "Applying all three amended blueprints and grepping the applied rcf/ tree for the five literal path strings returns zero matches",
15
+ "testPointer": "test/blueprint/probe-path-alignment.test.js::assertion 3: no literal probe path outside probe-endpoints prose or Historical ADRs in applied tree",
16
+ "status": "pending",
17
+ "scope": "library"
18
+ }
19
+ ],
20
+ "status": "draft",
21
+ "createdAt": "2026-09-04T00:00:00Z",
22
+ "updatedAt": "2026-09-04T00:00:00Z"
23
+ }