You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(estimate): count every attempt, and price runtime by prompt size
Review follow-ups. Both blocking items understated cost in the same
direction, and both are fixed from data the run records already carry.
Output tokens counted only the final attempt while prompt tokens were
multiplied by the attempt count, so a retried pass recorded prompt x2 and
output x1. Because calibrate divides output by a request count that
includes retries, every retry dragged outputTokensPerRequest down and
estimate then understated output for everyone.
runAuditWithAutoFix now reports promptChars and outputChars accumulated
across attempts, so both sides are exact rather than the final attempt
scaled up: the retry's prompt carries a correction section the x2
approximation missed, and its discarded first response cost tokens to
generate. Characters rather than tokens keeps the approximation in one
place, and keeps whole prompts from being retained on the result.
Runtime was requests x a flat msPerRequest, which is prompt-size-blind —
the exact case the command is pitched at. Calibration now carries a fixed
msPerRequest plus a marginal msPerPromptToken, least-squares fitted
across records when they differ in prompt size. When they cannot separate
the terms — one record, or every run the same size — the measured average
is split using the proportion the defaults imply, so the magnitude stays
measured even where the shape is assumed. A negative fitted term falls
back the same way. The defaults still sum to the previous 45s at a
2,500-token prompt.
Also:
- The --clone warning selected on the post-applies_to count, so a repo
that was checked out but matched no files was told to clone what it
already had. RepoEstimate carries the pre-scoping count and the two
cases now get separate warnings; the second is the more useful, since
it means a pack is pointed at a repo it cannot see.
- Docs and --help claimed the command "mutates nothing" while documenting
--clone. Reworded, and the runtime model is documented.
- formatDuration handed over to minutes at 90s while rounding minutes
from 60s, so "1 minute(s)" was unreachable: 89s rendered as seconds and
90s jumped to 2 minutes.
- runEstimate printed targetErrors to stderr even when the report went to
stdout, where the caveats already list them. Now only when --output
redirects the report to a file. The 0 exit is left as it was, with a
comment marking it deliberate rather than an oversight.
Left alone: the unguarded readFileSync(configPath). It matches runRun, so
fixing one without the other would just make the two inconsistent.
Breaking change, from the original commit rather than this one:
PackOutcome.usage is required and PackOutcome is exported from
source/index.ts, so an external consumer constructing one breaks at
compile time.
Copy file name to clipboardExpand all lines: docs/cli/index.md
+5-3Lines changed: 5 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -60,7 +60,7 @@ The same validator, dedup logic, and findings model apply in both contexts, so w
60
60
61
61
## `estimate`
62
62
63
-
Sizes an audit **before** it runs: how many repositories and rule packs are in scope, how many files they put in front of the model, and roughly how many model requests, tokens, and minutes that costs. It runs no model, files nothing, and mutates nothing — useful when you are about to point Sentinel at a dozen more repositories, or adding a pack to every target and want to know what that does to the nightly window.
63
+
Sizes an audit **before** it runs: how many repositories and rule packs are in scope, how many files they put in front of the model, and roughly how many model requests, tokens, and minutes that costs. It runs no model and files no issues — `--clone` is the one flag that writes anything, checking out missing repos. Useful when you are about to point Sentinel at a dozen more repositories, or adding a pack to every target and want to know what that does to the nightly window.
64
64
65
65
```bash
66
66
npx @nanocollective/sentinel estimate
@@ -90,8 +90,10 @@ Calibrated from the last 6 run record(s).
90
90
91
91
### How the figures are produced
92
92
93
-
The token figure is **measured, not guessed**: `estimate` assembles the same prompts the audit would send — the pack body, the reporting contract, and the source files scoped by each pack's `applies_to.paths` — and counts them. What varies between installs is the per-request cost, so the request, token, and runtime figures are calibrated from the run records the last ten runs committed. Every run is instrumented for this: it records how long each pack pass took, how many model requests it made (auto-fix retries included), and the tokens it sent and received.
93
+
The token figure is **measured, not guessed**: `estimate` assembles the same prompts the audit would send — the pack body, the reporting contract, and the source files scoped by each pack's `applies_to.paths` — and counts them. What varies between installs is the per-request cost, so the request, token, and runtime figures are calibrated from the run records the last ten runs committed. Every run is instrumented for this: it records how long each pack pass took, how many model requests it made (auto-fix retries included), and the tokens it sent and received across every attempt — an auto-fix retry resends the prompt and generates a second response, and both are counted.
94
+
95
+
Runtime is **not** a flat per-request average. A request costs a fixed amount regardless of size plus an amount that tracks prompt size, and both terms are fitted from the records, so sizing a config far larger than anything you have run is not priced as though the prompts stayed the same. When the records cannot separate the two — a single run, or every run the same size — the measured average is split using the proportion the built-in defaults imply.
94
96
95
97
Until a run has been recorded, the figures fall back to built-in defaults, and the output says so. Treat a first, uncalibrated estimate as an order of magnitude rather than a number to schedule against.
96
98
97
-
Repositories already checked out under `--workspace` are measured from their real files. Any that are not are counted with zero files and called out in the output, so a partial estimate never reads as the whole picture — pass `--clone` to check the rest out first.
99
+
Repositories already checked out under `--workspace` are measured from their real files. Any that are not are counted with zero files and called out in the output, so a partial estimate never reads as the whole picture — pass `--clone` to check the rest out first. A repo that *is* checked out but whose files no pack matches gets a separate warning: nothing needs cloning, but a pack is pointed at a repository it cannot see.
0 commit comments