docs: narrow qonto blocker, record key-cape lane ownership

key-cape corrected two blockers that had stopped being true after our
2026-08-28 source-read:

- rapp-qonto-keycape-client: `keycape service-token` (2026-09-05) is the
  native exchange the blocker recorded as absent, and `keycape verify-client`
  (2026-09-08) is rotation step 3 as one command. Narrowed to steps 1-2 --
  successor generation and the CAS write -- rather than cleared, as they
  asked. rotation.automatable -> false so a future executable driver is not
  told a lane with no admitted custody transport is drivable; the per-step
  truth moves into the steps.
- key-cape-oidc-login: ownership ACCEPTED by key-cape, so verified moves from
  asked-and-waiting to owner-confirmed. Lane stays interim -- acceptance
  covers the identity half, while the fetch_command yields an OpenBao token
  whose mount, role mapping and enforcement are not key-cape's.

Two tests pinned `key-cape-oidc-login` to sitting `asked-and-waiting`, so
answering the question broke them -- they failed on good news. Both now
assert the property instead: an unverified blocker is stale regardless of
date, over whatever lanes are in that state.

Verifying the routing answer against our own front door turned up a defect:
`warden plan` returns `autonomous` for a custody *write* and answers it with
read transports, because it has no read-versus-mutate intent. Recorded as
WARDEN-WP-0038 (proposed) -- the WP-0033-T06 shape, as a class this time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EPuTc18FjU5WFqoSEKH3C

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1276224@bnt-lap001
Assistant-Session: 426ec497-e1c4-4dd3-b417-dfce1ca1dbc3
This commit is contained in:
tegwick 2026-09-08 14:55:02 +02:00
parent 96dbb22aab
commit c1330049d9
5 changed files with 290 additions and 24 deletions

View file

@ -994,12 +994,31 @@ def test_asked_and_waiting_is_not_verification():
def test_stale_gaps_flags_unverified_even_when_the_date_is_today():
"""Property, not a named lane.
Originally pinned to `key-cape-oidc-login` sitting `asked-and-waiting`;
key-cape answered on 2026-09-08, so the fixture lane moved and the test
failed on someone else's good news rather than on a defect. The claim being
made is about the verification method, so assert that instead: any lane
whose blocker was never re-established is stale on the day it was reviewed.
"""
catalog = load_catalog(_repo_catalog())
stale = {e.id for e in catalog.stale_gaps(include_draft=True, today=date(2026, 8, 21))}
# Asked of key-cape on 2026-08-21 and unanswered -- zero days old, still stale.
assert "key-cape-oidc-login" in stale
# Confirmed by the owner the same day -- fresh.
assert "issue-core-ingestion-api-key" not in stale
today = date(2026, 9, 8)
stale = {e.id for e in catalog.stale_gaps(include_draft=True, today=today)}
unverified = [
e for e in catalog.gaps(include_draft=True)
if not e.effective_delegation.is_verified
]
for entry in unverified:
assert entry.id in stale, f"{entry.id} is unverified but not stale"
# A lane the owner confirmed today is fresh, so staleness is not vacuous.
fresh = [
e.id for e in catalog.gaps(include_draft=True)
if e.effective_delegation.is_verified
and e.effective_delegation.reviewed == today.isoformat()
]
assert fresh, "expected at least one owner-confirmed-today lane"
assert not (set(fresh) & stale)
def test_invalid_verification_method_rejected(tmp_path):
@ -1027,10 +1046,10 @@ def test_cli_route_gaps_fail_on_stale_exits_3(repo_catalog_env):
assert result.exit_code == 3
rows = json.loads(result.stdout)
assert any(r["stale"] for r in rows)
# An asked-and-waiting lane stays stale until it is verified, regardless of
# how many calendar days have elapsed since the request.
assert any(
r["stale"]
and r["verified"] == "asked-and-waiting"
for r in rows
)
# A lane whose blocker was never re-established stays stale regardless of
# how many calendar days have elapsed since it was reviewed. Asserted over
# the verification method rather than one named lane -- see
# test_stale_gaps_flags_unverified_even_when_the_date_is_today.
for row in rows:
if row["verified"] in ("asked-and-waiting", "unverified"):
assert row["stale"], f"{row['id']} is unverified but not stale"