rcf-lite 0.17.0 → 0.19.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 (161) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/blueprints/application-api-rest/README.md +5 -1
  3. package/blueprints/application-api-rest/blueprint.json +12 -4
  4. package/blueprints/application-api-rest/contributions/adrs/adr-304-application-api-rest-logging.json +3 -3
  5. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-006.json +4 -4
  6. package/blueprints/application-api-rest/contributions/tacs/tac-306-application-api-rest-operability.json +9 -8
  7. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2103.json +3 -3
  8. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2108.json +27 -27
  9. package/blueprints/application-api-rest/docs/topics.md +6 -4
  10. package/blueprints/application-api-rest/guide/application-api-rest.md +5 -1
  11. package/blueprints/application-error-handling/README.md +42 -0
  12. package/blueprints/application-error-handling/assets/schemas/error-record.schema.json +17 -0
  13. package/blueprints/application-error-handling/blueprint.json +27 -0
  14. package/blueprints/application-error-handling/contributions/adrs/adr-1701-application-error-handling-record-shape.json +25 -0
  15. package/blueprints/application-error-handling/contributions/adrs/adr-1702-application-error-handling-classification-vocabulary.json +20 -0
  16. package/blueprints/application-error-handling/contributions/adrs/adr-1703-application-error-handling-transport-mapping.json +20 -0
  17. package/blueprints/application-error-handling/contributions/requirements/application-error-handling-req-001.json +15 -0
  18. package/blueprints/application-error-handling/contributions/requirements/application-error-handling-req-002.json +15 -0
  19. package/blueprints/application-error-handling/contributions/requirements/application-error-handling-req-003.json +15 -0
  20. package/blueprints/application-error-handling/contributions/requirements/application-error-handling-req-004.json +15 -0
  21. package/blueprints/application-error-handling/contributions/tacs/tac-1701-application-error-handling-boundary.json +45 -0
  22. package/blueprints/application-error-handling/contributions/tacs/tac-1702-application-error-handling-record-factory.json +40 -0
  23. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16101.json +25 -0
  24. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16102.json +25 -0
  25. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16103.json +34 -0
  26. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16104.json +25 -0
  27. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16105.json +25 -0
  28. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16106.json +25 -0
  29. package/blueprints/application-error-handling/contributions/user-stories/application-error-handling-us-16107.json +25 -0
  30. package/blueprints/application-error-handling/docs/topics.md +24 -0
  31. package/blueprints/application-error-handling/guide/application-error-handling.md +35 -0
  32. package/blueprints/application-spa/blueprint.json +12 -2
  33. package/blueprints/application-spa/docs/topics.md +4 -2
  34. package/blueprints/delivery-ci-workflows/docs/topics.md +2 -2
  35. package/blueprints/deploy-cloudflare-workers/docs/topics.md +2 -2
  36. package/blueprints/email-smtp-resend/docs/topics.md +2 -2
  37. package/blueprints/observability-essentials/README.md +6 -2
  38. package/blueprints/observability-essentials/blueprint.json +133 -33
  39. package/blueprints/observability-essentials/contributions/adrs/adr-801-observability-essentials-health-probes.json +4 -4
  40. package/blueprints/observability-essentials/contributions/adrs/adr-802-observability-essentials-readiness-semantics.json +4 -4
  41. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +4 -4
  42. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +4 -4
  43. package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +10 -9
  44. package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +17 -11
  45. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +12 -3
  46. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7102.json +12 -3
  47. package/blueprints/observability-essentials/docs/topics.md +15 -8
  48. package/blueprints/observability-essentials/guide/observability-essentials.md +9 -3
  49. package/blueprints/observability-logging/README.md +44 -0
  50. package/blueprints/observability-logging/assets/samples/log-line.json +13 -0
  51. package/blueprints/observability-logging/blueprint.json +27 -0
  52. package/blueprints/observability-logging/contributions/adrs/adr-1601-observability-logging-line-shape.json +25 -0
  53. package/blueprints/observability-logging/contributions/adrs/adr-1602-observability-logging-correlation-id-header.json +25 -0
  54. package/blueprints/observability-logging/contributions/adrs/adr-1603-observability-logging-redaction-categories.json +25 -0
  55. package/blueprints/observability-logging/contributions/adrs/adr-1604-observability-logging-level-vocabulary.json +20 -0
  56. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-001.json +15 -0
  57. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-002.json +15 -0
  58. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-003.json +15 -0
  59. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-004.json +15 -0
  60. package/blueprints/observability-logging/contributions/requirements/observability-logging-req-005.json +15 -0
  61. package/blueprints/observability-logging/contributions/tacs/tac-1601-observability-logging-logger-factory.json +46 -0
  62. package/blueprints/observability-logging/contributions/tacs/tac-1602-observability-logging-redaction-boundary.json +27 -0
  63. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15101.json +34 -0
  64. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15102.json +43 -0
  65. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15103.json +34 -0
  66. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15104.json +25 -0
  67. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15105.json +34 -0
  68. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15106.json +25 -0
  69. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15107.json +25 -0
  70. package/blueprints/observability-logging/contributions/user-stories/observability-logging-us-15108.json +25 -0
  71. package/blueprints/observability-logging/docs/topics.md +21 -0
  72. package/blueprints/observability-logging/guide/observability-logging.md +36 -0
  73. package/blueprints/observability-probe-endpoints/README.md +5 -1
  74. package/blueprints/observability-probe-endpoints/blueprint.json +116 -24
  75. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json +5 -5
  76. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +11 -2
  77. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14107.json +11 -2
  78. package/blueprints/observability-probe-endpoints/docs/topics.md +6 -6
  79. package/blueprints/observability-probe-endpoints/guide/observability-probe-endpoints.md +10 -0
  80. package/blueprints/persistence-data-d1/docs/topics.md +2 -2
  81. package/blueprints/persistence-data-sqlite/docs/topics.md +2 -2
  82. package/blueprints/security-auth-clerk/docs/topics.md +2 -2
  83. package/blueprints/security-auth-keycloak/docs/topics.md +2 -2
  84. package/blueprints/security-auth-magic-link/docs/topics.md +2 -2
  85. package/blueprints/security-auth-oauth2/docs/topics.md +2 -2
  86. package/blueprints/security-secrets-management/docs/topics.md +2 -2
  87. package/fixtures/canary-manifest.json +6 -6
  88. package/guidance/harness-template.md +8 -0
  89. package/guidance/managed/agent-instructions-block.hash +1 -1
  90. package/guidance/managed/agent-instructions-block.md +8 -0
  91. package/package.json +1 -1
  92. package/rcf/code-nodes/cn-074.json +19 -0
  93. package/rcf/code-nodes/cn-075.json +15 -0
  94. package/rcf/code-nodes/cn-076.json +14 -0
  95. package/rcf/code-nodes/cn-077.json +14 -0
  96. package/rcf/code-nodes/cn-078.json +15 -0
  97. package/rcf/code-nodes/cn-079.json +14 -0
  98. package/rcf/code-nodes/cn-080.json +15 -0
  99. package/rcf/code-nodes/cn-081.json +15 -0
  100. package/rcf/code-nodes/cn-082.json +15 -0
  101. package/rcf/code-nodes/cn-083.json +14 -0
  102. package/rcf/code-nodes/cn-084.json +15 -0
  103. package/rcf/code-nodes/cn-085.json +14 -0
  104. package/rcf/code-nodes/cn-086.json +16 -0
  105. package/rcf/code-nodes/cn-087.json +14 -0
  106. package/rcf/code-nodes/cn-088.json +14 -0
  107. package/rcf/code-nodes/cn-089.json +14 -0
  108. package/rcf/code-nodes/cn-090.json +14 -0
  109. package/rcf/code-nodes/cn-091.json +14 -0
  110. package/rcf/code-nodes/cn-092.json +15 -0
  111. package/rcf/code-nodes/cn-093.json +15 -0
  112. package/rcf/code-nodes/cn-094.json +14 -0
  113. package/rcf/code-nodes/cn-095.json +14 -0
  114. package/rcf/code-nodes/cn-096.json +14 -0
  115. package/rcf/code-nodes/cn-097.json +14 -0
  116. package/rcf/fbs/fbs-024.json +24 -0
  117. package/rcf/fbs/fbs-025.json +25 -0
  118. package/rcf/fbs/fbs-026.json +27 -0
  119. package/rcf/fbs/fbs-027.json +25 -0
  120. package/rcf/fbs/fbs-028.json +27 -0
  121. package/rcf/fbs/fbs-029.json +27 -0
  122. package/rcf/fbs/fbs-030.json +27 -0
  123. package/rcf/fbs/fbs-031.json +27 -0
  124. package/rcf/fbs/fbs-032.json +27 -0
  125. package/rcf/fbs/fbs-033.json +27 -0
  126. package/rcf/fbs/fbs-034.json +27 -0
  127. package/rcf/requirements/req-012.json +22 -0
  128. package/rcf/requirements/req-013.json +22 -0
  129. package/rcf/requirements/req-014.json +22 -0
  130. package/rcf/requirements/req-015.json +21 -0
  131. package/rcf/test-suites/ts-034.json +32 -0
  132. package/rcf/test-suites/ts-035.json +23 -0
  133. package/rcf/test-suites/ts-036.json +65 -0
  134. package/rcf/test-suites/ts-037.json +55 -0
  135. package/rcf/test-suites/ts-038.json +41 -0
  136. package/rcf/test-suites/ts-039.json +41 -0
  137. package/rcf/test-suites/ts-040.json +57 -0
  138. package/rcf/test-suites/ts-041.json +57 -0
  139. package/rcf/test-suites/ts-042.json +57 -0
  140. package/rcf/test-suites/ts-043.json +49 -0
  141. package/rcf/test-suites/ts-044.json +41 -0
  142. package/rcf/user-stories/us-1201.json +34 -0
  143. package/rcf/user-stories/us-1202.json +25 -0
  144. package/rcf/user-stories/us-1203.json +43 -0
  145. package/rcf/user-stories/us-1204.json +25 -0
  146. package/rcf/user-stories/us-1301.json +43 -0
  147. package/rcf/user-stories/us-1302.json +43 -0
  148. package/rcf/user-stories/us-1401.json +43 -0
  149. package/rcf/user-stories/us-1402.json +43 -0
  150. package/rcf/user-stories/us-1403.json +43 -0
  151. package/rcf/user-stories/us-1404.json +43 -0
  152. package/rcf/user-stories/us-1501.json +43 -0
  153. package/releases/releases.yaml +21 -1
  154. package/src/blueprint/apply.js +8 -0
  155. package/src/blueprint/companions.js +485 -0
  156. package/src/blueprint/index.js +17 -0
  157. package/src/blueprint/loader.js +243 -1
  158. package/src/blueprint/remove-resolution.js +104 -0
  159. package/src/cli/blueprint.js +350 -0
  160. package/src/cli/doctor.js +76 -1
  161. package/src/cli/validate.js +7 -0
@@ -0,0 +1,25 @@
1
+ {
2
+ "usId": "observability-logging-US-15108",
3
+ "prdId": "PRD-001",
4
+ "reqId": "observability-logging-REQ-003",
5
+ "version": "1.0.0",
6
+ "status": "approved",
7
+ "title": "A redaction category unknown to the boundary is refused at configuration time rather than silently ignored",
8
+ "asA": "operator elicited into ADR-1603 with a mis-spelled additional category name",
9
+ "iWant": "the factory to refuse the redaction category at configuration time with a message naming the offending value",
10
+ "soThat": "a typo in an added category does not silently disable redaction for that field pattern",
11
+ "acceptanceCriteria": [
12
+ {
13
+ "id": "AC-15108-1",
14
+ "description": "The factory's redaction configuration accepts kebab-cased or dotted-namespace category names (matching the ADR-1603 recommended-default shape) and refuses any other shape with a message naming the offending value and the accepted grammar.",
15
+ "given": "an application configured with a redaction categories list including 'PII Email' (space, mixed case)",
16
+ "when": "the factory is constructed",
17
+ "then": "construction throws with a message naming 'PII Email' as the offending value",
18
+ "testable": true,
19
+ "scope": "runtime"
20
+ }
21
+ ],
22
+ "tacIds": ["TAC-1602-observability-logging-redaction-boundary"],
23
+ "createdAt": "2026-09-04T12:20:00Z",
24
+ "updatedAt": "2026-09-04T12:20:00Z"
25
+ }
@@ -0,0 +1,21 @@
1
+ # observability-logging: coordination vocabulary
2
+
3
+ ## Global topics
4
+
5
+ | Topic | Owning ADR | Meaning | Composition note |
6
+ |---|---|---|---|
7
+ | `logging` | `ADR-1601-observability-logging-line-shape` | Structured single-line JSON emission contract with the shared minimum field set. | Shelf-canonical claim from v1.0.0. A composing blueprint that ships a different logging contract (structured multi-line, per-service special format, non-JSON) conflicts by design; the operator resolves at project level via `rcf define blueprint supersede logging --incoming <source>`. A library-registered logging provider (wsd-logging, acme-log-emit) is preferred over this shelf provider by the companion-suggestion mechanism. |
8
+
9
+ ## Deliberately unclaimed topics
10
+
11
+ - `logRedaction` (text-level redaction of the `message` string). Named here so a future companion blueprint can claim it cleanly; this blueprint's redaction is field-name granularity per ADR-1603.
12
+ - `logTransport` (the transport downstream of stdout). Owned by the surrounding platform; a future blueprint may claim it if the shelf ever ships one.
13
+ - `logMetricsBridge` (emitting log-derived metrics). Named here so a future `metrics-store` companion can claim it cleanly.
14
+
15
+ ## Shelf id band and suffix block
16
+
17
+ | Blueprint | US band | ADR/TAC suffix block | Status | Global topics |
18
+ |---|---|---|---|---|
19
+ | observability-logging | 15101-15899 | 16xx | shipped v1.0.0 | `logging` |
20
+
21
+ The shelf-wide band registry lives in `packages/rcf-lite/docs/blueprint-authoring.md` section 5.
@@ -0,0 +1,36 @@
1
+ # Guide: observability-logging (v1.0.0)
2
+
3
+ ## What it is
4
+
5
+ A shipped, org-neutral logging contract for a rcf-lite project. Every log emission lands as one JSON object per line on stdout with a shared field set the applying operator's ingestion pipeline can consume without a per-service parser. Correlation identifiers propagate through the request-scoped context and reflect on outbound requests. A field-name redaction boundary keeps PII out of emitted lines by rule, not by hope. The operator elicits the correlation header name, the redaction category additions and the minimum level per environment at apply.
6
+
7
+ ## What it deliberately is not
8
+
9
+ - Not a log transport. The blueprint ships to stdout; the applying platform pipes it into whatever ingestion service the operator chose. Elastic Common Schema, Loki, Datadog and Splunk all consume one JSON object per line without a per-blueprint adapter.
10
+ - Not a metrics or tracing surface. Metrics belong to a future `metrics-store` companion; tracing belongs to a distributed-tracing companion. This blueprint contributes neither.
11
+ - Not a text-level PII scrubber. Redaction is field-name granularity per ADR-1603; a PII value concatenated into the `message` string is not caught.
12
+
13
+ ## When to reach for it
14
+
15
+ - Any project that has not yet applied a logging companion. Applying this blueprint gives a working structured emission surface without registering a library.
16
+ - Any project whose applied service blueprints (application-api-rest, application-spa) declare `suggestedCompanions: ["logging"]` and no more specific library provides the role.
17
+
18
+ ## When it does not fit
19
+
20
+ - A project standing on an organisation with a shipped logging library (`wsd-logging`, `acme-log-emit`) that provides the `logging` role. Register the library and the companion-suggestion mechanism resolves to the library's provider over this shelf fallback.
21
+ - A project that needs multi-line stack trace emission for a legacy consumer. This blueprint ships single-line JSON only; a project-level `logging` topic supersede lets the project author a different contract.
22
+
23
+ ## What a good outcome looks like
24
+
25
+ - One JSON object per line on stdout, correlation identifier threaded across services, PII fields redacted at the boundary, level filter honoured per environment, in-memory capture mode used in tests. `rcf define validate` clean; log ingestion pipeline queries partition cleanly by environment, serviceName and serviceVersion.
26
+
27
+ ## The operator decisions that remain open
28
+
29
+ - **The inbound correlation header name** (ADR-1602). Recommended default `X-Correlation-Id`; elicited alternative per project. Set the value the surrounding platform's proxy or client tooling already stamps.
30
+ - **The redaction categories additions** (ADR-1603). Recommended defaults cover the six common cases; a project with a domain-specific field (ssn, iban, jwt) adds it at apply.
31
+ - **The minimum log level per environment** (ADR-1604). Recommended vocabulary is trace / debug / info / warn / error / fatal; elicited minimum per environment. Production is typically info; development is typically debug or trace.
32
+ - **The log transport downstream of stdout.** Out of scope for this blueprint; the surrounding platform's pipe wires ingestion.
33
+
34
+ ## Cost-honesty
35
+
36
+ Applying this blueprint adds five REQs, eight USs, two TACs and four ADRs to the project's chain. The runtime cost is one factory per boot plus one redaction pass per emission. There is no runtime dependency added to the project's `package.json`; the factory is authored against the applying project's own runtime. The main hidden cost is the discipline of routing every emission through the factory: the guide's `Known mechanism-reach gaps` section names the class and the project-side workarounds.
@@ -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