instar 1.3.785 → 1.3.786

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,42 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ - **Amortized subscription display (operator decision #3 — "amortize but show the math"):**
9
+ `routingSpend.subscriptions` (reporting-only) declares a monthly price per CLI door; the spend
10
+ view amortizes it by CALENDAR TIME over the door's active days and shows the FULL derivation
11
+ (`$200.00/mo ÷ 30.4375 avg days/mo = $6.5708/day × 2 active day(s) = $13.1417`) per door —
12
+ never cap-enforced, counted once per door in totals; the Spend tab renders the figure inline
13
+ with a math footnote. Undeclared doors keep the honest `$0 (subscription)` wording.
14
+ - **Scheduled web-research price checks (operator directive):** `--scope +web-verify` in the
15
+ deterministic prober fetches the OFFICIAL Groq + Google pricing pages, extracts tracked-model
16
+ prices with conservative fail-closed parsers (registered in SCRAPE_PARSERS, fed the REAL
17
+ captured page bytes) + a >10x plausibility clamp vs the reviewed canonical price, and writes
18
+ forward-only OBSERVATIONS into the gate-ineligible observed cache. Zero spend (no LLM, no
19
+ metered key — the FD-8 budget refusal now exempts exactly this deterministic scope). New
20
+ OFF-by-default weekly `routing-price-web-verify` job (tier-1 supervised, Bash-only).
21
+
22
+ ## What to Tell Your User
23
+
24
+ If you tell me what your AI subscriptions cost per month (e.g. "Claude Max is $200/mo"), the Spend
25
+ tab stops showing a bare $0 for them — you'll see an amortized share for the reporting window with
26
+ the exact arithmetic printed underneath, clearly labeled as a time-based estimate that never
27
+ affects any spending cap. And once you enable the weekly price-check job, I'll quietly re-read the
28
+ providers' official pricing pages and flag drift against the reviewed prices — you always keep the
29
+ final say (PIN) on what price the books use.
30
+
31
+ ## Summary of New Capabilities
32
+
33
+ - (⚗️ Experimental) Amortized subscription costs with visible derivation math + scheduled
34
+ web-research price observations. This completes the money-increment train (B → C → 1c → PR 4);
35
+ the pool-scope reconciliation merge stays tracked under CMT-1929.
36
+
37
+ ## Evidence
38
+
39
+ `tests/unit/routing-price-web-verify.test.ts` — 7 cases: both parsers over the REAL captured page
40
+ bytes (groq $0.15/$0.60; flash-lite $0.25 text-rate/$1.50 thinking-inclusive), reshaped-page
41
+ refusal, plausibility-clamp refusal, and the amortization math (derivation string pinned verbatim,
42
+ door-level totals, undeclared-door nulls). Realness lint green; docs-coverage floors held.
@@ -0,0 +1,50 @@
1
+ # Side-Effects Review — Routing Control Room PR 4 (operator additions)
2
+
3
+ **Spec:** `docs/specs/routing-control-room-spend-alerts.md` (review-convergence r7, approved, parent-principle: Token-Audit Completeness) — FD-7 deferral resolved by the operator + FD-8 web-verify, both operator decisions 2026-07-07 (topic 29723).
4
+ **Worktree:** `echo/money-increment-pr4` off `JKHeadley/main` @ `d70a546f8` (contains merged Increments B, C, and Layer 1c).
5
+ **Scope (PR 4 of the train, tracked CMT-1929 — the FINAL increment):** the two operator additions.
6
+
7
+ ## Phase 1 — Principle check (signal-vs-authority)
8
+
9
+ **Does this change involve a decision point?** No blocking decision anywhere. The amortized display is REPORTING-only arithmetic over an operator-declared config value; the web-verify parsers write OBSERVATIONS into the gate-ineligible observed cache, and their failure mode is REFUSAL (no data) — never a wrong price entering any gate path. Compliant.
10
+
11
+ ## Phase 2 — Plan
12
+
13
+ - **Decision points touched:** none with authority. The web-verify parsers DECIDE only whether a page is confidently parseable (fail-closed both ways: unparseable → no point; implausible vs canonical → refused).
14
+ - **Existing detectors/authorities interacted with:** `RoutingPriceAuthority` (unchanged — the observed cache remains gate-ineligible by construction); the FD-8 budget refusal (narrowed: the DETERMINISTIC `+web-verify` scope is exempt because it spends nothing — no LLM, no metered key; metered probes stay budget-fail-closed); `SCRAPE_PARSERS` (both parsers registered with REAL captured fixtures per the Fixture Realness standard); `installBuiltinJobs` (the new template reaches existing agents on update — Migration Parity by the existing non-destructive install path).
15
+ - **Rollback path:** additive; remove the config key / leave the job disabled and behavior reverts byte-for-byte. The fixtures and job template are inert.
16
+
17
+ ## Phase 4 — Side-effects review (rider content, reviewed)
18
+
19
+ The operator additions land here as the train's final increment (both operator decisions 2026-07-07, topic 29723):
20
+
21
+ 1. **Amortized subscription display ("amortize but show the math"):** `routingSpend.subscriptions` (reporting-only config — never a gate input) declares a monthly price per CLI door; the composer amortizes by CALENDAR TIME over the door's ACTIVE days in the window (30.4375 avg-month constant, NAMED in the output) and emits the full `amortizationDerivation` string per door; totals count each door once; the Spend tab renders the amortized figure with the math as a visible footnote block. Undeclared doors keep the honest `$0 (subscription — not per-token billed)`. Over-block: none (display only). Under-block: an operator-declared wrong price shows wrong REPORTING — labeled as door-level calendar allocation, never cap-enforced.
22
+ 2. **Scheduled web-research price checks:** `--scope +web-verify` in the deterministic prober — fetches the OFFICIAL Groq + Google pricing pages (the two doors without machine-readable price APIs), extracts tracked-model prices with CONSERVATIVE fail-closed parsers (registered in SCRAPE_PARSERS; fed the REAL captured page bytes per the Fixture Realness standard) plus a plausibility clamp (>10x off the reviewed canonical → refused). Zero spend (no LLM, no metered key — the FD-8 budget refusal now exempts exactly this deterministic scope; metered probes stay budget-fail-closed). Observations only; PIN promotion unchanged. New OFF-by-default job template `routing-price-web-verify` (weekly, tier-1 supervised, Bash-only).
23
+
24
+ Signal-vs-authority: both riders are reporting/observation surfaces with zero blocking authority; the web-verify parsers' failure mode is REFUSAL (no data), never a wrong price entering the gate path (observed cache is structurally gate-ineligible).
25
+
26
+ 5. **Interactions:** the amortized figure never feeds netUsd/grossUsd/committed (a separate labeled column + totals line, counted once per door); the web-verify observations ride the EXISTING forward-only merge + promote-me drift surface — no new interaction with the money layer. 6. **External surfaces:** two outbound HTTPS fetches to official public pricing pages from an OFF-by-default weekly job; no data leaves the machine. 7. **Multi-machine:** the observed cache stays machine-local BY DESIGN (declared in the sibling job); the subscriptions config is per-machine reporting (the pool-merge label already names the adjustments source). 8. **Rollback cost:** config/job revert; no state migration.
27
+
28
+ ## 6b. Operator-surface quality
29
+
30
+ The one operator surface touched is the Spend tab's subscription-cost display (a READ surface — no new controls, no forms). Answered in writing:
31
+ 1. **Leads with its primary action?** Yes — the tab's primary content is unchanged (the spend headline + rows); the amortized figure lands IN the existing Net column where the operator already looks, as `~$13.14 amortized ⓘ` — a value, not a control.
32
+ 2. **Zero raw internals as primary content?** Yes — the derivation math is a hover title + a compact footnote block BELOW the table, in plain sentences ("$200.00/mo ÷ 30.4375 avg days/mo = $6.5708/day × 2 active day(s) = ..."), never JSON or config keys; the config key itself appears nowhere on the surface.
33
+ 3. **Destructive actions de-emphasized?** N/A — the change adds no actions at all (display only); the existing tab's control asymmetry (freeze easy, arm PIN-gated) is untouched.
34
+ 4. **Plain language at phone width?** Yes — one short suffix per row plus a wrapping footnote paragraph; no new table columns (phone tables were the 2026-06-12 lesson), no horizontal growth; the ⓘ affordance signals the hover/footnote for touch users who cannot hover.
35
+
36
+ ## Phase 5 — Second-pass review
37
+
38
+ Not-required by the Phase-5 trigger list (no block/allow decisions, no session lifecycle, no gate/sentinel authority — display arithmetic + fail-closed observation parsers). The parsers' realness posture is enforced by the SCRAPE_PARSERS lint rather than reviewer eyes.
39
+
40
+ ## Self-action convergence (unbounded-self-action — closure: n/a)
41
+
42
+ No new self-triggered loop: the web-verify job is a fixed-cadence, OFF-by-default scheduled job (calendar-driven, not feedback-driven — its output never changes its input), and the display change has no emission at all. Declared n/a: one-shot/cadenced observation work, not a self-triggered controller.
43
+
44
+ ## No-deferrals accounting
45
+
46
+ This is the train's final increment; the pool-scope reconciliation merge remains the one tracked follow-up under CMT-1929 <!-- tracked: CMT-1929 -->.
47
+
48
+ ## S2-2 hardening round (post-CI, staged with this fix)
49
+
50
+ CI's string-level S2-2 ratchet (`the prober source never names routing-prices.manifest.json`) caught the plausibility clamp's `readManifest` naming the canonical manifest in CODE — a genuine violation of the prober's structural manifest-blindness, not just a comment. Fixed by inverting the dependency: the prober now takes a generic READ-ONLY `--plausibility-baseline <path>` argument (absent → the clamp passes, no baseline), and the CALLER (the web-verify job template) passes the manifest's location. The prober source contains zero references to the reviewed price file; write-incapability is preserved by construction; the clamp behavior is unchanged (verified: sane passes, >10x refused, no-baseline passes).