Skip to content

fix(downgrader): inline $refs into keywords replaced by 3.1 to 3.0 - #44

Open
dinwwwh wants to merge 4 commits into
mainfrom
claude/sweet-faraday-2h6o85
Open

dinwwwh wants to merge 4 commits into
mainfrom
claude/sweet-faraday-2h6o85

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

Problem

danglesIn keeps a $ref while its location still exists in the output. It treated only a missing location, or the items: {} placeholder, as gone. But 3.1 → 3.0 writes new values over some converted keywords, so a $ref into one of them was kept and resolved to the new value:

{
  properties: { a: { type: 'null', enum: ['x'], not: { type: 'string' } } },
  not: { $ref: '#/properties/a/not' },
}

a matches nothing, so the converter gives it not: {} in place of not: { type: 'string' }.

root not accepts 1
3.1 input { type: 'string' }, through the $ref yes
main { $ref: '#/properties/a/not' }, which now finds {} no
this PR { type: 'string' }, inlined yes

The same happens in components.schemas, and for two more keywords:

  • const replaces the enum beside it. The new enum has the same length, so the index check missed it, and a $ref to enum/0 got the const value.
  • "null" in type sets nullable: true over a 3.0 nullable: false.

Fix (packages/downgrader/src/shared.ts)

  • replace(target, key, value) writes a value that stands in for the source's instead of converting it, and tags key on target, with one WeakSet per key name.
  • danglesIn treats a tagged key like a removed one, so the $ref is inlined with the converted original.
  • not: {}, enum from const, nullable: true, and the items: {} placeholder now go through replace(). It replaces placeholder(), which tagged the value and so could not mark an entry inside it, such as enum/0, or a primitive, such as true.

Tests

  • schema/references.test.ts: a $ref to each replaced keyword, and to an enum replaced by a null const and then narrowed by a null-only type.
  • spec/components.test.ts: the not case in components.schemas.
  • All five fail on main. pnpm test (697 passed), pnpm lint and pnpm type:check are clean.

Known limits

  • Overwrites that only invalid input reaches still keep the $ref: required: true over a path parameter's required: false, minimum or maximum over a value that is not a number, and XML attribute or wrapped over false.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pgu7SuAf7FD4Muuwafi9z5

claude added 2 commits October 2, 2026 09:48
`danglesIn` kept a `$ref` whenever its location still existed in the
output, but the 3.1 → 3.0 converter writes new values over some converted
keywords: `const` replaces the `enum` beside it, a null-only `type` whose
`enum` excludes null sets `not: {}`, and `"null"` in `type` sets
`nullable: true`. A `$ref` into the original keyword was kept and resolved
to the replacement, e.g. a root `not: {$ref: '#/properties/a/not'}` came
out rejecting everything.

Such writes now go through `replace()`, which tags the key on its parent.
`danglesIn` treats a tagged key like a removed one, so the `$ref` is
inlined with the converted original. This replaces the value-based
`placeholder()` tag, which only `items` used and which could not mark an
array entry or a primitive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pgu7SuAf7FD4Muuwafi9z5
Only four key names are ever replaced, so a WeakSet per name avoids a
Set per tagged object, drops the hand-written object guard, and lets
`danglesIn` check the tag where it steps into the output, leaving the
array-length check as it was.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pgu7SuAf7FD4Muuwafi9z5
@pullfrog

pullfrog Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

your Pullfrog Router balance is empty, and this repo has no provider key to fall back on, so the agent never ran.

To fix, any one of: add a payment method or top up your Router balance · add a provider API key (GitHub Actions secret or Pullfrog secret) · switch this repo to a free model.

Top up Router → · Model settings → · Setup docs → · Ask in Discord →

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | 𝕏

…2h6o85

# Conflicts:
#	packages/downgrader/src/shared.ts
#	packages/downgrader/src/v3.1-to-v3.0.ts
@dinwwwh dinwwwh changed the title Inline $refs to keywords replaced during downgrade fix(downgrader): inline $refs into keywords replaced by 3.1 to 3.0 Oct 2, 2026
@pullfrog

pullfrog Bot commented Oct 2, 2026

Copy link
Copy Markdown

your Pullfrog Router balance is empty, and this repo has no provider key to fall back on, so the agent never ran.

To fix, any one of: add a payment method or top up your Router balance · add a provider API key (GitHub Actions secret or Pullfrog secret) · switch this repo to a free model.

Top up Router → · Model settings → · Setup docs → · Ask in Discord →

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | 𝕏

dinwwwh commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

The pullfrog check failing on 77c355a is not caused by this PR. Its log stops at action failed: your Pullfrog Router balance is empty, and this repo has no provider key to fall back on, so the agent never ran, before any review starts. The same check fails the same way on every PR since at least #40, including runs against main's head.

No change in this PR can fix it. It needs a Pullfrog top-up or a provider key in the repo's secrets. I'm not re-running it, because it would fail on the same billing error. The repo's own CI (lint_and_typecheck and test_matrix) is what gates this PR.


Generated by Claude Code

@codecov

codecov Bot commented Oct 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…2h6o85

# Conflicts:
#	packages/downgrader/src/v3.1-to-v3.0.ts
@pullfrog

pullfrog Bot commented Oct 2, 2026

Copy link
Copy Markdown

your Pullfrog Router balance is empty, and this repo has no provider key to fall back on, so the agent never ran.

To fix, any one of: add a payment method or top up your Router balance · add a provider API key (GitHub Actions secret or Pullfrog secret) · switch this repo to a free model.

Top up Router → · Model settings → · Setup docs → · Ask in Discord →

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | 𝕏

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.

2 participants