Skip to content

Cut D PR 2a: pair-serving authority on its own event-log partition, read by every effectful consumer - #11550

Closed
gunbai-bot[bot] wants to merge 9 commits into
mainfrom
plan/dsv41-cut-d-2a
Closed

gunbai-bot[bot] wants to merge 9 commits into
mainfrom
plan/dsv41-cut-d-2a

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Second Cut D PR (docs/plans/dsv41-cut-d-redesign.md). D0 must move Group A through Active → SuspensionPendingReconciliation → SuspendedForAuthorizedSuccessor under a lease, and a pure fold returning the next state changes nothing a consumer reads. This lands the store and routes the effectful consumers through it; D0 itself (incumbent-first question, occupancy reconciliation, LeaseGrant↔HeldLease join, entry receipt, baseline contract) is PR 2b.

Design call (agreed with operator): the source row spark_pair_serving_authorities stays the claim and resting authority — membership is pure and suspension keeps the claim. The log carries open-transaction state, folded from the resting row. Empty partition ⇒ the authored resting state governs; unreadable partition ⇒ every effectful consumer refuses, never falls back to the row.

Store: DESIGN §3b puts serving-side occupancy on the event chain, so the authority goes on gunbc.fabric_event_log partition pair-serving-authority/<group> — same leased-push CAS as seats.

  • gunbc.fabric_event_log — read/append generic in the payload (*_with take encode/decode); PoolEvent entries are specializations. No caller churn.
  • product.capacity.event_json — chain envelope codec once, for any payload; pool_events consumes it. EventDecode<P> replaces PoolEventDecode.
  • gunbc.spark.pair_serving_authority_log — codec for all five arms (flat prev_/next_ members); authority_fold refuses an event leaving a non-current state or naming another group; current_pair_serving_authority; pair_serving_authority_transition — one CAS, no retry (a stale transition returns the now-current state; unlike a seat the decision must be re-made).
  • Consumers: spark_pair_serving_apply_wet plans under the executor's live authorities; fabric_capacity_standing reads them. Both keep a supplied-roster seam (*_current) their witnesses drive at generation 0.
  • std.content_hash.parse_content_hash — wire inverse moved to the grammar's home (was materialization_object.parse_recorded_store_key); wire inverses for HeldLeaseObservedState, FabricGroup beside their wire forms.

Test plan

  • pair_serving_authority_log_witness (hermetic): every arm round-trips; wire distinguishes arms/fields; foreign/incoherent doc refuses; fold walks from resting through transitions (gen 0 → 2); fold refuses non-current previous at that event; refuses cross-group next. 6/6 PASS.
  • pair_serving_authority_log_real_execution_witness (wet lane, enrolled in ci_layer_roots / local_repo_wet_terminal / floor_route_gap): against a bare remote — empty log reads resting at gen 0; transition appends and reads back at gen 1; a second transition expecting the resting state is Stale carrying the current, appends nothing; unclaimed group refuses at claim. 2/2 PASS.
  • Touched witnesses re-run and passing: capacity standing (live entry via supplied roster), apply plan, authority seam, pool-event codec round-trip, store-key round-trip + trailing-prefix refusal, event-log append real execution.
  • Pre-existing, untouched: spark_pair_serving_apply_witness.every_promoted_group_plans_and_the_second_is_group_b_headed_by_srv9 fails identically on clean origin/main (expects two groups; roster has one since DS4.1 #11501).

🤖 Generated with Claude Code

Brian Searls and others added 4 commits September 17, 2026 23:52
…ad by every effectful consumer

A transaction that suspends Group A has to change what the apply seam and the
capacity instrument read, without a commit, under a compare-and-set. The source row
stays the claim and the resting authority (membership is pure and suspension keeps
the claim); the open-transaction state lives on gunbc.fabric_event_log partition
pair-serving-authority/<group>, folded from the resting row through every recorded
transition. An empty partition is the authored resting state; an unreadable one
refuses every effectful consumer and never falls back to the row.

- gunbc.fabric_event_log: read and append are generic in the payload
  (event_log_read_partition_with / event_log_append_with take the codec); the
  PoolEvent entries are those two with the pool codec supplied.
- product.capacity.event_json: the chain envelope encoded and decoded once, for any
  payload; pool_events consumes it. EventDecode<P> replaces PoolEventDecode.
- gunbc.spark.pair_serving_authority_log: codec for every authority arm, fold that
  refuses a transition leaving a non-current state, current_pair_serving_authority,
  and pair_serving_authority_transition (one CAS, no retry: a stale transition returns
  the current state for the caller to re-decide).
- The apply seam plans under the executor's live authorities; the capacity instrument
  reads them too. Both keep a supplied-roster seam their witnesses drive at gen 0.
- std.content_hash parse_content_hash: the wire inverse moved to the grammar's home
  (was materialization_object parse_recorded_store_key). Wire inverses for
  HeldLeaseObservedState and FabricGroup beside their wire forms.

Witnesses: codec/fold hermetic claims; a real-execution claim on the wet lane that
appends a transition against a bare remote, reads it back at generation 1, and
refuses a stale second transition with the current state. Every touched claim
passes locally; spark_pair_serving_apply_witness
every_promoted_group_plans_and_the_second_is_group_b_headed_by_srv9 fails
identically on origin/main (stale two-group expectation) and is untouched here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…eachable arm

review 67407: the lookup was repeated to re-obtain the value the outer arm had
already matched, and the inner Absent arm could not be reached. One bind, one
match (DESIGN §2, §6 bare minimum cost).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The build lane's generated-artifact phase refused the drift: std/content_hash.dag
gained parse_content_hash and its seed mirror src/v1/stage0/src/std_content_hash.rs
is a committed projection of it. Installed from the --required-regen candidate,
byte-identical to what the phase emits.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…c claim for what it drives

review 67439: converting the pairing control to a supplied roster left
fabric_capacity_standing() -- hostname, layout, authority read, verdict --
executed by nothing. A wet-lane claim now runs the real entry and asserts the
route by its refusal text (every claimed group reported unread at the read's
step, never judged from the source row); the hermetic claim is renamed to say
it drives the verdict over the resting roster. Enrolled in ci_layer_roots
(new executor-identity reason row), local_repo_wet_schedule, floor_route_gap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 18, 2026
…it, and the settled authority

docs/plans/dsv41-cut-d-redesign.md §D0, on top of the authority log (#11550).

- gunbc.spark.released_baseline: ReleasedBaselineSpec = QuiescentReservedBaseline |
  FleetReleasedBaseline, the cleanup contract the suspended authority now carries
  (SuspendedForAuthorizedSuccessor.cleanup was a NonEmptyStr).
- The LeaseGrant rides on the transition event; the fold keeps the latest; every
  read derives the HeldLease's observed state from the grant and the reading
  instant (running / stale past expiry / inaccessible with no grant) -- the join
  between product.capacity.lease's term and std.temporal_effect's observation,
  which pair_serving_successor_may_launch then consumes.
- serving_incarnation_observe read_unit_occupancy: installed / not installed /
  unread, with activity and bytes, for a unit that may not be running.
- gunbc.spark.pair_serving_d0: Active -> SuspensionPendingReconciliation by one
  CAS (both actuators off), then the incumbent question first (answering and
  Established -> restore Active carrying PairRealizationKeyed, the one mint;
  answering otherwise -> fenced), then per-rank reconciliation (observed or
  drifted -> SuspendedForAuthorizedSuccessor under the grant; unread -> fenced;
  an uninstalled rank is unread with the stated cause, since foreign occupancy
  is not read here). Second CAS settles; a stale settle is reported, not
  overwritten. Receipt at target/pair-serving-d0-receipt.txt; exit 0 only on
  D0Eligible written.

Witnesses: 11 hermetic D0 claims over supplied readings (every branch of the
redesign's table, the expected drifted-eligible case, the key mint on restore,
the written suspension admitting launch and refusing apply); the authority-log
real-execution claim now also proves the grant-derived lease standing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brian Searls and others added 2 commits September 18, 2026 03:42
…f a two-group literal

The floor refused two things: the namespace-wave-admission wall saw member_nat
and member_nonempty in pool_event_kind_decode rebind from pool_events to
event_json (TargetChanged) with no authored admission -- two rows now carry it;
and touching the apply witness planned a claim that had been outside the gate,
whose two-group expectation has been false since #11501 made membership a
projection of the authority. It now reads its expected count from that
population.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… follow-up for the codec-move rows

The wave-admission wall: touching the roster brings every consumed row due --
the CONVERGENCE-ONE C2 rows (gunbc#11425) were satisfied at the base and are
deleted here -- and a used row must name the pull request that deletes it.
The two codec-move rows now name #11555 (Cut D 2b), which removes them.

The other floor blocker on the previous head, MemoryStallRefusedPageThrash on
srv4-01 (138161 major faults/minute, swap off), is the runner's, not the diff's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 18, 2026
…g (their named follow-up)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brian Searls and others added 3 commits September 18, 2026 06:31
The floor budgets a claim at the work its assertions cost; twelve render-and-parse
cycles under one conjunction cost 180437 steps against 72300. One claim per arm
(and one for the previous position) keeps the coverage and drops each under budget.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ply seam's unread arm

The floor's whole-corpus namespace resolves bare helper names pool-wide, so a
helper named like one in another witness (admit, env, with_temp_dir ...) can
resolve to the other module's declaration under the fold -- which is invisible
to a single-entry run. Every helper in these files now carries the file's prefix.

review 67565: a hermetic claim supplies CurrentAuthorityUnread and requires the
plan to refuse with the read's cause; a wet-lane claim executes the apply
seam's live log read (spark_pair_apply_plans) and asserts the route by its
refusal text, enrolled beside the capacity entry's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 18, 2026
…ws stay while stacked

The floor's pool-wide namespace resolved this branch's witness helper  to
another witness's  (a FailureScenarioAdmission producer), which a
single-entry run cannot see; every helper in the D0 and log witnesses now carries
its file's prefix. The two codec-move admission rows come back: this PR is their
named deletion follow-up, and the deletion is owed once #11550 has landed and this
branch's diff against main no longer carries the rebinding.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls added this pull request to the merge queue Sep 18, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 18, 2026
@briansrls
briansrls added this pull request to the merge queue Sep 18, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 18, 2026
@gunbai-bot

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Transition-admission migration for gunbc#11704. No action until the operator sequences #11704's landing.

gunbc#11704 moves namespace transition admissions out of the tree. Once it lands, any file under dag/gunbc/namespace/transition_admission/ refuses at this PR's own gate, and the admission has to be carried in a commit message on this branch instead. The block below was derived mechanically from this PR's 2 row file(s) at its current head. The only edits: deletion_follow_up, owner_pull_request and their now-unused imports are dropped, because those fields no longer exist. All 2 blocks load through the production fold (carried_admissions_from_messages) with no refusal.

To migrate (paste + delete), after #11704 is on main and merged into this branch:

git rm \
  dag/gunbc/namespace/transition_admission/product_capacity_pool_events_pool_event_kind_decode_member_nat_event_json.dag \
  dag/gunbc/namespace/transition_admission/product_capacity_pool_events_pool_event_kind_decode_member_nonempty_event_json.dag
git commit -F msg.txt   # msg.txt = the text below, verbatim

-F keeps the lines exactly as they are. The squash merge carries the message into the queue run, and nothing lands in the tree. If a row is wrong later, a later block with the same stem supersedes it.

msg.txt
Move transition admissions into the commit message (gunbc#11704)

```transition-admission
module gunbc.namespace.transition_admission.product_capacity_pool_events_pool_event_kind_decode_member_nat_event_json

import std.types { NonEmptyStr, List }
import std.decl_ref { decl_ref }
import gunbc.compiler_frontend_program_interlock { TargetChanged }
import gunbc.namespace.transition_admission { TransitionAdmission, Binding }

data product_capacity_pool_events_pool_event_kind_decode_member_nat_event_json: TransitionAdmission = TransitionAdmission {
  label: "Cut D 2a: the chain-envelope JSON codec moves to product.capacity.event_json; pool_events consumes member_nat from there" as NonEmptyStr,
  subject: Binding {
    enclosing: decl_ref("product.capacity.pool_events", "pool_event_kind_decode"),
    spelling: "member_nat" as NonEmptyStr,
    expected_candidates: [decl_ref("product.capacity.event_json", "member_nat")],
  },
  disposition: TargetChanged,
}
```

```transition-admission
module gunbc.namespace.transition_admission.product_capacity_pool_events_pool_event_kind_decode_member_nonempty_event_json

import std.types { NonEmptyStr, List }
import std.decl_ref { decl_ref }
import gunbc.compiler_frontend_program_interlock { TargetChanged }
import gunbc.namespace.transition_admission { TransitionAdmission, Binding }

data product_capacity_pool_events_pool_event_kind_decode_member_nonempty_event_json: TransitionAdmission = TransitionAdmission {
  label: "Cut D 2a: the chain-envelope JSON codec moves to product.capacity.event_json; pool_events consumes member_nonempty from there" as NonEmptyStr,
  subject: Binding {
    enclosing: decl_ref("product.capacity.pool_events", "pool_event_kind_decode"),
    spelling: "member_nonempty" as NonEmptyStr,
    expected_candidates: [decl_ref("product.capacity.event_json", "member_nonempty")],
  },
  disposition: TargetChanged,
}
```

@briansrls
briansrls added this pull request to the merge queue Sep 19, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 19, 2026
@gunbai-bot

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Closed per operator decision (2026-09-20): main's #11723 replaced git under the fabric event log; this PR's diff is carried by #11555, which is being re-realized on the fabric DB. — sent from proud-deer-538

@gunbai-bot gunbai-bot Bot closed this Sep 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants