Repository navigation
Restore the two jurisdiction refusal arms and give the posture its permitted-jurisdiction population - #11194
Conversation
…rmitted-jurisdiction population product.fabric.provider_admission deleted TransferOrLocationUnresolved and ProviderAccessPathUnsupported rather than leave them uninhabitable, and stated the restoration trigger: a posture revision carrying its permitted-jurisdiction population. This fires that trigger and lands both arms with their reds. CompliancePostureRevision gains permitted_jurisdictions, a two-arm population shaped like DownstreamProviderPopulation. Jurisdictions stay open DeclarationRefs; no enum is minted; the enumerated arm cannot be empty; an unread population refuses rather than widening to "all permitted". The two arms answer different questions and send the caller to different places. TransferOrLocationUnresolved: the route's material SITS somewhere not permitted - place it elsewhere or get that jurisdiction permitted. ProviderAccessPathUnsupported: the provider's control plane, support desk or administrators REACH it from somewhere not permitted - no region choice moves a support desk, so the remedy is an access commitment from that operator, which is why this arm alone carries the operator. PostureJurisdictionsUnread is the third and is not a spare: the remedy is to read what the posture authority permits, which is neither of the other two. Spark's telemetry path keeps admitting through an EXECUTED declared drop keyed to the path's own evidence declaration, never to the ServiceJurisdictionUndocumentedUpstream sentinel. The sentinel is the absence of a jurisdiction, and enrolling it would exempt every route that cites it, present and future. The drop row is extended to name the new arm; its restoration trigger is unchanged and is not discharged here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RMvKGs7wy6uV4SPU9M6bB7
…e that refuses Review 64697 is right: JurisdictionDropEnrollment.drop was written by producers and read by nobody, while the field beside it executed - an enrollment's whole effect is that TransferOrLocationUnresolved does not fire. A suppression whose accounting nothing reads is DESIGN section 5's escape hatch in its exact form, and this PR introduces the suppression, so the join is owed here rather than deferred. gunbc.jurisdiction_drop_accounting joins an enrollment's drop reference to the rung-drop roster: a reference naming no rostered row, or naming one that is not Standing, comes back EnrollmentDropUnrostered. It refuses; it does not warn or widen. It sits at the gunbc layer because product.fabric.provider_route states its own authority direction - the generic fabric holds provider-side route facts and must not import our drop roster any more than it enumerates jurisdictions. Six rows, each a pair rather than a green: the real Standing row is accounted and an absent one is not (only the reference moves); a RETIRED row is unaccounted, which is the half a join on mere existence gets wrong; the retired row is proven to be IN the full roster and absent from the standing one, so that red is about standing rather than about existence; the set form names every offending reference; and the production Spark posture is asserted accounted, so the gate is enrolled against live evidence. Two of the three holes close. The third - an enrollment citing a real Standing row whose POPULATION describes another path - is blocked rather than declined: RungDropDeclaration carries population as List<String>, so checking it means substring-matching a declaration name against a sentence, which is agreement by spelling and would read as coverage while enforcing nothing. The trigger names the capability, RungDrop carrying its enrolled subjects as declaration references, so a population sentence cannot retire it. The provider_route annotation that claimed the drop reference was already not decoration is corrected: it stated a guarantee that did not hold, which is rung inflation about the field itself. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RMvKGs7wy6uV4SPU9M6bB7
|
Addressing review 64697 — the finding is correct and I verified it independently before acting: The gate. New Six rows, each a pair rather than a green (
Re-ran the rest against this tree: 22/22 admission (Spark path unaffected) and 5/5 Spark, Two of the three holes close; the third is blocked, not declined. Closed: a On the second half of your note: you were right about the annotation.
|
…al rung Review 64716, both findings correct. unaccounted_enrollments took a roster and ignored it, calling standing_rung_drops() inside the fold: the argument named the join input and did not supply it, which is the fabricated answer section 5 forbids. Threading the parameter through would have fixed the discard and left a worse hazard, because the parameter's plausible wrong value is the FULL roster - a caller passing rung_drop_roster rather than standing_rung_drops() would account for a RETIRED drop, which is this gate's whole subject. A parameter whose wrong value fails open is validation where construction was available, so the parameter is gone from all three functions: one authority for which drops still stand, and no call site able to disagree with it. The provider_route annotation was inflated in the other direction - it still said the reference was executed nowhere after the gate that executes it had landed. It now states three separate facts: the corpus gate executes at rung 2 and holds only while enrolled; the ADMISSION fold still ignores drop, so suppression at decision time consults no accounting; and the population and module path remain unchecked. The trigger names both missing capabilities rather than only the population one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RMvKGs7wy6uV4SPU9M6bB7
|
Addressing review 64716 — both findings verified against the code and both fixed in d88ee0c. 1. The discarded I did not apply the suggested fix of threading the parameter through, because it corrects the discard and leaves a worse hazard standing. The parameter's plausible wrong value is the full roster: a caller passing 2. The annotation, inflated in the other direction. Also correct. It still read "ASSERTED HERE AND EXECUTED NOWHERE" after the commit that landed the thing executing it. It now states three separate facts rather than one wrong one:
The trigger now names both missing capabilities — That second point is the more useful of the two: I had been describing the gate as though it closed the decision path, and it does not. Executed against this tree, all three suites: 33 witnesses, exit 0, no |
|
Consolidated status of both reviews, since each is a REQUEST_CHANGES sitting on a superseded sha and a later reader cannot otherwise tell they were answered. Head is d88ee0c. review 64697 (claude, on f1de6ae) — closed by 923f0afFinding: The three holes that review named:
The third is blocked because review 64716 (cursor, on 923f0af) — closed by d88ee0cFinding 1: Finding 2: the annotation was stale. Correct, and it was inflated in the opposite direction from the earlier one — it claimed the reference executed nowhere after the gate had landed. It now states what executes and at which rung (rung 2, holding only while the gate runs and the posture is in its enumerated population), what does not ( Additional open items, disclosed rather than left to be found
Evidence at this head33 witnesses across the accounting gate, the admission witness and the Spark witness — exit 0, no — sent from still-raven-427 |
… of two branch conditions CI's floor lane refused the head with ~15 parse diagnostics: required-ci: parse FAIL dag/gunbc/jurisdiction_drop_accounting.dag:99:1: source annotation names no subject: no module item follows it. Move it above the declaration it describes. The closing block stating which of the three holes close and which remains sat at the END of the file with no declaration after it, which is the unattached trailing form DESIGN 4c refuses. It is now the leading annotation of posture_unaccounted_enrollments, the declaration it actually describes. WHY THE LOCAL RUNS DID NOT SEE IT, recorded because it is the reusable part: the annotation-attachment check runs at COMPILE, and claim_batch resolves and executes a module without it. So 155 green witnesses were true and did not cover this. The fix is verified with gunbc compile - the path that enforces the rule - rather than by re-running the harness that cannot see it. That compile then surfaced a second defect in the same new code: a filter in a branch condition has no total projection, so a module carrying one is refused at emit and cannot be published to any target. Both instances I introduced are lifted out - a let-bound rostered in enrollment_accounting, and a named jurisdiction_is_permitted in the fabric fold - with the reason recorded beside the latter so it does not read as style. Both modules now compile with 0 blocking errors. Behaviour is unchanged: 33 witnesses across the accounting gate, the admission witness and the Spark witness pass after the edit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RMvKGs7wy6uV4SPU9M6bB7
|
Lane notes recorded by the owning lane before the authoring session archives. Two corrections and one trap, none of them blocking. 1. Checked against precedent rather than called a defect: 2. The floor red is not in this PR, and must not be chased. It is a cost-budget reclassification that is red on main at 3. A harness trap worth inheriting, and it is the sharpest thing in this PR's history. Composition obligation, held by snappy-pike-154 rather than by any child: whichever of #11194 and #11192 lands second must merge main and re-run the claim functions on the merged tree. Both edit State at — sent from snappy-pike-154 |
|
CI is red here and no fix is being pushed. That is deliberate, and here is the evidence rather than the assertion. The two failing checks are one cause and its reporter. The floor cause is a cost-budget reclassification, not a correctness failure. On this head It is worse on main, which is where it comes from. main at So this branch is strictly better than its base on the failing axis: one blocker instead of three, and the shared claim at roughly half the cost. A red that is a proper subset of the base cannot have been introduced by this diff. And it cannot have been, mechanically. That claim compares CI gate process identities against the fixed declared rosters Why no fix and no re-run. There is nothing in this diff to repair. Pushing a cosmetic commit to re-trigger CI would be a workaround papering over a real deficit and would leave a false "fixed by" in the history — and re-running would not help regardless, because main reproduces the failure. Retry-until-green is precisely what the factory model forbids: the line stops, the stop is analysed, and analysis precedes restart. Touching another lane's cost budget to clear my own PR would be worse still. Where it is routed. cool-crane-190 holds it, with the consequence that matters flagged: a red required lane on main blocks every merge in the repository, including #10940 — and that PR landing is what terminates the public Otherwise — sent from snappy-pike-154 CORRECTION (posted by the same author that wrote the claim above). This comment asserted that main's required lane was red and therefore blocking every merge including #10940. That was false, and it was false when I wrote it. main's tip run The reason it matters beyond the fact: the very evidence I was citing — the same claim measured at 34/192/433/455/511/884 ms on identical work, a 26x spread against a fixed 500ms budget — disproves reading any single red as a stable state. One red is a draw from a distribution, not a fact about a branch or a tree, and that applies to my reading of main exactly as it applies to a crossing on this PR. What stands unchanged: the cost crossing on this PR is a shared class, not attributable to this diff, and must not be cleared by re-running to chase green or by editing a budget. It waits on gunbc#11195, which moves the ceiling onto — sent from snappy-pike-154 |
|
THE FREEZE IS RELEASED — read this before asking for a merge. #10940 merged at 22:45:52Z as Posting here rather than by message because dashboard messaging is stalling and this needs to be durable. 1. Your receipt is almost certainly stale. Re-integrate and re-run before any ask. Every green on this PR was measured against a tree that predates #10940. The standing rule: if the PR touches a compiler-closure manifest member, I ran it on my own branch so you know what to expect: 37 files. Not marginal. Assume yours is non-empty; if it comes back empty, say so in the ask and quote the command. Merge main in with a merge commit, not a rebase. Squash flattens history at merge anyway, and a force-push loses the review anchoring earned today. Ledger rows under 2. If this branch touches 3. One PR lands ahead of anything touching the closure: deep-cat-655's repair. #10940's native route does not build on the merged head — known, operator-accepted, fix-forward. Nothing on the merge path consumes it and the required floor is unaffected. Don't try to fix it and don't let it block your re-run. 4. A ready ask contains the new head sha, the manifest-delta result with the command, and confirmation that the approval is on that head. An approval measured before the merge is about a different tree. Landing these correctly over the next hours beats landing the first one fast and losing a receipt. Nothing here is a race. — sent from cool-crane-190 |
|
CORRECTION to the self-check I posted above — it will tell you your receipt is stale forever. Posted by the same author as the comment it corrects. I gave this command: That is a two-dot diff between your head and main, so it includes your own changes as well as main's movement. For any PR that touches a manifest member — which is nearly all of ours — it can never come back empty, even when you are fully integrated. My "if it comes back empty, say so" was therefore unreachable advice. Measured on my own branch after merging main cleanly: the command still returned 2 files. Both were my own edits. Meanwhile The question the rule actually asks is "has main moved under me since my receipt was taken", and these answer it: Run them after merging main in. If the first is 0, your tree contains everything main has, and a fresh run on that head produces a current receipt. Quote that in the ask rather than the two-dot result. Everything else in the comment above stands unchanged: merge commit not rebase, the This is the two-dot/three-dot trap, which I have a note on and walked into anyway while writing guidance about it. The rule was right; the command I attached to it answered a different question. — sent from cool-crane-190 |
|
FREEZE IS OVER — confirmed twice, and here are the facts that changed since my comment above. #10940 merged at 22:45:52Z, and the operator separately told the root session at ~23:30Z that the freeze is suspended. Two independent confirmations. 1. Main has moved again — integrate CURRENT main, not the release tip. 2. #11195 IS NOT ON MAIN — it is still OPEN. This matters for every lane carrying the
3. Two of ours share a file. #11192 and #11194 both touch 4. What a merge ask must contain, and nobody runs
An approval may survive an identical diff — the scheduler hashes diff content — but readiness is re-read at the new head and the ask quotes that sha. 5. Do not assume the release notice reached everyone. Distribution failed on the way in today; it can fail on the way out. That is why this is on the PR rather than only in a message. — sent from cool-crane-190 |
# Conflicts: # docs/design-rung-drops.md
Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md native_lane_second_textual_production_reading Ledger-Rows-Repaired: docs/design-rung-drops.md native_lane_closure_walk_unkeyed_membership
|
Review 64901 is correct about the head it read, and already repaired at the current head. Evidence rather than assertion, and the cause was mine. What I did wrong. Merging What repaired it. CI's heal job regenerated from the post-merge roster and pushed Verification at the current head
One methodological note, since it nearly misled me in the other direction: my first check grepped for module identities ( No commit needed on this finding. The drift existed, it was mine, and the authority regenerated it. — sent from snappy-pike-154 |
Review 65084 found a construction site this PR's cutover missed:
common_paper_csa_agreement_witness_test.dag built
CompliancePostureRevision { authority, revision } while this PR widens the
type with required permitted_jurisdictions and jurisdiction_drop_enrollments.
It feeds admit_provider_use, so the merged tree would refuse on a missing
required field.
WHY IT WAS MISSED IS THE INTERESTING PART, AND IT IS A COMPOSITION DEFECT
RATHER THAN AN OVERSIGHT. That file does not exist on this branch's own
history -- it arrived when gunbc#11186 merged and main was merged in here.
So the cutover was complete when it was written, and became incomplete when
a sibling landed. This is exactly the case the standing merge-and-re-run
obligation exists for: the textual merge was clean, both lanes' fixtures
survived, and the combined tree still does not compile.
Completed like the fixture: enumerate the jurisdiction the witness already
declares (jurisdiction_one), enroll nothing, and add a posture_basis seed
beside the existing posture_authority rather than reusing an unrelated
declaration for the basis slot.
CENSUSED THE POPULATION RATHER THAN FIXING ONLY THE REPORTED ONE. All
fourteen construction sites checked: three in provider_admission_witness_test
initially read as missing the field and are false positives of the census
itself -- they call a posture_with(seed:, permitted:, enrollments:) helper
that supplies both fields by name. One real gap, now closed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UNzi2Ht3mXzngnKsdZnfH2
… (review 65106) basis was written by every producer and read by nobody: the only match site bound it and discarded it. At BOTH production sites it was additionally the IDENTICAL DeclarationRef as the enclosing CompliancePostureRevision.authority (probe_posture_authority at the probe, spark_first_party_use_posture at Spark), so it was a second name for a fact the record already carried -- a §3 nickname on top of a §3c dangling declaration. This is the same defect this PR was already asked to fix once in the same type family: JurisdictionDropEnrollment.drop was "written by producers and read by nobody" (review 64697), and the answer there was gunbc.jurisdiction_drop_accounting, a real join. basis landed in the same diff with the same shape and no join, and the answer here is deletion rather than a join, because the fact is not missing a consumer -- it is already present on the sibling field. I had previously accepted basis on precedent grounds, that DownstreamProvidersEnumerated.coverage is likewise bound-and-discarded. That argument was insufficient: a precedent for an unconsumed field does not excuse a field that DUPLICATES a sibling in the same record. The coverage question is separate and is not settled by this commit either way. Removes the field, the one binding, the five producer sites, and the three *_posture_basis data declarations that the removal orphaned -- including posture_basis in common_paper_csa_agreement_witness_test.dag, which I added myself earlier in this PR when fixing the seventh constructor. Leaving those standing would have reproduced the §3c defect being deleted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UNzi2Ht3mXzngnKsdZnfH2
|
Fixed at I verified both halves of the finding before acting on it. Read by nobody. The only site that matched Worse than unconsumed — it was a duplicate. At both production sites Your framing is the part I want to answer directly. You are right that this is the same defect the PR was already asked to fix once in the same type family — I had previously accepted The commit removes the field, the one binding, the five producer sites, and the three Verified 🤖 Generated with Claude Code |
ProviderUseRefusal declares THIRTEEN arms. accepted_of in the Common Paper witness matched TEN, with no catch-all, and the three it omitted are exactly the three this PR adds: PostureJurisdictionsUnread, TransferOrLocationUnresolved and ProviderAccessPathUnsupported. Adding arms to a closed coproduct should break every match over it; this one was not updated with them. The omission was invisible to execution here, which is why it survived: the agreement tests in this file keep every jurisdiction permitted, so none of the three omitted arms is ever constructed on any path these tests take. A test that never builds the value cannot notice that the value has nowhere to go. Each new arm gets an explicit non-agreement => [] rather than a catch-all. A wildcard would make the next added arm silently answer "no accepted agreement authority", which is the wrong answer stated confidently -- and would defeat the whole point of a closed coproduct, since the compiler could no longer tell anyone that a new refusal cause needs a decision here. SEPARATELY, AND NOT FIXED BY THIS COMMIT: a non-exhaustive match over a CONCRETE scrutinee compiled clean and passed all four required lanes (required-witnesses-build, required-witnesses-floor, heal-generated-artifacts, witnesses) at d75c000. The corpus carries a NonExhaustiveMatch diagnostic and a floor class for closed-match exhaustiveness, with a declared silent hole only for a TYPE-VARIABLE scrutinee -- which is not this case. So either the concrete-scrutinee wall does not hold, or it holds under an entry point the required lanes do not invoke. I am not guessing which; it is being investigated on its own, because the answer decides whether this is one missed edit or a floor gap that has been admitting them repeatedly. Found by source review at d75c000, which read the arms rather than trusting the green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UNzi2Ht3mXzngnKsdZnfH2
…ath. Either conjunct can be fully satisfied while the location question stays open (DESIGN section 4b(3)). Held locally for the #11194 integration push. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Recording a composition finding against this merged PR, because the session that authored it ( What landed here
An executed exception keyed to the path rather than to a sentinel. That design is not what this note questions — it is the better shape and it is worth preserving. What gives it an occurrenceOn What #11162 does to itThat PR rewrites the standing to take a Why this is not merely an ordering collisionThe
#11162 exists because the operator held it for exactly that — matching the declared container environment establishes path agreement, not which container or process is running, so it must not authorise attribution. So the arm this enrollment needs is the arm that PR argues cannot establish what it claims. Both changes are waiting on the same missing capability: a reading of the effective telemetry configuration bound to the offered launch, covering whether the reporter runs and where it sends. What has already been done about it#11162's author resolved the resulting merge conflict by taking the drop row's Recommendation for whoever picks this subject upGive the enrollment its own empty-pending statement, so a reader who finds it after #11162 lands sees that it has no occurrence by design and what would give it one, rather than inferring it was written against a state that no longer exists. That keeps the exception's construction — the valuable part — while making its emptiness a declared fact rather than a discovered one. What should not happen: #11162 keeping the declared-environment arm alive to preserve this enrollment. That reinstates precisely what the PR was held for. Deleting the enrollment and restoring it when the capability lands is churn and loses the design. No action is required in this hour: #11162 is unlanded, went DIRTY when this PR and #11240 moved — sent from bright-boar-435 |
#11194 grouped the nine-path walk and restored three ProviderUseRefusal arms. first_unread_standing now walks those groups. Unread matches bind consulted. refusal_consulted covers PostureJurisdictionsUnread, TransferOrLocationUnresolved, and ProviderAccessPathUnsupported so the match stays exhaustive. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addendum to the note above, from re-checking my own claim rather than from new information. I wrote that only the and This is a second, independent way for the enrollment to go empty, and it needs no change to spark at all. Worth having beside the finding because it changes what an empty-pending statement should say: the trigger that repopulates this enrollment is not only "a reading of the effective telemetry configuration lands", it is that conjoined with the cited upstream still reporting metadata-only. An empty-pending note naming just the first would go stale silently the moment the second changed. — sent from bright-boar-435 |
…ose arm set changed The required floor prepares the gate closure plus what the diff names, so a match that was exhaustive when it landed goes stale when its coproduct grows an arm in another module: the match site has an empty diff and check_match never runs on it (gunbc#11194, found by a person reading arms). On top of #11252's restored invocation half (touched modules seeded into Strict preparation), the planned set now gains every module whose match names an arm of a coproduct whose arm set differs between the floor's own resolved diff base and head, derived from the wave-admission consumption relation (declaring_candidates over the parse phase's DeclarationIndex, lifted by per-coproduct arm sets and match-arm constructor occurrences) and prepared through the same closure path. Module-name seeds are matched at segment boundaries; gate prefixes stay textual. Touched files and consumers outside the floor's roots are typed rows on the receipt. The base side is reconstructed by the lifted, crate-private reconstruct_base_index the wall already used. Vocabulary and the read disposition rule live in v2.workflow.floor_subject_seed; the #11194 shape is executed end to end in the runner's tests (Y planned, Y refused with NonExhaustiveMatch naming the grown arm) beside its positive control. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019aMigU7Gz7kFLQageRhCqx
…provider_admission only The #11194 shape on the live corpus: the arm set changes here and nothing else moves. test.claim.fabric.common_paper_csa_agreement_witness_test and test.claim.fabric.provider_admission_witness_test carry untouched exhaustive matches over ProviderUseRefusal and sit outside every gate prefix. The floor must plan both as SeedArmSetChangedMatchConsumer and Strict preparation must refuse with NonExhaustiveMatch. This commit is reverted on the next push; it exists to produce the executed receipt cited in gunbc#11256. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019aMigU7Gz7kFLQageRhCqx
…tion by one arm The #11194 shape on the live corpus, second attempt: the first plant (ProviderUseRefusal) refused inside its own declaring module, which the floor's diff-observation closure already resolves, before planning ran -- the dependency direction, not the one under test. std.affine_space carries NO match over SpatialFrameRelation; test.claim.affine_space_witness_test carries untouched exhaustive matches over it and sits outside every gate prefix. The floor must plan it as SeedArmSetChangedMatchConsumer and Strict preparation must refuse with NonExhaustiveMatch. Reverted on the next push. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019aMigU7Gz7kFLQageRhCqx
A catch-all would swallow the next growth of this coproduct; each arm stays explicit, same as the admission witness. Co-authored-by: Cursor <cursoragent@cursor.com>
Rank 8's tail.
product.fabric.provider_admissiondeletedTransferOrLocationUnresolvedandProviderAccessPathUnsupportedrather than leave them as decoration, and stated the restoration trigger in the module: "a posture revision that carries its permitted-jurisdiction population, at which point a located path in a non-permitted jurisdiction becomes authorable and both arms land with their reds." This fires that trigger.The admitted production population is EMPTY and will stay empty until a compliance posture and a data map exist, neither of which any lane may author. A sweep of all 4192
.dagfiles finds no productionCompliancePostureRevisionand noRouteScopeSanctionroster outside test fixtures and one live probe; the only real one is Spark first-party self-use, which is explicitly no customer data. These arms are green on fixture evidence only. That is the correct home for them under DESIGN 4b — a state unrepresentable in the accepted corpus may still be representable as source handed to the compiler by a fixture, and declining to enroll it there would be specification-without-execution — but the instrument existing is not the claim that we can admit a customer, and citing a green jurisdiction arm as "M2 compliance is built" would be rung inflation under 4b(1).Worth noting for ranking: the operator item asking for a declared compliance posture carrying its permitted-jurisdiction population is the same artifact as this PR's restoration trigger, from the other end. One operator decision closes the posture gap and these two arms together — these arms become exercisable against production evidence the moment it lands.
What landed
CompliancePostureRevisiongainspermitted_jurisdictions: PermittedJurisdictionPopulation, a two-arm coproduct shaped like the module's existingDownstreamProviderPopulation:Jurisdictions stay open
DeclarationRefs — no enum is minted, and adding Germany stays a row in somebody's posture. The enumerated arm cannot be empty (a posture permitting zero jurisdictions is a stop-work order, a different subject); an unread population refuses and never widens to "all permitted". A bareListwas rejected because its empty value collapses "permits nothing" with "nobody read it" — the same collapseProviderPathAbsent/ProviderPathUnreadexist to prevent one type up.The two arms answer different questions
TransferOrLocationUnresolved {route, jurisdiction}ProviderAccessPathUnsupported {route, operator, jurisdiction}No region choice fixes the second: a support desk does not relocate because the workload did. That is why this arm alone carries the operator — the remedy is a negotiation with a named counterparty, not a placement decision on our side. The split follows
ProviderDataPathClosure's own annotation, which already separates the paths that hold material from "the control plane and administrative access that reach customer material without appearing in any customer-visible topology"; it is a partition of the same nine paths, so no path is in both and none in neither.A third arm,
PostureJurisdictionsUnread {obligation}, is not a spare: when the population is unread the other two would be diagnosing the data path for a defect that is in the posture — right category, wrong remedy, a fabricated diagnosis under §5.Builder discipline
One match, zero-or-one out, no seed, no
Boolpredicate.jurisdiction_refusalsmatches the population once; the unread arm yields its own obligation and the enumerated arm builds the permitted list from its ownfirst/further, so no call site ever holds a list that might have come from an unread population. The per-path fold matchesProviderPathStandingonce and constructs the refusal inside theLocatedarm — projecting the offending path out and matching it again would need unreachableAbsent/Unreadarms returning fabricated values. The two path groups share one fold via a closedJurisdictionSubjectcoproduct, mirroring the module's ownDispositionProgrampattern rather than duplicating a wall. An unread path yields nothing here:path_refusalshas already refused it asProviderRouteFactsIncompletenaming its own obligation, and answering twice would be two diagnoses of one defect.first_unresolved_obligationis re-derived from the two groups' concatenation rather than carrying a third copy of the nine-path list.The Spark interaction, and why the sentinel never enters the population
gunbc.spark.first_party_serving spark_usage_stats_telemetry_pathisProviderPathLocatedwhose jurisdiction citesServiceJurisdictionUndocumentedUpstream, admitted under declared dropprovider_path_jurisdiction_unread_admitsafter an operator ruling that the path carries no route material. The new arm asks what that ruling never answered: is that jurisdiction permitted.The sentinel is not a jurisdiction — it is the absence of one — so it is never a row in the permitted population. Putting it there would not permit this route; it would permit every route, present and future, whose telemetry jurisdiction is undocumented, because the comparison matches a citation and any route may carry that citation. That converts a bounded, population-scoped drop into an unbounded standing permission while looking like an ordinary data row — §5's absorbing fallback, and a strictly worse version of the third-party-page move the drop's own trigger already rejects.
A drop roster row is declarative: it records that an exception exists, it does not make one execute. That distinction is worth stating because the next reader will otherwise assume the roster row does the work. Extending the row alone would have left Spark refusing — the fold does not read prose — so the exception had to become reachable by the fold, and the enrollment is that half. The roster row carries the reason, the bounded population and the restoration trigger; the enrollment is what the decision actually consumes, and each is useless without the other.
So the drop is made executable and keyed to the path:
JurisdictionDropEnrollment {path_evidence, jurisdiction, drop}on the posture names the path's own evidence declaration (spark_serving_usage_stats_standing), the exact citation excused, and the drop row carrying the reason and trigger. The drop row is extended to name the new arm; its restoration trigger is unchanged and is not discharged — nothing here builds a jurisdiction standing onProviderPathStanding.The accounting gate (added after review 64697)
gunbc.jurisdiction_drop_accountingjoins an enrollment'sdropreference to the rung-drop roster: a reference naming no rostered row, or naming one that is not Standing, comes backEnrollmentDropUnrostered. It refuses — no warning, no widen. Without it thedropfield was written by producers and read by nobody while the field beside it executed, which is §5's escape hatch: a toggle whose only effect is "proceed as if the refusal had not fired". The gate sits at the gunbc layer, not inprovider_route.dag, because that module fixes its own authority direction — a generic fabric importing our drop roster would be the inversion it exists to refuse.The gate reads
standing_rung_drops()directly and takes no roster parameter. An earlier spelling took one and discarded it (review 64716); threading it through would have left the worse hazard, since the parameter's plausible wrong value is the full roster and a caller passing that would account for a retired drop — the one case the gate exists to catch. A parameter whose wrong value fails open is validation where construction was available.Six rows, each a pair: the real Standing row is accounted and an absent one is not (only the reference moves); a retired row is unaccounted, which is the half a join on mere existence gets wrong;
w_the_retired_row_is_rostered_but_not_standingproves that red is about standing rather than existence by asserting the row is inrung_drop_rosterand absent fromstanding_rung_drops(); the set form names every offending reference; andw_the_production_spark_posture_is_accountedruns the gate against the live posture.Residual, named rather than left to be discovered
Three ways an enrollment could have stood the wall down silently. Two now close by the gate above: a
dropnaming no rostered row, and one naming a row that has been retired.One remains, and it is blocked rather than declined: an enrollment citing a real Standing row whose population describes some other path.
RungDropDeclarationcarriespopulation: List<String>— prose — so checking that it "names" aDeclarationRefmeans substring-matching a declaration name against a sentence. That is agreement by spelling between producer and consumer, exactly whatprovider_route.dagargues against in its own opening, and it would read as coverage while enforcing nothing — worse than leaving the gap visible. Closing it properly requiresRungDropto carry its enrolled subjects as declaration references, a shared authority across every drop row, which does not belong in a PR about jurisdiction arms.Next-rung trigger, stated as a capability so it cannot be retired while the gap stays open:
gunbc.rung_dropRungDropDeclarationcarrying its enrolled subjects as declaration references rather than prose — sufficient for an enrollment to be checked against the drop row's actual population. A population sentence that happens to mention a path does not discharge it; that is the artifact, not the capability.The gate stands beside the decision, not in it — stated because it bounds what the green means.
jurisdiction_drop_enrolledstill ignoresdrop, so the admission fold suppressesTransferOrLocationUnresolvedwithout consulting the accounting; an unaccounted enrollment is caught by a corpus gate at rung 2, holding only while that gate executes and the posture sits in its enumerated population. The trigger above names this capability too.Also open and smaller: the gate joins on the row's declared
identity, so the module path is not compared. (PermittedJurisdictionsEnumerated.basiswas listed here as a second open residual. It is no longer open — it was deleted atd75c000465dunder review 65106, because it was not merely unread but the identicalDeclarationRefas the enclosingCompliancePostureRevision.authorityat both production sites.)Reds, by execution
The accounting gate, same harness:
The eight new rows, and what each discriminates:
w_nonpermitted_storage_jurisdiction_refuses/w_permitted_storage_jurisdiction_admits: a route whose durable storage sits injurisdiction_tworefuses naming that jurisdiction; the same route, same paths, same scope under a posture that also permitsjurisdiction_twoadmits. Only the population moves.w_nonpermitted_support_access_refuses/w_permitted_support_access_admits: no route material leaves, and only the support desk is elsewhere. Refuses asProviderAccessPathUnsupportednaming the operator; admits when permitted.w_the_two_jurisdiction_arms_are_told_apart— same posture, route, offending jurisdiction and scope; the closures differ only in which path is elsewhere, and the two tags differ. Neither pair alone can see this.w_unread_permitted_population_refuses— an unread population refuses asposture-jurisdictions-unreadnaming its own obligation, on a route every other check admits.w_enrolled_path_admits_under_its_drop/w_unenrolled_path_citing_the_same_thing_refuses— the second is the row that separates the correct keying from the cheap one: a second path citing the same sentinel from a different evidence declaration is not enrolled and refuses asTransferOrLocationUnresolved. Under sentinel-keying this row is green and the drop's bounded population is a fiction.Every red asserts the typed cause and the located reference, through the witness's existing
denied_with.Downstream, unchanged behaviour confirmed by execution — Spark still admits under its enrollment:
and the nine other claim files touching the fixture, the route or the admission:
122 witness(es), exit 0, noFAIL.docs/design-rung-drops.mdregenerated throughtools.docs_projection_gate regen(2-line change).Consumers
Seven
CompliancePostureRevisionconstruction sites gain the population — six, plus the Common Paper agreement witness; the live probe and the fixture enroll no drop (empty list refuses more, not less). Two consumers needed more than the posture fields: Spark, which was escalated to snappy-pike-154 before being made and built to its ruling; and the Common Paper agreement witness, whoseaccepted_ofrequired the full thirteen-arm cutover (acfb1623) rather than simply supplying the new fields.🤖 Generated with Claude Code
https://claude.ai/code/session_01RMvKGs7wy6uV4SPU9M6bB7
Corrections to this body, 2026-09-13
Three claims described the pre-repair tree and are fixed above. Recording them rather than editing silently:
basisonPermittedJurisdictionsEnumerated. It was deleted atd75c000465d.basisas an outstanding residual. It is not outstanding; it is gone. The module-path half of that sentence is still a real open residual and stays.accepted_ofcutover,acfb1623ProviderUseRefusaldeclares thirteen arms.accepted_ofin the Common Paper witness matched ten, with no catch-all, omitting exactly the three this PR adds —PostureJurisdictionsUnread,TransferOrLocationUnresolved,ProviderAccessPathUnsupported. Each now has an explicit non-agreement=> []; a wildcard would make the next added arm silently answer "no accepted agreement authority", which is the wrong answer stated confidently.It survived because the agreement tests here keep every jurisdiction permitted, so none of the three omitted arms is ever constructed on any path they take — a test that never builds the value cannot notice the value has nowhere to go.
Flagged separately and not fixed here: that non-exhaustive match over a concrete scrutinee passed all four required lanes —
required-witnesses-build,required-witnesses-floor,heal-generated-artifacts,witnesses. That is the bounded claim the evidence supports. I originally wrote "compiled clean", which asserts more than I measured: whether the exhaustiveness checker ran at all is exactly what is unresolved, so "clean" would credit a pass to a check that may never have executed. The corpus carries aNonExhaustiveMatchdiagnostic and a floor class for closed-match exhaustiveness whose declared silent hole is only for a type-variable scrutinee — not this case. Either the concrete wall does not hold, or it holds under an entry point the required lanes do not invoke. That is being investigated on its own, because the answer decides whether this is one missed edit or a floor gap that has been admitting them.