Repository navigation
fix(conformance): the delegation-lifetime case proves the lifetime without racing the clock - #65
Merged
antoinetoussaint-byte merged 1 commit intoOct 30, 2026
Conversation
…thout racing the clock A host carries a delegation's end in whole seconds and signs the issued root until that second, so a one-second delegation was issuable for anywhere between a few milliseconds and one second. The case asked for one and issued at once, and failed whenever the end landed before the issue. The case now asks for ten seconds, checks the carried end lies within the lifetime of the host's own now (issued_at of the first issue), and waits from that carried end on the host's clock before asserting the host refuses to issue and reads the delegation as not standing. Each lifetime in the loop is also checked to end no later than asked. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The two ejections
module-saas-starter's required check Host interface conformance (authority main) failed twice today on merge-group runs, with green PR runs on the same heads:
conformance.go:950: a standing one-second delegation does not issue: rpc error: code = Unauthenticated desc = work context: invalid: parent session expired at 2026-10-30T15:59:19Z; it can open no further sessionparent session expired at 2026-10-30T21:49:12Z(subtest took 0.18 s)The race
The case asked for a one-second delegation and issued from it at once. The shared core (
authority-coredelegation.go) starts the root untild.ExpiresAt, and core'sworkcontextderive reads the parent's end astime.Unix(expires_at_unix, 0), which is whole seconds. A delegation asked athh:mm:11.85for 1 s ends at12.85but is signed to end at12, leaving 0.15 s. So a one-second delegation could be issued for anywhere from a few milliseconds to one second. Whenever Delegate and Issue straddled that truncated second, the issue was refused. This is a whole-second race in the case, not a host bug. Runner load only makes it more likely.The fix
Only the case changes, in
libraries/conformance/go/conformance.go:issued_at_unixof the first issue, thensleep(at + 1 − now) + 250 ms. That is past the host's precise end, whatever offset the suite's clock has.[now + 5, now + 10]of the host's now: within the lifetime asked and not much sooner.issued_at + ttl. A host may clamp a lifetime shorter, never longer.What stays proven
Mutation runs against the local authority (core edited temporarily, not committed). Each one fails the case:
a delegation asked for 60 s ends at 0… ends at …, past the host's now … plus its lifetimeits module reads an expired delegation as standingUnchanged: an issued capability never outlives its delegation, a negative lifetime is InvalidArgument, no lifetime carries no end, the module reads the same end, and after the end the host refuses to issue (PermissionDenied) and reads the delegation as not standing.
Evidence
go vet ./...inlibraries/conformance/go: clean.TestTheLocalAuthorityPassesTheSuiteEveryImplementationMustPass: full suite ok (43.5 s).-count=20: 20/20 PASS (11.25 s each, 225 s total).a75fae35), with-modfilereplacing only the conformance library with this branch and nothing in that checkout changed: fullTestAccountsPassesTheHostInterfaceConformanceSuiteok (72 s, 294 PASS lines). The case with-count=20: 20/20 PASS (11.30 s each).Cost: the case now waits about 11 s instead of 1.5 s.
🤖 Generated with Claude Code