Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions scripts/pm/check-half-states.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12325,16 +12325,30 @@ function selfTest() {
const busy = { unclaimed: 15, inFlight: 7 };
const idleLane = { unclaimed: 15, inFlight: 0 };

// The `@ <repo>` specimens below DERIVE both board names rather than spelling
// them, because `seatLane` judges an at-repo suffix against the LIVE resolved
// sweep repo — `SWEEP_REPO`, not a constant. A row that hard-codes `objectui`
// as the sibling and `objectstack` as the own board therefore asserts THIS
// BOARD instead of the property, and inverts wholesale wherever the file is
// installed next: run verbatim in objectui on 2026-08-28 the suite failed
// exactly the four rows those two names feed, which is the one thing a file
// adopted BY COPY (see `resolveSweepRepo`) may not do. `OWN_BOARD` is the
// resolved repo's name half — the same half the predicate compares, derived
// here rather than shared, so a predicate that switched to the OWNER half
// still goes red. `SIBLING_BOARD` is a real neighbouring board picked so the
// two can never coincide, which is what stops the FOREIGN rows going
// vacuously green on a board that happens to be named after the specimen.
const OWN_BOARD = SWEEP_REPO.repo.split('/')[1];
const SIBLING_BOARD = OWN_BOARD === 'objectui' ? 'objectstack' : 'objectui';
const ownLaneSeat = (status = '🟢 os-x') => seat(`[PM seat] domain:devx @ ${OWN_BOARD} — ${status}`);
const siblingLaneSeat = (status = '🟢 os-x') => seat(`[PM seat] domain:devx @ ${SIBLING_BOARD} — ${status}`);

// The lane parse, across the three measured title shapes.
t('H32 lane: a plain domain lane is own-board', seatLane(seat(HELD)).lane, 'domain:spec');
t('H32 lane: …and not foreign', seatLane(seat(HELD)).foreign, false);
// ADAPTED FOR THIS REPO. `seatLane` compares the `@ <repo>` suffix against
// the LIVE `SWEEP_REPO`, so which name is FOREIGN is install-dependent and
// upstream's two rows invert here. The property is identical — a sibling
// board's lane is unreadable from this sweep, this board's own lane is not.
t('H32 lane: an `@ sibling` suffix is FOREIGN', seatLane(seat('[PM seat] domain:devx @ objectstack — 🟢 os-x')).foreign, true);
t('H32 lane: an `@ own-repo` suffix is NOT foreign', seatLane(seat('[PM seat] domain:devx @ objectui — 🟢 os-x')).foreign, false);
t('H32 lane: …and keeps the bare lane label', seatLane(seat('[PM seat] domain:devx @ objectui — 🟢 os-x')).lane, 'domain:devx');
t('H32 lane: an `@ sibling` suffix is FOREIGN', seatLane(siblingLaneSeat()).foreign, true);
t('H32 lane: an `@ own-repo` suffix is NOT foreign', seatLane(ownLaneSeat()).foreign, false);
t('H32 lane: …and keeps the bare lane label', seatLane(ownLaneSeat()).lane, 'domain:devx');
t('H32 lane: a repo-scoped seat has no countable lane', seatLane(seat('[PM seat] repo:cloud — 🟢 os-x')).lane, null);
t('H32 lane: …and is foreign', seatLane(seat('[PM seat] repo:cloud — 🟢 os-x')).foreign, true);
t('H32 lane: a lane-less seat (skills) is foreign', seatLane(seat('[PM seat] skills — 🟢 os-zhuang (session_x)')).foreign, true);
Expand All @@ -12343,7 +12357,7 @@ function selfTest() {

// The held/vacant gate — an unheld seat is a ROUTING gap, never 怠工.
t('H32 held: 🟢 with a holder', seatIsHeld(seat(HELD)), true);
t('H32 held: ⏳ vacant is NOT held', seatIsHeld(seat('[PM seat] domain:devx @ objectui — ⏳ vacant')), false);
t('H32 held: ⏳ vacant is NOT held', seatIsHeld(siblingLaneSeat('⏳ vacant')), false);
t('H32 held: 🔴 收班 vacant is NOT held', seatIsHeld(seat('[PM seat] domain:spec — 🔴 收班 vacant · 上一班 os-warren')), false);
t('H32 held: ⏸️ paused is NOT held', seatIsHeld(seat('[PM seat] domain:spec — ⏸️ paused')), false);
t('H32 held: a Routine seat is excluded (no claim cadence of its own)', seatIsHeld(seat('[PM seat] triage (objectstack-wide) — 🟢 Routine')), false);
Expand All @@ -12355,7 +12369,7 @@ function selfTest() {
t('H32: work IN FLIGHT is a working seat -> clean', h32SeatIdleOverQueue(seat(HELD), marker('Round-start marker — R6.', 600), busy, NOW32), null);
t('H32: an EMPTY queue is a finished lane -> clean', h32SeatIdleOverQueue(seat(HELD), marker('Round-start marker — R6.', 600), { unclaimed: 0, inFlight: 0 }, NOW32), null);
t('H32: a vacant seat is out of scope however deep the queue', h32SeatIdleOverQueue(seat('[PM seat] domain:spec — ⏳ vacant'), marker('收班', 6000), idleLane, NOW32), null);
t('H32: a FOREIGN lane is out of scope (its inventory is unreadable here)', h32SeatIdleOverQueue(seat('[PM seat] domain:devx @ objectstack — 🟢 os-x'), marker('Round-start marker', 600), idleLane, NOW32), null);
t('H32: a FOREIGN lane is out of scope (its inventory is unreadable here)', h32SeatIdleOverQueue(siblingLaneSeat(), marker('Round-start marker', 600), idleLane, NOW32), null);
t('H32: a non-seat card is out of scope', h32SeatIdleOverQueue({ ...issue(['pm:queue']), title: HELD }, marker('x', 600), idleLane, NOW32), null);

// The threshold, at both edges of SEAT_IDLE_STALE_MINUTES.
Expand Down Expand Up @@ -12401,7 +12415,7 @@ function selfTest() {

// The gathering gate buys a fetch only for seats the row can speak about.
t('H32 gate: a held own-board seat is a candidate', h32NeedsSeatComments(seat(HELD)), true);
t('H32 gate: a foreign-lane seat buys no fetch', h32NeedsSeatComments(seat('[PM seat] domain:devx @ objectstack — 🟢 os-x')), false);
t('H32 gate: a foreign-lane seat buys no fetch', h32NeedsSeatComments(siblingLaneSeat()), false);
t('H32 gate: a vacant seat buys no fetch', h32NeedsSeatComments(seat('[PM seat] domain:spec — ⏳ vacant')), false);
t('H32 gate: a non-seat card buys no fetch', h32NeedsSeatComments(issue(['pm:queue'])), false);

Expand Down
22 changes: 2 additions & 20 deletions scripts/upstream-port-pin.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"upstream": {
"repo": "objectstack-ai/objectstack",
"ref": "2b4178aa53ca62089f43e2cfae0b7838cf340dd1"
"ref": "bf10debd587f6ba891be9eadc2b76c91e15bd82b"
},
"files": [
{
"ported": "scripts/pm/check-half-states.mjs",
"upstreamPath": "scripts/pm/check-half-states.mjs",
"upstreamSha256": "c06c84517630e180eb9e4bc1f0e13d069e5dfc71b6889baac0ebcd37256ea1bc",
"upstreamSha256": "449a0aec0cfa36738e0fc5651ec978faf846316522daeb9ca6efa1714daf6ac9",
"divergences": [
{
"id": "default-sweep-repo",
Expand Down Expand Up @@ -57,24 +57,6 @@
"upstream": " t('summary: an unfloored pass adds no floor clause', summaryLine({ repo: 'r', issues: 1, unscoped: 1, prs: 0, merged: 0, closed: 200 }, 0).includes('are judged'), false);\n",
"ported": " t('summary: an unfloored pass adds no floor clause', summaryLine({ repo: 'r', issues: 1, unscoped: 1, prs: 0, merged: 0, closed: 200 }, 0).includes('are judged'), false);\n // The DISABLED branch still wins over a floor: a 0-page window read nothing,\n // so the line must keep saying UNREAD rather than describing a floored pass.\n t('summary: a disabled reader with a floor set still reads UNREAD', summaryLine({ repo: 'r', issues: 1, unscoped: 1, prs: 0, merged: 0, closedWindowDisabled: true, closedFloor: '2026-08-28' }, 0).includes('UNREAD'), true);\n"
},
{
"id": "h32-lane-own-board",
"why": "`seatLane` reads the LIVE resolved sweep repo, so upstream's two rows invert in this install: here `@ objectui` is the own board and `@ objectstack` is the sibling. The property asserted is unchanged.",
"upstream": " t('H32 lane: an `@ sibling` suffix is FOREIGN', seatLane(seat('[PM seat] domain:devx @ objectui — 🟢 os-x')).foreign, true);\n t('H32 lane: an `@ own-repo` suffix is NOT foreign', seatLane(seat('[PM seat] domain:devx @ objectstack — 🟢 os-x')).foreign, false);\n t('H32 lane: …and keeps the bare lane label', seatLane(seat('[PM seat] domain:devx @ objectstack — 🟢 os-x')).lane, 'domain:devx');\n",
"ported": " // ADAPTED FOR THIS REPO. `seatLane` compares the `@ <repo>` suffix against\n // the LIVE `SWEEP_REPO`, so which name is FOREIGN is install-dependent and\n // upstream's two rows invert here. The property is identical — a sibling\n // board's lane is unreadable from this sweep, this board's own lane is not.\n t('H32 lane: an `@ sibling` suffix is FOREIGN', seatLane(seat('[PM seat] domain:devx @ objectstack — 🟢 os-x')).foreign, true);\n t('H32 lane: an `@ own-repo` suffix is NOT foreign', seatLane(seat('[PM seat] domain:devx @ objectui — 🟢 os-x')).foreign, false);\n t('H32 lane: …and keeps the bare lane label', seatLane(seat('[PM seat] domain:devx @ objectui — 🟢 os-x')).lane, 'domain:devx');\n"
},
{
"id": "h32-foreign-out-of-scope",
"why": "Same inversion, in the H32 predicate row: the FOREIGN specimen must name a board this sweep cannot read.",
"upstream": " t('H32: a FOREIGN lane is out of scope (its inventory is unreadable here)', h32SeatIdleOverQueue(seat('[PM seat] domain:devx @ objectui — 🟢 os-x'), marker('Round-start marker', 600), idleLane, NOW32), null);\n",
"ported": " t('H32: a FOREIGN lane is out of scope (its inventory is unreadable here)', h32SeatIdleOverQueue(seat('[PM seat] domain:devx @ objectstack — 🟢 os-x'), marker('Round-start marker', 600), idleLane, NOW32), null);\n"
},
{
"id": "h32-foreign-no-fetch",
"why": "Same inversion, in the H32 comment-fetch gate row.",
"upstream": " t('H32 gate: a foreign-lane seat buys no fetch', h32NeedsSeatComments(seat('[PM seat] domain:devx @ objectui — 🟢 os-x')), false);\n",
"ported": " t('H32 gate: a foreign-lane seat buys no fetch', h32NeedsSeatComments(seat('[PM seat] domain:devx @ objectstack — 🟢 os-x')), false);\n"
},
{
"id": "sweep-repo-self-test",
"why": "Upstream pins the objectstack leg against DEFAULT_SWEEP_REPO because there the two strings are equal. Here the default is objectui, so the leg is pinned to its literal and the default gets its own row.",
Expand Down
Loading