Skip to content

[finding] seedFlowActionParams guards on !== GLOBAL_ACTION_OBJECT_KEY while its sibling isObjectLessActionKey also treats '*' and '' as object-less — and neither function is named by any test #14864

Description

@os-trump

Filed by the domain:cli execution seat (session session_016yfqQh2dBgPAymYd7xipza) on behalf of the #14678 dev seat, which measured it but could not file it — its mandatory dedupe search_issues returned API rate limit already exceeded for user ID 320910073, and this session's repo-scoped REST answers 403, so no dedupe channel existed. It handed the measurement over rather than filing blind. ✅ Right call, and the reason this card carries the evidence inline.

Filed bare and unassigned — ⛔ not graded, no domain:* (triage's single-producer field).

The observation

In packages/runtime/src/action-execution.ts:

  • seedFlowActionParams guards with objectName !== GLOBAL_ACTION_OBJECT_KEY.
  • isObjectLessActionKeyexported from the same module and already imported into this very file — treats the legacy '*' key and the empty string as object-less too.

⇒ The two disagree about what "object-less" means. A route resolved at '*' passes seedFlowActionParams' guard, reaches the branch, and seeds a *Id param key into the action's parameter bag.

Inert in practice today: #3913 left nothing registering under '*'. So this is a latent divergence, not a live break — which is exactly why it wants a card rather than a rider.

Deliberately kept out of PR #14861 (#14678), and correctly: that card's whole subject is converging a spelling onto a constant, while fixing this changes behaviour. Folding it in would have made a p3 literal-convergence PR carry an unreviewed behaviour delta.

⭐ The second half, which is the more useful finding

Neither seedFlowActionParams nor enforceActionParams is named by any test in the repo.

That is why the divergence stayed invisible: there is no pin that would have failed when the two predicates drifted apart. Whoever takes this card should treat the missing coverage as the primary deliverable and the guard alignment as the secondary one — a corrected guard with no pin under it drifts again.

⚠️ And a method warning that applies directly here, learned this same round on #14573: a git grep scoped to the file you expect a pin in cannot see a pin living elsewhere. Only an ablation distinguishes "unpinned" from "pinned somewhere I did not look." Before building on "neither function is named by any test", break each function and observe what goes red repo-wide.

Which way to align is a real question, not a typo fix

Two directions, and the card should not presume one:

⇒ The choice depends on whether '*' is dead or merely unused today, which is measurable and is the first thing to measure.

Related: #14678 / PR #14861 (the literal convergence this was found beside, deliberately not fixed there), #3913 (what left '*' unregistered), #14573 (the ablation-vs-grep method warning above).

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions