openspec/changes/archive/2026-09-10-add-cartridge-model/reviews/2026-09-10-re2-advise.md
add-cartridge-model — re-advise 2 (2026-09-10)
ADVISE: accept READER: fable-5-1-arch-review SPAWN: .spawns/add-cartridge-model-1789067468-1483-6791f63e
Blind take (written before design.md, tasks.md, prior reviews)
Sources: proposal Why, openspec/specs/hardware-kit/spec.md, the delta specs/cartridge-runtime/spec.md, sim/3090/check_catalog.py, sim/3090/catalog.json.
- Pin: pack axis is memory (vram+host on 3090, unified elsewhere) plus NVENC sessions. Nothing else refuses a seat.
- Pin: watts is a record per cost and per envelope; sag is hardware-kit’s rule (“Split power tree” and “Record-first under AI drop”). The catalog must not grow a watts ceiling check.
- Pin: swap formula is Σ(always-on) + max(slottable) per memory axis and per NVENC; resident envelopes are Σ(all). The checker must encode exactly that, not max-over-set.
- Pin: envelope ids are
3090,t4000,6000and nothing else; hardware-kit “Four compute envelopes” owns the list. - Pin: null cost ≠ free. Always-on null → absent and logged, pack legal. Slottable null → no seat.
- Refuse: disk weight size recorded as VRAM peak (klein-4b 16 GB).
fact:falseplus a src that says so is the guard. - Refuse: any preset homed on 3090 that needs two slottables co-resident (talent-tracking, ar). On a swap envelope those are a gauge, not a seat.
- Concern: the catalog carries
envelopes.<id>.residencyand the checker keys on it, but the delta says swap-vs-resident is owned elsewhere and never declares that field. Either name it as a mirror of the hardware-kit default or the fold leaves an undocumented field driving the packer. - Concern: the delta cites
add-sim-box-mixthree times. That change is folded into hardware-kit as of 860bae4; a living spec should cite the capability, not an archived change id. - Tradeoff: Σ(always-on)+max(slottable) is right for steady state but ignores the swap transition (unload A while B loads). That belongs to the 3090 loader, not this catalog; accept the formula as the pack contract and let
add-3090-cartridge-loadown transition headroom.
Compare against design.md, tasks.md, prior reviews
Rigor: architecture. Density: lean. Reader family: Claude (Fable 5.1). Author this pass: grok.
Read order after the take: reviews/2026-09-10-advise.md, reviews/2026-09-10-re-advise.md, design.md, tasks.md, then python3 sim/3090/check_catalog.py (exit 0) plus three probes.
Both re-advise sentences are closed in the spec and in the checker.
- Power axis. “Latency vs pack” now reads “memory, host/unified RAM, and NVENC only. Watts
SHALL be recorded per cost and per envelope; power enforcement is sag (
hardware-kit), not seat/bounce.” “Envelope ceilings” now reads “Watts may be recorded on the envelope but SHALL NOT be a pack axis.” The checker never reads watts, so the acceptance line in tasks.md is now true as written. Take lines 1 and 2 are satisfied. - Swap formula. “Swap envelope pack” now reads “Σ(always-on) + max(slottable) against the
envelope ceiling, not the max over the whole set and not the sum of all peaks”, with a
scenario. The checker’s
swapbranch accumulates always-on and maxes slottable on each memory axis and on NVENC. Probe: klein-4b + sam2-tiny + clip on3090seats (10 + 0.3 VRAM, 8 + 0.2 host), which is the loadout the harness actually runs. Take line 3 is satisfied.
Take lines 4, 5, 6, 7 hold without change. Envelope ids match hardware-kit “Four compute
envelopes”. cuvslam null on 3090 is absent and both 3090-home presets seat without it. klein-4b
carries fact: false and a src that names 16 GB as disk weights. Presets that need two
slottables co-resident (ar, talent-tracking) are homed on t4000 only. The 4K pair refuses
on the shared tag (probe: sam2-4k + maxine-4k → refuse), and the untagged talent-tracking preset
seats.
Take line 8 (undeclared residency field), steelmanned and downgraded. The prior re-advise
withdrew the same point: hardware-kit says “Pack and residency default by envelope and SHALL be
overridable”, so the catalog carrying the default per envelope is that rule, not a fork. I agree
on ownership. What remains is that the delta enumerates the envelope fields in “Envelope
ceilings” and does not list residency, while the checker keys on it. That is a documentation
gap the packer author will close by reading the checker. It does not change what a packer
refuses on. Not blocking.
Take line 9 (cites to add-sim-box-mix), downgraded to a fold note. The delta says
“residency is swap (add-sim-box-mix)”, “30 fps residency is add-sim-box-mix”, and
”add-sim-box-mix owns which box is which”. That change folded into hardware-kit at 860bae4.
Since this delta will itself fold into a living cartridge-runtime spec, the folder should
rewrite those three cites to hardware-kit “Resident 30 fps design target”. The pointer is still
resolvable in archive/, so the contract is not ambiguous today.
Take line 10 (swap transition headroom). Not this change’s concern; the loader owns it. Nothing to ask.
Steelman for the author. Grok did exactly the two sentences asked, touched no seed rows, and updated the checker to the stated formula rather than leaving the coincidence. That is the right size of change for a re-advise. The residual items below are all outside the packer contract.
Notes for fold and for add-cartridge-pack (not blocking, not nits on the verdict)
design.mdstill says “On3090the packer uses max-of-peaks (swap).” The spec is the contract and is correct; design.md is stale by one sentence. Fold from the spec.check_catalog.pydocstring still says “(swap, max-of-peaks)“. Same staleness; the code is right.check_catalog.pyraisesUnboundLocalErrorwhen no cart seats (probe:["cuvslam"]on3090, or an empty set), because the ceiling compare reads accumulators set inside the loop. Not reachable from the acceptance presets. The packer must not copy that shape.- Absent always-on is “logged” per the null-cost scenario. The checker shows absence only by omission from the seated list. Packer concern, same as the prior review said.
- The 4K-pair refusal and the 3090 swap-set scenario are in the spec but not in the checker’s
main(). Both pass when probed. Worth adding whenadd-cartridge-packinherits the checker.
Why accept
The two sentences the re-advise asked for are in the spec, the checker implements them, and the acceptance command exits 0 on a catalog whose presets seat on their home envelopes under the spec’s own rules. A packer author can read this delta and know exactly which axes refuse a seat and how a swap envelope sums. Everything left is fold hygiene or belongs to the packer change.