docs(pm): R-TLS-02 needs the owner — the drafted spec amendment, recovered and restated

The R-TLS-02 analysis and its drafted spec amendment were written on
feat/coverage-debt-paydown (b37defe, 2026-09-07) and lived ONLY in that branch's copy of
DECISIONS-LOG.md. That branch's tree is ~107 commits behind main and must never be merged,
so the amendment went out of view with it — the second time this decision has been raised
and lost. Recovered, re-checked against today's main, and written where it cannot vanish
with a branch.

THE SUBSTANCE IS UNCHANGED. R-TLS-02 says certificates MUST be automatically "issued,
renewed, and revoked without manual steps". Issuance and renewal hold. Revocation is not
implemented and is not implementable with the stack ADR-0006 selects: cert-manager has no
revoke-on-delete, no Certificate field requesting revocation, and no controller that calls
ACME revokeCert, and neither ADR-0006 nor docs/08 specifies a mechanism.
enableCertificateOwnerRef is NOT the remedy — it garbage-collects the Secret, which is
cleanup, not revocation — and it is a global controller flag that would drop the Gateway's
wildcard-home-tls Secret on any future Certificate rename/prune, so it needs its own risk
assessment rather than a side effect of a test task. Still not set.

WHAT CHANGED SINCE THE FIRST ESCALATION, and why it now matters more: R-TLS-02 is no
longer a COVERAGE gap (l0-static/tls-lifecycle-automated + l2-behavioral/
cert-lifecycle-automated both carry the label and main counts it covered), and the L0 check
is honest about the boundary in its own verdict line ("'revoked' is NOT proven at any
layer"). But the L2 test deletes a Certificate and requires its Secret to disappear, and
its failure message says "set enableCertificateOwnerRef: true ... (owner decision — WS-TEST
does not weaken the assertion instead)". That assertion is written to FAIL on a live run
until the owner decides. The decision is now arriving as a red test rather than as a
question, which is exactly how it gets weakened by whoever meets it next.

Two options are recorded verbatim for the architect, in the drafted preference order:
amend the requirement so revocation is an explicitly manual, documented break-glass action
(which also makes enableCertificateOwnerRef a CONSEQUENCE of the requirement), or keep the
text and record a reviewed DOCUMENTED_GAPS entry naming the clause, the reason and the
removal condition.

NOT APPLIED, and not appliable by an agent: the spec repo is read-only under R-TEST-06.
This is a request for a human decision, stated plainly as one.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
jakman85andClaude Opus 5 committed 2026-09-13 16:28:21 -05:00
1 parent a76ae3bdfa
commit aff80d1d7a
1 file changed
+82
+82
View File
@@ -3042,3 +3042,85 @@ shared etcd/Longhorn device plus the I/O-pressure alert that missed the prod-1 o
Branch pruning was deliberately NOT done: four agent branches read as "merged, no unique commits"
only because their agents had not committed yet, and deleting those would have destroyed live work.
## R-TLS-02 — the "revoked" clause still needs the OWNER's decision (recovered 2026-09-13)
**This is a decision only the repo owner/architect can make. It has now been escalated twice and
lost twice, which is why it is written into this log rather than into another branch's commit
message.** The analysis was first drafted on `feat/coverage-debt-paydown` (`b37defe`, 2026-09-07),
a branch whose tree is ~107 commits behind main and which must never be merged; the drafted
amendment lived only in that branch's copy of this file, so it disappeared from view the moment the
branch went stale. Recovered here, re-checked against today's main, and restated unchanged in
substance.
**R-TLS-02, verbatim (spec `docs/00-vision-and-scope.md`):** *"Certificates MUST be automatically
**issued, renewed, and revoked** without manual steps."*
Three verbs. Two hold; the third does not, and cannot with the stack ADR-0006 selects:
- **Issued — satisfied.** Both ClusterIssuers are declarative (ACME DNS-01, Cloudflare token
referenced by name from SOPS), the wildcard Certificate plus its apex SAN make onboarding
certificate-free, and the active issuer is chosen per environment by `${ACME_CLUSTER_ISSUER}`.
- **Renewed — satisfied, and unhobbled.** cert-manager renews at ~2/3 of lifetime with no operator
action; nothing in the repo sets a `duration`/`renewBefore` that would defeat it, and
`CertificateExpiringSoon` / `CertificateExpiryImminent` / `CertificateNotReady` fire if renewal
silently stops.
- **Revoked — NOT implemented, and not implementable here.** cert-manager has no automatic ACME
revocation: no revoke-on-delete, no `Certificate` field that requests revocation, no controller
that calls ACME `revokeCert`. Deleting a `Certificate` stops renewal; it does not revoke, and the
issued certificate stays valid at the CA until it expires. Neither ADR-0006 nor `docs/08`
specifies a mechanism — `docs/08`'s own "Renewal & revocation" section describes replacement
issuance, which is rotation.
**`enableCertificateOwnerRef` is NOT the remedy, and is still not set.** That cert-manager
controller flag makes a `Certificate` own its `Secret`, so deleting the Certificate
garbage-collects the key material. That is *cleanup*, not revocation. It does remove one real
manual step (today a deleted Certificate leaves an orphaned TLS Secret and private key to be
deleted by hand), so it is defensible on its own merits — but it is a GLOBAL controller flag, and
any future rename or prune that deletes and recreates a `Certificate` would take the Gateway's
`wildcard-home-tls` Secret with it, dropping TLS on every service until reissuance, against Let's
Encrypt rate limits, on two clusters. It deserves its own risk assessment, not a side effect of a
coverage or test task.
**WHAT HAS CHANGED SINCE THE FIRST ESCALATION.** R-TLS-02 is no longer a COVERAGE gap — main
carries `l0-static/tls-lifecycle-automated` and `l2-behavioral/cert-lifecycle-automated`, and the
coverage report counts it covered. The honesty was kept where it matters: the L0 check's own verdict
line ends *"R-TLS-02 'without manual steps' clause only — issued/renewed/revoked are RUNTIME verbs
(see l2-behavioral/cert-lifecycle-automated; 'revoked' is NOT proven at any layer)"*. But the
decision is now also LOAD-BEARING on the gate in a second way: the L2 test deletes a Certificate and
requires its Secret to disappear, and on failure prints *"set enableCertificateOwnerRef: true in
platform/cert-manager values (owner decision — WS-TEST does not weaken the assertion instead)"*. So
that test is written to FAIL on any live cluster run until the owner decides. Nobody should weaken
it to make a run green; that is the decision below, arriving as a red test instead of as a question.
**THE TWO OPTIONS, in the drafted preference order. The spec repo is READ-ONLY to every agent
(R-TEST-06), so neither has been applied — this is a request for a human decision.**
1. **PREFERRED — amend R-TLS-02 to the property that is achievable and actually protective**, and
move revocation to an explicitly manual, documented break-glass procedure:
> **R-TLS-02** — Certificates MUST be automatically **issued and renewed** without manual steps,
> and decommissioning a service MUST NOT leave its key material behind. Certificate
> **revocation** is an exceptional, operator-initiated action (suspected key compromise); it is
> NOT automated, and MUST have a documented procedure. Rationale: the ACME / Let's Encrypt model
> relies on SHORT certificate lifetimes plus automated rotation rather than on revocation — Let's
> Encrypt retired OCSP in 2025 and cert-manager implements no automatic revocation — so an
> "auto-revoked" requirement cannot be met by the stack ADR-0006 selects, and could only be met
> by bespoke revocation automation the threat model does not justify.
Under this wording R-TLS-02 becomes fully testable: issuance and renewal are already asserted
statically, and "no key material left behind" is exactly what `enableCertificateOwnerRef`
implements — which makes that flag a *consequence of the requirement*, decided on its own risk
assessment, rather than a fudge to turn a gate green.
2. **Keep R-TLS-02 as written and accept it as permanently partially satisfied**, with a reviewed
`DOCUMENTED_GAPS` entry in `conformance/run.sh` naming the revocation clause, the reason (no ACME
revocation exists in cert-manager) and the removal condition (cert-manager ships revocation, or
the requirement is amended). Cheaper, and records a requirement the system does not meet.
**Until the owner picks one, the state is: R-TLS-02 counted as covered, its third clause
unimplemented and labelled as such in the test's own output, and the L2 withdrawal assertion
standing as a deliberate red.** Writing a test tagged R-TLS-02 that silently verifies only issuance
and renewal would report the requirement as met while a third of its normative text is
unimplemented — which is the one thing this harness exists to prevent. The choice is the
architect's, not an agent's.