Repository navigation
feat(packs): add candidate openai 4 to 7 migration pack - #130
Open
lucasbraum wants to merge 2 commits into
Open
lucasbraum wants to merge 2 commits into
lucasbraum wants to merge 2 commits into
Conversation
This was referenced Oct 14, 2026
lucasbraum
added a commit
that referenced
this pull request
Oct 14, 2026
Candidate-pack smoke tests previously required editing verification.json to pretend the pack was verified. This adds a local-only opt-in without changing any pack record or ground truth. - Add `--allow-candidate` to `check` and `fix`, including worker requests, companion preflight and alternate leads. Only registered packs with an explicit candidate record qualify; missing, blocked and inconsistent records keep the existing behavior, and verified packs remain unchanged. - Reject the flag in `scripts/action.ts`, the Action runner, the Action subprocess boundary and CLI invocations in GitHub Actions. Reject it with `--pr`, `--yes` or publication intent before migration work. Persisted candidate runs also refuse later publication. - Show **candidate pack, not verified** in terminal output, stored report.json and the generated PR body preview. Internal reports add optional `packWarning`; the `uptide.run/v1` projection uses its existing `error` field, with no schema or enum changes. - Use the claiming pack rule id for assisted sites when no transform applies, including `--no-llm`. The regression recreates OpenAI tool-call union sites from the PR #130 smoke case synthetically; no third-party repository or pack truth was modified. - Document the smoke workflow in CONTRIBUTING “Write a pack”, README and command/pack docs; include a patch changeset. Validation: regression tests failed first (candidate eligibility, local execution/banner, Action/publication refusals and tool-call rule labels). `pnpm lint` and `pnpm typecheck` pass. `pnpm test -- --maxWorkers=4` passes: 2,097 tests passed, 31 network-gated tests skipped. The first shell run hit localhost permission errors; a host run had one existing compiler-test timeout under concurrent load. The final full run used four workers with unchanged timeouts. Created in an isolated git worktree, installed with `--frozen-lockfile --ignore-scripts`, signed off with the commit author's identity, and rebased on current main before opening this PR. Fixes https://linear.app/uptide/issue/UPT-51/fix-allow-candidate-for-local-smoke-tests-of-unverified-packs Signed-off-by: Lucas Braum <lucasbraum@gmail.com>
Merged
7 tasks done
lucasbraum
added a commit
that referenced
this pull request
Oct 15, 2026
… a blocker (UPT-50) (#142) ## What and why [UPT-50](https://linear.app/uptide/issue/UPT-50/plan-peers-and-dependencies-the-target-version-requires), found by the openai pack (#130). The planner moved a package's release group (#135, `companions.ts`) but never a package the **target version requires**. openai 7 peers on `zod ^3.25 || ^4.0`, yet batch-ai stayed on zod 3.24.2. This builds on #135; it does not change it. A new step, `check/required.ts`, runs after the release group: - **What a planned version declares.** Take every planned version: the lead's target and each companion it moves. When one declares a peer or dependency range the installed copy rejects, that package moves to the **lowest release of its line** that satisfies the range. A line is one major, or one minor for 0.x (what a caret range reaches). Example: zod 3.24.2 → 3.25.0. - The rule applies only when the upgrade **introduces** the violation, i.e. the installed host accepted the installed copy. A range the repository already breaks today is not this upgrade's (see morphic below). - **What depends on the lead.** A direct dependency whose own dependency range rejects the lead's target moves the same way, within its line. - **A required move across a major is never made.** - A peer or a dependent becomes a **blocker** with the exact range: `openai 7.9.0 needs zod ^4.0.0; installed 3.25.76, and only a new major satisfies it (zod 4.0.0)`. - A plain dependency gets its own nested copy. That is not a blocker. - Blockers appear in `check` (`✗ blocked: … a new major, never made by Uptide`), in the PR body, and in `pack test` (`✗ blocked: …`, and on each `with` entry they keep behind). - `fix` still runs, leaves the blocked package where it is, and rates the risk High ("a required move is blocked"). - **Shown apart from release-group companions.** A required move is a companion marked `required`, so `fix` installs it in the same single install. The PR body lists it separately, next to #135's "Left where they are": ``` Upgraded with openai, so the install stays consistent: ← release group, unchanged Moved because the new version requires it: - `zod` 3.24.2 → 3.25.0 (moved because openai 7.4.0 requires zod ^3.25 || ^4.0) Blocked: a required move only a new major makes, which Uptide never makes: - @openai/agents 0.1.11 depends on openai ^5.20.2; only a new major accepts openai 7.9.0 (@openai/agents 0.15.0, which needs zod ^4.0.0; installed 3.25.76) Left where they are (not released with it): ← #135, unchanged ``` - **The install scope guard allows exactly these moves.** The allowed set is still the lead plus its companions, so a planned move is allowed. Testing the other half turned up a gap on npm: a root dependency the user declares (`zod`) could change without the plan saying so, because npm resolves it as a moved package's peer and so it counted as inside openai's subtree. pnpm and Yarn already refused that. Now on npm too, an importer's declared dependency changes only when the plan names it (`lock-guard.ts`). Not in this PR: UPT-54 (@types stub removal) touches the same planner and comes after this. ## How it was verified **Failing tests first** (the commit `test(check): …`): 14 tests fail on main's code and pass here, plus one more added with the refinement. - `check/required.test.ts`, synthetic, modeled on #130's repositories: - batch-ai: zod 3.24.2 → 3.25.0; a prerelease is skipped. - openai-guardrails-js: `@openai/agents` 0.1.11 only reaches openai 7 at 0.15.0, a new 0.x line that needs zod 4. This is a blocker naming both, and neither package is moved. - A within-line dependent that moves, plus what its new release then requires. - A peer that needs a new major (blocker); a 0.x minor treated as a major. - A plain dependency: moves within its major, or keeps a nested copy (no blocker). - Workspace visibility (sibling vs. hoisted root). - Release-group companions unchanged next to a required move. - A requirement the install already breaks (morphic). - `fix/managers/required-scope.test.ts`, for npm, pnpm and Yarn: the lead plus the required move is allowed; the required package moving unplanned is refused (failed on npm before); anything else moving next to the plan is refused. - `fix/generic.test.ts`: - `fix` installs the required move in one install (`also`), and the PR body names it. - With a blocker, `fix` moves nothing extra, and the PR body names the blocker. - PR body and risk (`fix/report.test.ts`), `check` output (`format-check.test.ts`), and `pack test` accounting (`pack-test.test.ts`: a required move counts as moved, a blocker is attached to what it keeps behind). **Re-scored every registered pack, before (main `9ba005a`) and after (this branch).** Same truth, scripts off: | Pack | Before: breaking P / R (tp fp fn) | After: breaking P / R (tp fp fn) | Overall P / R before → after | Gate before → after | | --- | --- | --- | --- | --- | | ai | 100% / 82% (9 0 2) | 100% / 82% (9 0 2) | 100% / 89% → same | PASS → PASS | | lucide-react | 100% / 100% (11 0 0) | same | 100% / 100% → same | PASS → PASS | | next | 100% / 85% (11 0 2) | same | 100% / 80% → same | PASS → PASS | | react | 100% / 80% (57 0 14) | same | 100% / 81% → same | FAIL → FAIL ¹ | | @sentry/browser | 100% / 100% (3 0 0) | same | 100% / 100% → same | PASS → PASS | | @sentry/nextjs | 100% / 100% (8 0 0) | same | 100% / 100% → same | PASS → PASS | | @sentry/react | 100% / 100% (2 0 0) | same | 100% / 100% → same | PASS → PASS | | stripe | 100% / 90% (18 0 2) | same | 100% / 90% → same | PASS → PASS | | vitest | 100% / 50% (16 0 16) | same | 0% / 50% → same | PASS → PASS | | zod | 100% / 74% (59 0 21) | same | 100% / 85% → same | PASS → PASS | **Breaking precision does not drop for any pack.** - The only plan change: in `ai` (vercel/chatbot), `swr` 2.3.3 → 2.4.1 moves because `@ai-sdk/react` 4.0.10 requires `swr ^2.4.1`. Its scores are unchanged. - The first after-run did drop `ai` precision: in miurla/morphic, react 19.2.0 → 19.2.1 moved and produced 59 false positives, 4 of them breaking. The installed `@ai-sdk/react` 3.0.182 already declares `react ~19.1.2 || ^19.2.1`, so that violation is the repository's today, not the upgrade's. The `fix(check): plan only requirements the upgrade introduces` commit fixes it, with a regression test. Then `ai` was re-scored. - The other packs were scored on the commit before that fix, which only narrows the rule. None of them had any required move or blocker in that run. ¹ `react` fails the same way on both sides for an environmental reason: tldraw/tldraw pins `yarn@4.7.0` and this container only has Yarn 1.22. The other `react` repositories score the same. **`pack test openai` on #130's truth**, from throwaway worktrees (main + #130 and this branch + #130, merged locally, never pushed; #130 and its truth are untouched): ``` openai/openai-guardrails-js@6c13ba08ab02 openai 4.104.0 → 7.9.0 predicted 5, expected 11, false positives 4, false negatives 10 ✗ blocked: @openai/agents 0.1.11 depends on openai ^5.20.2; only a new major accepts openai 7.9.0 (@openai/agents 0.15.0, which needs zod ^4.0.0; installed 3.25.76) ✗ @openai/agents: the upgrade moved it to 0.17.2, check leaves it (blocked: …) ✗ zod: the upgrade moved it to 4.5.4, check leaves it (blocked: …) grantsingleton/batch-ai@05c7e9f132b3 openai 4.83.0 → 7.4.0 predicted 0, expected 2, false positives 0, false negatives 2 with zod 3.24.2 → 3.25.0 (moved because openai 7.4.0 requires zod ^3.25 || ^4.0) microsoft/prompty@e878b6b7789f openai 4.104.0 → 7.10.0 predicted 52, expected 0, false positives 52, false negatives 0 ✗ blocked: @azure/ai-projects 2.4.0 depends on openai ^6.16.0; no release accepts openai 7.10.0 breaking (sites) 43% 15% 3 4 17 (before: 43% 15% 3 4 17) FAIL openai: 4 false positives among breaking findings ``` - **batch-ai's zod move is no longer missed.** That is UPT-50's done condition. Its upgrade chose 4.4.3; check picks the lowest release of the same major that satisfies the range, and `with` compares names only. - **guardrails is the needs-a-major case, and it reports the blocker with the exact ranges.** Its real upgrade moved both packages across their majors (agents 0.1 → 0.17, zod 3 → 4). Uptide never makes such a move, so the pack's `with` stays unmet there, now with the reason. - **prompty gets a new, accurate blocker:** no `@azure/ai-projects` release accepts openai 7 yet. - Scores are unchanged. #130 still fails its gate on its 4 compile-scope false positives, its engine gap 2, which is outside this PR. **Repository checks:** - `pnpm lint`: only the warning and info that were already there. - `pnpm typecheck` passes. - `pnpm test`: core 1,667 passed / 32 skipped, CLI 453 passed. ## Checklist - [x] Tests for the change (a bug fix starts with a failing test) - [x] `pnpm lint && pnpm typecheck && pnpm test` pass - [x] README and docs updated if behavior changed (`docs/architecture.md` Companions, `docs/packs.md` `with`, README one line) - [x] Changeset added if a user would notice (`.changeset/required-moves.md`, minor) - [x] No new dependency, or it was agreed in an issue - [x] No private code, names or paths in fixtures, tests or docs (synthetic registries modeled on public repositories) - [x] The rules in CONTRIBUTING.md ("Rules that do not bend") still hold (installs with scripts off; nothing moves across a major) The task brief pointed to AGENTS.md, but there is no AGENTS.md in the repository; I followed CLAUDE.md and CONTRIBUTING.md. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01H9K3U7AeqmsqU2z6wKKxhw --- _Generated by [Claude Code](https://claude.ai/code/session_01H9K3U7AeqmsqU2z6wKKxhw)_ --------- Signed-off-by: Claude <noreply@anthropic.com> Co-authored-by: Claude <noreply@anthropic.com>
lucasbraum
added a commit
that referenced
this pull request
Oct 15, 2026
Related to [UPT-49 — Compile scope must match the repo's own tsconfig](https://linear.app/uptide/issue/UPT-49/compile-scope-must-match-the-repos-own-tsconfig). Explicit importer roots bypassed TypeScript project selection, so `check` reported compiler errors in files outside the repository's own tsconfig. In guardrails, that meant four errors in its excluded `examples/` files. ### Changes - Apply project scope only to compiler diagnostics. Pack rules, patterns, inventory/config files and build-option findings remain reportable outside a tsconfig. - Discover include/exclude/files, inherited configs, recursive references and workspace projects using the repository compiler. Membership comes from parsed config roots and lazy import edges, without building a program per config. - Check affected files in their nearest covering default project, then a named/referenced project when needed, and never again under every importing consumer's options. - Reuse the scanner's program for the workspace default config, and release alternate programs after use. - Without a tsconfig, keep importer-based compilation and say so in coverage. - Anchor missing members supplied by an unchanged dependency's augmentation (jest-dom) at the side-effect setup import, keeping the failing calls as evidence. This is required for this change: tsconfig scope now type-checks test files under the app config. Without it, the vitest pack gets **1,443 breaking false positives** on opentelemetry-ecosystem-explorer (measured with the commit removed); with it the pack matches main. Its module-level cache is registered with shared-state (the `shared-state.test.ts` failure on the previous head). - Documentation and a patch changeset. The earlier React Router `verification.json` refresh was dropped in the rebase: main already carries the identical record. ### Validation Head `02f8eb4`, rebased on main `7aa3d58`. - `pnpm lint`, `pnpm typecheck`: pass. - Focused: `vitest run src/shared-state.test.ts src/adapters/typescript src/check src/packs/stripe`: 357 passed. - Full `pnpm test` on the previous rebase (onto `0b88170`): core 1763 passed, cli 456 passed. ### Resources: `check`, main vs branch Local macOS, Node 22.20.0, `--max-old-space-size=4096`, warm offline cache. The harness calls `check` in-process with the registered pack (as pack test does). Two alternating rounds each (main, branch, main, branch). Measured on engine `3895d17` against main `0881185`. The later rebases only brought in main's own commits, so these runs were not repeated. | Repository / upgrade | main wall (mean) / peak RSS | branch wall (mean) / peak RSS | Wall | RSS | | --- | --- | --- | ---: | ---: | | Excalidraw `9ee0b8f`, React → 19.0.0 | 38.2 s / 2.73 GiB | 40.3 s / 2.79 GiB | +5.5% | +2.2% | | vxsuite `5cb3c7d`, Vitest → 5.0.2 | 133.8 s / 2.79 GiB | 134.5 s / 2.88 GiB | +0.5% | +3.2% | Both are within the ~10% target. Host load averages were 4.5–7.9 on 11 CPUs. ### Pack re-score: main vs branch Engine `3895d17` vs main `0881185`, one pack at a time with cache eviction. Breaking TP / FP / FN: | Pack | main | branch | Site-level result | | --- | --- | --- | --- | | ai | 9 / 0 / 2 | 9 / 0 / 2 | identical | | lucide-react | 11 / 0 / 0 | 11 / 0 / 0 | identical | | next | 11 / 0 / 2 | 11 / 0 / 2 | identical | | react | 89 / 0 / 40 | 89 / 0 / 40 | breaking identical; +2 `unverified` sites (below) | | react-router | 14 / 0 / 2 | 14 / 0 / 2 | identical (main then failed only on its stale record, since fixed on main) | | @sentry/browser | 3 / 0 / 0 | 3 / 0 / 0 | identical | | @sentry/nextjs | 8 / 0 / 0 | 8 / 0 / 0 | identical | | vitest | 16 / 0 / 16 | 16 / 0 / 16 | breaking identical; 3,619 fewer `unverified` FPs on opentelemetry-ecosystem-explorer, none added | | @sentry/react, stripe, zod | — | — | not compared locally (the branch-side storefront fixture had no install, and one @sentry/react repository failed to install on both sides); CI's full Pack test covers them | The react difference: excalidraw `dev-docs/` is part of the root workspace. On main, the root workspace's analysis aborts with `EEXIST` (symlinking `@types/react-dom` into `node_modules`), so main never reports these sites. The branch analyzes it and reports `dev-docs/src/components/Homepage/index.tsx:7` and `dev-docs/src/theme/ReactLiveScope/index.js:10`, both `unverified`. That `EEXIST` is an existing main bug, not changed here. ### OpenAI (#130), throwaway overlay `uptide pack test openai` on `02f8eb4` with #130 cherry-picked, in a throwaway worktree. Nothing was pushed. | | #130 as recorded | this branch + #130 | | --- | --- | --- | | Breaking TP / FP / FN | 3 / 4 / 17 (42.86% precision) | **3 / 0 / 17 (100% precision)** | | Overall FP | 56 | 52 | - The four guardrails `examples/…multiturn_with_prompt_injection_detection.ts` false positives (`:331, :413, :428, :430`) are gone. No `examples/` site is predicted. - `src/base-client.ts:368` is still reported (breaking). - The remaining 52 FPs are prompty's `unverified` sites, unchanged from #130's own run. - The run reports #130's `verification.json` as stale because it improves on the recorded precision. #130 should re-record after this lands. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Lucas Braum <lucasbraum@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
One pack for openai >=4 <5 to >=7 <8, from the openai-node migration guide and changelog pinned at v7.32.0 (read 2026-10-14): 5.0 carries the API changes, 5.12.1 the tool-call unions, 6.0 one output widening, 7.0 the Node 22 floor. RESEARCH.md classifies every change. Rewrites where unambiguous: named path parameters, del -> delete, beta.chat promoted, runner event renames, removed entry points, request-option overloads, core/* paths (deprecated). Guides for the tool-call union, httpAgent, fileFromPath and other removals, with options reported as decisions. Syntactic detects for APIError.headers, node-fetch Response members and double-encoded path ids, which the compiler cannot see through any. Decisions carry repository evidence (Node 22, zod peer and helpers, fetch/proxies, global types, client subclasses). requiresBuild: 7.x exports explicit subpaths only. Ground truth: seven public 4.x -> 7.x upgrades. The pack's own rules add no false positive, but the pack stays a candidate: check reports four breaking sites in files outside guardrails' tsconfig, and leaves behind zod and @openai/agents that two upgrades moved. Both are engine gaps, documented and left for separate changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FX2nBoNEvDh9v71yDhEzxL Signed-off-by: Claude <noreply@anthropic.com>
…quired-move fixes Rebased on main after #138, #142 and #154 and re-ran pack test --write on the unchanged ground truth: breaking 3 TP / 0 FP / 17 FN (100% precision, 15% recall). It stays a candidate: check reports openai-guardrails-js blocked on a required @openai/agents major and prompty blocked on @azure/ai-projects' openai ^6 dependency. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FX2nBoNEvDh9v71yDhEzxL Signed-off-by: Claude <noreply@anthropic.com>
lucasbraum
force-pushed
the
claude/keen-brahmagupta-qbatc4
branch
from
October 15, 2026 06:14
526ff10 to
47b4307
Compare
lucasbraum
marked this pull request as ready for review
October 15, 2026 06:14
Collaborator
Author
|
Rebased on main (
It stays a candidate. The run itself measures candidate, so there is no override:
Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pack
openai>=4 <5→>=7 <8(queue entryopenai). Candidate, not verified. Kept as a draft: the gate fails on two engine gaps found while scoring (below), not on the pack's rules. The queue entry is set toblockedwith that reason.One pack covers 4 → 7, not three. 5.0 carries nearly all API changes (MIGRATION.md). 6.0's only breaking entry is one type widening; 7.0's only breaking entry is the Node 22 floor. 5.12.1 (a minor) made tool calls a function | custom union. Nothing later reverts 5.0, and every public upgrade found jumps 4.x → 7.x directly. Evidence:
packages/core/src/packs/openai/RESEARCH.md, "One pack, not three".Sources
Pinned at v7.32.0, read 2026-10-14 (all in
meta.sources):package.jsonand.d.tsof 4.104.0, 5.0.0, 5.11.0, 5.12.0, 5.12.1, 6.0.0, 6.49.0, 7.0.0 and 7.32.0Each change is classified as mechanical, assisted, behavior note, or not compiler-visible in RESEARCH.md.
Rules and behavior notes
Rules:
named-path-params(M):runs.retrieve(threadId, runId)→runs.retrieve(runId, { thread_id })for 28 methods, which includes 3 the guide's list omits (runs.poll,submitToolOutputsAndPoll,submitToolOutputsStream; taken from the 7.x.d.ts). It rewrites only inert arguments and an unambiguous third argument; anything else goes to the agent. It also has a syntactic detect, so clients typedanyare found.delete-method(M):.del()→.delete(). A barefiles.del/models.delis detected only on a known client binding.beta-chat(M):beta.chat.completions.parse|stream|runTools→chat.completions.*.runner-renames(M):functionCall*events andfinalFunctionCall*()→functionToolCall*.removed-modules(M/A): deletes a side-effectopenai/shims/*import; moves beta chat types toopenai/resources/chat/completionswhen every imported name exists there;openai/src→openai. Everything else (openai/core, deepersrcpaths) goes to the agent.core-paths(M, deprecated):openai/error|pagination|resource|streaming|uploads→openai/core/*.request-options(M):list({ headers })→list({}, { headers }). It is detected syntactically because 7.x types those keys?: never, so the compiler message doesn't name them.http-agent(A): the agent picks one ofundiciProxyAgent,undiciAgent or a custom fetch, and the choice goes to Decisions for you.file-from-path(A): the agent picksfs.createReadStreamortoFile(…, name), and the choice goes to Decisions for you.run-functions,page-helpers,page-classes,removed-exports,tool-call-union(5.12.1),function-output-union(6.0): all assisted (A).Behavior notes:
error-headers,web-response,encoded-path-params: reported as findings. Each has a syntactic detect for what the compiler can't see throughany/unknown:catch (e) { e.headers['retry-after'] }res.body.pipe(...)afterasResponse()encodeURIComponent(id)passed to an SDK methodplatform-minimums,zod-helpers,builtin-fetch,global-types,client-subclass: reported as decisions, each shown only with evidence from the repository (applies()). The evidence covers Node/TypeScript pins, zod below the^3.25 || ^4peer,openai/helpers/zodimporters, proxy agents and global dispatchers, tsconfiglibwithout DOM, andextends OpenAI.also-review: a decision pointing to the guide.Pack settings:
requiresBuild: true: 7.x exports explicit subpaths only, where 4.x exported./*. A deep import thatmoduleResolution: noderesolves from disk can therefore fail in Node or a bundler.openai, and@openai/agentsis on its own 0.x line.Ground-truth repositories
All are public, pinned at the parent of a merged upgrade, and installed with scripts off. They were drafted with
pnpm packs:truth(with--alsofor what the upgrade moved because of openai) and assigned by hand before scoring, then left unchanged.b9a476d9ef509fde+67ae240ftool-call-union6c13ba08@openai/agents0.17.2, zod 4.5.4)genericd46ec64dgenericb7308489generic05c7e9f1generic047fc448runtime/typescript)e878b6b7I found these by web search and by mining the npm registry for packages whose published manifests moved
openai ^4→^7. The screened-out candidates and the reason for each are listed in RESEARCH.md.Results
tool-call-unionThe pack's own rules and detectors add no false positive in any of the seven repositories. Every false positive comes from
check's generic findings:examples/…multiturn_with_prompt_injection_detection.ts:331, 413, 428, 430. These are real TS2345/TS2769 errors at 7.9.0. Butexamples/is outside the repository's only tsconfig, so the upgrade didn't touch it and the tsconfig-scoped truth doesn't list it. They stay false positives.@prompty/core, socheckskips the compile and lists type-diff sites asunverified.Misses:
:119: found, but asgeneric. The compiler message (Property 'name' does not exist on type '{}') names nothing of openai, so the rule does not claim it.:135: a knock-on parameter change with no diagnostic.client.ts×10: a client-subclass rework forwithOptions()cloning with no compiler error. Theclient-subclassdecision names this file, but decisions aren't scored.max_tokens→max_completion_tokens), which the pack never makes by design.What the engine could not express (why this is a candidate)
check/companions.tsmoves packages that depend or peer on the lead, but never the lead's own peers or a dependent the upgrade moved. batch-ai keeps zod 3.24.2 even though openai 7 peers onzod ^3.25 || ^4.0. guardrails'@openai/agentsand zod are left behind too. Both repos therefore failwith.checkcompiles importers outside every tsconfig, whilepacks:truthcompiles tsconfigs only. That mismatch is the source of all 4 breaking false positives above.applies()only sees the declared inventory, so the pack declares source globs to find helper imports and subclasses.--no-llm, an assisted site that wasn't rewritten is labelled in the PR body by its symbol path rather than its rule. The agent's task does use the rule.With 1 and 2 fixed and the same truth, the breaking predictions left would be the three true positives;
pack test --writethen needs a rerun.CI: the Packs workflow runs
pack testand will fail on this PR for the reasons above. It is a draft until the engine changes land.uptide pack testoutputFull output of
pnpm uptide pack test openai --offline --write(summary inline)Smoke test (not ground truth)
I ran
uptide fix openai --no-llm --keep-templocally on uptide-test/alanagoyal, upgrading openai 4.104.0 → 7.33.0.verification.jsonlocally for the run. The edit was never committed and was restored right after.tc.function.*), whichtool-call-unionclaims.PR body produced by
uptide fix openai(The test log inside is shortened here; "Tier: verified" and "Verified by ✅ the openai migration pack" reflect the local forced activation described above.)
Checklist
meta.sourceskeep)verified; otherwise the pack ships as a candidate (7 public repositories; candidate because of the 4 engine false positives and 2 left-behind upgrades)pnpm uptide pack test <package>passes and its output is pasted above;verification.jsonwritten with--write: it fails (4 breaking false positives, all fromcheck's generic compile). The output is pasted above, andverification.jsonrecordscandidatevia--write.pnpm lint && pnpm typecheck && pnpm testpass (core 1548 passed / 32 skipped, CLI 438 passed;pnpm lintreports one pre-existing warning innext/platform.test.ts)🤖 Generated with Claude Code
https://claude.ai/code/session_01FX2nBoNEvDh9v71yDhEzxL
Generated by Claude Code