Cohort-12: a fillable market at last, and the wall standing behind the one we knew — 2026-09-02

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

Tree root /Users/ember/dev/dclutch. Every deployed byte is built from e39efbb0b31afeb7a03b10a71b6e2e5d6da0e040, the commit COHORT12_RELEASE_GREEN_2026_09_02.md recorded the first green checked-release-candidate.sh --genesis-cohort at. That file staged this work and stopped deliberately before the first irreversible step; this is the sequel, and it spends.

Headline. Cohort-11 is closed, cohort-12 is deployed, laddered, and founded at exactly 50 basis points on cuts centred on a measured spot; two strangers hold Positions and the buyer holds an exactly-delegated allowance; five routing tables are the first on-chain proof that dc07c73a froze them. The fee-bearing trade did NOT execute. It is blocked by a wall nobody had measured, and the wall is structural rather than incidental: a full-redeploy cohort can never produce the checked execution release a Direct fill demands. Section 8 is the finding.

1. Cohort-11 closed

Irreversible, and the reason the redeploy could be afforded: the deployer held 38.738044775 SOL and the seven new programs cost 42.03. Program ids derived from cohort-11's own keypair files, never transcribed from its evidence doc.

rolecohort-11 program idrent reclaimed (SOL)
trading4fhQyBPgvaZw6jEWwT3U64tHfgTNRPuWuH5MjPLrxjzk14.487909105
coreFinXxc9drpmCYA7Cy4aGWSa1jYY87K6pNPfY9qFWzJCF7.556972577
claimsHQYqqdzn5s6tEM6ywgeCr7Bd56tEuhpoop3ruvHRfAq68.654608137
registryADB72ar6ZSstXEg76Q1bPb5UY2EGmH6mrVfwr8K2fzom1.486412097
rentHA31aDmTnLFjBYQoCXeyRBsfdddxne1apyfzfq4tSp8e0.902408169
custodyCdh8Vv7DRyk7rhLcee574potYfaiVEsYR5HUPCrNPzCB3.619974465
resolution3WqTxq6uKMK2d9f6uRujh8hCZvVB78KjGo9AYxvPQNVM5.183820153
total41.892104703

Deployer 4zrxtw5c4oPLpuTQbLYjRCXFUudvFCNNjzR9LqVQvEwP: 38.738044775 → 80.630114478 SOL. The 41.892069703 that actually arrived is the table's total less seven 5,000-lamport fees, which is the arithmetic closing exactly.

Cohort-11's market is now unreachable. It could never have taken a fill anyway — founded at 30 basis points, where direct_token_setup_v1 admits only 50.

2. The redeploy

Seven programs, fresh identities, each verified by dumping the on-chain image back before the next one started. Every dump is byte-identical to the ELF: the prefix compares equal and the on-chain tail is all zero.

roleprogram idbytesELF SHA-256deploy signature
registry5c4CfHXHaLoJRtVSZFURp6Qhub8P4x8Hk4yZ3KJNrK53234,536ed70f8bda12b77d663126218ad05f36dd77c5bf3100642879cef1441a845afe72ShFZNRHJfqtqK7sKYmkv8b5S25wNhhUUD2ExEUqvtTPqJZZXvv9nz4VZoq4GfanurnJVAfT1w2tswKXW4sfhQ8T
rentHD72aKvtRzBrVdmDGn8UrcocVA6g4NuG9Bt94GRLMYcW142,320d46e5f0a64fd7d5e296118c2e7a62a3b67aed2c2ac4420e85069fb8dca6328375qn1XVjNSWvd5avBZLjQbRsNFSUroLCA57GnpCuwaUdJeU7djtxy8yJR9Hh5kvBKs3i27s7EozjCYCGNXuTZHwCm
custody2MHNgYoCtDzqRryjgAxzFwLVPztSN6NTUr7RmjiMrcLc571,4322823c82351638566e295d7f7acc2e559ab61b3ea43750759e84f73bc0f80d56741vXQzNG8fxytGEtsMz7M8mmj1ACgEjUDsf5GqSB3AY97H7ZAE7FPRm6hFzB6NtReUcuxGs5gf6EqL8wsCVJuqpp
resolution9vs7atqDTAZTMo2a9iMZXD6Nf39jQZ7sZFf2X4pGDDvs818,368307bc81c604f1a3c52a0dc5ff1b66b094f12faf6be8f8d66b7d337e08c8873e02WzwBeremdsUA2s2PanpvUP5jDU6iChEmef3XDrLLrxLm35geQM9Gix1424t84LLxyX9b124r5c58ijB4QUu8JYh
claimsGwduZB13AgqLxsoxi8wZEQndYBsQERea35dhuYKJzCvc1,366,416268d527e600706b9062921e0a35f0ea2ba13f5bc7790a4351b6b7f0fff5e910f3fA5YCCwFMzc3aEKtDehTbhgYhzAw3uMZw8kQn3Sx3wtMrYy8dsYDkFmj5yLwBzSvjUhreoCu31YJ57vvrRAvsG7
tradingAhzug4zYhG8sc4t6tXjaSjnqbv7bTkgNYRc4kWUxYGJe2,308,320b0cff55ab0ef162d7e427b8cb894f1468b1804d997ab35c52710df3268a8e3ed4UhtrTbaYgKf65NGUyrUG5kGm7GsGtuW78bJyj7y65DrQo97cScRjiB1a4kfstkuLG5HFVsi9XX8RWLSYT3AZYuL
coreG4Wz4fj4zqBPFWYFF9CeYeJtTK5UqSZUu2fyCr9ANjYG1,187,4329ef7df559565effb780db6b26bf9fd3c89cefb2b86ae5205d37c688d1a5ea58b2fjKzdinW7XjDiGoBQdWjtbWLjYVn2tX1SSLYijc6g4tak5XbnsXHNwhuTHdecxFWhWy1SnUnm9umNhQ21AokDaX

The seven ELFs were built twice, in two independent detached worktrees at e39efbb0, on the ordinary release invocation rather than the candidate's --features hot-cu-profile trading link, and are byte-identical across both builds. Registry, rent and custody are byte-identical to cohort-11's; the other four carry everything between 8ae2c9c9 and e39efbb0, Direct's frame repair 58b077f8 among them.

All seven are mutable under the deployer's ExactAuthority, as cohort-11's were, read back off chain rather than assumed:

roleProgramDataauthoritylast deployed slotdata length
registryFbfJYjjyULLJYX8wzXqv5M5U2fxWLhCwwhvWaxCfWAsu4zrxtw5c…491,871,867234,536
rent7kuFuNDjMGTeYqodG3Aq8ynSBLdN6rLQsSWDyF5mvMGp4zrxtw5c…491,871,910142,320
custodyHCiJ7DfkqLagqQPfGQ5sXUXPyMuttds8EvtSQGEaVH4f4zrxtw5c…491,871,984571,432
resolution2XiYgQfRAKivMxWaTZLpRZbXtvN14WUKGv7acriTWhcW4zrxtw5c…491,872,069818,368
claims9gA7cT9mhFwDLjFzWYprzE44Vzu8U9e8tgArrSAL3uJL4zrxtw5c…491,872,1861,366,416
tradingGx2b9xPmUcyLN79DHy9ExncTnAmedXX3pVmRpG2zVqqA4zrxtw5c…491,872,3742,308,320
core6wzSk1ip5uuiiqQoCDUuJPNjDZdHtdaJZL5DSQHG4kcy4zrxtw5c…491,872,4871,187,432

And a third, independent agreement: capture-and-prepare.sh hostile-decodes each live ProgramData account and hashes the ELF tail it actually carries. For all seven roles live_elf_tail_sha256 == built_elf_sha256. The dump comparison, the byte count and the tail digest are three different instruments reading the same claim.

Deployer 80.630114478 → 38.601927539 SOL; the redeploy cost 42.028186939 SOL.

3. The ladder, re-observed from chain

campaign --through activation, executed with the deployer as Core upgrade authority. The runbook's ladder script refused first, and correctly:

Error("campaign omitted required keypair paths: campaign-payer")

administration_required_roles_v1 adds the campaign payer whenever the succession stage is Absent or Partial, and it is Absent here. So the payer was funded first and the flag added — the refusal is the tool declining to open a signer for a stage it cannot pay for, before any key was read.

33 transactions, zero errors, 4,084,967 CU, 2,475,000 lamports of fee: 27 record publications in Begin/Append/Finalize triples for nine records, one initialize Core infrastructure profile (both profiles, one instruction, 254,739 CU), and five activate immutable release-set role — Core 635,845, Claims 714,192, Trading 1,184,004, Resolution 449,898, Custody 338,997 CU.

Succession executed nothing, and said so rather than being assumed:

campaign stage succession: nothing to execute -- this cohort is born at V2
and carries no ceremony; observed complete

Re-observed after the run, by a second preflight that reads the chain rather than the driver's own exit code — the discipline cohort-10 paid for with 2 SOL of landed work its tool had reported as failed:

stagestate
substratecomplete
publicationcomplete
initializecomplete
successioncomplete
activationcomplete

Deployer 38.601927539 → 36.564742699 SOL, which reconciles exactly: 2 SOL to the campaign payer, 5,000 lamports for that transfer, 2,475,000 lamports of ladder fees, and 34,704,840 lamports of rent now sitting in the nine published records.

4. The market, founded at exactly 50 basis points

The cuts were re-centred, because the runbook's were three months stale

Cohort-11's --cuts 14800,15200 --band-anchor 15000 centred a $150 SOL. Read on 2026-09-02 from three independent venues — Coinbase $100.005, Kraken $99.970, CoinGecko $100.04 — and then from the account the market itself resolves against, the sponsored devnet PriceUpdateV2 7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE:

price 10003917148  expo -8  conf 1082854   =>  $100.03917148

Founding on the runbook's numbers would have asked whether SOL ends between $148 and $152 when it is worth $100 — a market whose answer is already known, which is precisely the defect centred_cuts_v1 and the founding band exist to refuse.

So: --cuts 9800,10200 --cut-denominator 100 --band-anchor 10004 — $98.00 and $102.00 straddling a measured $100.04, with the anchor stating spot rather than a round number. Under the triangular model the band implies (volatility 200 bps over a 10,000-slot window, three plausible half-widths: a characteristic displacement of $2 and a plausible range of $94.04–$106.04) the three ordinary cells carry roughly 22% / 56% / 22%, well inside the 9,000-bps ceiling MAX_CELL_EX_ANTE_SHARE_BPS_V1 enforces.

The rate is the one thing that could not be got wrong twice:

directFeeBasisPointsPerSide        50
directTokenSetupAdmitsThisRate     true
feeRateIsIrreversible              true
maximumGrossCollateralAtomsWhoseFeeFloorsToZero  199

Four devnet markets before this one were founded unfillable — three at 0 and cohort-11's at 30 — because every stage before the fill is indifferent to the rate. This one is the first that direct_token_setup_v1 will admit.

5. The routing tables, and the first on-chain proof of the freeze

Since dc07c73a — "routing: every routing table is frozen, because a mutable one is both halves of the route" — publish_routing_table refuses unless every table it publishes reads back owned by the Address Lookup Table program, with authority None, deactivation_slot == u64::MAX, last extended strictly before the observation slot, and byte-exact addresses. dc07c73a is an ancestor of e39efbb0 and is not an ancestor of 8ae2c9c9, the commit cohort-11 was built from. No cohort has founded since it landed, so cohort-12's founding is the first on-chain proof, and cohort-11 is the control.

Read by address, never by scan — 8fda79bf established that getProgramAccounts over the ALT program answers an absence on devnet rather than a refusal, so the addresses come from each founding's own CreateLookupTable transactions, where the table sits at account index 0 of its own instruction.

The control, cohort-11 at 8ae2c9c9: five tables published, and only the one its own label calls frozen is authority-less.

tablelabelauthorityaddresses
6in3trBkcQYGVhq2pRkgiwq4YYYvmm5PX7ExDB7QuKW5Found373CZxcpGp… mutable36
7a6vYnjrz1F4fwcj8tUhXEMJcGRHWRUnTpdfuRRf9TVSDCLTCFQ13CZxcpGp… mutable46
EMtgeNZMvcgY5xfbC7k2XXEYz1AM2L92keDqH6AXV8DdDCLTCF1A3CZxcpGp… mutable16
6Q5Gvq21kQRp5rcEccv1xvAqUtokSfCAtHsH1ALph2NfDCLTPCB23CZxcpGp… mutable57
6Pwb16HHphgvDbr6RW4p7k82qTGDccQHizJzk3LDXZwkDCLTGMF3 frozenNone64

Four of cohort-11's five routing tables are still held by its campaign payer today. That is exactly the shape dc07c73a closed: a table whose authority survives its publication is both the route and the power to change the route.

Cohort-12 publishes five, and all five read back frozen. Re-read by address at observation slot 491,885,451, every one owned by the ALT program, not executable, authority None, deactivation_slot 18446744073709551615 (u64::MAX), last extended strictly before the observation slot:

tablelabelauthoritydeactivation_slotlast extendedaddresses
83ZLegT7FhPJkSRSV66T7LfwTHzu9wL26WqFqns6cU7bFound37 frozenNoneu64::MAX491,882,17635
8qpF6HVeEoceSgfY3LBqqmQRoxnpfnh5sz3SLcpU5rdjDCLTCFQ1 frozenNoneu64::MAX491,883,11145
9gDFww7wUbAzdT3ywudT2moCNQXACdCzdYkL95A3FZXwDCLTCF1A frozenNoneu64::MAX491,883,36015
7HWmjshupa7hEWigbAG2FHJjqqfhqSN2PLGEH9DdoYzHDCLTPCB2 frozenNoneu64::MAX491,883,61256
HvZktruUHznQNC2CY93BR7bARaZrHLM2zmCkQQ9eNdoEDCLTGMF3 frozenNoneu64::MAX491,884,71262

The transaction labels changed with the code: cohort-11 emitted "create Found37 routing address lookup table" and no freeze for four of the five; cohort-12 emits "create Found37 frozen routing address lookup table" and then "freeze Found37 routing table after its one complete extension plan" for every one. dc07c73a is proved on chain.

It has a cost nobody had measured, and it is the founding's new dominant term. A frozen table is usable only strictly after the slot that last extended it, so each freeze must finalize before the next table is created. Cohort-12's founding took 186 transactions over roughly 40 minutes, against cohort-11's 188 over about 26 — the extra quarter-hour is four additional freeze-and-await-finalization barriers, not extra work.

6. Which address is which, read off chain

A founding produces two Core-owned DCLTCOR3 accounts of 368 bytes and the campaign labels do not say which is live. Read at byte 10 (phase), byte 11 (readiness) and the u64 at 272 (identity generation), with each one's Claims aggregate derived rather than inferred:

campaign labeladdressphasereadinessgenerationderived aggregate
market9jJqs6UA1KhCspJZ3ACW9yq9cn9Gp13zbkhTrLj1FdH20x00 Founding0x00 Prepaid12J2vfzg2… bump 254 — VACANT
founding_marketEQnYCUMkzSG2pHnzkdEC7vxqYgabPgBserq9oS4VmGs10x01 Open0x02 Consumed2GZzSimhqU5o7XDoUCSMq1szM7xt29Ae9zwExMbpa48WU — exists, 288 B

The OPEN Core Market is EQnYCUMkzSG2pHnzkdEC7vxqYgabPgBserq9oS4VmGs1, and the founding record still in Founding/Prepaid is 9jJqs6UA…. The same instrument reproduces cohort-11's addendum exactly — ARuPAuyJ… Founding/gen 1 with a vacant ERd4rTg9… at bump 253, 3rBfDBpa… Open/gen 2 with 5wdhigoU… at bump 250 — which is the positive control for it.

Note the generation: the Open market is generation 2, not 1. Cohort-11's prepared trade terms table says --generation 1, "the Open Market identity generation". That is wrong in both cohorts, and the producer reads the generation off chain and refuses a ticket that disagrees.

7. Two strangers admit, and the buyer arms itself for the fill

Through the load simulator, against the live Open market, fee payer the campaign payer and never the deployer.

whataddressbytesowner
participant-1 ownerFrvzdn6QupyCGRQEbXo7kCgkuxYLWYFfwiJzbLSdtF9Q
participant-1 PositionAKYMkQD4BZKZytdGAh9v2BkfC8jY2tdDqqkun4o1EFRn160 DCLLBP02Claims GwduZB13…
participant-1 admissionFLpPZvTCTFBgJsKA7UTt9Yw8GYZYkKVSQNxxwwEvMFfa512 DCLPPS02Claims GwduZB13…
participant-2 ownerDNX9dDu4YyGgGGGAfaCqw6ed5EEZWsu33AYg55tSPL8Y
participant-2 PositionGLgV7gJJdaLbtJ6bx1dPNDvbqZsCW7UYYcfq4AgDgBB6160 DCLLBP02Claims GwduZB13…
participant-2 admission8ARZMtT9EYM9m7saymDcZ9yafwuz6s6vFwmsrM9GZYUu512 DCLPPS02Claims GwduZB13…
legsignatureslot
participant-1 admission25JqtNCRjVHeCEEnFiiMSbLtPF1JYjfFZPQCirMFaWUtKcUrsczJYqLJiQursiTm7Y5MAKDhXvHZNNv2yuyXJ2dq491,887,654
participant-2 admission4RoGqjMDfB3ZsUGcPyCjBnmEZpDJP7U4Df95Cjx8ukz3oqdnnPtcDUdE7gczdxots7efpVxSm1Fwq959N7HtHc2m491,887,968
participant-2 collateral5aegz3ChQSKmVgxtsBPmwdHYwoMZrrW3QxixDKnbDTEvdkjfbBfm4kGGr5dooVuExRB7JRAkQVExjSvpqVfU5FzW491,888,047

Cohort-11 stopped short of the collateral leg on purpose, because its market could never trade. This one ran it, and the buyer's account reads back exactly what the producer demands — amount 201, delegated_amount 201, an equality and not a floor, because the allowance authorizes one trade and is spent to zero:

9GgaqNyk4prm2zwoGvzfFZddPLi1qkGQMtNBSr5VzWdY  165 B  owner Token-2022
   amount 201   delegate present   delegated_amount 201

201 is gross + buyer_fee for the fee-bearing trade this cohort exists to demonstrate: fill 200 at limit price 1,000,000 against a price scale of 1,000,000 gives gross 200, and floor(200 x 50 / 10_000) is 1 — the smallest fill at 50 bps whose fee does not floor to zero.

The preflight run poisoned the execute run, and the chain caught it

simulator.py run without --execute writes a durable Planned admission journal. The subsequent --execute run resumes that journal rather than replanning — and the prefund branch is taken only under --execute, so the resumed plan still carried its two System top-up transfers inline. The Position owner is debited by them, a debited account is writable, and UserPositionAdmissionFrameV1 requires the owner to sign readonly. The program refused:

Error processing Instruction 4: custom program error: 0x4003   (TradingSbfError::Content)
consumed 12233 of 1399400 compute units, no CPI
positionTopUpLamports 1823904 + admissionTopUpLamports 4053120 = 5877024
instruction 0: System, Frvzdn6Q… signer WRITABLE
instruction 1: System, Frvzdn6Q… signer WRITABLE

12,233 CU and no CPI is cohort-11's Wall 3 signature exactly, and the cause is the same message-level owner promotion — reached by a different route. Cohort-11's repair (require_fee_payer_never_declared_readonly_v1) closes the fee-payer half; this is the rent half, and the driver already closes it too, by prefunding in a separate finalized transfer. What is not closed is that a preflight journal survives into the execute run and skips that branch.

Nothing landed: the signature 7fc5cLEJ… was confirmed absent on chain and all four PDAs vacant before the journals were archived (to sim-archive-01-preflight-planned/, never deleted) and replanned. The replanned admissions carried zero top-ups and both finalized first try.

The lesson is narrow and worth writing down: on this driver, a preflight is not free. It leaves a plan the execute run will adopt, built under different assumptions than the one that will spend.

The census caught the collateral leg, and was right to

With the two Positions admitted and 201 atoms moved, the first census halted loudly:

VIOLATED L1: tracked 999999799 atoms across 2 accounts != Mint supply 1000000000;
             201 atoms are in accounts this ledger does not name

Exactly the 201 atoms the collateral leg had just moved, into an account nothing had named. Not a protocol divergence — a law asked to check a total over a set missing a member. Three bindings were added: the buyer's delegated collateral account in census.tokens, and both admitted Positions in census.positions (the buyer's before the fill, or L3 falls short by the traded atoms at the traded outcome). With them supplied:

HOLDS L1: tracked 1000000000 atoms across 3 accounts == Mint supply 1000000000
HOLDS L3: 3 Positions sum to the aggregate supply vector [500000000, 500000000, 500000000, 500000000]
HOLDS L4: Hoard 500000000 >= worst outcome 500000000 x unit 1 = 500000000
INAPPLICABLE L2, L5, L6: the first census has no predecessor
INAPPLICABLE L7, L8: external census -- the transactions between boundaries were
                     not driven by this ledger

That is the pre-fill baseline, and it holds.

8. THE TRADE IS BLOCKED, and the blocker is structural

Everything the fee-bearing trade needs is in place except one artifact, and that artifact cannot be produced for any full-redeploy cohort.

devnet-checked-execution-release-v1, given cohort-12's plan and the five checked.bin from the green candidate, refuses:

REFUSED: [checked-execution/plan-unsealed]
         devnet plan omitted its authenticated permanent checked deployment set

The conjunct is one line — direct_hot_route_manifest.rs:375:

let set_pin = plan.checked_upgrade_set.as_ref().ok_or_else(|| { ... })?;

plan.checked_upgrade_set is populated only by prepare --deployment-set-journal (main.rs:1411), and that journal is audited by devnet-deployment-set-journal-v2, whose own documentation states the shape it demands:

Registry and Rent must be CarryForward under one exact finalized nine-account snapshot and exact live dumps; Custody, Resolution, Claims, Trading, and Core must be receipt-backed Upgrades. … only two fresh carries plus five fresh receipts produce the v2 final digest.

A full redeploy performs no upgrade, so it can produce no Upgrade receipts, so it can have no deployment-set journal, so its plan can never be sealed, so it can never yield a checked execution release, so it can never take a Direct fill. The command is an auditor, not a producer — handed a path that does not exist it answers set journal … cannot be inspected: No such file or directory.

Measured across every cohort on this machine, and it is not a cohort-12 accident:

cohortlineagedeployment-set journalplan.checked_upgrade_set
7upgradeupgrade/deployment-set.jsonSEALED
8upgradeupgrade/deployment-set.jsonSEALED
10full redeployabsentNone
11full redeployabsentNone
12full redeployabsentNone

The two sealed plans are exactly the two upgrade-lineage cohorts. Since cohort-9 every cohort has been a full redeploy, because that is condition (a) of the standing devnet grant — "full redeploy only … fresh identities, the old cohort abandoned in place; no partial or incremental program deploys."

So the standing grant's condition (a) and the checked-execution requirement are in direct structural conflict, and have been since cohort-9. This is the real reason no Direct fill has ever executed on devnet. Cohort-11's file names the blocker as the red release candidate and lists the checked release as item 2 of three; the candidate is green now, its five checked.bin exist and hash correctly, and the next wall was standing behind it unmeasured.

This lane stops here rather than improvising past it. The two routes onward are both outside what this lane may decide:

  1. Seal a redeploy cohort without an upgrade lineage — teach prepare to accept a checked deployment set (seven fresh receipt-backed deploys) as it accepts a checked upgrade set. This is the honest fix: the artifact the fill needs is a statement about which bytes are live, and a fresh deploy can prove that at least as well as an upgrade can. It is a change to the plan schema and its authenticator, and it needs an owner.
  2. Run one cohort as an upgrade of cohort-12 rather than a redeploy. Five devnet-upgrade-v1 runs would produce the five receipts and the journal. It costs another full upload of the five large ELFs (the deployer holds 36.56 SOL against a ~42 SOL redeploy) and it is explicitly not what condition (a) authorizes.

Fabricating the journal was never an option: authenticate_complete_deployment_set_for_prepare_live revalidates every row against the chain.

What is nevertheless proved about the trade

What is NOT proved, and must be said plainly: the fill-boundary conservation laws landed at 49c8fa92 and be67416e still have never judged a real fill. They are exercised only by the faked fill in tools/gauntlet/journey/src/ledger.rs. That remains the first real test, and it is still queued.

9. Cost, against the budget stated before spending

Stated in advance: at most 2 SOL per step beyond the deploy itself, and stop at any step that would exceed it without an executing result.

stagedeployercampaign payer
before anything38.738044775—
after closing cohort-1180.630114478—
after the seven-program redeploy38.601927539—
after funding the payer and the ladder36.5647426992.000000000
after the founding36.5647426991.663405281
after funding two participants36.5647426991.563395281
after the admissions and collateral leg36.5647426991.561349712
stepcostagainst the 2 SOL bound
redeploy (the deploy itself, exempt)42.028186939—
ladder: 2,475,000 lamports fee + 34,704,840 record rent0.037179840within
campaign payer capitalization2.000000000at the bound, by design
founding0.336594719within
two participants0.100000000within
admissions + collateral (fees + participant PDA rent)0.013799767within

The deployer has not moved since the ladder. Every population lamport came from the campaign payer, never the deployer.

10. What remains, and who owns it

  1. The checked execution release for a redeploy cohort — section 8. Until an owner takes one of the two routes, no full-redeploy cohort can take a Direct fill, and the fill-boundary laws stay untested.
  2. Resolving this market. Three things stand between EQnYCUMkz… and a terminal payout, and all three exist: - the relay — devnet-sponsored-push-v1, which reads the sponsored PriceUpdateV2 7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE, derives the immutable candidate and canonical head from the authenticated release, and binds the executing Resolution deployment through the active release set; - the observable — SOL/USD in USD cents over denominator 100, against cuts $98.00 and $102.00, resolving into one of four outcomes at the window this founding stamped; - the resolution — flagship-resolution-v1, devnet-capable in three phases: --produce-input (key-free, needs --pyth-facts from the relay), --provision-tables (three exact typed tables, one journaled create, ordered extension or freeze per invocation), then the executor --through submit|execute|reclaim|complete. - the retirement path is the gap. Terminal settlement has devnet-terminal-sequence-v1 and devnet-wallet-terminal-payout-v1, but AggregateRetirement is owned-loopback only — COMMAND_V1 is local-private-validator-aggregate-retirement-v1 and there is no devnet arm. So this market can be resolved and paid out on devnet, and cannot yet be retired there, which is the only route to an empty aggregate and the collateral. The founder key is held (5YzYwcwio7wm88CXdh6ir8w3xstfwRcwU7ZFRtJ3aLRq), so unlike the three markets decision 0015 section 8 names, this one is not stranded by a lost identity — only by a missing driver. That is a well-shaped lane: relay, resolve, pay out, and name what retirement needs.
  3. The web lane's redemption test — handed off with the market and both participants.

Devnet evidence. Not mainnet evidence.

Addendum, 2026-09-02: the sealing route was tried, and there are three more walls behind the first

The coordinator's reading of the standing grant is right — condition (a) forbids a partial deploy, not an upgrade of the whole set, and cohorts 7–8 sealed exactly that way. So the route was attempted. Every step below is a measurement, taken key-free with --preflight; nothing was signed, sent, or changed. The deployer sits at 36.564742699 SOL, unmoved, and every live program is byte-for-byte what section 2 recorded.

First, two facts that reshape the goal

Any upgrade mints a new release set, even to identical bytes. release_facts binds (elf_sha256, deployment_slot, upgrade_authority) (plan.rs:1080-1117), so the deployment slot alone moves release_set_id.

And the founded Market pins its release set immutably. Read off chain at STATE_SELECTED_RELEASE_SET_OFFSET = 208:

EQnYCUMkzSG2pHnzkdEC7vxqYgabPgBserq9oS4VmGs1
  selected_release_set = 797e83ac0522787898b24a963182b846f61f96c6968e4bfdbfbb8dc5bcf7e9a1
  plan.release_set_id  = 797e83ac0522787898b24a963182b846f61f96c6968e4bfdbfbb8dc5bcf7e9a1   MATCH

So upgrading to seal would strand the market this file just founded and handed to the web lane: the fill would need a second founding under the new set. The activation account is per-release-set (find_program_address([ACTIVATION_PDA_DOMAIN_V1, release_set_id], registry)), so the old activation survives — the market stays Open and resolvable. It simply becomes unfillable, exactly as cohort-11's did, for a different reason.

Wall B: an upgrade may not re-upgrade to bytes already live

Measured, as a positive control, by placing the gate's own trading ELF and re-running the custody preflight:

Error("current live payload already equals candidate without a bound receipt")

upgrade.rs:4543. So "upgrade the five to the same bytes to mint receipts cheaply" is refused by design. A receipt requires a payload that actually changes, which requires a new checked gate at a new commit.

Wall C: the checked gate can never authorize the trading bytes a cohort runs

This is the deepest one, and it has nothing to do with redeploy-versus-upgrade.

checked-release-candidate.sh builds dclutch-trading-sbf with --features hot-cu-profile, a diagnostic profile. build-elfs.sh deliberately does not — "a diagnostic profile and not what a cohort should run". So the gate's admitted trading artifact and the cohort's deployable trading artifact are different by construction:

trading ELF SHA-256
gate's provenance/trading.json shipped_elf5354b4cd78aa0bfd2e6ab838c2b52c3f6baee663be303108755a1ce3cb209336
deployed, and what cohort-12 runsb0cff55ab0ef162d7e427b8cb894f1468b1804d997ab35c52710df3268a8e3ed

Six of the seven role ELFs are identical between candidate and cohort; trading alone differs, and only because of that feature flag.

The gate admits the release as a SET of twelve links, so this blocks every role, not only trading. The custody preflight — custody's own bytes being identical to the candidate's — refuses:

Error("trading ELF bytes or SHA-256 changed after checked-release admission")

Wall D: AlreadyCurrent is consumed by the tree and written by nothing in it

There is an escape hatch that would solve all of this without a single upgrade. The deployment-set journal admits three dispositions, and the third is already-current — "admitted on byte equality alone" (upgrade.rs:2091), carrying a baseline and a dump, receipt.sha256: null, no transaction at all. Cohort-8's journal uses it for its resolution role.

Cohort-12's custody, resolution, claims and core all qualify today — their live payload already equals the checked candidate. If they could be journaled already-current, no upgrade would run, no deployment slot would move, release_set_id would stay 797e83ac…, and the market already founded would become fillable in place.

The tree validates such a row, audits it live on every invocation, and builds the plan pin from it (upgrade.rs:3457-3520). What it does not have is anything that writes one. Cohort-8 produced its single already-current row with an out-of-tree patched binary — ~/jobs/dclutch-cohort8-20260831/bin/bootstrap-alreadycurrent, built 2026-08-31 — driven by a hand-written refresh-journal.py that maintains the journal's digests by hand. That capability never landed in the tree; only its reader did.

And even it would not save trading, whose live bytes can never equal a candidate built with a different feature set.

So the fix is two release-tool changes, and they are smaller than a cohort

Named for an owner, because this is release tooling and not a cohort lane's work:

  1. The checked candidate must ship the ORDINARY trading link. The hot-cu-profile build is a measurement, and measuring it is right; admitting it as the shipped artifact is what makes the gate unable to authorize any cohort's real bytes. Until this changes, no cohort — redeployed or upgraded — can be sealed against the bytes it actually runs.
  2. A writer for the already-current disposition. The reader, the auditor and the plan projection all exist. With a writer, a genesis cohort whose live payload already equals the checked candidate seals with no upgrade, no new release set, and no second founding — which is strictly better than the upgrade route and leaves the market in this file fillable.

With both, cohort-12 seals in place and the trade in section 8 runs against EQnYCUMkz… with nothing stranded. The earlier suggestion — teach prepare to accept a genesis deployment's receipts — is subsumed by (2), which the tree is already most of the way to.

The fee-bearing trade, its DCLTDFS1 settlement, and ledger-census across the fill therefore remain undone, and the fill-boundary laws 49c8fa92 / be67416e remain unjudged by a real fill. Everything else the trade needs is in place and recorded above: the 50-bps market, the exactly-delegated 201 atoms, both Direct token PDAs derived and vacant, and the census bindings.

The shape wall C shares with two other findings tonight

Worth naming because it is the third instance in one night, in three subsystems, found by two lanes independently. The Redemption/web lane reports two of its own (its measurements, not re-verified here): a liveness test that asked the Program stub rather than the account holding the code, and a header check that had never followed the Registry's bump offset. Wall C is the same shape one level up — a gate that certifies something adjacent to the thing it claims to certify. The checked release gate does measure a real artifact, built from the real sources, with a real frame report; it simply measures the hot-cu-profile build, and no cohort runs that.

AGENTS.md already carries the probe-level version — "a probe measures what it touches, not what you meant" — learned from a heap probe that measured entrypoint!'s hardcoded HEAP_LENGTH instead of the granted frame. This is that lesson at the gate level, and it is more expensive there, because a probe misleads one investigation while a gate silently authorizes nothing at all for as long as it stands. The cheap defence is the same one that caught it here: name the artifact the gate certifies and the artifact production runs, put the two digests side by side, and require them to be equal rather than merely both present.

Addendum, 2026-09-02: the market is ACTIVATED, and the deadline was not attached to what it looked attached to

The UX reading lane found, and was right about, a vacancy with a clock on it: EQnYCUMkz… had Direct trading founded but not activated, no activation root at 88jJTMmU…, and capability entry 0 had to be activated by slot 492,091,890 or the market could never trade — the fate of the four earlier devnet markets.

It is activated. Read back off chain:

activation signature2hr4RJJTS12XmszvLUFysFq9k27E5DKT67sSa1wdv44hvdnTMzCmVbYW6oiG5YSkCiHxwMeUiCAvm1rFZguMbcQJ
activation root 88jJTMmUGr4tB92SwAVpNnQ5CYnWYsg19cu3ULgrZmd4exists, 256 B, DCLTCRT1, owner Trading Ahzug4zY…, phase Open
entry / generation0 / 2
deadline slot492,091,890
activated near slot491,906,637 — about 185,000 slots to spare
instruction35 accounts, 528 bytes, fee 75,000 lamports from the campaign payer

And the premise attached to the deadline was wrong, which is the part worth writing down. The reading held that the already-current seal and the checked execution release were what activation needed. They are not. devnet-direct-capability-activation-v1 takes --plan, --market-input, --campaign-report and a payer — all of which this cohort has had since the founding finished. Had the two been coupled, a nine-hour clock would have been run against two release-tool changes that, as measured below, cannot be landed for this cohort at all. Activation and fill are separate gates, and only the fill needs the checked execution release.

The activation also published a sixth frozen routing table, which extends the dc07c73a proof past the founding path: create DIRECT-ACT frozen routing address lookup table (7GrhHyWV…), two extends, then freeze DIRECT-ACT routing table after its one complete extension plan (bKa52k8V…).

Addendum: the two release-tool changes, and why this cohort still cannot be sealed

Both fixes named in the previous addendum are landed (28ff0823).

Wall C is closed at its cause. checked-release-candidate.sh no longer admits the profiled build. sbf_feature_suffix splits into a shipped suffix (empty for every package) and a measurement suffix (Trading alone); the frame gate keeps the profile, a new explicit profiled build keeps existing so its digest can be stated beside the shipped one, and metadata.txt's build_command describes the shipped artifact. Two new refusals: the profiled measurement may not be byte-identical to the shipped link — if it were, the feature has stopped doing anything and the profile is a lie rather than a measurement — and Trading's provenance must carry the feature in its frame command and not in its plain one. That second gate was proved red against cohort-12's own real pre-fix descriptor before it was trusted:

