Define derived rail and Qonto readiness architecture

This commit is contained in:
codex 2026-07-26 11:45:07 +02:00
parent 0b95c3029c
commit 8901ae4b15
9 changed files with 845 additions and 0 deletions

View file

@ -0,0 +1,31 @@
# ADR-0005: Derived Rail Composition
Date: 2026-07-26
Status: Accepted
## Context
Knative provides distinct workload activation and revision semantics but runs
on Kubernetes. Treating it as an unrelated peer rail would duplicate generic
workload lifecycle and substrate assumptions.
## Decision
Railiance distinguishes base and derived rails.
`rail-kubernetes` is the default base rail for platform workloads.
`rail-knative` is a derived rail that inherits a versioned
`rail-kubernetes` common contract and overrides only Knative-specific
activation, revision, autoscaling, traffic, cold-start, and rollback semantics.
The detailed contract is
[`docs/rail-composition-contract.md`](../rail-composition-contract.md).
## Consequences
- New platform workloads continue to use `rail-kubernetes` unless a specialized
rail is justified.
- Derived rails declare base-rail compatibility rather than copying lifecycle
contracts.
- Fabric and conformance tooling must understand rail dependency and readiness.
- Knative installation stays with the S2 substrate owner.

View file

@ -0,0 +1,29 @@
# ADR-0006: Reef Production Admission
Date: 2026-07-26
Status: Accepted
## Context
Fabric topology can say that a reef hosts a rail or binds a workload, but that
does not demonstrate capacity, isolation, recoverability, or approval for a
critical internet-facing service.
## Decision
Rail and `rapp` bindings use explicit readiness states: `declared`,
`installed`, `verified`, `production-approved`, and `deprecated`.
Critical workloads require machine-readable conformance evidence plus explicit
acceptance of residual risks that cannot be automated. Mixed-rail reefs use
defined split triggers.
The detailed contract is
[`docs/reef-production-readiness-contract.md`](../reef-production-readiness-contract.md).
## Consequences
- `hosts_rail` and `binds_rapp` no longer imply deployability.
- `reef-railiance` may host Knative in wave 2, but Qonto cannot be called
production-approved solely from that declaration.
- Repeated evidence collection should become functional automation.

View file

@ -0,0 +1,121 @@
# Qonto Knative Runtime Contract
Date: 2026-07-26
Status: Architecture baseline; implementation values require measured evidence
## Purpose
Define the end-to-end runtime boundary for an internet-reachable Qonto service
that holds access to a company bank credential and scales to zero.
## Ownership And Flow
```text
authenticated client
-> reef ingress capability
-> rail-knative request activation and revision routing
-> rapp-qonto package
-> qonto-assistant domain service
-> OpenBao credential lane
-> Qonto API
```
- `railiance-cluster` owns ingress, DNS, certificate, Knative installation,
and cluster-level network capabilities.
- `rail-knative` owns activation, buffering, revisions, autoscaling, traffic,
cold-start, and rail-specific rollback semantics.
- `rapp-qonto` owns package manifests, runtime configuration, rail bindings,
workload-specific smoke checks, and secret references.
- `qonto-assistant` owns Qonto domain behavior, default-deny financial policy,
authorization integration, and application audit events.
- `reef-railiance` owns placement, local binding, and readiness evidence.
The raw workload service is never a public unauthenticated endpoint.
## Steady-State Identity And Secret Names
The steady runtime identity is named for `rapp-qonto`, not its source repo.
Recommended stable identifiers:
- workload principal: `rapp-qonto`
- tenant: the canon-approved Binky tenant identifier
- Kubernetes service account: `rapp-qonto`
- OpenBao role: `rapp-qonto`
- bank credential reference: `tenants/binky/qonto-api`
- caller OIDC client: `rapp-qonto-client`
Any `qonto-assistant` runtime principal or secret role is a time-bounded
migration bridge and must not become the steady-state declaration.
## Request And Cold-Start Contract
Implementation must measure and publish:
- cold-start service-level objective
- caller timeout
- activator or gateway buffering timeout
- maximum concurrency
- retry ownership and retry limit
- readiness deadline
- scale-down grace period
Financial or side-effecting operations must carry an idempotency key across
activation, retries, and client reconnects. A timeout must not silently imply
that an operation did not reach Qonto.
Until measured values exist, implementation may use conservative development
defaults but must not claim `production-approved`.
## Dependency Failure Rules
- If caller identity cannot be verified: deny before activation when possible.
- If workload identity cannot be established: fail closed.
- If OpenBao or the bank-credential lane is unavailable: fail closed and emit
an audit event; never fall back to a static embedded secret.
- If Qonto is unavailable: return a bounded upstream failure and preserve
idempotency/audit context.
- If audit delivery is unavailable: follow the application security contract;
critical mutations must not become unaudited best-effort operations.
## Network And Secret Controls
- default-deny ingress and egress
- ingress only through the approved authenticated entry path
- egress only to DNS, the approved OpenBao endpoint, required identity and
authorization services, and Qonto API endpoints
- `0.0.0.0/0:443` is not production-approved without a documented exception
and compensating control
- short-lived workload identity and least-privilege secret access
- no secret value in Git, logs, State Hub, chat, or parent-shell output
- automated revocation and negative-access tests
## Rollback And Fallback
Rollback order is:
1. previous verified Knative revision
2. keep the verified revision warm by setting a temporary minimum scale
3. declare the service unavailable
A direct `rail-kubernetes` deployment is an exceptional, time-bounded fallback.
It requires an explicit exception record, the same security controls, an owner,
and an expiry. It is not a parallel steady-state production path.
## Verification
Before production approval, automated evidence must cover:
- authenticated activation from scale zero
- rejected unauthenticated and wrong-tenant requests
- bounded cold start and timeout behavior
- idempotent retry behavior
- OpenBao positive and negative access
- Qonto-only egress enforcement
- audit delivery
- revision rollback
- credential revocation
- dependency-failure behavior
The implementation path should progress from attended proof to agent-executed
conformance and finally to scheduled functional automation.

View file

@ -0,0 +1,143 @@
# Rail Composition Contract
Date: 2026-07-26
Status: Adopted for the second implementation wave
## Purpose
Define how a specialized Railiance execution rail composes with the default
`rail-kubernetes` contract without duplicating it.
Railiance platform workloads use `rail-kubernetes` by default. A specialized
rail is justified only when a workload needs materially different execution
semantics and those semantics cannot be expressed safely as a small workload
profile.
## Rail Kinds
Rails have one of two composition kinds:
- `base`: owns a complete workload execution contract for a substrate class
- `derived`: inherits a versioned base-rail contract and owns only its
specialization
`rail-kubernetes` is the default base rail.
`rail-knative` is a derived rail:
```text
Kubernetes substrate profile
-> rail-kubernetes common workload contract
-> rail-knative activation and revision specialization
-> rapp-qonto workload binding
```
Knative installation remains an S2 cluster capability. The derived rail owns
how Railiance workloads use that installed capability.
## Required Declaration Fields
Every rail declaration must publish:
- `contract_version`
- `composition_kind`
- `ownership_repo`
- `execution_architecture`
- `required_substrate_capabilities`
- `supported_rollout_modes`
- `readiness_state`
A derived rail must additionally publish:
- `base_rail`
- `base_rail_contract`
- `inherited_semantics`
- `overridden_semantics`
- `compatibility_constraints`
## Inheritance Rule
A derived rail inherits, rather than copies:
- workload identity and ownership metadata
- common criticality and approval semantics
- health, evidence, promotion, and rollback vocabulary
- common dependency and secret-reference representation
- common audit and conformance requirements
A derived rail may override only semantics intrinsic to its execution model.
For `rail-knative`, those are:
- revisions
- request activation and buffering
- scale-to-zero and minimum scale
- concurrency and autoscaling
- traffic splitting between revisions
- cold-start readiness and timeout behavior
- Knative-specific rollback
## Non-Goals For `rail-knative`
`rail-knative` must not own:
- Kubernetes or k3s bootstrap
- Knative operator installation or cluster-scoped lifecycle
- generic namespace, RBAC, ingress-controller, certificate, storage, or
observability ownership
- Qonto-specific manifests, policies, secret paths, or health checks
- a fork of the generic Railiance promotion vocabulary
## Rail-Neutral Workload Contract
Managed workload declarations have a common section and one or more rail
bindings.
The common section owns:
- workload and ownership identity
- criticality and data classification
- dependencies
- workload identity and secret references
- health, smoke, audit, recovery, and approval requirements
- reliability objectives
Each rail binding owns:
- rail and contract version constraint
- rail-specific deployment artifacts
- scaling, routing, rollout, and rollback parameters
- required substrate capabilities
This makes Kubernetes the default binding while allowing a workload such as
Qonto to add a justified Knative binding without changing domain ownership.
## Compatibility And Readiness
Declarations distinguish:
- `declared`: source-controlled contract exists
- `installed`: required runtime components are present
- `verified`: conformance and smoke evidence passes
- `production-approved`: criticality-specific admission gates pass
- `deprecated`: no new bindings are accepted
Fabric relations describe topology, not readiness. A `hosts_rail` or
`binds_rapp` edge must carry or resolve a readiness state before automation
may treat it as deployable.
## Automation Requirement
All deterministic checks should be function-executable and idempotent:
- schema validation
- base-rail compatibility resolution
- substrate-capability matching
- binding and ownership integrity
- readiness evidence freshness
- drift detection
Human interaction is reserved for policy acceptance, exceptional risk, or
authority that cannot safely be delegated. Repeated evidence collection,
credential routing, reconciliation, and deployment verification should move
from human operation to agentic interaction and then to functional automation
as the contract stabilizes.

View file

@ -0,0 +1,79 @@
# Reef Production Readiness Contract
Date: 2026-07-26
Status: Adopted for the second implementation wave
## Purpose
Prevent a topology declaration from being mistaken for permission to run a
critical workload.
`hosts_rail` and `binds_rapp` describe intended composition. Production use
requires explicit readiness evidence.
## Admission States
Every hosted rail and bound `rapp` uses:
- `declared`
- `installed`
- `verified`
- `production-approved`
- `deprecated`
Promotion is monotonic only while its evidence remains current. Failed or
expired evidence returns the binding to the last proven state.
## Required Reef Evidence
Before a rail becomes `verified`, the reef must provide machine-readable
evidence for:
- substrate and Kubernetes version compatibility
- control-plane and workload capacity with documented headroom
- ingress, DNS, and certificate path
- storage and stateful-workload constraints
- workload identity and approved secret-delivery path
- network isolation and egress enforcement
- logs, metrics, traces, alerting, and audit delivery
- backup, restore, and rollback path
- upgrade and maintenance ownership
- failure-domain and recovery assumptions
## Critical Workload Gate
Before a critical, internet-facing, or high-value-credential workload becomes
`production-approved`, its binding must additionally record:
- threat-model reference
- availability, cold-start, and recovery objectives
- identity, secret revocation, and audit evidence
- negative authorization and network tests
- rollback and temporary-fallback rules
- accepted residual risks and their owner
The single-server and shared-control-plane risks of `reef-railiance` must be
explicitly accepted or mitigated for `rapp-qonto`; the reef name or `high`
criticality label is not evidence by itself.
## Mixed-Rail Rule
`reef-railiance` may host `rail-kubernetes` and `rail-knative` during the
second wave, while `rail-kubernetes` remains primary.
Reassess or split the reef when any of these triggers occurs:
- incompatible maintenance or upgrade windows
- inability to meet a critical workload recovery objective
- control-plane or workload resource contention
- materially different network or tenant-isolation requirements
- independent scaling or availability requirements
- failure in one rail cannot be contained from the other
- premium-security or regulatory policy requires a separate boundary
## Automation Requirement
Readiness evidence should be produced by idempotent probes and stored as
source-linked, timestamped records. Agents may execute and reconcile the
probes. Human approval should consume the evidence only where policy requires
explicit risk acceptance; it should not be used as a substitute for tests.

View file

@ -31,6 +31,11 @@ For the current phase of Railiance:
This means the repo model is intentionally ahead of the repo count.
Rails may compose. `rail-kubernetes` is the default base rail, while
Kubernetes-hosted execution specializations such as `rail-knative` are derived
rails with an explicit, versioned base-rail dependency. A derived rail owns
only the semantics it changes; it does not fork the common workload lifecycle.
## The Four Repo Families
| Prefix | Axis | Unit | Primary question answered |
@ -90,6 +95,10 @@ A rail owns the execution semantics for workloads on that architecture:
A rail is not the workload itself and not the substrate it runs on.
A rail declaration identifies whether it is a `base` or `derived` rail. A
derived rail names its base contract, inherited semantics, overrides,
compatibility constraints, and readiness state.
In the current Railiance model, `rail-kubernetes` is the default base rail.
Other rails should be introduced only when their runtime semantics justify a
distinct lifecycle, contract, or operator model.
@ -187,6 +196,10 @@ This separation reduces confusion between:
- workload identity
- deployment location
Topology and readiness are also separate. A reef may declare that it hosts a
rail or binds a `rapp` without that combination yet being installed, verified,
or production-approved.
## Creation Rules
Use the following default rules.