Add reproducible S1 handoff workplan
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02994-7685-7940-bf34-3555b8256018
This commit is contained in:
parent
3734a1c3bc
commit
c8cb1c8edf
2 changed files with 243 additions and 0 deletions
|
|
@ -14,6 +14,7 @@
|
|||
| workplan | RAIL-HO-WP-0008 | finished | — | workplans/RAIL-HO-WP-0008-railiance01-resource-and-commercial-evidence.md |
|
||||
| workplan | RAIL-HO-WP-0009 | finished | — | workplans/RAIL-HO-WP-0009-firewall-declared-state-and-api-exposure.md |
|
||||
| workplan | RAIL-HO-WP-0010 | finished | — | workplans/RAIL-HO-WP-0010-new-reef-ports-need-a-grant.md |
|
||||
| workplan | RAIL-HO-WP-0011 | ready | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
| task | ADHOC-2026-08-22-T01 | done | — | workplans/ADHOC-2026-08-22.md |
|
||||
| task | ADHOC-2026-08-22-T02 | done | — | workplans/ADHOC-2026-08-22.md |
|
||||
| task | ADHOC-2026-08-22-T03 | done | — | workplans/ADHOC-2026-08-22.md |
|
||||
|
|
@ -40,3 +41,11 @@
|
|||
| task | RAIL-HO-WP-0009-T05 | done | — | workplans/RAIL-HO-WP-0009-firewall-declared-state-and-api-exposure.md |
|
||||
| task | RAIL-HO-WP-0009-T06 | done | — | workplans/RAIL-HO-WP-0009-firewall-declared-state-and-api-exposure.md |
|
||||
| task | RAIL-HO-WP-0010-T01 | done | — | workplans/RAIL-HO-WP-0010-new-reef-ports-need-a-grant.md |
|
||||
| task | RAIL-HO-WP-0011-T01 | todo | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
| task | RAIL-HO-WP-0011-T02 | todo | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
| task | RAIL-HO-WP-0011-T03 | todo | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
| task | RAIL-HO-WP-0011-T04 | todo | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
| task | RAIL-HO-WP-0011-T05 | todo | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
| task | RAIL-HO-WP-0011-T06 | todo | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
| task | RAIL-HO-WP-0011-T07 | todo | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
| task | RAIL-HO-WP-0011-T08 | todo | — | workplans/RAIL-HO-WP-0011-reproducible-s1-declaration-and-handoff.md |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,234 @@
|
|||
---
|
||||
id: RAIL-HO-WP-0011
|
||||
type: workplan
|
||||
title: "Make the S1 declaration reproducible and the handoff verifiably green"
|
||||
domain: financials
|
||||
repo: railiance-infra
|
||||
status: ready
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
created: "2026-08-23"
|
||||
updated: "2026-08-23"
|
||||
related:
|
||||
- RAIL-HO-WP-0002
|
||||
- RAIL-HO-WP-0009
|
||||
---
|
||||
|
||||
# RAIL-HO-WP-0011 — reproducible S1 declaration and handoff
|
||||
|
||||
## Goal
|
||||
|
||||
Close the highest-leverage gaps identified in
|
||||
`history/2026-08-23-scope-against-intent.md`: distinguish adopted resources
|
||||
from provider-managed resources, make the host baseline contract executable,
|
||||
produce a green per-host handoff gate, and make every declared secret input
|
||||
fail closed. Then add the evidence and rotation mechanics needed for an
|
||||
auditable provisioning path.
|
||||
|
||||
This workplan improves the source and validation path. It does **not** authorize
|
||||
a Terraform apply or destroy, a live firewall change, a credential rotation,
|
||||
or any other live-host mutation. Those actions require their normal reviewed
|
||||
plan and operator approval.
|
||||
|
||||
## Delivery Order
|
||||
|
||||
The critical path is T01 → T02 and T03 → T04 → T05. T06 can proceed
|
||||
independently. T07 depends on T02 and T05. T08 depends on T06.
|
||||
|
||||
## T01 — Define and validate adopted-versus-managed inventory
|
||||
|
||||
```task
|
||||
id: RAIL-HO-WP-0011-T01
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Define one explicit inventory contract for common host identity and
|
||||
provider-specific lifecycle fields. At minimum it must distinguish:
|
||||
|
||||
- provider (`hosteurope`, `hetzner`, or a documented extension value)
|
||||
- lifecycle mode (`adopted` versus provider-managed)
|
||||
- connection identity used by Ansible
|
||||
- provider-specific provisioning fields used by Terraform
|
||||
|
||||
Add a side-effect-free validator and fixtures for the two current adopted Host
|
||||
Europe hosts, a valid provisionable Hetzner host, and invalid mixed records.
|
||||
Preserve stable host names and connection behavior.
|
||||
|
||||
**Done when:** the current inventory validates as adopted Host Europe
|
||||
resources, a complete Hetzner fixture validates, incomplete or contradictory
|
||||
records fail with actionable errors, and no provider command is needed to run
|
||||
the validation.
|
||||
|
||||
## T02 — Make Hetzner planning select only managed Hetzner resources
|
||||
|
||||
```task
|
||||
id: RAIL-HO-WP-0011-T02
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Update the Terraform and helper path to consume the T01 contract and exclude
|
||||
adopted or non-Hetzner records. Audit any existing Terraform state before
|
||||
changing resource addresses or selection logic. Correct provisioning docs and
|
||||
Make targets so they name the provider-token source actually used.
|
||||
|
||||
Add an isolated plan test or equivalent deterministic validation that proves
|
||||
the current Host Europe records cannot become Hetzner creates or destroys.
|
||||
|
||||
**Done when:** current adopted records pass through the inventory-to-Terraform
|
||||
boundary without missing-field errors or managed resources, a provisionable
|
||||
Hetzner fixture produces the expected resource shape, and a reviewed plan shows
|
||||
no unintended create, replace, or destroy. Do not apply the plan in this task.
|
||||
|
||||
## T03 — Model host-specific baseline profiles and reconcile declared state
|
||||
|
||||
```task
|
||||
id: RAIL-HO-WP-0011-T03
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Replace the permanent `CoulombCore` expected failure with an explicit baseline
|
||||
profile or declared exception. Reconcile `spec/server-baseline.yaml`, Ansible,
|
||||
and the intended live posture for packages, users/sudo, SSH, firewall,
|
||||
fail2ban, SOPS tooling, swap, and resource limits.
|
||||
|
||||
Exceptions must say which control replaces the default, why it is accepted,
|
||||
and who owns removing it. An unmanaged control must not silently count as
|
||||
verified.
|
||||
|
||||
**Done when:** both current hosts resolve to complete declared profiles, the
|
||||
UFW-managed and externally-filtered postures have explicit assertions, and the
|
||||
spec no longer claims properties that convergence neither establishes nor
|
||||
deliberately delegates.
|
||||
|
||||
## T04 — Add automated baseline contract-parity tests
|
||||
|
||||
```task
|
||||
id: RAIL-HO-WP-0011-T04
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Add repository tests that fail when the human baseline, convergence roles, and
|
||||
Goss assertions diverge on governed properties. Prefer a single
|
||||
machine-readable model or generated artifacts where that reduces duplicated
|
||||
declarations; otherwise implement explicit parity checks with clear failure
|
||||
messages.
|
||||
|
||||
Cover the profiles introduced by T03 and run the tests in Forgejo CI without
|
||||
requiring host access or secrets.
|
||||
|
||||
**Done when:** a deliberate mismatch in a governed package, SSH setting,
|
||||
firewall rule, service, or user property fails locally and in CI, while all
|
||||
declared profiles pass from a clean checkout.
|
||||
|
||||
## T05 — Provide a fresh green S1 handoff gate
|
||||
|
||||
```task
|
||||
id: RAIL-HO-WP-0011-T05
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Provide one operator-facing, non-ambiguous command that checks inventory and
|
||||
contract validity, runs the applicable profile for every selected host,
|
||||
collects evidence, and exits non-zero if any required control is failed,
|
||||
unknown, stale, or skipped without an accepted declaration.
|
||||
|
||||
The receipt must identify the source revision, inventory digest, host/profile,
|
||||
check time, and result without including credentials or sensitive host output.
|
||||
Define freshness and the exact interface S2 can consume.
|
||||
|
||||
**Done when:** both current hosts can return green against their declared
|
||||
profiles in an attended verification run, a failing or stale host makes the
|
||||
aggregate gate fail, and the evidence is sufficient for an S2 handoff without
|
||||
interpreting an expected-red exception.
|
||||
|
||||
## T06 — Repair and enforce the secret-source contract
|
||||
|
||||
```task
|
||||
id: RAIL-HO-WP-0011-T06
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Remove, relocate, or SOPS-encrypt the plaintext
|
||||
`inventory/group_vars/secrets.sops.yaml` placeholder. Inventory every path that
|
||||
documentation or automation describes as secret-bearing, extend the
|
||||
pre-commit/CI check to those paths, and make playbooks fail clearly when an
|
||||
expected encrypted input is absent or malformed.
|
||||
|
||||
Align README, provisioning, convergence, Make targets, and playbooks on the
|
||||
actual Hetzner token source and on the fact that the host role installs tools
|
||||
but does not distribute an age private key.
|
||||
|
||||
**Done when:** plaintext fixtures at any declared secret path are rejected,
|
||||
the committed tree contains no file falsely presented as encrypted input, and
|
||||
the documented controller and host secret flows match the executable paths.
|
||||
|
||||
## T07 — Emit non-secret provisioning and handoff receipts
|
||||
|
||||
```task
|
||||
id: RAIL-HO-WP-0011-T07
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
Define a versioned receipt linking inventory and source revisions, provider
|
||||
plan/apply identity, provider resource ID, cloud-init completion, Ansible
|
||||
convergence, and the T05 handoff result. Separate plan, apply, and verification
|
||||
events so a plan receipt cannot be mistaken for proof of a live change.
|
||||
|
||||
Exercise the format with a dry-run or synthetic fixture first. A live provider
|
||||
apply remains separately approved and is not required merely to prove schema
|
||||
and redaction behavior.
|
||||
|
||||
**Done when:** the receipt schema validates, sensitive fields and provider
|
||||
tokens cannot be serialized, incomplete phases fail closed, and a synthetic
|
||||
end-to-end example is consumable without prose interpretation.
|
||||
|
||||
## T08 — Automate bounded SOPS recipient rotation
|
||||
|
||||
```task
|
||||
id: RAIL-HO-WP-0011-T08
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
Build a dry-run-first rotation workflow for the repository's SOPS files. It
|
||||
must inventory affected files and recipients, detect recipient drift, require a
|
||||
reviewed change set, verify decryption through an approved non-printing check,
|
||||
and emit a metadata-only receipt. Never print a decrypted value or private age
|
||||
key.
|
||||
|
||||
Live recipient removal or credential replacement requires explicit operator
|
||||
approval after the dry run. Scheduling may be proposed only after rollback and
|
||||
recovery-key custody are documented.
|
||||
|
||||
**Done when:** CI can detect recipient drift without secrets, an attended dry
|
||||
run identifies the exact files and before/after recipient set, rollback is
|
||||
documented, and a sample receipt proves verification without exposing values.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] Adopted Host Europe records and provider-managed Hetzner records cannot
|
||||
be confused by validation or Terraform selection.
|
||||
- [ ] The declared baseline, Ansible convergence, and Goss verification have an
|
||||
automated parity contract.
|
||||
- [ ] Every current host can produce a fresh green result against an explicit
|
||||
profile, and the aggregate handoff fails closed.
|
||||
- [ ] Every documented secret-bearing path is encrypted or deliberately absent
|
||||
and protected by local and CI checks.
|
||||
- [ ] Provisioning/handoff and rotation paths emit metadata-only receipts with
|
||||
reviewed redaction behavior.
|
||||
- [ ] No live provider, firewall, credential, or host mutation occurs without a
|
||||
separately reviewed plan and the required operator approval.
|
||||
|
||||
## Completion Evidence
|
||||
|
||||
Record the final inventory schema and examples, Terraform plan safety result,
|
||||
baseline parity tests, CI run, attended all-host gate receipt, secret-path
|
||||
negative tests, provisioning receipt fixture, and SOPS rotation dry-run receipt
|
||||
here before marking the workplan finished.
|
||||
Loading…
Add table
Add a link
Reference in a new issue