refusing: the shipped Trading command carries --features hot-cu-profile, so the
gate would admit a diagnostic build no cohort runs:
  … cargo build-sbf --manifest-path programs/dclutch-trading-sbf/Cargo.toml --features hot-cu-profile -- --locked

Wall D is closed. devnet-deployment-set-already-current-v1 writes the disposition the reader has always validated: key-free, read-only against the cluster, admitting on byte equality against a fresh finalized observation and refusing by name — with both digests — any role that differs. It also refuses a role that already has a receipt, and one with a receipt file on disk, because the journal loader rejects a receipt that exists while no digest is pinned and this command will not delete evidence to get past it. Three fake-chain tests: the admit path asserts the row it writes reloads through the real loader, the refusal path asserts the journal is byte-identical afterwards, and preflight writes nothing.

And cohort-12 still cannot be sealed, measured twice.

  1. checked-release-candidate.sh refuses unless it is the script at --commit: refusing: invoke the checked-release runner from the exact --commit source revision. Correct, and it means the fix cannot be applied retroactively to e39efbb0 — the commit whose bytes are live.
  2. A gate at any commit carrying the fix therefore describes that commit's bytes. Built and compared rather than inferred: HEAD's ordinary Trading link is 1d92debe9a24d11cee73b3a8da3d6b01b935ada3c4b1df6429f0bbb4674e7319 at 2,308,328 bytes, against the deployed b0cff55ab0ef162d7e427b8cb894f1468b1804d997ab35c52710df3268a8e3ed at 2,308,320. Twenty-one commits touched programs/ and crates/ since e39efbb0.

Trading can therefore never be already-current for this cohort, so the seal fails, so the checked execution release cannot be built, so the fee-bearing trade and ledger-census across the fill remain undone on cohort-12 and 49c8fa92 / be67416e remain unjudged by a real fill.

What the two fixes buy is the next cohort: one deployed from a commit that contains them seals in place with no upgrade, no new release set and no second founding — and can trade.

The repaired candidate is green, and the gate now admits the bytes a cohort runs

Run from a worktree at 28ff0823 — the candidate refuses to run as any commit but its own, so proving the fix means running the fixed script as itself:

source_revision=28ff0823b53c8c17b202cbe2432ca14c9fb2888c
sbf_build_freshness=passed            sbf_build_freshness_links=12
sbf_build_diagnostics_total=0         trading=0   (all twelve links zero)
checked Upgrade gate  sha256=91379329972a6881d5f9d7698046776f7aa6ce060369d4fd665ac4496ffa0af5
CANDIDATE_EXIT=0

The gate's Trading link is now the ordinary artifact, and the candidate states both digests rather than leaving a reader to guess which one was admitted:

trading_elf_sha256=1d92debe9a24d11cee73b3a8da3d6b01b935ada3c4b1df6429f0bbb4674e7319
trading_elf_bytes=2308328
trading_profiled_elf_sha256=d2eb0013e3e0e1345d76b10d9197f11600815fd1355f15e805e9069ef4745d77
trading_profiled_elf_bytes=2314456
trading_admitted_artifact=shipped

provenance/trading.json carries the inverse of what it carried before the fix: shipped_elf is 1d92debe…, the feature is absent from plain_build.invocation and present in frame_measurement.invocation. The profiled measurement is 6,128 bytes larger and is never admitted.

The admitted digest 1d92debe… was independently reproduced by an ordinary cargo build-sbf of dclutch-trading-sbf in a separate detached worktree at the same commit — two builds, two roots, one digest. That is the property the whole repair exists for: the gate now certifies an artifact a cohort would actually deploy.

Addendum: the seal route was run to its end, and the root cause is one hardcoded list

The coordinator's branch plan was right on its own terms, and it was executed.

The premise held exactly. Neither tool commit touches programs/ or crates/, so a branch at e39efbb0 carrying them builds the same program bytes. Branch seal/cohort-12, both commits cherry-picked (unsigned — 1Password declined, which AGENTS.md names as the honest signal of autonomous work), differs from e39efbb0 in five tools/ files and nothing else. The ordinary Trading build on that branch:

seal branch ordinary trading: b0cff55ab0ef162d7e427b8cb894f1468b1804d997ab35c52710df3268a8e3ed  (2308320 bytes)
cohort-12 DEPLOYED trading:   b0cff55ab0ef162d7e427b8cb894f1468b1804d997ab35c52710df3268a8e3ed  (2308320 bytes)

Equal. And the full candidate at 96a3b04e is green — SEAL_CANDIDATE_EXIT=0, gate 82298c60…, whose Trading link is b0cff55a…, the deployed bytes. Its profiled measurement reproduces 5354b4cd…, the original candidate's digest, which independently confirms the source is unchanged. The repaired gate now certifies exactly what cohort-12 runs.

Two further walls were cleared on the way, both recorded because they will recur:

And then the root cause, which none of the previous addenda had reached

The deployment-set journal refuses cohort-12 at its first role:

Error("set journal target at index 0 is not exact permanent devnet
       registry:Hies39GBowHUMZw9rVCfaDTAXNorkQqMGKnukY2MD4Qj:ENRSwrUEymWaXyrNtyD4QXXXk3tsTmcTGPTUFvnpsRVz")

PERMANENT_DEVNET_UPGRADE_TARGETS_V1 (upgrade.rs:129) hardcodes seven program/ProgramData id pairs — cohort-7/8's — and the capture family "accepts no caller-supplied Program set". So the entire checked-upgrade lineage is scoped to one fixed substrate.

Condition (a) of the standing grant requires FRESH IDENTITIES. The sealing machinery requires THE PERMANENT IDENTITIES. They are mutually exclusive by construction, and no fix to the candidate, no already-current writer and no rent top-up can bridge them.

And the pinned substrate is gone:

Error: Program Hies39GBowHUMZw9rVCfaDTAXNorkQqMGKnukY2MD4Qj has been closed

Closed by the very redeploy discipline condition (a) mandates. So the deployment set can seal neither cohort-12 (wrong ids) nor the permanent set (no longer exists). It is unreachable for every cohort, present and future, until that constant is re-pointed — which is decision 0012's territory and not a cohort lane's to decide. That, not the feature flag and not the missing writer, is why no devnet Direct fill has ever executed.

So the fee-bearing trade, its DCLTDFS1 settlement, and ledger-census across the fill remain undone, and 49c8fa92 / be67416e remain unjudged by a real fill. Cohort-13 from HEAD does not change this: it too would have fresh ids. The unblocking change is one of:

  1. make the permanent target set an authenticated input rather than a constant — the journal already re-reads every row against the chain, so the constant adds no safety a fresh observation does not; or
  2. re-point PERMANENT_DEVNET_UPGRADE_TARGETS_V1 at a live cohort and hold that cohort's identities stable across redeploys, which is a decision about what "permanent" means.

What this lane leaves ready for whoever takes it: the repaired candidate, the already-current writer with its tests, branch seal/cohort-12 at 96a3b04e, a green gate whose Trading link equals the deployed bytes, a captured carry-forward closure, five clean baselines, and a journal skeleton — every input the seal needs except an admissible identity set.

Addendum, 2026-09-02: the seal COMPLETES — and the market it was for is unreachable, for a third reason

The root cause the previous addendum named is fixed and the fix works. Cohort-12 is the first full-redeploy cohort in this project's history to produce a complete checked deployment set. It cost zero SOL: every step below is key-free and read-only against the cluster, and the deployer stands at 36.327394469 SOL, the same figure it has held since the ladder.

What was changed

PERMANENT_DEVNET_UPGRADE_TARGETS_V1 is retired (8e1f9850, cherry-picked onto seal/cohort-12 as 190146e8). The seven ids are now an authenticated input read off the deployment-set journal that names them — exact width, canonical role order, the Loader-derived ProgramData coordinate of every Program, fourteen distinct non-native accounts — and the safety is what it always was: every row re-read against the cluster under the journal's own retained authority. Decision 0012 carries the amendment. require_rent_exempt now reads the live Rent sysvar out of the same finalized context as the balances it judges; devnet quotes lamports_per_byte_year 6333, exemption_threshold 1.0 at slot 491,925,181, which reproduces the 1,038,612 lamports the closure accounts hold to the unit against Rent::default()'s 1,141,440.

First, the question that decided whether this was a formal change: it was not. Decision 0012's Lean model takes the release/target set as an INPUT and names no constant. ProtocolInfrastructure.lean has Identity := Nat and carries SlotPin/Binding/Profile as structures the adapter fills — its own docstring says the observed fields are "read out of the live ProgramData account in this very invocation". ExecutionRelease.lean's ReleaseSet is a structure with releaseSetValid a predicate over the supplied value, not an enumeration. The Lean-decided corpus landed at d418cc8b carries zero Pubkeys — fill bytes and slots only. And the constant appeared in no formal/, no programs/, and no crates/ file: two host-tool sources, a tool README, GOAL.md, and this document.

The seal, measured

Branch seal/cohort-12 at 190146e8 = 96a3b04e + the amendment, and its diff from e39efbb0 touches only tools/ and docs/ — no programs/, no crates/ — so the ordinary Trading link is unchanged at b0cff55ab0ef162d7e427b8cb894f1468b1804d997ab35c52710df3268a8e3ed, the deployed bytes, which the green gate 82298c60da8b9fc249b9fa673f5337a95ee42606ff44237e20b927e65448bb72 certifies. The auditor was built from that tip; the journal keeps the gate's own source_revision 96a3b04e, because the gate is the artifact and the auditor is not.

The refusal that stood for eight cohorts — "set journal target at index 0 is not exact permanent devnet registry:Hies39GB…" — is gone. All five owned roles preflight equal: true against a fresh finalized observation:

rolelive ELF = checked candidateobserved slot
custody2823c823…491,928,063
resolution307bc81c…491,928,088
claims268d527e…491,928,120
tradingb0cff55a…491,928,152
core9ef7df55…491,928,175

Trading's line is the whole repair in one row: the gate's Trading link and the deployed bytes are the same digest.

Journaled already-current, then audited:

completed_role_count 7      next_role null
final_set_sha256 60f113e27232ea98391ce902ffa52fa3c82966c1726da9f59c57324550857bec
registry carry-forward   rent carry-forward
custody / resolution / claims / trading / core: already-current

And prepare --deployment-set-journal produced a plan whose checked_upgrade_set_final_sha256 is that same 60f113e2…. plan.checked_upgrade_set is Some. No upgrade ran, no deployment slot moved, no key was opened.

And the third wall, which is the finding

release_set_id did not stay 797e83ac…. It is 6dcda3224f0d1a251d2a91bb64ae25b10967e6133b40e0a0a008ae3057a75c90.

Every deployment slot is identical between the founded plan and the sealed one. What moved is three semantic_release_id values — custody, claims, core — and the cause is exact:

// upgrade.rs, checked_semantic_release_id
"trading"    => COMPILED_DIRECT_RELEASE_ID_V1        // a fixed constant
"resolution" => RESOLUTION_CONTROLLER_RELEASE_ID_V7  // a fixed constant
_            => digest(source_semantic_release_preimage_v1(role, source_revision))

Registry and Rent are CarryForward and reproduce byte-for-byte; Trading and Resolution carry fixed semantic ids; custody, claims and core hash the GIT REVISION. The founded plan used e39efbb0; the journal must use the gate's revision, and the gate cannot be at e39efbb0 because that commit's candidate ships the profiled Trading link. So:

A release-tooling fix necessarily changes the release-set identity of three roles whose program bytes did not change at all. e39efbb0 and 96a3b04e have byte-identical custody, claims and core sources — the diff is tools/ and docs/ — and they mint different semantic release ids, therefore a different release set, therefore a different activation, therefore a different market. The semantic identity of program bytes is derived from a tree revision that includes files those bytes do not depend on. That is the same shape as wall C one level further out: an identity that names something adjacent to the thing it identifies.

This is not repairable for cohort-12 by any commit. There is no commit whose sha is e39efbb0 other than e39efbb0, and the candidate refuses to run as any commit but its own.

The fee-bearing trade: its disposition, by code and conjunct

Attempted, with the sealed plan, against the live market:

devnet-checked-execution-release-v1
  Error("missing Registry activation cache account 2pdhpxkYxZ6QZpG43ocrdWN5cqUZfKeJfrjNQv88qz1w")

2pdhpxkY… is find_program_address([ACTIVATION_PDA_DOMAIN_V1, 6dcda322…], registry) — the sealed plan's activation, which does not exist, because what was activated on chain is 9H5Jy4kjXJFiLtj8uGrCwhzYVw3nYsxRMAHA7s86p8cE for release set 797e83ac…. Had that account existed, the next conjunct is direct_hot_route_manifest.rs's checked-execution/release-set — "activation cache selects release set X, the plan pins Y" — because the market pins 797e83ac… at STATE_SELECTED_RELEASE_SET_OFFSET, re-read at slot 491,931,501 and unchanged.

The other door is the one cohort-12's own plan takes, and it is the refusal this file recorded before: checked-execution/plan-unsealed, "devnet plan omitted its authenticated permanent checked deployment set". Both doors are shut, and they are shut by the same fact from opposite sides: the plan that matches the market has no checked set, and the plan that has a checked set does not match the market.

On the closed observation window, read from the conjunct rather than assumed: WINDOW_SPEC_MAGIC (DCLTWIN1) occurs in exactly one crate, dclutch-source-contract — the observable and resolution side. The Trading Direct fill route never reads it. A Direct fill is gated by the Market phase (still 0x01 Open, generation 2, re-read at slot 491,931,501) and by each intent ticket's own valid_from/valid_through slots, not by the observation window. So the closed window is not what refuses the fill; it was never reached. That is a source-level determination, not a live measurement, and it is labelled as one.

Resolution is blocked by the same wall, so it is not a separate lane's win

flagship-resolution-v1 --produce-input on devnet calls authenticate_checked_upgrade_plan, which requires plan.checked_upgrade_set — so cohort-12's founded plan refuses outright. And the sealed plan's resolution input takes activation_cache: plan.activation (flagship_resolution.rs:3630), which is the vacant 2pdhpxkY…. Resolving EQnYCUMkz… needs the same release-set identity the fill needs, and neither can be had. The market can be neither filled nor resolved on this plan.

What is now true, and what it costs

Addendum, 2026-09-02: the identity is fixed at its cause, and cohort-12 is still the market it stranded

The previous addendum named the defect. It is now repaired, and the repair was re-run against cohort-12 key-free — the deployer has still not moved: 36.327394469 SOL, and the campaign payer 1.554337728.

What changed (0785bd52, 2da012cd)

checked_semantic_release_id no longer takes a git revision. A role with a code-owned semantic constant uses it (Trading's COMPILED_DIRECT_RELEASE_ID_V1, Resolution's RESOLUTION_CONTROLLER_RELEASE_ID_V7); a role without one uses the ordinary shipped-ELF digest the candidate already computes, under a role-labelled domain. Two commits whose program sources are byte-identical now mint one id, and a commit that really does change a program's bytes still mints a new one — the property the revision hash was reaching for and missing. The loopback path stops keeping its own parallel copy of the rule, and SEMANTIC_DERIVATION_V1 moves with the derivation, so a pin minted under the old one is refused by name by the four consumers that already compare that field.

Three siblings landed with it. The carry-forward snapshot now carries the Rent rate its own finalized context quoted (schema v2) and the offline re-validation judges against that rather than Rent::default() — the sibling named as owed two addenda ago, closable only by the snapshot, because the re-validator has no cluster in reach. tools/release/devnet_upgrade_dryplan is deleted with its CI row: its ROLES, its DEPLOY1_FACTS and its parked-lamport pin were a frozen rehearsal of the cohort-7/8 substrate, every account of which is closed on chain. And prepare now emits the public cut's checkedReleases row verbatim beside the plan, keyed and shaped exactly as publicCutStaging.ts admits it, so the browser never computes and nobody types a release identity.

The fourth is what makes cohort-13 work rather than hopefully work: a genesis cohort supplies its five artifact-derived semantic ids on the command line, and validate_prepare now derives each from the role's own artifact and refuses a mismatch by name. While those two could disagree, an operator copying last cohort's semantic-release-ids.txt founds under one release set and seals under another — which is exactly the accident, one layer up from the one that already happened.

Re-run against cohort-12, key-free

Branch seal/cohort-12 re-cut to ccc004f1; its diff from e39efbb0 still touches zero programs/ or crates/ paths, so Trading is still b0cff55a…. A fresh carry-forward capture (schema v2, slot 491,938,160) records the live rate lamports_per_byte_year 6333, exemption_threshold 1.0, burn_percent 50 and passes rent exemption without any top-up, which is the same fact the 0.2373 SOL of over-funding was bought to paper over. The seven-role journal audits completed_role_count 7 / next_role null, final set c4e9acf6ca02d6dab8dbec8ea73b5a4f0a18ce861dfdf59c2c6af19da26cef14, and prepare seals.

planderivationrelease_set_id
founded, e39efbb0revision-hashed797e83ac0522787898b24a963182b846f61f96c6968e4bfdbfbb8dc5bcf7e9a1
first seal, 96a3b04erevision-hashed6dcda3224f0d1a251d2a91bb64ae25b10967e6133b40e0a0a008ae3057a75c90
second seal, ccc004f1artifact-derivedb9eea7fe68ffde7fb3bbb627748d6156174cd0c77ab5e9d961f539f2205ebc71

So the answer to "do the founded plan and the sealed set now agree" is NO, and the reason is the honest one: the founded plan's id is fixed at the old derivation. 797e83ac… embeds Custody, Claims and Core semantic ids that are hashes of e39efbb0, and nothing can re-mint them into a market already founded. The repair is forward-only by construction. Cohort-13 is the path, deployed from a commit at or after 0785bd52.

The new ids were reproduced independently, outside the tool, from (role label, shipped ELF digest) alone:

roleshipped ELFsemantic idreproduced offline
custody2823c823…14c06925…yes
claims268d527e…4435fc6c…yes
core9ef7df55…a4a5b3d8…yes
trading—79fad2f0…code-owned constant, artifact-independent
resolution—6e4b9a54…code-owned constant, artifact-independent
registryed70f8bd…74ea1b5d…no, and correctly so
rentd46e5f0a…847238e9…no, and correctly so

Registry and Rent are CarryForward rows: their ArtifactRelease records are reproduced byte-for-byte from the chain, not re-minted, so they keep the ids the cluster already holds — including, for this cohort, ids minted under the old derivation. That is the carry-forward doing its job, and it is why the table is worth printing rather than summarising: an unexplained "reproduced=false" is how a reader concludes a fix did not land.

The commit is therefore not an input to any id a cohort mints from here on. It is a function of the seven artifacts and two code constants, and for a carried role, of what the chain already says.

The cut fragment, emitted rather than typed

{
  "checkedReleases": {
    "b9eea7fe68ffde7fb3bbb627748d6156174cd0c77ab5e9d961f539f2205ebc71": {
      "gateDigest": "82298c60da8b9fc249b9fa673f5337a95ee42606ff44237e20b927e65448bb72",
      "sealedSet": "c4e9acf6ca02d6dab8dbec8ea73b5a4f0a18ce861dfdf59c2c6af19da26cef14"
    }
  },
  "schema": "dclutch-public-cut-checked-releases-fragment-v1"
}

This row is for a release set no market selects, so publishing it would turn the browser's release wall off for nothing. It is recorded here as the shape cohort-13's runbook hands the cut, not as a row to ship.

And one line of that runbook has to be worded carefully, or the guarantee evaporates. The staging tool takes --release-set HEX64 and refuses a fragment whose key is not that value. Two independent proofs are supposed to meet there: the ingester proves the fragment is ABOUT the set the cut's Market selects, and validate_prepare proves the value inside it is the one the artifact derives. prepare prints release_set_id in its own result JSON, so pasting the argument from there is the fastest way to fill it — and it silently collapses the two into one producer asserting the same value twice, comparing a file against itself. A refusal that cannot fire is worse than no refusal, because it reads as coverage. The value must be read off the CHAIN — the market page prints it, and the Direct spine returns it as releaseSetId. The web lane wrote the prohibition into the staging tool's own header (52de7519), which is the right place for it and remains the owner; this is the note for whoever writes the cohort-13 step, because a runbook line that says "copy it from the prepare output" would undo a guarantee neither tool can defend on its own. The load-bearing sentence is quoted here rather than only pointed at, so it survives that script being renamed or folded into a shared staging tool by a lane that never reads this file:

SO DO NOT COPY IT OUT OF THE PRODUCER'S OWN OUTPUT. The sealing driver's prepare puts the same string in its result JSON as release_set_id and uses it as the fragment's single key, so pasting it from there is quicker and silently destroys the guarantee: two independent proofs collapse into one producer asserting the same value twice. The producer proves the row's VALUE is what its artifact derives; this argument proves the row is ABOUT the set the market selects. Only a chain read can supply the second.

Note the phrasing, which is the part that does the work: it says where the value may NOT come from. "Read it off the chain" alone is satisfied, in a reader's mind, by any string that arrived from somewhere official — including the producer's own result JSON, which is exactly the string that must not be used.

What cohort-13 owes

Deployed from a commit at or after 0785bd52: found, then seal against its own gate, and the two identities agree by construction rather than by luck — validate_prepare will not let them diverge, and the fragment the cut needs falls out of prepare. Everything cohort-12 proved about the populated market holds and is reusable: the 50-bps founding, the exactly-delegated 201 atoms, both Direct token PDAs derived and vacant, the census bindings, and the six frozen routing tables. 49c8fa92 / be67416e remain unjudged by a real fill, and that is now a cohort lane's to close rather than a repair's.

Devnet evidence. Not mainnet evidence.