|
48 | 48 | * the stamped detector is STILL ABSENT from this tree's spec. Once the published |
49 | 49 | * spec catches up, the stamp is expired and says so instead of passing. |
50 | 50 | * |
| 51 | + * ## Why packages/spec is NOT in ci.yml's console filter (objectstack#9710) |
| 52 | + * |
| 53 | + * That filter lists the pin, the build script and this gate's own sources — not |
| 54 | + * packages/spec — so a spec-only PR never schedules Console Pin Gate and never |
| 55 | + * reaches this check. Adding it is the obvious next thought; it was measured and |
| 56 | + * DECLINED, and the reason is not cost, which is why it is recorded here rather |
| 57 | + * than left on a card: the job it would schedule is vacuous, not expensive. |
| 58 | + * |
| 59 | + * Count what this gate can fail on. Of its six failure verdicts, FIVE are pure |
| 60 | + * functions of the RESTORED DIST and its stamp — a missing dist, unreadable |
| 61 | + * assets or a malformed stamp, a missing stamp, the published-only detector |
| 62 | + * present in the bundle, the stamp's own fresh witness missing from it. A |
| 63 | + * spec-only diff cannot move any of those: the cache key is the one spelled at |
| 64 | + * the top of this header — the pin and the build script, nothing else — and |
| 65 | + * entries under it are IMMUTABLE, so all five replay what the last |
| 66 | + * console-filtered run already saw. Exactly ONE verdict reads this tree, the |
| 67 | + * expiry re-check, and it needs packages/spec/dist because readSpecBlob resolves |
| 68 | + * the package's exports map. So the restore-only job proposed there — no |
| 69 | + * install, no turbo build — would start the gate 15 more times per 100 commits |
| 70 | + * (6/100 today, 21/100 with packages/spec added, measured over real first-parent |
| 71 | + * history) and skip the only tree-sensitive assertion on every one of them. |
| 72 | + * |
| 73 | + * Paying for the build instead does not rescue it, because the headline scenario |
| 74 | + * is one this gate deliberately does not test. With the dist and stamp held |
| 75 | + * fixed and only the tree varying: spec unbuilt PASSES (expiry not re-checked), |
| 76 | + * spec unchanged PASSES, spec MOVED FORWARD PASSES, and only a spec that has |
| 77 | + * caught up to the published text FAILS. "Spec moved forward since the dist was |
| 78 | + * built" is precisely what a spec trigger would be bought for, and PR |
| 79 | + * objectstack#9706 already ruled it "not a failure — the ruled cache design |
| 80 | + * accepts lag". The lag is the trade-off objectstack#9667 accepted when it |
| 81 | + * rejected the cache-key option, not a defect a trigger change can catch. What |
| 82 | + * remains has a low ceiling: only 5 of those 15 commits add any `describe()` |
| 83 | + * text under packages/spec — the only text the probes read — and expiry is a |
| 84 | + * tree STATE, not an event, so once it is true today's 6/100 console runs still |
| 85 | + * catch it. Widening the filter buys latency, not coverage. |
| 86 | + * |
| 87 | + * The exit, for whoever asks a third time: objectstack#10428 proposes deriving |
| 88 | + * the expiry probe from packages/spec SOURCE text — `describe()` arguments are |
| 89 | + * plain string literals — which would make that one assertion BUILDLESS. The |
| 90 | + * light job is worthless only because its single meaningful assertion needs a |
| 91 | + * build; remove the build and this question reopens on entirely different terms. |
| 92 | + * Full working — the paths-filter replay under both picomatch versions, the |
| 93 | + * per-commit attribution — is on objectstack#9710's ruling comment. |
| 94 | + * |
51 | 95 | * ## Failure response: FAIL, deliberately, rather than rebuild |
52 | 96 | * |
53 | 97 | * GitHub Actions cache keys are IMMUTABLE. A gate that reacted to a bad restore |
|
0 commit comments