key-cape/workplans/KEY-WP-0030-tenant-precondition-guard.md
tegwick 5f516a0fbb
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 44s
Make the static-registration precondition a checked condition
informed-decision asked for the caveat under which a registration-bound human
tenant is safe to be a condition of the capability rather than reasoning in a
message, so a future change to registration policy has to confront it. They were
right that it was only prose: the contract stated it, a separate test asserted
registration_endpoint is absent, and nothing connected the two -- so a session
adding dynamic registration would have seen a test about discovery metadata, not
a warning about relabelling users.

The test asserts both halves together: that a client-declared tenant is issued,
and that dynamic registration is not advertised. Whichever is removed first, the
failure points at the other. The message carries the reasoning rather than the
observation -- anyone able to register a client could relabel the users who log in
through it -- and names the two ways out.

Verified in both directions rather than assumed: advertising a
registration_endpoint fails it with the escalation message, and neutering
humanTenant fails it with the message saying to remove the guard along with the
capability it protects.

This is not a vote on the tenant question. It makes one option's precondition
checkable; if option 1 lands, the capability and this guard are removed together.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713576@bnt-lap001
Assistant-Session: 384c511d-9bce-4cb8-a676-2aef6c0c8df6
2026-09-09 23:23:48 +02:00

2.8 KiB

id type title domain repo status owner topic_slug created updated
KEY-WP-0030 workplan Make the static-registration precondition a checked condition infotech key-cape finished claude tenant-precondition-guard 2026-09-09 2026-09-09

informed-decision replied on KEY-WP-0013-T05 and asked for one thing that is ours to do: the caveat under which a registration-bound human tenant is safe should be "a condition of the capability, so a future change to registration policy has to confront it", not reasoning left in a message.

They are right that it was only prose. docs/tenant-claim-contract.md states it, and a separate test asserted registration_endpoint is absent — but nothing connected the two, so a future session adding dynamic registration would see a test about discovery metadata, not a warning about relabelling users.

Tie the exclusion to the capability it protects

id: KEY-WP-0030-T01
status: done
priority: medium

TestRegistrationBoundTenantRequiresStaticRegistration asserts both halves together: that a client-declared tenant is issued, and that dynamic client registration is not advertised. Whichever is removed first, the failure points at the other.

The failure message carries the reasoning rather than the observation. Adding dynamic registration while a registration may declare its users' tenant means anyone able to register a client can relabel the users who log in through it into a zone of their choosing; the message says that and names the two ways out, drop the capability or gate it to statically configured registrations.

Verified in both directions rather than assumed: advertising a registration_endpoint fails it with the escalation message, and neutering humanTenant fails it with the message saying to remove the guard along with the capability it protects.

This is deliberately not a vote on the tenant question. It makes the precondition of one option checkable; it does not choose between them, and if option 1 lands the capability and this guard are removed together.

What stays with the owners

id: KEY-WP-0030-T02
status: done
priority: medium

informed-decision prefers option 2 and explicitly declines to treat that as the answer, flagging it to gate-house on GH-DEC-2026-012 and naming approval-engine's stake. KeyCape leans the same way, which is a reason for more care rather than less: the code already implements option 2 (329e48f), so the doctrine question is being decided against a working implementation. That is worth saying out loud to everyone waiting on it, and was.

Their scope set [openid, approval:read, approval:approve] is confirmed and already published. client_id and callback follow at their T07, deliberately not before the tenant question resolves — registering a client that fails closed at first use is the failure this exchange existed to avoid.