Skip to content

dispatch-gates: STAGE-THEN-RUN reaches a program by an edge neither follow traverses — check:objectui-changeset inherits nothing from scripts/bump-objectui.sh #14290

Description

@baozhoutao

Found by the per-edge audit on #14013 (provenance; that card is an audit, ⛔ not a fix, so this is filed separately per its triage fence). Measured on a39b02a6b.

The edge

scripts/objectui-changeset-digest.mjs (the file behind check:objectui-changeset) copies scripts/bump-objectui.sh into a throwaway repo and then EXECUTES the copy — four spawn sites, all of the same shape:

execFileSync('bash', [join(fwDegraded, 'scripts', 'bump-objectui.sh'), '--no-commit', head], …)
spawnSync('bash', [join(fwTrunc,  'scripts', 'bump-objectui.sh'), '--no-commit', c6to], …)
spawnSync('bash', [join(fwTrunc2, 'scripts', 'bump-objectui.sh'), '--no-commit', c6to], …)
spawnSync('bash', [join(fwDir,    'scripts', 'bump-objectui.sh'), ...args], …)

Neither follow traverses it:

⇒ The digest genuinely performs bump-objectui.sh's work, and inherits 0 of the 6 hints that file spells.

This is the same family as #13000 (whose specimen was the digest staging a copy of check-adr-0087-registration.mjs) one turn further: #13000 closed the case where the card edits the STAGED FILE ITSELF; the case where the card edits something in the staged program's own population is still open.

Measured cost, stated honestly

Small, and the thinness is part of the report rather than a reason to withhold it. The 6 hints scripts/bump-objectui.sh spells are .changeset/*.md, scripts/bump-objectui.selftest.sh, .github/workflows/cut-rc.yml, docs/releases-maintenance.md, .changeset/console-82a94170c405.md, packages/console/dist. Two of those are already under .changeset, which the family declares itself; packages/console/dist is a build output. So the novel-and-plausible lead is essentially scripts/bump-objectui.selftest.sh.

⛔ That is a reason to price this carefully, not to close it as a one-off: the shape — copy a program to a scratch path, execute the copy — is what a sandboxing gate does, and it is invisible to both follows by construction rather than by accident.

⛔ What the repair is NOT

Not this gate's name in a table (ruled against four times in this lane), and ⛔ not admitting a basename literal as a read target — readProgramTargetsInSource's own docblock refuses that explicitly ("Do not close that by admitting the basename literal: that is the grep above", measured at 924 mentions in 451 files).

The shape that would fit the #14012 precedent: intersect two scans that already run over the SAME file — a spawn site whose base is unresolvable but whose trailing segments equal a target the read scan already resolved to a tracked path — and let the followed program declare what a follower inherits (declaredInheritedPopulation). That is an intersection inside one file, not a grep over the corpus. ⚠️ Note that scripts/bump-objectui.sh carries no inherited-population marker today, so a declaration-gated version of this follow ships 0 live leads until that marker is added; whether the marker or the follow comes first is the design question this card owes.

Re-check

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --residue scripts/objectui-changeset-digest.mjs

⚠️ scripts/pm/dispatch-gates.mjs changes several times a day — re-derive rather than quoting any figure above.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions