Skip to content

[finding] create-objectstack's declared bin is tracked non-executable, so pnpm install dirties every fresh worktree #10991

Description

@os-elon

Filed unassigned by the dev on #10836 (draft PR #10989) as an out-of-scope observation. Not touched there.

What was measured

In a fresh worktree, pnpm install leaves the tree dirty with a file nobody edited:

$ git worktree add ../objectstack-10836 -b <branch> origin/main && cd ../objectstack-10836 && pnpm install
$ git status --porcelain
M packages/create-objectstack/bin/create-objectstack.js
$ git diff --stat packages/create-objectstack/bin/create-objectstack.js
packages/create-objectstack/bin/create-objectstack.js | 0
1 file changed, 0 insertions(+), 0 deletions(-)
$ git diff packages/create-objectstack/bin/create-objectstack.js
old mode 100644
new mode 100755

No content changes — a mode change only.

Why it happens

The file is a declared bin with a shebang, but it is tracked non-executable:

$ git ls-files -s packages/create-objectstack/bin/create-objectstack.js
100644 924fff1230b60d80ceddc0a0a332e12fa95cc9f0 0	packages/create-objectstack/bin/create-objectstack.js
$ head -1 packages/create-objectstack/bin/create-objectstack.js
#!/usr/bin/env node
// packages/create-objectstack/package.json"bin": { "create-objectstack": "./bin/create-objectstack.js" }

pnpm chmods a declared bin to 755 when it links it, and this repo has core.fileMode = true, so that chmod registers as a tracked modification on every install.

The sibling declared bin has the mode the tracked file should have, which is what makes this look like an oversight on one file rather than a repo-wide convention:

$ git ls-files -s 'packages/*/bin/*'
100644 … packages/cli/bin/run-dev.js ← not a declared bin (shebang `tsx`), not affected
100755 … packages/cli/bin/run.js ← declared bin, tracked executable ✅
100644 … packages/create-objectstack/bin/create-objectstack.js ← declared bin, tracked 644 ❌

packages/cli/bin/run-dev.js is not in any bin map, so pnpm never chmods it and it is not part of this.

Why it is worth a card rather than a shrug

The effect is cosmetic; the hazard is not. Every agent worktree in this repo starts with one pre-dirtied tracked file that the agent did not touch, and a routine git add -A sweeps it into an unrelated PR. That is the same failure shape the shared-stash rule in AGENTS.md exists for — someone else's change riding into your commit while every command reports success. It also costs a beat of "did I break this?" on every fresh worktree.

Verified as a real install effect, not a local accident: reproduced in a worktree created from origin/main at 471cfbd97, and git checkout HEAD -- <path> restores it cleanly.

Suggested landing (hint for triage, not a routing decision)

git update-index --chmod=+x packages/create-objectstack/bin/create-objectstack.js, committed — one mode bit, matching packages/cli/bin/run.js. Worth a moment's thought on whether a gate should assert "every declared bin with a shebang is tracked 100755", since this class recurs whenever a package adds a bin.

Duplicate scan before filing: one keyword search over open issues (create-objectstack + bin/executable/mode) and one broader scan; the only create-objectstack finding open is #10325 (hardcoded version banner), unrelated.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions