Cohort-11: strangers admit — 2026-09-02

Devnet evidence. Not mainnet evidence. Nothing here says anything about mainnet, and no mainnet act is authorized.

COHORT11_GENESIS_FOUNDED_2026_09_01.md ends with the market founded, open, and its population life not demonstrated: the load simulator stopped at BlockhashNotFound on an admission whose prefund had already landed. This file is the sequel. Two strangers now hold Positions in the cohort-11 SOL/USD market, admitted through the simulator, and six conservation laws hold across four census boundaries.

Three walls stood between those two states. Only the first was the one the previous lane named.

Tree root /Users/ember/dev/dclutch. Source commits:

Wall 0: the driver had not compiled since 061eaa39

Before anything could be run, nothing could be built. 061eaa39 made classes a required parameter of Ledger::observe — correctly, because "a law whose input is optional is a law that reports nothing" — and did not update the ledger-census caller in the successor bootstrap's main.rs. dclutch-local-successor-bootstrap had not compiled since, which means every devnet driver in the tree had not compiled since: the campaign, the admission, the census, the trade producer. Nothing went red because no gate builds that binary.

This is the red umbrella AGENTS.md describes, in its purest form: a shared signature deepened, every file the deepening touched still green, one downstream consumer in another workspace left behind.

The value it takes is the one already beside it. An external census does not drive the transactions between its two observations, so it cannot say which compartments they crossed, exactly as it cannot guess their fees: ClassClaimV1::inapplicable, not unchanged(), which would be the claim that not one atom changed class.

Wall 1: a blockhash lives twenty-five seconds on this chain

The named defect, and the measurement that explains it.

Devnet was producing 6.0 blocks per second (measured 2026-09-02: block height 479,590,576 → 479,590,701 across 20.8 seconds; 6.15 slots/s). Solana's MAX_PROCESSING_AGE is 150 blocks, so a blockhash on this chain is a twenty-five second artifact, not the minute the 400 ms slot assumption suggests.

build_report fetched the blockhash, and then — before the driver was permitted to sign — spent a full finalized re-observation of every semantic account, a fresh getFeeForMessage, a poststate probe, and a prestate re-read. That pass is longer than twenty-five seconds through a load-balanced endpoint. Both of the previous lane's attempts died on it, and the existing guard passed both times, because getBlockHeight was measured with two more round trips still to come before the send — twelve blocks of a hundred-and-fifty-block life.

The repair is not a retry. A blockhash is not a fact about the market; it is the submission parameter that decides which banks still accept the packet, and it is the only field of a planned admission that expires. So it is bound last:

The previous lane's dead packet was the first thing the repaired driver met, and it said the right thing:

Dispatching admission packet expired while absent; archive the journal
rather than re-signing

Archived after confirming on chain that its signature was absent and the Position and admission PDAs were still vacant. Note that the simulator had been reading that failure as backpressure — "blockhash not found" is a BACKPRESSURE_MARKERS entry — and therefore as something to wait out. The repaired driver's refusal names expiry instead, so the loop halts on it.

Wall 2: the routing table was being searched for, and could not be found

frozen_routing_table_for scanned getProgramAccounts over the entire AddressLookupTable program and kept the frozen table whose address list held the market. On devnet that scan returns nothing usable, so it answered None for a table that demonstrably exists — and answered it as an absence, not a refusal.

The predicate was wrong as well as unscannable, which the scan's failure hid. Cohort-11's frozen table 6Pwb16HHphgvDbr6RW4p7k82qTGDccQHizJzk3LDXZwk routes founding_market 3rBfDBpaXjKSbUU5HRaRTr6yhDQq4S1oKp2mQRsdoyb6 and sixty-three other accounts. It does not contain the Core Market ARuPAuyJbJoLdMWGDzSqvcV9py25EkmMj8ABnfKP56s, which is the address a reader naturally reaches for. [Corrected by the addendum dated 2026-09-02 at the end of this file: both addresses are Core Market accounts, and 3rBfDBpa… is the live one. The paragraph's conclusion about the scan is unaffected; the labels are not.] A search handed the wrong one of those two answers a confident None even on a chain small enough to scan.

Nothing has to be searched. The founding's own create transaction is in the campaign evidence under the label create DCLTGMF3 frozen routing address lookup table (5iyBJssn…), and CreateLookupTable puts the table it creates at account index 0 of its own instruction. Two reads by address replace the scan, and then the account is authenticated against the founding it claims to serve — owned by the ALT program, authority None, routing this founding's market — so a wrong pick refuses by name rather than routes.

Wall 3: the owner cannot pay its own fee, and only the chain said so

With the blockhash bound late, the admission stopped refusing at the endpoint and reached the program — where it refused TradingSbfError::Content (0x4003) after 12,233 CU with no CPI, at instruction 2. Content is exactly the undifferentiated code AGENTS.md names: one accusation over thousands of sites.

One comparison found it. Of the twenty-seven outer coordinates, exactly one presented a privilege the plan did not declare:

coordinateaccountcompileddeclared
245nTAZrNLeebevH1nrmfvNpKAsTqE6qPZMz1GDaTzAhKisigner, writablesigner, readonly

Coordinate 24 is the Position owner, which UserPositionAdmissionFrameV1 requires to sign readonly. The compiled v0 message presented it writable because the owner was also the transaction's fee payer, and a fee payer is writable unconditionally — the fee debits it. num_readonly_signed was 0 where the frame needs it to count the owner. The two requirements are jointly unsatisfiable: an admission whose owner pays its own fee can never land, on any chain.

The driver knew half of this already. prefund_admission_rents_v1 exists because a System transfer debiting the owner in the same transaction forces the same promotion, and it pays rent in a separate finalized transfer to avoid it. That repair cannot reach this one. So the prefund landed, the plan carried zero top-ups exactly as designed, and the message was still unsatisfiable.

Nothing offline could have caught it before. authenticate_fresh_admission_plan_v1 reconstructs and compares the intent, which carries the operator's own metas — the same metas on both sides, and the frame satisfied in both. The promotion happens later, in the v0 compiler, and only the compiled message knows.

Two checks now close it, in the two places their causes live:

Controls, read-only, spending nothing

Against the live cohort-11 market, with --execute withheld:

owner named as its own fee payer:
  instruction 2 coordinate 24 declares 3CZxcpGp... readonly, and that account
  is this transaction's FEE PAYER, which the message marks writable
  unconditionally because the fee debits it. No plan and no prefund can
  satisfy both: name a different --fee-payer

same owner, distinct fee payer, still owing rent:
  phase: planned      (no signature; the preflight path intact)

And the repair, on the packet that landed: num_required_signatures 2, num_readonly_signed **1**, static key 0 the campaign payer (writable signer), static key 1 the Position owner (readonly signer).

What executed

Simulator tools/load-simulator/simulator.py run --execute, cohort-11's real market, participants funded from the campaign payer and never from the deployer.

whatsignatureslotCUfee
participant-1 admission4dFZ9APHud96oNbZvhRCRnehjTCZZDDDmbKDBECoF1A2rm9SM1Zf1tLEgCLMfEfT4dkVc9fRN78LTNYqAdaz1CX3491,815,185282,94080,000
participant-2 rent prefund2Pip9hrZj9KKm7qY6NWFNtrHTrZvMWFjuDPz6Y9B5pwvYafhV8RLHSiVSikWdUntWh8nKYroLtpEZUuQenbaoCFN491,815,25130010,000
participant-2 admissionJKdY7qzML69C4TzUcumaEoSRj6ARnjFHnmRFg3oj3zVYRboQxx1vfmP4nFjbVD8McKbfAD68jKVgW3rgj3FVa9R491,815,409288,94080,000

Both admission journals are phase: finalized. The poststate, re-read off chain rather than taken from the driver:

accountaddressownerbytes
participant-1 Position5SYqhNVT8hUetS6GopkxdVNXWpKfHG1CpMwwZKXzVtAPClaims HQYqqdzn…160
participant-1 admissionG5JTNALRHfSTDGCmJCh1V1DTYoEyQS8skkFHQxGQRoYtClaims HQYqqdzn…512
participant-2 Position4AHZpdJi8RFoh2VUKGuNqzgnqqjzXA5x2naHq8t5MjueClaims HQYqqdzn…160
participant-2 admission48KkQPsugrpH5y9sAnTAFNwpeig7mKcnaQ3Lza6XZc63Claims HQYqqdzn…512

Both Positions were System-owned and data-empty before the run. The identities are campaign-local keys held under a mode-700 job directory beside the founder's.

The two Market accounts, settled against the chain

The Redemption lane found the cohort-11 genesis table mixing two addresses. It is mixing them, and the answer is sharper than "a Market and a founding record": both are Core-owned DCLTCOR3 Market accounts of 368 bytes, each storing its own address at offset 16, and they differ in phase.

STATE_PHASE_OFFSET is 10 and STATE_READINESS_OFFSET is 11 (crates/dclutch-market-core-codec/src/generated.rs:38-39). Read off chain:

campaign labeladdressbyte[10] phasebyte[11] readiness
marketARuPAuyJbJoLdMWGDzSqvcV9py25EkmMj8ABnfKP56s0x00 Founding0x00 Prepaid
founding_market3rBfDBpaXjKSbUU5HRaRTr6yhDQq4S1oKp2mQRsdoyb60x01 Open0x02 Consumed

3rBfDBpa… is the live Open Market. The genesis file's headline row named ARuPAuyJ… as "the Market is OPEN"; that account is the one still in Founding. Two independent confirmations that the Open one is 3rBfDBpa…:

The readiness byte agrees with the story the genesis file already tells: the Open market reads Consumed, which is the post-Open V7 funding suffix (core-funding-create-v1, resolution-funding-activate-v1, core-funding-accept-v1) having run against it.

Nothing in this lane's work bound the wrong one — the admissions, the Positions and the census all reach the market through the campaign evidence rather than through the label. The one place the wrong address appears is cosmetic: the simulator config's market_address, which is only a status-file label. The reconciliation of the genesis file itself belongs to the Witness lane; this section is the measurement, offered rather than duplicated.

The census: six laws, four boundaries

ledger-census ran once per cycle for four cycles. The first attempt halted loudly, and it was right to:

VIOLATED L1: tracked 500000000 atoms across 1 accounts != Mint supply 1000000000
VIOLATED L3: Positions sum to [0,0,0,0] but the aggregate owes [500000000 x 4]

Neither is a protocol violation. Both are the census being asked to check a law without the input it needs: census.tokens and census.positions were empty and claim_unit_atoms was 0, which also made L4 vacuous (x unit 0 = 0). The config now names the founder's collateral wallet, the three Positions, and the true claim unit of 1. Naming what exists is not weakening a law; it is the same lesson 061eaa39 drew about L8.

With the inputs supplied, at cycle 4:

HOLDS L1: tracked 1000000000 atoms across 2 accounts == Mint supply 1000000000
HOLDS L2: the Hoard moved 0 atoms since load-sim-cycle-000003, exactly as declared
HOLDS L3: 3 Positions sum to the aggregate supply vector [500000000 x 4]
HOLDS L4: Hoard 500000000 >= worst outcome 500000000 x unit 1 = 500000000
HOLDS L5: tracked collateral moved 0 atoms since load-sim-cycle-000003
HOLDS L6: no watched account closed at this boundary

L3 counts three Positions. Before this run it could have counted one. That is the sentence this lane exists for.

Cost, and the budget it was held to

Stated before spending: nothing from the deployer, and stop at any step costing more than 2 SOL without an executing result. The simulator additionally carried an enforced budget.max_lamports_spent of 500,000,000.

lamportsSOL
deployer 4zrxtw5c… before38,738,044,77538.738044775
deployer after38,738,044,77538.738044775
campaign payer before1,562,479,3451.562479345
campaign payer after1,562,309,3451.562309345
campaign payer spent (three fees, exactly)−170,000−0.000170
participant-2 own rent (its two PDAs)−5,877,024−0.005877024

The deployer did not move. Total chain cost of demonstrating population life: 0.000170 SOL in fees plus 0.005877024 SOL of rent that now sits in the participant's own accounts.

What is still not demonstrated: the Direct trade

Population life here is admission life. No trade executed, and preparing one found a wall bigger than the missing artifacts.

Cohort-11's market cannot be filled, and no artifact repairs it

The market was founded at 30 basis points. Read off chain, not off the staging file: the finalized direct_execution_config_record 62kFf7i2vRkGEGCwdvK5AKfk18Jt56UjihoaVEqUjHNQ (64 bytes, owner ADB72ar6… = Registry) decodes DCLTDEC1, price_scale 1000000, fee_basis_points 30, fee_recipient EP4CMPQKidMRzA4bsbpVRx6eBgpQRpiMvU7p6uJzsYpx.

programs/dclutch-trading-sbf/src/direct_token_setup_v1.rs:477 refuses TradingSbfError::Content unless the Market's finalized Direct config reads exactly DIRECT_TOKEN_SETUP_FEE_BASIS_POINTS_V1, which is 50 (crates/dclutch-direct-codec/src/token_setup_v1.rs:25). direct_token_setup_v1 is the sole creator of the seller's and the venue's Direct token accounts, and it precedes every fill. So those accounts can never be created for this market, and this market can never take a fill — not when the checked execution release ships, not ever. A Direct config is a finalized Registry record; it is immutable by construction.

This is a founding parameter, not a defect in the code that refuses it. The stager says so in capitals already:

--direct-fee-basis-points has no default and must be stated. The rate is sealed into the Market at founding and cannot be changed afterwards. PASS 50. Not 0. … Devnet market19 6WZXJ7jB was founded at 0 on 2026-08-30 and is permanently unfillable for that reason alone.

Three markets were already known to be unfillable this way. Cohort-11's is a fourth, founded on 2026-09-01 — the day after that warning was written — at a rate that is neither 0 nor 50. The genesis evidence file records the band, the cuts, the coefficients and the denominator, and does not record the fee rate; nothing read it back, and the founding succeeded, because every stage before the fill is indifferent to it.

And the fill has NO size ceiling — corrected 2026-09-02 by the Direct lane

This section read the opposite until it was measured, and the correction matters because it was deciding the ticket terms. It said a trade whose gross collateral exceeds 199 atoms floors to a nonzero fee, takes a two-CPI branch at 1,515,003 CU, and is "over the ceiling until the second-transaction fee leg ships". The second-transaction fee leg SHIPPED on 2026-08-31 (docs/evidence/FEE_SECOND_TRANSACTION_PAIR_2026_08_31.md), and the two-CPI branch it describes no longer exists in the ordinary Direct fill at all: DIRECT_INLINE_CUSTODY_EFFECT_CAPACITY_V2 = 1 (crates/dclutch-direct-codec/src/inline_candidate_v2.rs:36). tx1 dispatches the seller-net leg and nothing else, at every size. This file's own later section — "The fee does not move at fill time, ever" — is the correct account, and the two passages contradicted each other.

Re-measured 2026-09-02 at HEAD 9c5e039a on five real role ELFs (trading 34430cc7241ff44702df2e5afa6b3fb70b80631c4aa04661e32f0605195e6711, zero frame diagnostics on every role), direct_hot_fee_pair and direct_hot_fee_bearing_margin_gate:

CUagainst 1,400,000
tx1, fee-bearing fill at gross 2001,317,129fits
tx2, DCLTDFS1 fee settlement173,662fits with 1.2M spare
fee-bearing sweep, 32/32 seeds1,312,628 – 1,329,130worst margin 70,870
zero-fee sweep, 32/32 seeds1,309,761 – 1,332,261worst margin 67,739

The fee-bearing arm's key-independent floor is 1,299,128 against the zero-fee arm's 1,299,259 — 131 CU BELOW it, less than a tenth of one PDA bump attempt, which is to say the two are the same route and size does not select a branch.

So a fee-bearing devnet trade is admissible at any gross this market can carry. The reason to keep the demonstration small is the one this file gives later and it is not compute: at gross ≤ 199 both fees floor to zero, so the fill leaves no fee_owed, no maker lockout, and no second transaction to crank.

Standing caution, not a ceiling. Both arms have lost about 31,200 CU of margin since 2026-08-31 — both margin-gate ratchets are red at HEAD for that reason — so the headroom above is 70,870 and shrinking, not a comfortable one.

The producer's own loopback defaults (FILL_ATOMS_V1 = 100_000_000, EXECUTION_PRICE_V1 = 500_000, direct_trade_producer.rs:103) give gross = 50,000,000 atoms and a fee of 250,000. That is not a blocked branch — it executes — but it is a trade that leaves 250,000 owed on the buyer's maker replay and locks that maker out of the market on both sides until a DCLTDFS1 transaction settles it. A first demonstration that keeps fee_owed at zero needs no second transaction and no lockout to reason about, so the terms below stay small on purpose rather than by necessity.

The prepared terms

gross = fill × price ÷ price_scale and must divide exactly (exact_quote_v1, direct_trade_producer.rs:3396):

fieldvaluewhy
--maximum-fill100atoms of claim on one outcome
--limit-price1000000equals price_scale, so gross = fill
gross100≤ 199, so the fee floors to 0
fee0the one-CPI branch, inside the CU ceiling
required_buyer_collateral100gross + fee
--fee-basis-pointsthe market's own configterms.fee_basis_points != config.fee_basis_points() refuses (:2296)
--outcome0must be < claim_count (4) and within the seller's balance
--generation1the Open Market identity generation
--lifecyclefokboth sides; the pair gate demands lifecycle 0
--sidesell / buyseller side 0, buyer side 1, distinct makers

--market is the founding_market, not the Core Market. [Corrected by the 2026-09-02 addendum: the founding_market is the live Core Market account; see below.] The producer takes it from campaign_address_v1(campaign, "founding_market") (direct_trade_producer.rs:2061) — 3rBfDBpaXjKSbUU5HRaRTr6yhDQq4S1oKp2mQRsdoyb6, not ARuPAuyJ…. This is the same trap the routing table set, and it is worth saying twice: on this cohort, "the market" is two different addresses depending on which authority is asking.

The makers are fixed by the chain, not chosen: the seller is founder_position's owner BmDp2LRfAUxPw6qhQr9ceGMoitMtkQf3H547iTS631rv (key held), and the buyer is the admitted participant's owner BffsiBzZYExGVFhMEQgZZjAgujEm5x55wxVUeDtHAHkC (key held). The ticket author never takes a key path as an argument — --keypair-env names an environment variable holding it.

The one preparable thing this lane did not do, and why

The buyer's ticket must name a --collateral-account, and the producer requires that account to hold at least required_buyer_collateral atoms and to carry a delegated allowance exactly equal to it — an equality, not a floor, because "the allowance authorizes one trade and is spent to zero, so more is as refused as less" (refusing_buyer_collateral_clauses_v1, :745). Participant-2 was admitted with collateral: null, so it has neither. The admission driver's --collateral-source-owner/-account/--collateral-quantity-atoms leg creates and delegates it, and re-running the same finalized journal with those flags adds it (resume_admission_and_collateral runs the collateral leg on a Finalized report).

That leg was not run, deliberately: it moves real collateral out of the founder's wallet into a delegated account bound to this market's trade, and this market cannot trade. Doing it would spend atoms to produce an artifact that can never be used.

The exact command, and what it is waiting on

dclutch-local-successor-bootstrap devnet-direct-trade-produce-v1   --rpc-url <devnet https> --i-mean-devnet EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG   --plan          <job>/plan.json                  --expected-plan-sha256 <hex64>   --market-input  <job>/market/market.json         --expected-market-input-sha256 <hex64>   --campaign-report <job>/market/campaign-open.json --expected-campaign-report-sha256 <hex64>   --buyer-participant <job>/sim/admissions/participant-2.json       --expected-buyer-participant-sha256 <hex64>   --checked-execution-release <release.json>       --expected-checked-execution-release-sha256 <hex64>   --seller-ticket <seller.json> --expected-seller-ticket-sha256 <hex64>   --buyer-ticket  <buyer.json>  --expected-buyer-ticket-sha256 <hex64>   --payer 3CZxcpGpWthrdcx55AciJUEPyjZzqHK7UuF7p77yPLyG   --payer-keypair <job>/keys/campaign-payer.json   --output-dir <ABSOLUTE EXISTING EMPTY DIR>

--buyer-participant is satisfied: participant-2.json is a finalized admission report of exactly the shape it wants, and this lane produced it.

What the command is waiting on, by commit:

  1. A market founded at 50 bps. Nothing in the tree fixes cohort-11's 30; the unblock is a founding, with stage-devnet-sponsored-market-open.sh --direct-fee-basis-points 50, cuts centred on spot. Not a release, not a rebuild.
  2. --checked-execution-release, from direct_hot_route_manifest::run_checked_execution_release, which the checked release candidate gates — and the candidate refuses at bfc8383f (the trading stack-frame regression bisected below).
  3. The buyer's delegated collateral leg, one re-run of the admission driver against a fillable market's participant.

What must then be observed

Read out of the codec and the finalization projection, not guessed. A fill writes ten accounts, named by DirectInlinePoststateRoleV3 (crates/dclutch-direct-codec/src/direct_finalization_v3.rs:231-251).

With the founder selling 100 atoms of outcome 0 at gross 100, fee 0:

observationbeforeafter
seller Position claims[500000000, 500000000, 500000000, 500000000][499999900, …] — checked_sub(fill) at :1481
buyer Position claims[0, 0, 0, 0][100, 0, 0, 0] — checked_add(fill) at :1479
Claims aggregatesupply [500000000 × 4]revision +1, supply UNCHANGED — the projection passes None for the balance selector (:577-583)
buyer token account100 atoms, allowance 100amount −= 100, delegated_amount −= 100 → both 0, delegate cleared because the fee is zero (:1326-1342)
seller Direct token PDA0+= seller_net_collateral_credit = gross − seller_fee = 100 (:625-633)
venue fee token PDA00 — the fill never moves it, at any size
Hoard500000000500000000, delta exactly 0
seller + buyer maker replay rootsvacantcreated, next_nonce +1 each, ~2,004,480 lamports rent each
Custody replay cursor—next_revision +1

Two things this lane had wrong in an earlier draft, corrected from the source:

The conservation declaration a fill must carry is --declared-collateral-delta 0 --declared-hoard-delta 0. Zero is the strong claim here, not the absent one: the fill is External → External between two accounts that must both be tracked, so the tracked total does not move, and the Hoard is not a party at all — the Direct path never touches it. L1, L2, L3, L4, L5 and L6 must all read holds; L7 and L8 are unconditionally inapplicable under ledger-census.

Two census bindings must be added before the fill or two laws correctly report a shortfall. Both are now closed, and the laws that catch them are tested:

And the laws themselves had never judged a fill. Every boundary this ledger has ever evaluated was a founding, an admission or a vault transfer; the single Direct fill this substrate has taken (FIRST_LOCAL_DIRECT_FILL_2026_08_31.md) was read back by a hand-written script, not by the census. So the first real fill would also have been the first test of the laws judging it. tools/gauntlet/journey/src/ledger.rs now fakes one: a two-outcome market where the seller sells 100 claims for 100 atoms at a fee that floors to zero, with L1–L6 and L8 asserted by name across the boundary, and three red proofs — the unnamed token destination (L1 short by exactly the traded atoms, L3 green beside it), the untracked buyer Position (L3 short, L1 green beside it), and a fill that declares a Hoard delta it did not move (L2). aggregate_supply is passed rather than summed from the Positions, so L3 holds only because the fill conserved the vector rather than by construction.

The genesis release candidate: it finally ran, and it refuses

Five attempts. The first three ended for reasons that were not the candidate's; the last two produced verdicts:

  1. At 8ae2c9c9 (the previous lane): thirteen SBF links, freshness gate, all thirteen frame reports and provenance descriptors — then died on the stale successor Cargo.lock that b2ac8a79 fixes, because the candidate archives the source of the commit it is handed and 8ae2c9c9 predates the fix.
  2. At 659d6f26: exited 1 during the registry link. Its work directory had been deleted underneath it by an unrelated /private/tmp sweep — the volume is at 96% — so the reason cannot be read and most likely was the deletion.
  3. At ae1c2bd4, in a work directory a sweep cannot reach: all thirteen SBF links built, SBF build freshness PASS links=13, build-diagnostics.txt all zero including trading, the release tool built — and then the process group was torn down. (nohup ... & does not survive this harness and macOS has no setsid; the fourth attempt was launched with start_new_session=True and ran to completion.)
  4. At 803ee31c: it finished, and it refuses. Two causes, both real, and neither this lane's.

The verdict, at last: two refusals

BUILD DIAGNOSTIC: trading emitted 3 SBF stack-frame overwrite reports
Error: A function call in method
  _ZN19dclutch_trading_sbf6hot_v328execute_authenticated_hot_v3...E
  overwrites values in the frame.
SBF build freshness PASS links=12
refusing: checked Upgrade admission requires the exact 13-link shipped set;
          enumerated 12

dclutch-dealer-sbf was deleted at e6b7bf1a — "the prototype the C-06 tier was witnessing" — taking SHIPPED_LINKS from thirteen to twelve. aa7f8892 swept the two Rust readers that went red. This shell gate was the third reader, and nothing turns it red: it hardcoded != "13" and refused every candidate at HEAD after building all twelve links cleanly. Fixed in 0f0ec379, which also writes down the debt it does not pay — the count still lives in two places, and the honest repair is for the successor binary to print its shipped set so this script can compare content rather than count.

hot_v3::execute_authenticated_hot_v3 grew past its SBF stack frame at bfc8383f — "hot: the tail-count agreement was unsatisfiable for every fixed-topology profile". Bisected to that single commit with two SBF builds of dclutch-trading-sbf from detached worktrees:

commitframe-overwrite reports
bfc8383f^ (723eed12)0
bfc8383f3

All three name the one symbol _ZN19dclutch_trading_sbf6hot_v328execute_authenticated_hot_v3…E. A frame overwrite is undefined behaviour at execution, not a warning, so the candidate is right to withhold the artifact — and this is the hottest route the protocol has.

It was still 3 at 5de38ef2 and still 3 at be67416e, each re-measured with a targeted dclutch-trading-sbf build rather than a whole candidate run — the narrowest thing that could refute "still regressed", and measured rather than inferred from the commit log, because a dependency change can move a stack frame without touching the file.

58b077f8 fixes it, and the count is zero. Direct's repair — "restore execute_authenticated_hot_v3's frame, and name what it cost" — was measured here the same way, at 83a8d0c7 (which contains it, with no later hot_v3.rs change): 0 frame-overwrite reports. Independently confirmed by a full candidate run at that commit, whose build-diagnostics.txt reads zero for all twelve links, trading=0 among them. The bisect table above is closed: bfc8383f broke it, 58b077f8 restored it.

The control is closed as a refusal, not as a pass. That is worth more than another queueing: for two days it could not say anything, and now it names two things nothing else was watching. Neither blocks cohort-11, which runs bytes built at 8ae2c9c9, where trading was clean and dealer-sbf still shipped.

With the link gate repaired at 0f0ec379, the fifth run got past it and refused on the substance instead, which is the whole point of repairing it:

BUILD DIAGNOSTIC: trading emitted 3 SBF stack-frame overwrite reports
SBF build freshness PASS links=12
refusing: 3 SBF build diagnostics; fix them at their owner, or re-run with
          --allow-build-diagnostics to record them explicitly

The link-count refusal had been masking this one. The trading stack-frame regression at bfc8383f is the open residue, left to its owner with an exact commit rather than a window.

Devnet evidence. Not mainnet evidence.

Addendum, 2026-09-02: both addresses are Core Markets, and the admissions landed on the right one

Read from chain today, Helius devnet RPC, finalized commitment, by getAccountInfo on each address; the API key was read from ~/.helius-key at use time and is not reproduced anywhere. Nothing was written.

The two-address trap this file names is real, but its labels are backwards. This file says 3rBfDBpa… is "the founding_market, not the Core Market" and that ARuPAuyJ… is "the Core Market". On chain both are Core Market accounts — DCLTCOR3, 368 bytes, owner FinXxc9dr… — and the live one is 3rBfDBpa…:

addressgenerationphase / readinessderived Claims aggregate
ARuPAuyJbJoLdMWGDzSqvcV9py25EkmMj8ABnfKP56s1Founding / PrepaidERd4rTg9… — VACANT
3rBfDBpaXjKSbUU5HRaRTr6yhDQq4S1oKp2mQRsdoyb62Open / Consumed5wdhigoU… — exists

COHORT11_GENESIS_FOUNDED_2026_09_01.md carries the same error in its founding table and now carries the same addendum.

THE ADMISSIONS LANDED AGAINST THE ACCOUNT THIS LANE NAMED, and that account is the right one. The producer took --market from campaign_address_v1(campaign, "founding_market") = 3rBfDBpa…, and both participant Positions read back off chain confirm it:

accountmagicits aggregatePosition owner
5SYqhNVT8hUetS6GopkxdVNXWpKfHG1CpMwwZKXzVtAPDCLLBP02, 160 B5wdhigoU…5nTAZrNL…
4AHZpdJi8RFoh2VUKGuNqzgnqqjzXA5x2naHq8t5MjueDCLLBP02, 160 B5wdhigoU…BffsiBzZ…

and 5wdhigoU…'s own LOGICAL_MARKET field (bytes 24..56) reads 3rBfDBpa…. Both admissions G5JTNALR… and 48KkQPsu… are 512-byte DCLPPS02 accounts owned by Claims. So the execution was correct throughout and only the prose mislabels which of the two addresses is which.

Derived, not inferred. find_program_address(["dclutch:lbv2:market", market], HQYqqdzn…) reproduces 5wdhigoU… from 3rBfDBpa… at bump 250, and gives ERd4rTg967WjVoezjFzko8rGtXrz9XDrJ2URvk8LcZ7U for ARuPAuyJ…, which has no account. That is the Redemption lane's "derived aggregate vacant" measurement, reproduced from a second direction.

What this does not change. The frozen-routing-table finding stands exactly as written: getProgramAccounts over the ALT program returns nothing usable on devnet, the search answered an absence rather than a refusal, and the two reads by address that replaced it are still the fix. The predicate was wrong for the reason given — it looked for the wrong address — and the correct address to look for is the live Core Market 3rBfDBpa…, which is what the table routes.

Devnet evidence. Not mainnet evidence.