Skip to content

docs(test): triage every pnpm-test-import gap with explicit support decisions#471

Merged
jdx merged 1 commit intomainfrom
claude/exciting-nightingale-c4f951
May 2, 2026
Merged

docs(test): triage every pnpm-test-import gap with explicit support decisions#471
jdx merged 1 commit intomainfrom
claude/exciting-nightingale-c4f951

Conversation

@jdx
Copy link
Copy Markdown
Contributor

@jdx jdx commented May 2, 2026

Summary

  • Reframes test/PNPM_TEST_IMPORT.md from "what's portable today" to "every documented divergence / skipped / blocked entry is a feature gap that needs an owner decision."
  • Adds a triage block at the top with three outcome categories (support / won't-support / test-only) and records decisions for all 16 untriaged gaps surfaced in the file.
  • Promotes three intentional divergences to the Tier 3 skip section with rationale: pnpmfile updateConfig hook (misc.ts:479), readPackage-on-importers (hooks.ts:551 + 661), and aube update --depth N (update.ts:599).
  • Each remaining support entry includes a concrete aube-side fix sketch with file:line pointers, so the next porter can act without re-reading the cluster.
  • One outcome flagged high-priority: bare user/repo GitHub-shorthand resolution in parse_git_spec (~20-30 LOC) unlocks four dropped kevva/is-negative assertions across update.ts:14/143/170/197.

Notes for the reviewer

  • The diff is doc-only (test/PNPM_TEST_IMPORT.md, +58/-8). No code changed.
  • One previously-recorded "blocked on git-resolver feature" claim turned out to be outdated — aube has full git resolution at crates/aube-resolver/src/local_source.rs and the fragment parser at crates/aube-lockfile/src/lib.rs already handles slash-bearing committishes. misc.ts:567 is now flagged test-only.
  • A new convention note allows network-dependent ports gated behind a slow=1 tag or a separate test/*_slow.bats file (relevant to lifecycleScripts.ts:128 node-gyp bootstrap and lifecycleScripts.ts:336 git-dep prepare).

Test plan

  • No tests required (doc-only change). Confirm renders cleanly on GitHub.

Note

Low Risk
Low risk: documentation-only updates that do not affect runtime behavior or test execution directly.

Overview
Adds a triage section to test/PNPM_TEST_IMPORT.md that reframes every skipped/divergent pnpm test as an explicit product decision (support / won't-support / test-only), including guidance for gating network-dependent ports behind slow=1.

Records decisions for all previously untriaged gaps, with concrete fix sketches for support items (notably a high-priority parse_git_spec change to accept GitHub user/repo shorthand) and promotes three intentional divergences (updateConfig, readPackage on importer manifests, and aube update --depth) into the Explicitly skipped (Tier 3) list with rationale.

Reviewed by Cursor Bugbot for commit fc37303. Bugbot is set up for automated code reviews on this repo. Configure here.

…ecisions

Reframes the file from "what's portable today" to "every documented
divergence / skipped / blocked entry is a feature gap that needs an
owner decision." Adds a triage block at the top with three outcome
categories (support / won't-support / test-only) and records decisions
for all 16 untriaged gaps. Three Tier 3 entries (`updateConfig` hook,
`readPackage`-on-importers, `aube update --depth N`) move to the
explicit-skip section with rationale; the rest are tagged with concrete
aube-side fix sketches and file:line pointers so the next porter can
act without re-reading the cluster.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jdx jdx merged commit 7f66aee into main May 2, 2026
11 checks passed
@jdx jdx deleted the claude/exciting-nightingale-c4f951 branch May 2, 2026 18:30
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 2, 2026

Greptile Summary

Doc-only change (+58/-8) to test/PNPM_TEST_IMPORT.md that adds a triage block classifying all 16 previously-undecided feature gaps as support, won't-support, or test-only, promotes three intentional divergences to the Tier 3 skip list with rationale, and converts each remaining gap entry into the new structured category format with concrete fix sketches and file:line pointers.

Three minor inconsistencies in the document as modified:

  • Line 20: lifecycleScripts.ts:128 triage entry is labelled support but carries a conflicting "(test-only)" parenthetical — the two are mutually exclusive categories per the triage key.
  • Line 85: update.ts:14 in the "Done" list has no note about the dropped kevva/is-negative assertion, while the triage block and body note both flag it as a high-priority outstanding item; future contributors will assume it is fully complete.
  • Line 104: The monorepo/index.ts:56 body entry still uses the old "Documented divergences" label instead of the new Support format used everywhere else in the updated sections.

Confidence Score: 4/5

Safe to merge; doc-only change with no code impact — three P2 documentation inconsistencies that should be addressed but do not block.

All findings are P2 (style/documentation quality). The triage logic and product decisions themselves are sound; the issues are label contradictions and a missed reformatting that could mislead future contributors. No P0 or P1 findings.

test/PNPM_TEST_IMPORT.md — lines 20, 85, and 104 need small corrections before the document can be used as an unambiguous reference.

Important Files Changed

Filename Overview
test/PNPM_TEST_IMPORT.md Adds a triage block classifying all 16 gaps, promotes three entries to Tier 3, and restructures divergence entries with explicit decision labels — three minor inconsistencies remain between the new triage block and existing body sections.

Comments Outside Diff (1)

  1. test/PNPM_TEST_IMPORT.md, line 104 (link)

    P2 monorepo/index.ts:56 body entry not updated to match triage decision

    The triage block (line 23) classifies monorepo/index.ts:56 as support (aube fix needed), but the corresponding body entry here still uses the old "Documented divergences (don't port without aube-side fix)" label. Every other section touched by this PR (misc.ts, hooks.ts, lifecycleScripts.ts, update.ts) was updated to the new Support / Won't-support / Test-only format, but this batch-1 monorepo entry was missed. The inconsistency means the document uses two different conventions to say the same thing, which will confuse the next person using the triage block as the authoritative source.

    Fix in Claude Code

Fix All in Claude Code

Reviews (1): Last reviewed commit: "docs(test): triage every pnpm-test-impor..." | Re-trigger Greptile

Comment thread test/PNPM_TEST_IMPORT.md
Triaged (decisions recorded, awaiting work):

- **support** — hooks.ts:580 — readPackage during `aube remove` in a workspace. Port the test.
- **support** — lifecycleScripts.ts:128 — node-gyp on PATH (test-only). Port with network, gate slow.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Contradictory category label

The triage entry is filed under support (meaning "aube bug or missing feature — fix aube first") but immediately qualifies itself with "(test-only)" — which is the explicitly distinct third category (feature already supported, gap is purely test coverage). These two labels are mutually exclusive per the triage key defined above. The body entry under the lifecycleScripts.ts section (line 73) correctly places it under Support with "aube fix needed before / alongside port," so the "(test-only)" here looks like a copy-paste leftover from an earlier draft. Either drop the parenthetical or reclassify to test-only if no aube-side work is actually needed.

Fix in Claude Code

Comment thread test/PNPM_TEST_IMPORT.md
@@ -42,8 +85,12 @@ Goal: highest install-path parity coverage for lowest cost. Each row is a pnpm s
- Done: update <dep> (14, ported twice — once via `update --latest <pkg>` translation and once via the new `<pkg>@latest` arg syntax), update --no-save (34), update --latest --prod (225), recursive update --no-save (72), recursive update --no-shared-workspace-lockfile (118), recursive update --latest on shared lockfile (426 — asserted per-project, see divergence below), recursive update --latest --prod on shared lockfile (478 — same), update with tag @latest downgrades prerelease (659 — translated from `update <pkg>@latest` to `update --latest <pkg>`), update --latest (143), update --latest --save-exact (170), update --latest specific dep (197), recursive update --latest specific no-shared (369 — same as 543 in aube's per-project model), recursive update --latest specific shared (543 — asserted per-project), update --latest doesn't downgrade higher-than-latest prerelease pin (615 — covers #7436), recursive update --latest preserves higher prereleases across workspace (728 — 4 projects), recursive update --latest preserves prerelease + bumps outdated workspace mix (807), update indirect dep (690).
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 update.ts:14 marked "Done" without noting dropped assertion

The Done list shows test 14 as fully ported ("ported twice"), but the triage block (line 31) lists update.ts:14 in the support, high priority bucket and the body note below (line 89) says the kevva/is-negative shorthand assertion is "the focus of 14." The pattern established for 143/170/197 is to call out the dropped assertion inline (the old text did: "dropped from the 143/170/197 ports"). Without a similar annotation on entry 14, a future contributor following this document will assume test 14 is fully complete and not know to re-add its assertion when the user/repo shorthand feature lands.

Fix in Claude Code

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

Benchmark changes

Public ratios: warm installs vs Bun 4x -> 4x; warm installs vs pnpm 9x -> 9x.

Benchmark aube bun pnpm
Fresh install (warm cache) 246ms -> 318ms (+29%) 1011ms -> 1404ms (+39%) 2227ms -> 2715ms (+22%)
CI install (warm cache, GVS disabled) 1174ms -> 1264ms (+8%) 1530ms -> 1424ms (-7%) 2049ms -> 2920ms (+43%)
CI install (cold cache, GVS disabled) 4273ms -> 4819ms (+13%) 4034ms -> 4873ms (+21%) 4940ms -> 6585ms (+33%)

fc37303 vs 6e64b72 | aube/bun/pnpm | 3 scenarios | 3 runs | 500mbit/50ms | generated by Codex.

jdx added a commit that referenced this pull request May 2, 2026
## Summary

- Adds bare `user/repo` GitHub-shorthand recognition to
[`parse_git_spec`](https://github.com/endevco/aube/blob/feat/lockfile-bare-github-shorthand/crates/aube-lockfile/src/lib.rs)
— npm/pnpm parity. Placed last after explicit URL/scheme branches so
existing forms (`github:user/repo`, `git+https://`, scp, full URLs)
shadow it.
- Adds a guard in
[`update.rs`](https://github.com/endevco/aube/blob/feat/lockfile-bare-github-shorthand/crates/aube/src/commands/update.rs)
that skips git-spec deps in the `update --latest` manifest rewrite.
Without this guard the parser change creates a footgun: `"is-negative":
"kevva/is-negative"` would be silently rewritten to `"^<some-version>"`
(a registry pin) and break install.
- Adds a network-test convention: `_require_network` skips unless
`AUBE_NETWORK_TESTS=1` is set, paired with a separate `test/*_slow.bats`
file. First use:
[test/pnpm_update_slow.bats](https://github.com/endevco/aube/blob/feat/lockfile-bare-github-shorthand/test/pnpm_update_slow.bats)
— one regression-guard port covering install + update --latest
end-to-end with `kevva/is-negative` alongside the registry deps from
update.ts:143.
- Restores most of the dropped test assertions referenced in the triage
doc (PR #471). The remaining assertions in update.ts:14/170/197 need
CLI-side `aube add <bare-shorthand>` support, which is its own feature
and is tracked as a follow-up in `test/PNPM_TEST_IMPORT.md`.

## Notes for the reviewer

- Two commits: parser branch (with the leading-dot bug fix from review
feedback already squashed in) + the update.rs guard / slow bats / doc
updates.
- Addresses Greptile/Cursor P1: `is_bare_github_shorthand` now rejects
owner starting with `.` so single-component relative paths (`./repo`,
`../repo`) are correctly rejected. Test extended to cover both single-
and multi-component forms.
- The slow bats file uses the same `git checkout` teardown pattern as
`pnpm_update.bats` to restore mutated `dist-tags` storage.
- Rebased onto current main (#471 merged after this PR opened).

## Test plan

- [x] `cargo build --workspace` — green
- [x] `cargo test -p aube-lockfile` — 239 lib tests pass (+8 new for
parser branch)
- [x] `cargo clippy --all-targets -- -D warnings` — no warnings
- [x] `cargo fmt --check` — clean
- [x] `mise run test:bats test/pnpm_update.bats` — 22/22 pass (offline,
unchanged)
- [ ] `AUBE_NETWORK_TESTS=1 mise run test:bats
test/pnpm_update_slow.bats` — not run locally (needs Verdaccio + github)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Expands git-spec parsing and changes `update --latest`
manifest-rewrite behavior; mistakes could misclassify paths/URLs as git
or skip/incorrectly rewrite dependency specifiers, affecting installs.
> 
> **Overview**
> **Git spec parsing now recognizes bare `user/repo` as GitHub
shorthand** by expanding it to `https://github.com/<user>/<repo>.git`,
with new validation to avoid colliding with relative paths, scoped
package names, and other non-git forms.
> 
> **`aube update --latest` now skips git-based dependencies when
rewriting `package.json`**, preventing git specs (including the new bare
shorthand) from being converted into registry `latest`/semver pins.
> 
> Adds a **network-gated bats regression test**
(`test/pnpm_update_slow.bats`) and updates the pnpm test-porting doc to
formalize `_require_network`/`AUBE_NETWORK_TESTS=1` for
upstream-dependent tests.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1f7bbf3. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request May 2, 2026
## Summary

- `aube update --depth N` was parsed for pnpm parity and silently
ignored. Now it emits a one-line warning pointing at `rm aube-lock.yaml
&& aube install` for the only useful semantic case (`--depth Infinity` /
refresh transitives).
- Regression-guarded by a new bats case asserting both the warning's
shape and that bare `aube update` stays silent.
- Updates [test/PNPM_TEST_IMPORT.md](test/PNPM_TEST_IMPORT.md) to mark
the update.ts:599 row "won't-support — landed."

## Why now

Triaged won't-support in #471: intermediate values (`--depth 1`,
`--depth 2`) have semantics that even pnpm users get tripped up on. aube
only ever refreshes direct deps (pnpm's `--depth 0` default), so any
other value is a no-op the user has no way to discover. The warning
closes that loop.

## Test plan

- [x] `cargo build --workspace` — green
- [x] `cargo clippy --all-targets -- -D warnings` — clean
- [x] `cargo fmt --check` — clean
- [x] `mise run test:bats test/pnpm_update.bats` — 23/23 pass (+1 new
`aube update --depth: parsed-but-warn`)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: behavior is unchanged except when `--depth` is provided,
where an extra stderr warning could affect scripts that assert on exact
output.
> 
> **Overview**
> `aube update` now prints a one-line warning when `--depth` is
provided, clarifying that the flag is ignored and pointing users to `rm
aube-lock.yaml && aube install` for a full transitive refresh.
> 
> The warning is emitted only once even under recursive workspace
fanout, and CLI/help text + generated docs are updated accordingly; new
bats tests assert the warning behavior and that plain `aube update`
stays silent.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
90bbef6. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
jdx added a commit that referenced this pull request May 2, 2026
…ls (#476)

## Summary

- Repeat `aube install` runs short-circuit through the warm path, which
returns before the unreviewed-builds warning fires. Users were silently
losing the nudge to run `aube approve-builds` between installs — exactly
the failure mode `strictDepBuilds` exists to backstop.
- Persist the unreviewed-build spec keys in `.aube-state` (new
`unreviewed_builds: Vec<String>` on both `InstallState` and
`FreshnessState`) and re-emit the same `tracing::warn!` line from both
warm-path branches (`missing_lockfile_restore_eligible` and
`warm_path_eligible`) when the set is non-empty. The allowBuilds
review-placeholder write stays on the full pipeline, so warm installs
nudge without re-seeding.
- Ports `pnpm/test/install/lifecycleScripts.ts:245` ('warning is shown
when an install with --no-frozen-lockfile reuses an existing
node_modules with ignored build scripts'). Wording substituted to aube's
canonical `ignored build scripts for N package(s)` per the existing
divergence note.

Background: triaged as `support` in #471 (`test/PNPM_TEST_IMPORT.md`).
Companion to #472, which landed the bare-shorthand parser fix.

## Test plan

- [x] `cargo build`
- [x] `cargo test --workspace` — 362+239+169+... all green; the two new
state round-trip tests
(`unreviewed_builds_roundtrip_persists_into_fresh_state`,
`unreviewed_builds_default_when_field_missing_in_state`) confirm legacy
state files load via the serde default and the new field round-trips
through the FreshnessState sidecar.
- [x] `cargo clippy --all-targets -- -D warnings`
- [x] `cargo fmt --check`
- [x] `./test/bats/bin/bats test/lifecycle_scripts.bats` — 34/34 ok
including the new `aube install re-emits ignored-build-scripts warning
on repeat install`
- [x] `./test/bats/bin/bats test/approve_builds.bats` — 10/10 ok
(regression check on the existing warning emission path)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches install warm-path short-circuit logic and the persisted
`.aube-state` schema; regressions could cause incorrect warning behavior
or state incompatibilities on upgrade, though the change is additive and
guarded with serde defaults.
> 
> **Overview**
> Repeat `aube install` runs that short-circuit via the warm path (and
the missing-lockfile-restore fast path) now **re-emit the ignored build
scripts warning** by reading a persisted `unreviewed_builds` list from
`.aube-state`.
> 
> The install pipeline now computes the unreviewed-build set once,
stores it in `InstallState`/`FreshnessState`, and centralizes warning
formatting in `emit_unreviewed_builds_warning`; new unit tests cover
round-tripping/defaulting of the new state field, and a new Bats test
asserts the warning appears on a repeat no-op install.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
daf7bf0. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request May 2, 2026
## Summary
- `aube rebuild` now takes zero or more positional package names. With
no args, the existing whole-policy rebuild runs unchanged (back-compat).
With names, only the named deps' lifecycle scripts run, the build policy
is bypassed for those deps, and the root preinstall / install /
postinstall / prepare hooks are skipped.
- Match is by graph `name` (the in-tree alias when one is configured),
so `aube rebuild my-alias` works for a manifest entry like `"my-alias":
"npm:real-pkg@1.0"`, matching pnpm. Unknown names hard-error and list
every unmatched entry.
- Workspace `aube --filter <something> rebuild <pkg>` composes: each
filtered importer runs only the named deps' scripts.

Triage decision in PR #471 (lifecycleScripts.ts:282).

## Test plan
- [x] `cargo build`
- [x] `cargo test`
- [x] `cargo clippy --all-targets -- -D warnings`
- [x] `cargo fmt --check`
- [x] `mise run test:bats test/rebuild.bats` — 15/15 pass, including 4
new selective-mode tests (single dep, two deps, policy-bypass,
unmatched-name error)
- [x] `mise run test:bats test/lifecycle_scripts.bats` — 33/33 pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Extends lifecycle-script execution paths and adds an explicit
policy-bypass mode, which could change when/which dependency scripts run
if used in automation. Scope is contained to `rebuild` and guarded by
explicit package arguments plus new error checks for missing
lockfile/unmatched names.
> 
> **Overview**
> `aube rebuild` now accepts optional positional package names; when
provided, it **runs lifecycle scripts only for the named installed
dependencies**, **skips all root hooks**, and **bypasses the
`allowBuilds`/`onlyBuiltDependencies` policy** as an explicit opt-in.
> 
> The dependency lifecycle runner (`run_dep_lifecycle_scripts`) was
extended with a selective mode filter (matching by lockfile graph
`name`/alias), and `rebuild` now hard-errors on missing lockfile or
unknown package names. CLI usage/docs were updated and new Bats tests
cover selective rebuild behavior, policy bypass, and error cases.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
7a72e31. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
jdx added a commit that referenced this pull request May 2, 2026
…y/why

Adds `project_or_workspace_root()` to `crates/aube/src/dirs.rs` and
routes the five workspace-scoped commands through it so a pure-
coordinator monorepo (Turborepo defaults: `pnpm-workspace.yaml` at the
root, sub-packages under `packages/*`, no root `package.json`) works
end-to-end. `install` synthesizes an empty `PackageJson` for the root
when no manifest is on disk; the other four commands skip the root
manifest read in the same way.

Single-project commands (`add`, `remove`, root-only `run <script>`,
`ci`, `version`, …) keep using `project_root()` and still hard-error
on yaml-only roots because they need a manifest to act on.

Triage decision in PR #471 (test/PNPM_TEST_IMPORT.md, monorepo/index.ts:56).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request May 2, 2026
…tall/query/why

Turborepo-style monorepos keep `pnpm-workspace.yaml` /
`aube-workspace.yaml` at the repo root with no sibling `package.json`.
The five workspace-scoped commands previously hard-errored at
`project_root()` because they walked up looking for a `package.json`
and found none. Add `crate::dirs::project_or_workspace_root()` that
falls back to a yaml-only ancestor and route the five commands through
it; install treats the missing root manifest as `PackageJson::default()`
so root deps and root lifecycle hooks no-op while workspace projects
still install. Single-project commands (`add`, `remove`, `version`,
`publish`, `patch`, etc.) intentionally stay on `project_root()`.

Triage decision tracked in PR #471 (`test/PNPM_TEST_IMPORT.md`).
Ports the empty-monorepo case from `pnpm/test/monorepo/index.ts:56` —
`aube list -r` from a yaml root with zero on-disk projects now prints
"No projects found in <dir>" and exits 0 instead of erroring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request May 2, 2026
## Summary

- Add `updateRewritesSpecifier` setting (default `true`) — restores pnpm
parity for the most common `aube update <pkg>` use case.
- With the setting on, `aube update <pkg>` (no `--latest`) rewrites
caret/tilde manifest ranges (`^X.Y.Z` / `~X.Y.Z`) to track the new
in-range max. Other shapes (`>=`, `1.x`, exact pins, dist-tags, git,
`workspace:`) stay frozen.
- Set `update-rewrites-specifier=false` in `.npmrc` (or env equivalent)
to keep aube's prior frozen-manifest behavior.
- Ports pnpm/test/update.ts:51 (single-project) and
pnpm/test/update.ts:95 (recursive) plus an opt-out test.
- Triage decision recorded in #471 — drop-in pnpm parity wins over the
cosmetic-coin-flip rationale.

The semantic divergence this closes:

- Existing aube: `^1.2.0` in manifest + `1.2.0` lockfile + `1.2.5`
in-range max → `aube update foo` bumps lockfile to `1.2.5`, leaves
manifest at `^1.2.0`.
- New aube (default): same flow rewrites manifest to `^1.2.5` to track
the resolved version. Matches pnpm.

## Test plan

- [x] `cargo build --workspace`
- [x] `cargo test --workspace` (all crates green)
- [x] `cargo clippy --all-targets -- -D warnings`
- [x] `cargo fmt --check`
- [x] `mise run test:bats test/pnpm_update.bats` (25/25 passing,
including 3 new tests)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes `aube update` to potentially rewrite `package.json` ranges (in
addition to the lockfile) based on a new default-on setting, which can
affect repo diffs and upgrade semantics for users relying on frozen
manifests.
> 
> **Overview**
> `aube update <pkg>` (without `--latest`) can now *optionally* rewrite
`package.json` caret/tilde ranges to the newly resolved in-range
version, aligning behavior with pnpm; non-caret/tilde specs (dist-tags,
exact pins, raw ranges, git, `workspace:`) remain unchanged.
> 
> Adds a new `updateRewritesSpecifier` setting (default `true`,
configurable via env/.npmrc) to control this cosmetic manifest rewrite,
updates settings docs accordingly, and adds Bats coverage for the
rewrite path, opt-out behavior, and dist-tag preservation (including
recursive `update -r`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
8c235ba. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
jdx added a commit that referenced this pull request May 3, 2026
## Summary

Ports three of the five test-only pnpm tests called out in the triage
brief, retriages the other two with empirical evidence:

| pnpm test | item | landed | file |
|---|---|---|---|
| `misc.ts:567` (git URL with hash containing slash) | 1 | yes |
`test/pnpm_install_misc_slow.bats` (network-gated, new file) |
| `hooks.ts:68` (readPackage returning undefined fails) | 2 | no —
divergence | already-skipped at `pnpm_install_hooks.bats:310`; triage
retriaged to won't-support |
| `hooks.ts:580` (readPackage during remove in workspace) | 3 | yes |
`test/pnpm_install_hooks.bats` |
| `lifecycleScripts.ts:108` (rollback-on-build-failure) | 4 | yes |
`test/lifecycle_scripts.bats` + new
`@pnpm.e2e/aube-test-failing-install` fixture |
| `lifecycleScripts.ts:179, 200` (verify-deps + preinstall sub-aube) | 5
| no — real bug | retriaged to support; needs aube fix before port |

### Items not ported (retriaged with evidence)

**Item 2 (`hooks.ts:68`)**: triage said aube errors with `readPackage
response missing pkg`. Empirically, the IPC shim at
`crates/aube/src/pnpmfile.rs:629` falls back to the original pkg via `if
(out && typeof out === 'object') result = out;` and writes back `{ id,
pkg: <original> }`. The Rust side at `pnpmfile.rs:809` sees `pkg`
present and continues with the original manifest — install succeeds
rather than fails. The existing skipped test at
`pnpm_install_hooks.bats:310` (added in a previous PR) already documents
this divergence correctly. Triage doc updated to move this to Tier 3
(won't-support / divergence).

**Item 5 (`lifecycleScripts.ts:179, 200`)**: triage said aube has the
parent-set recursion guard, but the only "parent-set" mechanism at
`run.rs:536` preserves `INIT_CWD`, not lifecycle context. Empirically:
- `verifyDepsBeforeRun=error` + `preinstall: aube run sayHello` → inner
`aube run` exits with `dependencies need install before run: install
state not found` (state isn't written until linking finishes).
- `verifyDepsBeforeRun=install` → inner `aube run` triggers
`ensure_installed` → `install::run`, which deadlocks on the project lock
the outer install holds (`Waiting for another aube process to finish in
this project...`, observed via 60s timeout).

Per the brief: "If porting surfaces a real recursion bug, STOP — don't
fight the bug." Aube fix needed: skip `ensure_installed` when
`npm_lifecycle_event` is set in the env (matches npm/pnpm's "no
verify-deps inside lifecycle scripts" contract). Tracked in the
retriaged entry in the triage doc.

### New offline fixture

`test/registry/storage/@pnpm.e2e/aube-test-failing-install/` (1.0.0,
`install: exit 1`) — minimal hand-built tarball + packument JSON,
mirrors the structure of the existing `@pnpm.e2e/install-script-example`
fixture. Used by the rollback test only.

### References

- Triage doc: `test/PNPM_TEST_IMPORT.md` (see PR #471 for triage
context).
- Network-test convention: PR #472 / `test/pnpm_update_slow.bats`.

## Test plan

- [x] `cargo build --workspace`
- [x] `cargo clippy --all-targets -- -D warnings` (zero warnings)
- [x] `cargo fmt --check` (clean — no Rust source changes)
- [x] `mise run test:bats test/pnpm_install_hooks.bats` — 21 passing (3
documented skips), including the new readPackage-during-remove test
- [x] `mise run test:bats test/lifecycle_scripts.bats` — 34 passing,
including the new rollback test
- [x] `AUBE_NETWORK_TESTS=1 ./test/bats/bin/bats
test/pnpm_install_misc_slow.bats` — passes (network required)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Test-only changes add new bats coverage (including a network-gated
case) plus an offline fixture; no production Rust code paths are
modified, so risk is limited to CI/test stability and reliance on
external GitHub availability for the slow test.
> 
> **Overview**
> Adds three new pnpm parity ports to the bats suite: a network-gated
`misc.ts:567` install-from-git regression test (new
`pnpm_install_misc_slow.bats`), a workspace `aube remove` path hook
regression test in `pnpm_install_hooks.bats`, and a lifecycle
rollback/retry contract test in `lifecycle_scripts.bats` backed by a new
always-failing offline fixture `@pnpm.e2e/aube-test-failing-install`.
> 
> Updates `PNPM_TEST_IMPORT.md` to mark the newly-ported items as done
and to retriage two previously “test-only” gaps: `readPackage` returning
`undefined` is now documented as an intentional aube divergence, and the
`verify-deps-before-run` + lifecycle-subcommand case is reclassified as
a real aube bug requiring a fix before porting.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
6072789. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request May 3, 2026
…y/why

Adds `project_or_workspace_root()` to `crates/aube/src/dirs.rs` and
routes the five workspace-scoped commands through it so a pure-
coordinator monorepo (Turborepo defaults: `pnpm-workspace.yaml` at the
root, sub-packages under `packages/*`, no root `package.json`) works
end-to-end. `install` synthesizes an empty `PackageJson` for the root
when no manifest is on disk; the other four commands skip the root
manifest read in the same way.

Single-project commands (`add`, `remove`, root-only `run <script>`,
`ci`, `version`, …) keep using `project_root()` and still hard-error
on yaml-only roots because they need a manifest to act on.

Triage decision in PR #471 (test/PNPM_TEST_IMPORT.md, monorepo/index.ts:56).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant