[GRV-27]: Resolve estimation API and catalog drift#43
Merged
github-actions[bot] merged 1 commit intoJun 5, 2026
Merged
Conversation
The estimation barrel re-exports attribution's implemented forecaster but still described ForecastIssueCost as a planned stub and exposed forecastProjectCost / calibrate as throwing "not implemented" placeholders, while their implemented analogs already shipped in attribution. - Re-export forecastProjectCost and calibrateCoverage from llm-cost-attribution; both now work with estimation-friendly signatures. - Keep calibrate as a deprecated shim whose error names calibrateCoverage. - Rewrite docs/use-cases.md so ForecastIssueCost / ForecastProjectCost / CalibrateCoverage describe shipped behavior, not planned stubs. - Drop calibrate from the README ready-use import example; document the real forecastProjectCost / calibrateCoverage signatures and the calibrate deprecation. - Update barrel smoke tests: forecastProjectCost forecasts an empty project, calibrateCoverage is exported, calibrate's error names its replacement.
github-actions Bot
pushed a commit
that referenced
this pull request
Jun 5, 2026
## Summary Part of the **llm-cost architecture contracts** Project. Two deliverables, both scoped to the `llm-cost-attribution` package (per this issue's title + `llm-cost-attribution` label): 1. **Repair the boundary guard** so its config reflects the package after the estimation extraction. 2. **Establish the attribution use-case catalog** as the canonical, complete source of truth for the attribution surface. ### Repair boundary guard — `packages/llm-cost-attribution/scripts/check-boundary.mjs` The boundary config carried two **dead references** to modules that were extracted to `llm-cost-estimation` (in GRV-2 / the estimation split) but never removed here: - `src/enrich.mjs` in `coreModules` - `src/linear-estimate-source.mjs` in `adapterModules` Neither file exists in this package, so `existsSync` silently skipped them — the guard *claimed* to protect/classify modules it can no longer see. Repaired by: - Removing both dead entries. - Replacing stale remediation text that still pointed at the moved `LinearEstimateSource` with port-neutral attribution guidance (`SessionSource` / `IssueMatcher` / `UsageRecordSource` / `UsageRecordSink`). The defensive `@linear` / `https` / `fs` / `child_process` forbidden-package rules are kept. To repair the *class* of bug (not just the instance), `test/boundary.test.mjs` now: - Adds **config-integrity tests** asserting every configured `coreModules` / `adapterModules` path exists on disk, so dead or phantom entries fail CI instead of silently passing. - Exercises the core-imports-adapter rule against a **real** adapter (`attribution-adapters.mjs`) instead of the removed Linear adapter. ### Establish attribution catalog — `docs/architecture/use-case-catalog.md` - Added a canonical intro, the inward dependency rule, and the linkage to the boundary guard that enforces it. - Cataloged the two remaining public use cases that were documented in the package catalog/README but missing here: **CreateAttributionWorkflow** and **ListKnownIssues**. The catalog now covers the full attribution public surface. ## Verification - `npm test` (llm-cost-attribution): **200 pass / 0 fail** (was 198; +2 new config-integrity tests). - `node scripts/check-boundary.mjs`: **Boundary check passed**. - `node --check` on changed `scripts/check-boundary.mjs` and `test/boundary.test.mjs`: ✓. - Project-acceptance, llm-cost-architecture-contracts — **GRV-26's portion is fully green**: - `architecture-boundary.check.mjs` (runs the repaired guard): ✓ - `attribution-ports.test.mjs`: ✓ - catalog/API alignment: **no findings for `llm-cost-attribution`**. - Rebased onto latest `origin/main` (includes #43 / GRV-27). ## Out of scope (observed, not fixed here) The non-required project-acceptance gate still reports **one** finding, in the separate **`llm-cost-estimation`** package, left by the just-merged GRV-27 (#43): `packages/llm-cost-estimation/docs/use-cases.md:67` marks the now-implemented `forecastProjectCost` as planned/stubbed. That is estimation-catalog territory (GRV-27's rollout), not this attribution issue — flagged here as a breadcrumb for a follow-up rather than mixing packages in one PR. `pr-build` (the required gate) excludes the project-acceptance directory, so this does not block merge. Co-authored-by: riddim-developer-bot <developer-bot@riddimsoftware.com>
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.
What & why
llm-cost-estimationre-exported attribution's implemented forecaster but its catalog still describedForecastIssueCostas a planned stub, and it exposedforecastProjectCost/calibrateas throwingnot implementedplaceholders — even though their implemented analogs already shipped inllm-cost-attribution. This PR makes the docs, README, public exports, and tests agree on what is implemented vs. unsupported, turning the catalog/API alignment check green for estimation.Resolves GRV-27.
Changes
src/index.mjsforecastProjectCostnow re-exports attribution's implemented project forecaster — estimation-friendly signatureforecastProjectCost(issues, usageSource?, options?)with{ size, model }IssuePlans, consistent withforecastIssueCost.calibrateCoverage, re-exported from attribution's implemented coverage backtester.calibratekept as a deprecated compatibility shim; its error names the supported replacement (calibrateCoverage) instead ofnot implemented.docs/use-cases.md— rewritesForecastIssueCostandForecastProjectCostto describe shipped behavior (no longer "Planned — stub throws"), adds aCalibrateCoverageentry, and documentscalibrateas deprecated.ForecastIssueCostnow reflects the real(cell, records)shape rather than the never-builtCalibrationDatasetmodel.README.md— dropscalibratefrom the ready-use import example; documents the realforecastProjectCost/calibrateCoveragesignatures and thecalibratedeprecation.test/smoke.test.mjs— no longer asserts ready APIs thrownot implemented:forecastProjectCostforecasts an empty project,calibrateCoverageis asserted exported, andcalibrate's error is asserted to name its replacement.Acceptance criteria
docs/use-cases.mdaccurately describes shipped behavior.ForecastIssueCostno longer described as a planned stub.forecastProjectCostdelegates to attribution's implemented project forecaster with a documented estimation-friendly signature.calibratedocumented as deprecated and omitted from ready-use examples;calibrateCoveragedelegates to the implemented calibration/coverage API.not implemented.calibrate) names its supported replacement.enrich.mjs,linear-estimate-source.mjs,bin/).Out of scope (unchanged)
No attribution forecast-math changes, no project-level quota forecasts, no npm publishing / version bumps.
Verification
Re-verified after rebasing onto
origin/main(which merged GRV-24's attribution port extraction): theforecastProjectCost/calibrateCoveragere-exports still resolve and all 37 tests pass.