Skip to content

The card-inset gate, outliving the defect it was written for (#215) - #216

Merged
bdelanghe merged 1 commit into
mainfrom
claude/bounded-tools-review-330px6
Aug 21, 2026
Merged

The card-inset gate, outliving the defect it was written for (#215)#216
bdelanghe merged 1 commit into
mainfrom
claude/bounded-tools-review-330px6

Conversation

@bdelanghe

@bdelanghe bdelanghe commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Closes #215. Rebuilt on the rewritten homepage — what this PR is has changed, so here it is again honestly.

What's left of the original

The two provenance cards this branch was opened to fix no longer exist: the homepage rewrite (#219, merged as c7dceb8) cut them. The .provenance CSS went with them, and the copy fix went with the copy.

What remains is the part worth keeping.

The gate ships anyway

.card is still used by the three repo cards and the try-it card on the homepage, and across /map, /desk, /contracts and /conformance. The failure mode it guards — a card variant that forgets to declare an inset, so its copy renders flush against a 1px border — is a property of the component, not of the two cards that happened to have it first.

Retiring a gate because its first catch got fixed is how the second one ships.

✓ card-inset: 8 card render(s) across 13 page(s) × 2 width(s);
  all text ≥12px clear of its border

Eight renders, down from sixteen: the rewritten homepage carries half as many cards as the old one did.

One thing that had to be re-aimed

The mutation step injected .provenance { padding: 0 }a class that is now absent. A mutation aimed at a class that's gone proves nothing and passes quietly, which is the exact failure the step exists to prevent. It strips .proof-card now, and the workflow's own script (extracted from the YAML, not retyped) takes the gate red on 6 cards.

That is the second time this lane's self-test has been wrong in a way that looked green. The first was a probe I validated as a hand-copy while CI ran a different one. Both times the fix was to run the committed script rather than a retyping of it.

Also here

The path-traversal fix. CodeQL was right that join("dist", req.url) escapes the root — verified, join("dist", "/../../../../etc/passwd") resolves to /etc/passwd. The server now serves from an allowlist built by walking dist, so no filesystem path is derived from a request at all. That's the org's own default-deny reasoning — unknown is not permission — with the property a filter can't have: an escape nobody thought of has nothing to escape into.

The lane proves it, over a raw socket because fetch() and every browser normalize .. out before sending:

HTTP/1.1 404 Not Found   /../../../../etc/passwd
HTTP/1.1 404 Not Found   /%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
HTTP/1.1 404 Not Found   /../../scripts/check-card-inset.mjs
HTTP/1.1 404 Not Found   /../package.json
✓ nothing outside dist/ is reachable; real routes still are

check-jargon keeps the comment strip, completed to (?:-->|$) so an unterminated comment swallows to end of file rather than surviving it. An authoring note that names a term was demanding a link for text that never renders.

Verified

20 checks green on 85f1ddf, including this PR's own card-inset lane and CodeQL. Locally: npm run check, brand content / coverage, axe (13 pages, 0 serious), the traversal probe and the mutation step both run from the committed workflow.

Comment thread scripts/check-card-inset.mjs Fixed
Comment thread scripts/check-card-inset.mjs Fixed
@bdelanghe
bdelanghe force-pushed the claude/bounded-tools-review-330px6 branch from d5a48d4 to fb14493 Compare August 21, 2026 01:57
Comment thread scripts/check-card-inset.mjs Fixed
Comment thread scripts/check-card-inset.mjs Fixed
…215)

The two provenance cards this branch was opened to fix no longer exist —
the homepage rewrite (#219) cut them — so the CSS half of the original
change is gone with them. What remains is the part worth keeping.

The card-inset gate ships anyway. `.card` is still used by the three repo
cards and the try-it card on the homepage, and across /map, /desk,
/contracts and /conformance, and the failure mode it guards is a class
that forgets to declare an inset. Retiring a gate because its first catch
got fixed is how the second one ships.

Re-aimed where it had to be:

  the mutation step injected `.provenance { padding: 0 }`, a class that is
  now absent. A mutation aimed at a class that is gone proves nothing and
  passes quietly — the exact failure the step exists to prevent. It now
  strips `.proof-card`, and the workflow's own script (extracted from the
  YAML, not retyped) takes the gate red on 6 cards.

  8 card renders across 13 pages, down from 16: the rewritten homepage
  carries half as many cards as the old one did.

check-jargon keeps the comment strip, completed to `(?:-->|$)` so an
unterminated comment swallows to end of file rather than surviving it.

The path-traversal fix stays as it was: the server serves from an
allowlist built by walking dist, so no filesystem path is derived from a
request. Verified through the workflow's own probe — four traversal
shapes non-200, real routes still 200.
@bdelanghe
bdelanghe force-pushed the claude/bounded-tools-review-330px6 branch from 45cc609 to 85f1ddf Compare August 21, 2026 13:53
@bdelanghe bdelanghe changed the title The provenance cards had no padding, and a gate that would notice (#215) The card-inset gate, outliving the defect it was written for (#215) Aug 21, 2026
@bdelanghe
bdelanghe marked this pull request as ready for review August 21, 2026 13:55
@bdelanghe
bdelanghe merged commit 0e967eb into main Aug 21, 2026
20 checks passed
@bounded-systems-front-desk bounded-systems-front-desk Bot moved this from Todo to Done in Front Desk Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Homepage: the two provenance cards have no padding, and the proof section is still the densest prose on the page

3 participants