enhance(#2671): brand raw vs calibrated token types so double-application is a compile error (#2676)
* test(#2671): add failing-first brand-typing compile fixtures * feat(#2671): brand raw vs calibrated token types * refactor(#2671): hoist type-compile into a before() hook Two review responses: - The fixture compile ran in the describe() body, so it executed at collection time even when the block was filtered out, and a failed precondition collapsed eight independent assertions into one opaque describe-level failure. A before() hook is this repo's documented idiom and preserves per-test granularity. - parseTokensFlag now records WHY it returns an unbranded number: it validates the magnitude of --tokens, but the basis is decided by --calibrated, so branding here would be wrong for half its callers. The assertion belongs to cmdEstimateCheck, its only caller. * test(#2671): pin each brand diagnostic to its OFFENDING marker Adversarial review demonstrated that asserting only exactly-one-diagnostic- at-code-N is not airtight. Repairing a fixture's brand violation while injecting an unrelated error of the same code (a string passed as the budget argument) still yielded exactly one TS2345, so the fixture would have reported green while no longer testing its regression at all. Each bad-* fixture now routes its violating value through a const named OFFENDING, and the test asserts the diagnostic's start offset falls inside that node — located through the AST, so it survives reformatting and never pattern-matches source text. Replaying the proof-of-concept against the new assertion rejects it: the diagnostic lands on the budget literal, not the marker. Also corrects a doc comment that claimed the program type-checks all of src/; it covers phase-estimation.cts and its transitive dependencies. * chore(#2671): backfill changeset PR number (#2676)
This commit is contained in:
@@ -114,6 +114,15 @@ export function readCalibrationSamples(cwd: string): ReturnType<typeof estimatio
|
||||
* digit match rather than Number()/parseInt so that "1; touch x", "1e5",
|
||||
* "0x10", and " 1 " are all refused — the value reaches us as argv, is never
|
||||
* shell-interpolated, and must not be coerced into looking valid.
|
||||
*
|
||||
* Returns a PLAIN number, deliberately (#2671). This function validates the
|
||||
* magnitude of `--tokens`; it cannot know the figure's basis, because that is
|
||||
* decided by a DIFFERENT flag (`--calibrated`). Branding here would force it to
|
||||
* pick RawTokens or CalibratedTokens for every caller, and it would be wrong
|
||||
* half the time — a type that lies is worse than no type. The basis assertion
|
||||
* therefore belongs to the caller that reads both flags; today that is
|
||||
* `cmdEstimateCheck`, which is this function's only caller. A future second
|
||||
* caller must make the same assertion explicitly rather than inherit a guess.
|
||||
*/
|
||||
export function parseTokensFlag(args: string[]): number {
|
||||
const idx = args.indexOf('--tokens');
|
||||
@@ -159,9 +168,15 @@ export function cmdEstimateCheck(cwd: string, args: string[], raw: boolean): voi
|
||||
// factor === 1, and 1^2 === 1). A plan's recorded `estimate.tokens` is
|
||||
// calibrated at emission time per ADR-2629 Decision 1, so the plan-checker
|
||||
// MUST pass this flag.
|
||||
//
|
||||
// `--calibrated` is the whole basis question, and argv cannot answer it for
|
||||
// the type system — so this is where the caller's claim is turned into a type
|
||||
// (#2671). Past this expression the basis is carried by RawTokens /
|
||||
// CalibratedTokens and the wrong composition stops compiling; the ambiguity
|
||||
// is confined to these two lines instead of running the length of the seam.
|
||||
const calibratedTokens = preCalibrated
|
||||
? inputTokens
|
||||
: estimation.applyCalibration(inputTokens, calibration.factor);
|
||||
? estimation.asCalibratedTokens(inputTokens)
|
||||
: estimation.applyCalibration(estimation.asRawTokens(inputTokens), calibration.factor);
|
||||
const classification = estimation.classifyAgainstBudget(calibratedTokens, budget);
|
||||
|
||||
output({
|
||||
|
||||
Reference in New Issue
Block a user