Add rapp declaration schema with composition block (WP-0021 T02, T03)
schemas/rapp.schema.json defines one normative shape for the rollout, smoke and rollback contracts in place of the three mutually unreadable variants found across the live rapps, promotes contract_version, readiness_state, data_classification and criticality to required, and forbids the rapp- prefix on workload_identity.name. composition replaces the flat members list per amendment f88f938d: purpose, member_repos with deployables, and pinned upstream_components. Repos are many:many with rapps; deployables are 1:1, which is what makes the T06 coverage check well-formed. ownership_repo left permissive pending an architecture-owner call; the tighter alternative is written up in schemas/README.md. Validated against all three live declarations: openbao 10 errors, postgres 10, qonto 4 — precisely the reported drift and nothing else. Also found: three further rapp-* repos (secrets-engine, tenant-engine, user-engine) carry no declarations at all, which the routed survey missed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
8fc92bd7d2
commit
28cbba1025
3 changed files with 525 additions and 2 deletions
|
|
@ -162,7 +162,7 @@ acquire a cluster dependency.
|
|||
|
||||
```task
|
||||
id: RAILIANCE-WP-0021-T02
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "87ae4551-1fac-4613-b258-28c8b22bbb82"
|
||||
```
|
||||
|
|
@ -190,11 +190,62 @@ Pick one normative shape for `rollout_contract`, `smoke_contract` and
|
|||
the schema which existing declaration the chosen shape most resembles, so
|
||||
migration cost is visible.
|
||||
|
||||
**Done 2026-08-11.** `schemas/rapp.schema.json` (draft 2020-12) and
|
||||
`schemas/README.md` written from the three live declarations rather than from
|
||||
the survey summary, which turned out to understate the drift — see the extra
|
||||
finding below.
|
||||
|
||||
Normative choices, with who pays:
|
||||
|
||||
- `default_mode` kept; all three declarations already carried it. No cost.
|
||||
- `supported_commands` → `commands` in all three contracts. Mechanical.
|
||||
- `smoke_contract.required` is required, `commands` optional — taken from
|
||||
`rapp-qonto`. This is the one migration with real cost: the platform rapps
|
||||
declare only commands and their owners must now name the outcomes those
|
||||
commands establish. A command list records what was run; a required list
|
||||
records what must be true, and only the second is checkable by anyone other
|
||||
than the person who ran it.
|
||||
- `rollback_contract.order` required, also from `rapp-qonto`, recoverable from
|
||||
the command sequences already documented. `direct_kubernetes_fallback`
|
||||
generalizes to `fallback`.
|
||||
- `workload_identity.name` is the workload, never the repo; the schema forbids
|
||||
the `rapp-` prefix outright.
|
||||
- `contract_version`, `readiness_state`, `data_classification`, `criticality`
|
||||
all promoted to required.
|
||||
- `consumer_contract` schema-defined but optional.
|
||||
|
||||
`ownership_repo` is left permissive — exactly one repo, not the rapp repo
|
||||
itself, layer and application repos both legal — so the schema does not
|
||||
silently invalidate two of three live declarations on a question the survey
|
||||
cannot settle. The tighter alternative and its consequence are written up in
|
||||
`schemas/README.md` for the architecture owner. Treat the permissive rule as
|
||||
provisional.
|
||||
|
||||
Validated against all three live declarations with `jsonschema` 4.10.3. The
|
||||
schema is well-formed and reproduces precisely the drift the survey reported,
|
||||
which is the intended result — it fails on real drift and not on anything else:
|
||||
|
||||
| Declaration | Errors | Character |
|
||||
|---|---|---|
|
||||
| `rapp-openbao` | 10 | four missing metadata fields, no composition, three contracts on the old shape |
|
||||
| `rapp-postgres` | 10 | identical set — the two platform rapps drifted together |
|
||||
| `rapp-qonto` | 4 | composition, `direct_kubernetes_fallback`, missing `package_type`, and `workload_identity.name` = `rapp-qonto` |
|
||||
|
||||
**Extra finding, not in the routed survey.** There are six `rapp-*` repos, not
|
||||
three: `rapp-secrets-engine`, `rapp-tenant-engine` and `rapp-user-engine` exist
|
||||
and carry no `declarations/` directory at all. The survey counted only declared
|
||||
rapps, so the real gap is wider than the roughly 17-workloads-versus-3-rapps
|
||||
figure suggests — three further repos claim the family prefix while declaring
|
||||
nothing. Raised to `railiance-platform`; whether these are stubs, abandoned, or
|
||||
undeclared live workloads should be settled before T06 draws its coverage
|
||||
baseline, since undeclared repos are invisible to a coverage check that reads
|
||||
declarations.
|
||||
|
||||
## T03 - Define the composition block and its cardinality rules
|
||||
|
||||
```task
|
||||
id: RAILIANCE-WP-0021-T03
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "8b130ff8-0601-40bb-8539-d6f5847c2f41"
|
||||
```
|
||||
|
|
@ -226,6 +277,28 @@ and rolls back together, not one per deployable. Grouping is legitimate only
|
|||
where members share rollout and rollback fate; make that testable rather than
|
||||
advisory where possible.
|
||||
|
||||
**Done 2026-08-11.** `composition` is required on every rapp, in
|
||||
`schemas/rapp.schema.json` under `$defs/composition`. A single-repo rapp
|
||||
declares exactly one member, so there is no second shape for the ungrouped
|
||||
case — the composition block is the only way to state membership.
|
||||
|
||||
`purpose` carries a `minLength` and is documented as the bounded-context
|
||||
statement: if it cannot be written without "and also", the grouping is probably
|
||||
wrong. That is the closest this schema gets to testing shared rollout fate;
|
||||
the substantive check is structural, in that `deployables` is required on every
|
||||
member, which is what T06 consumes.
|
||||
|
||||
Both cardinalities are encoded where they bite. `member_repos[].repo` is
|
||||
unconstrained across rapps, so a repo may appear in several — many-to-many.
|
||||
`member_repos[].deployables` is documented as one-to-one and enforced by the
|
||||
validator's coverage check rather than by the schema, since no single-file
|
||||
schema can see across declarations. `upstream_components` requires an exact
|
||||
`version` pin, with the schema stating that ranges and floating tags are not
|
||||
pins.
|
||||
|
||||
`workload_identity.package_type` gains a `grouped-composition` value for rapps
|
||||
whose members carry their own package types.
|
||||
|
||||
## T04 - Schematize rail.yaml and reef.yaml, and derive bound_rapps
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue