Skip to content

feat(catalog): add claude-fable-5-1 to model metadata - #3293

Closed
Veritas-7 wants to merge 1 commit into
lidge-jun:devfrom
Veritas-7:feat/fable-51-model-metadata
Closed

feat(catalog): add claude-fable-5-1 to model metadata#3293
Veritas-7 wants to merge 1 commit into
lidge-jun:devfrom
Veritas-7:feat/fable-51-model-metadata

Conversation

@Veritas-7

@Veritas-7 Veritas-7 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR fills the generated-metadata gap for claude-fable-5-1: the Anthropic registry, expected-prices overlay, and tests already knew the model, but the generated-metadata path did not.

  • Added the model row to scripts/model-metadata.source.json.
  • Regenerated src/generated/model-metadata.ts from the source; the generated output was never hand-edited.
  • Costs: input 10, output 50, cacheRead 0.25, cacheWrite 12.5.
  • The cache-read ratio is deliberately 0.025x and must not be aligned to the older sibling's value.
  • The thinking block uses anthropic-adaptive, matching the current-generation Anthropic entries. An earlier revision of this description wrongly called it a mirror of the older sibling; that wording was incorrect, not the value.
  • Bedrock and regional aliases are deliberately out of scope, matching the earlier upstream change's Anthropic-only surface. Widening this scope is the maintainer's call.

Verification

Base commit: 664d80c76 (upstream/dev); branch head a52ccb96c; not behind dev.

  • bun run typecheck — exit 0.
  • OCX_TEST_NO_QUEUE=1 bun test tests/model-metadata-sync.test.ts tests/usage-cost.test.ts83 pass, 0 fail, 456 expect() calls; exit 0.
  • OCX_TEST_NO_QUEUE=1 bun scripts/test.ts --changed=upstream/dev --path-ignore-patterns '**/tests/management-integration-routes.test.ts'14018 pass, 11 skip, 1 fail, Ran 14030 tests across 759 files. [150.35s]; exit 1. The single failure is tests/muse-passive-quota-cache.test.tsa defaulted read is memoized, and invalidation is what clears it, which hits the 5 s per-test timeout under parallel load. It behaves the same way on a second gate run and passes twice when its file is run alone (13 pass, under a second each), on a machine whose load average was between 6 and 9 during the gate. This change adds a model row and its regenerated output, so it has no path to that cache test.
  • The one excluded suite is tests/management-integration-routes.test.ts, which builds the GUI bundle. It cannot run on this machine: the bundler's CSS minifier reports Cannot find module '../lightningcss.darwin-arm64.node'. That is a local toolchain problem unrelated to this change.
  • Source and generated output agree: the source row carries input 10, output 50, cacheRead 0.25, cacheWrite 12.5 with thinking mode anthropic-adaptive, and the generated entry carries the same four cost values.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. No additional docs or release notes are needed for this metadata-only change.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. This change touches only model identifiers and price constants; it adds no secrets, no auth surface, and no defaults that affect request handling.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • New Features

    • Added support for the Claude Fable 5.1 model, including text and image inputs, extended context, reasoning, adaptive thinking, and tool selection.
  • Bug Fixes

    • Corrected cost attribution for Claude Fable 5.1 across Anthropic connection types.
  • Tests

    • Updated usage-cost coverage to verify canonical pricing and provider resolution for supported Anthropic surfaces.

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: 3ee4024a-dee7-4204-880f-868aa11741f2

📥 Commits

Reviewing files that changed from the base of the PR and between b15cbb2 and 4de6d1a.

⛔ Files ignored due to path filters (1)
  • src/generated/model-metadata.ts is excluded by !**/generated/**
📒 Files selected for processing (3)
  • scripts/model-metadata.source.json
  • src/usage/expected-prices.ts
  • tests/usage-cost.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The change adds Claude Fable 5.1 model metadata and updates Anthropic pricing tests to confirm jawcode precedence for both anthropic and anthropic-apikey surfaces.

Changes

Claude Fable 5.1 support

Layer / File(s) Summary
Model metadata definition
scripts/model-metadata.source.json
Adds claude-fable-5-1 with Anthropic Messages support, reasoning, text and image inputs, pricing rates, token limits, adaptive thinking, and automatic tool choice.
Anthropic pricing resolution
src/usage/expected-prices.ts, tests/usage-cost.test.ts
Documents jawcode as canonical for both Anthropic surfaces. Tests retain overlay lookup checks and expect source: "jawcode" with jawcodeProvider: "anthropic".

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to a52cc

This adds Claude Fable 5.1 metadata and aligns Anthropic pricing resolution coverage. No current merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding claude-fable-5-1 to the model metadata catalog. It matches the changes in scripts/model-metadata.source.json and the related genera…
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2 files. (1 skipped: 1 unsupported.)

Full details: Title check

Explanation

The title clearly and concisely describes the primary change: adding claude-fable-5-1 to the model metadata catalog. It matches the changes in scripts/model-metadata.source.json and the related generated metadata and pricing updates.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the enhancement New feature or request label Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

Hygiene

Deterministic PR hygiene checks passed.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 46 / 80

이 PR은 #3203이 Anthropic 레지스트리·expected-prices·테스트에는 claude-fable-5-1을 넣었지만, 생성 메타데이터 소스에는 안 넣은 구멍을 메우려는 작업입니다. 지금 dev HEAD(938c0136a)를 보면 src/usage/expected-prices.ts에는 anthropic / anthropic-apikey / cursor 오버레이가 있고, 테스트도 overlay 경로(source: "expected")를 기대합니다. 그런데 scripts/model-metadata.source.json의 anthropic 블록과 src/generated/model-metadata.ts에는 claude-fable-5만 있고 claude-fable-5-1 행이 없습니다. 그래서 가격은 오버레이로 맞지만, jawcode/bundled 메타데이터 경로로는 Fable 5.1이 아직 “없는 모델”입니다.

PR이 하는 일은 짧고 분명합니다. 소스 JSON에 Fable 5.1 객체를 넣고 bun run generate:model-metadata로 generated 파일을 갱신합니다. 비용은 input 10 / output 50 / cacheRead 0.25 / cacheWrite 12.5로, 이미 있는 CLAUDE_FABLE_51과 같습니다. cacheRead 0.25는 다른 Claude 패밀리의 0.1x가 아니라 0.025x라는 Fable 5.1 공식 비율이라서, 여기를 1.0이나 다른 값으로 복사하면 안 됩니다. PR은 그 숫자를 맞게 넣었습니다.

src/usage/cost.ts 쪽 순서를 보면, 유효한 nonzero bundled(jawcode) 행이 있으면 일반 overlay보다 먼저 쓰입니다. 그래서 이 행이 생긴 뒤 resolveMatchedPrice("anthropic", "claude-fable-5-1")source: "jawcode" / jawcodeProvider: "anthropic"이 되고, 테스트도 그렇게 바뀝니다. 오버레이 행은 지우지 않고 호환·직접 조회로 남깁니다. 계정 풀 라벨 anthropic-pb…가 같은 가격으로 접히는지도 테스트에 남아 있습니다. 방향은 #3203이 열어 둔 “공식 가격을 카탈로그에도 같은 숫자로”와 맞습니다.

다만 이 브랜치는 dev 최신보다 behind입니다. 베이스가 #3286(Gemini 3.8)·#3246(write_stdin 브리지) 이전이라, 브랜치 트리만 보면 Gemini 플랜/코드가 “사라진” 것처럼 보입니다. 실제 PR 세 점 디프는 메타데이터 네 파일뿐이고, 머지 전에 최신 dev로 리베이스해야 #3286/#3246을 되돌리지 않습니다. 또한 PR이 draft이고 readiness 체크리스트가 아직 비어 있습니다. 리뷰·CI 준비가 끝나기 전에는 랜딩하면 안 됩니다.

작은 정확도 이슈도 있습니다. 본문은 thinking 블록을 claude-fable-5에서 그대로 가져왔다고 하는데, HEAD의 fable-5는 "mode": "budget"이고 PR의 5-1은 "anthropic-adaptive"입니다. 생성기가 thinking을 소비하지 않는다면 런타임 영향은 없지만, “미러” 설명은 사실과 다릅니다. 또 Bedrock/EU/global 등 다른 프로바이더 블록의 fable-5 대응 행은 이번 범위 밖입니다. #3203이 Anthropic 표면만 다뤘다면 이번에도 Anthropic만으로 충분할 수 있지만, “카탈로그 완전성”을 어디까지 볼지는 메인테이너 몫입니다.

라인 scripts/model-metadata.source.json claude-fable-5-1 - cacheRead 0.25는 Fable 5.1 공식 0.025x라서 유지가 맞고, fable-5의 cacheRead 1과 섞이면 안 된다
라인 같은 파일 thinking.mode - 본문은 fable-5 미러라고 했지만 fable-5는 budget, 여기는 anthropic-adaptive다. 생성기가 안 읽더라도 설명을 고치거나 값을 맞출지 정하라
경로 src/generated/model-metadata.ts - 소스에서 regenerate한 anthropic 행만 바뀌어야 한다. 손편집 금지
경로 브랜치 - dev에 이미 있는 #3286/#3246보다 behind이므로, 리베이스 없이 머지하면 충돌·되돌림 위험이 있다
경로 PR 상태 - draft + checklist 미완료라 review-ready가 아니다

메인테이너의 판단이 필요한 지점

  • draft 해제·체크리스트·CI green 전에 머지할지, 준비될 때까지 기다릴지
  • Bedrock/지역 별칭 메타데이터에도 fable-5-1을 같은 유닛에서 넣을지, Anthropic만으로 닫을지
  • thinking.mode를 fable-5와 맞출지, anthropic-adaptive를 의도적으로 둘지

너의 추천
의도는 좋고 HEAD의 실제 구멍과도 맞습니다. 최신 dev로 리베이스 → draft 해제·CI 확인 후 머지하세요. 지금 상태 그대로 랜딩하지는 마세요. thinking 설명/값 불일치는 한 줄만 정리하면 됩니다.

이 댓글은 grok-bot이 작성했습니다

@Veritas-7

Copy link
Copy Markdown
Contributor Author

The branch is now rebased onto latest dev, so the two commits you were concerned might be reverted are no longer at risk.
The thinking-mode issue was a wrong description, not a wrong value: current-generation Anthropic entries use anthropic-adaptive; the older sibling using budget is the outlier.
I corrected the PR body to say that explicitly.
The cache-read ratio remains the confirmed 0.025x value (cacheRead: 0.25).
Bedrock and regional aliases remain out of scope pending your call.

@Veritas-7
Veritas-7 force-pushed the feat/fable-51-model-metadata branch from 8c168a7 to 4d78ee9 Compare September 3, 2026 08:58
@Veritas-7
Veritas-7 marked this pull request as ready for review September 3, 2026 09:05
@github-actions
github-actions Bot marked this pull request as draft September 3, 2026 09:05
@Veritas-7
Veritas-7 force-pushed the feat/fable-51-model-metadata branch from 4d78ee9 to 4de6d1a Compare September 3, 2026 09:39
@Veritas-7
Veritas-7 marked this pull request as ready for review September 3, 2026 10:49
@github-actions
github-actions Bot marked this pull request as draft September 3, 2026 10:49
@Veritas-7
Veritas-7 marked this pull request as ready for review September 3, 2026 10:50
lidge-jun#3203 added the registry and pricing rows but not the model metadata; this fills that gap.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Veritas-7
Veritas-7 force-pushed the feat/fable-51-model-metadata branch from 4de6d1a to a52ccb9 Compare September 3, 2026 16:59
@github-actions
github-actions Bot marked this pull request as draft September 3, 2026 17:00
@Veritas-7
Veritas-7 marked this pull request as ready for review September 3, 2026 17:19
lidge-jun added a commit that referenced this pull request Sep 4, 2026
…credit, Ultra Fast opt-in) (#3478)

* docs(devlog): roadmap the 260904 triage gap closure

Three gaps the triage verified as NOT done: the half-shipped fable-5-1 metadata, the missing CREDITS row for #3284, and Ultra Fast.

The Ultra Fast doc carries the finding that shapes the whole phase: upstream-models.json advertises only priority, so there is no ultrafast tier to forward and re-adding the catalog row would reproduce exactly what #2994 was closed for. What is separately true is that a forced ultrafast request is classified not-requested and gets no speed label — an observability lie fixable without advertising anything.

* feat(catalog): add claude-fable-5-1 to model metadata

Carries PR #3293 by @Veritas-7, whose metadata half never landed while its
pricing half did.

On dev, src/usage/expected-prices.ts asserts an expected price for
claude-fable-5-1 on four surfaces, but neither scripts/model-metadata.source.json
nor the anthropic array of src/generated/model-metadata.ts knew the model
existed. The pricing rows arrived through unrelated commits that happened to
touch expected-prices.ts; #3293 is the only source of the metadata, and it is
still open. Pricing without metadata is the wrong half to have.

The generated file is regenerated from the source entry rather than hand-edited,
which is what keeps the two consistent:

  ["claude-fable-5-1",1000000,128000,"text,image",1,null,10,50,0.25,12.5]

Note cacheRead 0.25, not the 1 that claude-fable-5 carries: Fable 5.1's published
cache-hit rate is 0.025x base input, which the existing expected-prices rows
already encode.

The PR's own test update comes with it. Adding the jawcode row changes where the
price resolves from — src/usage/cost.ts prefers an exact jawcode provider-bundle
row over the expected-price overlay — so the assertion moves from
source: "expected" to source: "jawcode" with jawcodeProvider: "anthropic", and
the overlay is asserted directly instead of through sourceRef. The resolved
cost4 is identical either way; only the provenance label changes.

Verification: bun run typecheck, bun test ./tests/usage-cost.test.ts (82 pass),
bun run test:changed (10752 pass / 0 fail across 569 files). Repository-wide
suite not run.

Co-authored-by: wj <wj@nas-backup>

* docs(credits): record #3284 as carried work

Closes the gap issue #3431 opened at @Ingwannu's request.

The Gemini 3.8 Flash Antigravity work first submitted by @mdwsk88 in #3284 landed
on dev via #3286 (3d3c4fe), and #3284 was closed as superseded rather than
merged — so the contributor graph shows nothing. CREDITS.md exists for exactly
that case.

The file sets two bars and both are met. It says "If you find a landing that
belongs on this page, open an issue"; #3431 is that issue. It also says entries
cite the maintainer's own words and are never inferred from diff similarity; the
quoted text is verbatim from @Ingwannu's closing comment on #3284.

Verified independently rather than taken from the issue body: 3d3c4fe is an
ancestor of origin/dev and is the #3286 merge, #3284 is CLOSED and not merged,
and src/providers/antigravity-models.ts on dev names gemini-3.8-flash 16 times,
so the suffix ladder that PR argued for is what shipped.

Verification: bun run privacy:scan passed (it reads CREDITS.md); table renders
with the existing column alignment.

* feat(codex): name the Ultra Fast tier, and move the account actions out of the page head

Two halves of issue #3429, plus the page-head relief the same surface needed.

PR #2994 added an ultrafast row to the pinned catalog and was closed unmerged:
the picker gained a choice the wire could not honor. That verdict stands and is
why nothing here synthesizes a catalog row. src/codex/data/upstream-models.json
advertises exactly one tier — priority — on every row that has any, so an
ultrafast entry would still be fabricated metadata.

What is separately true is the half #3429 actually reports. A caller who supplies
service_tier: "ultrafast" themselves gets the request forwarded, and then
canonicalFastTierMarker folds it to undefined, fastIntent goes false, and the
attempt is recorded as fastOutcome "not-requested" — the log asserting the user
asked for nothing. requestLogSpeedLabel returns undefined for the same value, so
the Logs speed column stays empty. The proxy was carrying a tier it refused to
name.

canonicalFastTierMarker now folds ultrafast to its own canonical rather than onto
priority, which would have been the opposite lie: claiming a 1.5x Fast tier when
the caller named a different one. There is deliberately no canonicalToWire entry,
so an ultrafast attempt lands on "unknown" instead of a false "applied" — the
truth is that it was requested and we cannot confirm it was honored.

The ultraFastTier flag follows the fastRows precedent exactly: optional, catch(false)
so a malformed hand edit degrades to off, read with === true, and off deletes the
key rather than persisting a false nobody chose. Its dashboard toggle gets the
boolean guard in config-routes.ts that fastRows never needed.

The page head carried a title, a status line, the Spark toggle and two buttons on
one row, with the account actions sitting above the cards they act on. Pause and
Refresh move to their own row below the account-mode banner. The embedded
Providers surface keeps them inline: it renders a bare .row with no title, so
there is nothing to crowd there.

Verification: bun run typecheck, bun run lint:gui, 408 focused backend tests
including the byte-golden default-path guard in fastwire-characterization-routing,
and the GUI head-wrap, toast-tone, controller and locale-parity suites. Live on a
scratch instance: the head shows only the title and Spark toggle, the two actions
render below, the toggle reads OFF by default, and enabling it writes
ultraFastTier: true to config.json. Repository-wide suite not run.

* fix(codex): make the Ultra Fast flag actually do something

Self-review caught the flag stored but never read: `grep ultraFastTier src/`
outside config/types/routes returned nothing, so the toggle persisted a
preference and changed no behavior. Shipping a switch whose description promises
the tier survives regeneration, while nothing consumes it, would be the #2994
failure in a new place — a control that implies an effect it does not have.

normalizeRoutedCatalogEntry now consults the flag. With it OFF the four deletes
run exactly as before. With it ON the row keeps an ultrafast the OPERATOR put in
their own catalog, which is the reported symptom: #3429's reporter hand-edited
opencodex-catalog.json and watched every regeneration delete it.

Preserving is narrowed, not blanket. retainOnlyUltraFastTier keeps the ultrafast
entry and drops everything else, because routed rows are stripped precisely so a
clone of a native template cannot inherit OpenAI's priority tier — reopening that
under an unrelated flag would be a worse bug than the one being fixed. A
service_tier or default_service_tier naming a tier the row no longer carries is
dropped for the same reason. And a row carrying only upstream's Fast is still
stripped with the flag ON: there is no ultrafast to preserve, and inventing one
is the line #2994 was closed for.

The flag is read through ultraFastTierEnabled(loadConfig()) inside parsing.ts
rather than threaded through deriveEntry. That function and its five call sites
are pure RawEntry -> RawEntry transforms with no config parameter; plumbing one
boolean through all of them would be a far larger change than the behavior it
gates. Callers holding a config can still pass opts.ultraFastTier explicitly,
which is what the new tests do, and a read failure degrades to OFF.

Four new tests cover both states, including the two refusals: the flag never
smuggles Fast onto a routed row, and it invents nothing when the operator
supplied nothing.

Verification: bun run typecheck, bun run lint:gui, 340 focused catalog/fastwire
tests including the byte golden, 10 in ultrafast-tier-honesty, and
bun run test:changed at 14419 pass / 0 fail across 785 files.

* fix(fastwire): forward an unmapped canonical tier instead of dropping it

Adversarial review found that the previous commit made the reported problem
worse, and that every suite still passed while it did.

Recognising ultrafast as a canonical marker routed it into the canonical-wire
lookup in decideTier. That lookup is keyed by canonicalToWire, which maps only
priority, so an unmapped canonical fell straight through to { kind: "drop" }.
Measured before and after:

  before   ultrafast -> forward-caller   wire service_tier=ultrafast
  after    ultrafast -> drop             wire service_tier=(absent)

So recognition was strictly worse than leaving the tier unrecognised: it used to
be a foreign tier, and foreignCallerTiers "verbatim" forwarded it untouched. The
operator's hand-configured tier stopped reaching the provider entirely, and the
new "ultrafast" speed label became unreachable on the Responses path because
tierValueAfterDecision had already cleared the value. That is the exact symptom
#3429 reported, reintroduced by the fix for it.

An unmapped canonical now falls through to the foreign-tier rules rather than
dropping.

Second finding, same root cause: callerCanonicalFast was widened to "any marker",
which made a fastMode:false request from an ultrafast caller record
callerFastSuppressedByConfig. The Fast toggle did not suppress a 1.5x Fast
request; it turned away a differently-named one. The predicate is back to
=== "priority" for the drop/suppression facts, and only fastIntent carries the
wider fast-family question.

Third: ultraFastTierOptIn called loadConfig() per catalog row, and
normalizeRoutedCatalogEntry runs in a per-entry sync loop — that is a chmod, three
secret hardenings, a file read and a full Zod parse per row. It is memoized with a
5s TTL plus a reset seam; callers holding a config still pass opts.ultraFastTier
and bypass it entirely.

Fourth: the expected-prices comment claiming claude-fable-5-1 has no jawcode row
was made stale by 21cb149, which added exactly that row.

Five new tests cover what the previous suite could not see: the wire decision
itself, and the suppression-vs-dropped distinction. The old tests all passed
against the broken behavior because none of them asserted decideTier.

Verification: bun run typecheck, bun run lint:gui, 720 focused fastwire/catalog/
request-log/usage tests, and bun run test:changed at 14466 pass / 0 fail across
787 files.

---------

Co-authored-by: jun <jun@lidge.dev>
Co-authored-by: wj <wj@nas-backup>
@lidge-jun

Copy link
Copy Markdown
Owner

Landed on dev as 3a9c4d297 (PR #3478), carrying your commit with Co-authored-by: wj <wj@nas-backup>.

Why it was carried rather than merged: the branch had been open long enough that only half of it was still missing. The pricing rows for claude-fable-5-1 had arrived on dev through unrelated commits that happened to touch src/usage/expected-prices.ts, while scripts/model-metadata.source.json and the anthropic array of src/generated/model-metadata.ts still did not know the model existed. Pricing without metadata is the wrong half to have, and this PR was the only source of the other one.

Your tests/usage-cost.test.ts update came with it and was necessary — I initially carried only the metadata and the test failed, which is how I confirmed your reasoning: adding the jawcode row moves resolution from the expected-price overlay to the provider bundle, so source: "expected" becomes source: "jawcode". The resolved cost4 is identical; only the provenance label changes. The cacheRead: 0.25 (not the 1 on claude-fable-5) was independently verified against the 0.025x published rate.

Verification on the exact head: bun run typecheck, bun test ./tests/usage-cost.test.ts (82 pass), and bun run test:changed at 14466 pass / 0 fail. Adversarial review separately re-ran bun run generate:model-metadata and confirmed the committed generated file has no drift from the source entry.

Thanks — this was a real gap, not a stale duplicate.

@lidge-jun lidge-jun closed this Sep 4, 2026
@lidge-jun lidge-jun added the landed-via-maintainer Original PR closed after landing via a maintainer merge train label Sep 4, 2026
lidge-jun pushed a commit that referenced this pull request Sep 4, 2026
Closes out devlog/_plan/260904_triage_gap_closure with what actually shipped and
the landing SHAs: PR #3478 (3a9c4d2) carried all three gaps, and #3293, #3431
and #3429 are closed citing it.

The part worth keeping is the review round. The first Ultra Fast implementation
passed every suite and was wrong: recognising ultrafast as a canonical marker
routed it into decideTier's canonicalToWire lookup, which maps only priority, so
an unmapped canonical fell through to drop and the tier stopped reaching the
provider — where previously, as a foreign tier, it was forwarded verbatim.
Recognition made the reported problem worse.

Every listed suite stayed green because they unit-tested the two edited functions
in isolation and never asserted the wire decision, and the byte golden pins
catalog bytes rather than the caller routing path. Two lessons recorded: a test
of the functions you edited is not a test of the behavior you changed, and
widening a predicate that serves three questions silently changes the other two.

Also records what was deliberately NOT done — Ultra Fast is still absent from the
model picker, because upstream advertises only priority and a catalog row would
offer a speed the wire cannot deliver, which is what PR #2994 was closed for.

This document describes carried work whose code already landed in #3478 with the
trailer. Repeating it here keeps the contributor graph correct for a body that
names #3293 as carried.

Co-authored-by: wj <wj@nas-backup>
lidge-jun added a commit that referenced this pull request Sep 4, 2026
Closes out devlog/_plan/260904_triage_gap_closure with what actually shipped and
the landing SHAs: PR #3478 (3a9c4d2) carried all three gaps, and #3293, #3431
and #3429 are closed citing it.

The part worth keeping is the review round. The first Ultra Fast implementation
passed every suite and was wrong: recognising ultrafast as a canonical marker
routed it into decideTier's canonicalToWire lookup, which maps only priority, so
an unmapped canonical fell through to drop and the tier stopped reaching the
provider — where previously, as a foreign tier, it was forwarded verbatim.
Recognition made the reported problem worse.

Every listed suite stayed green because they unit-tested the two edited functions
in isolation and never asserted the wire decision, and the byte golden pins
catalog bytes rather than the caller routing path. Two lessons recorded: a test
of the functions you edited is not a test of the behavior you changed, and
widening a predicate that serves three questions silently changes the other two.

Also records what was deliberately NOT done — Ultra Fast is still absent from the
model picker, because upstream advertises only priority and a catalog row would
offer a speed the wire cannot deliver, which is what PR #2994 was closed for.

This document describes carried work whose code already landed in #3478 with the
trailer. Repeating it here keeps the contributor graph correct for a body that
names #3293 as carried.

Co-authored-by: jun <jun@lidge.dev>
Co-authored-by: wj <wj@nas-backup>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request landed-via-maintainer Original PR closed after landing via a maintainer merge train review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants