Newer
Older
openstack-caracal-dc-dc / docs / changelog-20260730-docfix205-d117-annotation.md

Changelog 2026-07-30 -- DOCFIX-205: the D-117 annotation half, and A12 becomes an assertion

Session changelog (GA-R2/D1: ONE per session). Branch dc-dc-stage5-preconditions. Status claims live ONLY in docs/CURRENT-STATE.md (GA-R1).

Trigger. The operator asked to rule on queued question Q1 (docs/audit/queued-findings-20260730.txt): whether substrate vr1-dc1 is dc1 by TOKEN or dc2 by POSITION for DNS/certificate identity. Measured before presenting options, per the standing discipline ("a finding is an observation, not a conclusion"). The question was WITHDRAWN, not ruled: its premise had been retired by D-117 on 2026-07-13. What follows is the repair, approved by the operator as a batch ("All four + code fixes").

No new D-number (GA-R3). Recording a supersession that D-117 already ruled is not architectural consequence beyond the stage; the runbook and script fixes are OPS. Doubt resolves DOWN. Next-free UNCHANGED: D 138 / DOCFIX 205 -> 206 after this / BUNDLEFIX 053.


1. D-106 annotated -- the causal surface

docs/design-decisions.md, D-106. Added an ANNOTATION block after the Status line recording that the dc1.vr1 / dc2.vr1 zone labels in the Decision block are SUPERSEDED by D-117, with the read-through mapping (dc1.vr1 -> dc0.vr1, dc2.vr1 -> dc1.vr1), the unchanged D-008 shape, why D-119's single vr1-dc0 token is NOT adopted for DNS, and the selector-is-not-a-label warning with the derivation. The Decision block itself is UNTOUCHED, per D-117's own ruled treatment ("ADOPTED decision text: ANNOTATE in place, do NOT rewrite").

Evidence. D-117 Status line: "Supersedes ... and the D-106 dc1/dc2 zone labels." D-117 amendment: "The repo's dc1/dc2 labels are retired in favour of dc0/dc1."

Revert. Delete the **ANNOTATION 2026-07-30 (DOCFIX-205) -- THE ZONE LABELS BELOW ARE SUPERSEDED BY D-117.** block through the line ending "the mechanism that hid it."

2. D-101, D-111, D-115 annotated -- the other three D-117 owed

Same ruled treatment; each scoped to what that entry actually carries.

  • D-101 -- the hardest, because it carries BOTH namespaces. Annotation reads the entry BY DATE: the 2026-07-09 text uses DC1/DC2 for VR1's first/second DC (and DC0 for VR0's), while amendments dated 2026-07-14+ already use vr1-dc0/vr1-dc1 correctly. This is D-117 TRAP 2 where it bites hardest -- the token dc1 means DIFFERENT datacenters in the two halves of one entry. Also restates that the ULA hextet tracks the GUA site nibble, not the DC index, and must not be "fixed".
  • D-111 -- read dc1 -> vr1-dc0, dc2 -> vr1-dc1; the ULA indexing is unchanged in substance. Additionally flags that its "Out of scope" line -- which defers the G5 site rename to "its own D-number when executed" -- is now HISTORICAL: that ruling IS D-117 and it went the other way (apex not renamed). A future session must not execute the rename it describes.
  • D-115 -- read DC1 -> vr1-dc0, DC2 -> vr1-dc1, but NOT the "VR0 DC1" table row (a different region, correctly labelled). Records that the OFFICE is explicitly out of D-117's scope and keeps its number, quoting the operator refinement.

Revert. Delete the three **ANNOTATION 2026-07-30 (DOCFIX-205) ...** blocks in D-101, D-111 and D-115.

3. D-117's Status line corrected by measurement (GA-R1/C2)

It read "FULLY EXECUTED BY D-119 (2026-07-14) -- the 'PARTIALLY EXECUTED' caveat below is DISCHARGED". That overstated what D-119 did, and the overstatement is the mechanism by which the un-done half survived 17 days. D-119 scopes its own discharge to the SELECTOR half: "executes D-117's own amendment (region-qualify the shell SELECTORS) across the three surfaces D-117 never touched" -- lib-net.sh, lib-hosts.sh, opentofu/. It never claimed, and never performed, the "ADOPTED decision text -- ANNOTATE in place" row of D-117's treatment table.

Status now reads "EXECUTED IN TWO HALVES", with an EXECUTION CORRECTION block recording the measurement (zero of four annotated), the concrete consequence (a Stage-5 session filed a retired question as a blocking ruling), and the standing lesson: a ruling's Status line is a CLAIM ABOUT EXECUTION, not evidence of it -- where a decision rules several treatments across surface kinds, a later decision discharging ONE does not discharge the rest, and no gate reads prose.

The **Status:** token still reads ADOPTED first, so ledger-scan (which keys on the LAST **Status:** line per block) is unaffected -- verified, scan output unchanged.

Revert. Restore the two-line Status line from git and delete the EXECUTION CORRECTION block.

4. runbooks/dc-dc-phase6-designate-cos-magnum.md -- an executable defect fixed

The defect. Step 3 built os-public-hostname as "keystone.omega.${DC}.vr1.cloud.neumatrix.local" while $DC is the D-119 region-qualified selector. Measured expansion: keystone.omega.vr1-dc0.vr1.cloud.neumatrix.local -- the region TWICE. The runbook's own variable line read DC=vr1-dc0|dc2, mixing both naming systems in one expression. This would have been baked into os-public-hostname and then into Vault-issued SANs at Stage 7, in a runbook phase-4 Step 4 delegates to "verbatim".

Root cause, stated generally: the D-119 SELECTOR token and the D-008 <dc> LABEL are different strings, and the runbook interpolated one into the other.

Fix. Step 0 now derives both labels from the selector and builds the zone once:

DC_REGION="${DC%%-*}"      # vr1-dc0 -> vr1   (D-008 <region>)
DC_DNS_LABEL="${DC#*-}"    # vr1-dc0 -> dc0   (D-008 <dc>, 0-indexed per D-117)
DC_ZONE="omega.${DC_DNS_LABEL}.${DC_REGION}.cloud.neumatrix.local"

All nine FQDN sites now use $DC_ZONE (Step 3 os-public-hostname, Step 6 zone + 2 recordsets, Step 7 neutron dns-domain, Step 9's getent/dig/curl). The variable line is corrected to DC=vr1-dc0|vr1-dc1. The D-106 blockquote at Step 1.3 is left VERBATIM (it quotes ratified text) with a following note that the quoted labels are superseded and must not be pasted.

Verified by execution, not by reading: the block was run for both sites and yields omega.dc0.vr1.cloud.neumatrix.local and omega.dc1.vr1.cloud.neumatrix.local.

Revert. git checkout <prev> -- runbooks/dc-dc-phase6-designate-cos-magnum.md.

5. scripts/octavia-pki.sh A12 -- refusal becomes assertion

A12 previously asserted only the REGION and then nrefused on the DC label, citing the now-dead premise. It now derives the full expected zone from the site token -- ${SITE%%-*} region, ${SITE#*-} DC label, never typed -- and asserts every DNS SAN falls inside it. Armed, a wrong zone FAILS; a cert with NO DNS SAN at all now also FAILS (previously the empty loop passed silently). Unarmed, it still reports INERT and passes, recording any mismatch as F9's reissue obligation.

nrefuse remains in use by seven other call sites; only A12's use was removed.

Revert. git checkout <prev> -- scripts/octavia-pki.sh.

6. tests/octavia-pki/run-tests.sh -- assertion REPLACED, not deleted

Per the standing rule ("when a test asserts a literal finding string, remediating the finding turns the harness red: REPLACE the assertion with the new invariant and say so, never delete it to go green"):

  • T20 re-pinned to the new message (is not in this DC's expected zone '...'), same rc=1.
  • T21 REPLACED -- was "armed + right region REFUSES on the unruled DC label" (rc=3); is now "armed + the D-117-correct zone PASSES" (rc=0). The comment records what it used to assert and why the premise died.
  • T21b NEW -- the capability the refusal never had: the OTHER DC's label in the RIGHT region FAILS. This is the cross-DC mix-up F1 proved possible on the PKI paths; region-only checking passed it.
  • T21c NEW -- vr1-dc1 derives its own zone, proving the expectation is per-DC and not a dc0 constant wearing a variable.

Harness 21/21 -> 23/23 PASS.

Revert. git checkout <prev> -- tests/octavia-pki/run-tests.sh.

7. Status surfaces corrected in the same commit (repo-lint L10 / GA-R1 C1)

  • docs/CURRENT-STATE.md -- the two paragraphs claiming a BLOCKING ruling-shaped gap are kept as history with a superseding block above them recording: the fork is closed by D-117; why it resurfaced; that "BLOCKING" was wrong as stated (A12 measures INERT and PASSES on both DCs live -- os-public-hostname is set in no deploy artifact); that A12 is now an assertion at 23/23; and that the F9 reissue obligation STANDS.
  • docs/session-ledger.md:274 -- the 2026-07-30 bookend line carrying the same wrong premise now carries a one-line WITHDRAWN correction pointing at CURRENT-STATE.

Revert. git checkout <prev> -- docs/CURRENT-STATE.md docs/session-ledger.md.


Verification

bash tests/octavia-pki/run-tests.sh     -> 23/23 PASS
bash scripts/repo-lint.sh              -> 0 fail, 1 warn (L1 legacy carve-out, 239 bytes,
                                          UNCHANGED -- new content is ASCII)
bash scripts/run-tests-all.sh          -> GAUNTLET: ALL GREEN (89 harnesses)
bash scripts/ledger-scan.sh            -> unchanged: 3 decisions, 21 SEC,
                                          D 138 / DOCFIX 205 / BUNDLEFIX 053

What this batch deliberately does NOT do

  • No cert reissue. Both live certs still carry dc0.vr0. F9's obligation stands and is now asserted rather than refused; reissue is a gated mint blocked by the D-137 fork-1 guard by design, and is not this batch's scope (hard rule 1).
  • No <cloud> label ruling. omega is D-008's <cloud> label carried unchanged by D-106; nothing here reopens it.
  • No change to D-008's shape. Collapsing <dc>.<region> into D-119's single token was considered and rejected on the reasoning recorded in the D-106 annotation; it would amend a ratified shape no ruling has touched.