Lane B S18 gate 1: commit(rig, {at}) carries the mid-storm clock, so seeding it cannot be forgotten
A's emergency flow is inherit -> commit -> put the dead corner down -> roll, and it goes through session.commit(rig) by design (the public-moves discipline). That door could not seed the sail's clock, so getting it right needed a SECOND call after commit — a step a caller can forget, on the one night where forgetting it understates every load ~4x and reads as "triage is easy" rather than as a bug. opts forward straight to attach; omitted, the ordinary night is byte-for-byte unchanged (clock at 0), pinned both ways. Selftest 535/0/0 (522 baseline + 13).
This commit is contained in:
parent
ae2f560ff2
commit
afef9abe0b
@ -541,8 +541,18 @@ export class RiggingSession {
|
||||
this.picks = ring.map((a) => byId.get(a.id));
|
||||
}
|
||||
|
||||
/** Hand the finished rig to the sim. Mirrors contracts.js sailRig.attach(). */
|
||||
commit(rig) {
|
||||
/**
|
||||
* Hand the finished rig to the sim. Mirrors contracts.js sailRig.attach().
|
||||
*
|
||||
* `opts` is forwarded to `attach` untouched, which exists for exactly one
|
||||
* reason (SPRINT18, Lane C's finding): an emergency callout's storm is already
|
||||
* 30 seconds old, and `attach({at, wind})` is what stops the cloth flying the
|
||||
* wrong sixty seconds of it. Without this the only way to seed the clock would
|
||||
* be a SECOND call after commit — a step a caller can forget, on the one night
|
||||
* where forgetting it silently understates every load by 4x. The session's
|
||||
* public-moves discipline and a correct clock should not be a choice.
|
||||
*/
|
||||
commit(rig, opts = undefined) {
|
||||
if (!this.canStart) throw new Error(`sail needs ${MAX_CORNERS} corners, have ${this.picks.length}`);
|
||||
// gate 2, the promise the sprint doc names ("enforces the budget cap at
|
||||
// commit"): by now the refusals above have made these states unreachable
|
||||
@ -570,7 +580,7 @@ export class RiggingSession {
|
||||
// shade cloth + C's 0.40 downdraft drop p1 to 1.08 kN, under a $5
|
||||
// carabiner's rating, which is the $10 that closes the $90 -> $80 gap.)
|
||||
if (rig.setFabric) rig.setFabric(this.fabric);
|
||||
return rig.attach(this.picks.map((p) => p.anchorId), this.picks.map((p) => p.hw), this.tension);
|
||||
return rig.attach(this.picks.map((p) => p.anchorId), this.picks.map((p) => p.hw), this.tension, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -605,6 +605,25 @@ test('gate 1: ⚠️ the refund cannot pay you for a stranger\'s steel — the k
|
||||
return `inherited steel refunds $0; the $${RATED.cost} the player bought refunds, and only that`;
|
||||
});
|
||||
|
||||
test('gate 1: commit carries the mid-storm clock through to the sail', () => {
|
||||
// The emergency flow is inherit -> commit -> put the dead corner down -> roll.
|
||||
// If commit cannot pass `at`, seeding the clock becomes a separate call on the
|
||||
// one night where forgetting it understates every load ~4x (C's finding).
|
||||
const s = session();
|
||||
assert(s.inherit(INHERITED).ok, 'inherit refused');
|
||||
const rig = s.commit(new SailRig({ anchors: ANCHORS, gridN: 10 }), { at: 30 });
|
||||
assert(rig.t === 30,
|
||||
`commit({at:30}) left the cloth at t=${rig.t}. It is now flying the storm's FIRST sixty seconds ` +
|
||||
'under a sky flying its last sixty, and nothing about that is visible from outside');
|
||||
assert(rig.clockSkew === 0, `a freshly seeded commit already reads ${rig.clockSkew}s of skew`);
|
||||
// and the ordinary night is untouched — no opts, clock at 0
|
||||
const plain = session();
|
||||
for (const id of ['h1', 'h3', 'p1', 'p2']) plain.rig(id);
|
||||
assert(plain.commit(new SailRig({ anchors: ANCHORS, gridN: 10 })).t === 0,
|
||||
'an ordinary commit no longer starts its storm at 0');
|
||||
return 'commit(rig, {at:30}) seeds the cloth to 30s; a plain commit still starts at 0';
|
||||
});
|
||||
|
||||
test('gate 1: an inherited rig still obeys the client, and refuses a rig it cannot build', () => {
|
||||
const s = session();
|
||||
s.setConstraints([HOUSE_BAN]);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user