instar 1.3.785 → 1.3.787
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.
- package/dashboard/index.html +48 -20
- package/dist/core/routingSpendView.d.ts +20 -0
- package/dist/core/routingSpendView.d.ts.map +1 -1
- package/dist/core/routingSpendView.js +47 -0
- package/dist/core/routingSpendView.js.map +1 -1
- package/dist/core/types.d.ts +12 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +2 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/scripts/lint-scrape-fixture-realness.js +17 -0
- package/scripts/routing-price-refresh.mjs +146 -4
- package/src/data/builtin-manifest.json +46 -46
- package/src/scaffold/templates/jobs/instar/routing-price-web-verify.md +32 -0
- package/upgrades/1.3.786.md +42 -0
- package/upgrades/1.3.787.md +42 -0
- package/upgrades/side-effects/dashboard-responsive-fix.md +51 -0
- package/upgrades/side-effects/routing-spend-pr4-operator-additions.md +50 -0
|
@@ -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,42 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
- **The "squished to the side" bug is fixed structurally.** Fourteen dashboard tab panels
|
|
9
|
+
(Routing Map, Spend, Tokens, LLM Activity, Integrated Being, PR Pipeline, Projects,
|
|
10
|
+
Initiatives, Secrets, Commitments, Resources, Blockers, Evidence, Threadline) are declared
|
|
11
|
+
after `</main>` and are therefore direct `.app` grid children; with the sidebar hidden they
|
|
12
|
+
auto-placed into the 280px sidebar COLUMN, rendering all content in a ~185px strip on a
|
|
13
|
+
1280px viewport (operator screenshots, topic 29723). A shared `.tab-panel` class
|
|
14
|
+
(`grid-column: 1 / -1; min-width: 0`) now places every one of them across the full content
|
|
15
|
+
area — one rule instead of fourteen inline copies. The pre-existing `.ph-root` tabs keep
|
|
16
|
+
their own placement + prose width.
|
|
17
|
+
- **A placement floor makes the bug unrepeatable.** `tests/unit/dashboard-panel-placement.test.ts`
|
|
18
|
+
scans the after-main markup region and fails the build when a top-level panel lacks a
|
|
19
|
+
placement-carrying class (with an instructive message naming the panel and the fix), asserts
|
|
20
|
+
the `.tab-panel` rule keeps its grid span, and guards its own matcher with a population floor.
|
|
21
|
+
The old defense was a CSS comment on `.ph-root` — a wish; every panel added since repeated
|
|
22
|
+
the bug. This is the guarantee (Structure > Willpower).
|
|
23
|
+
|
|
24
|
+
## What to Tell Your User
|
|
25
|
+
|
|
26
|
+
The dashboard tabs that used to render squeezed into a narrow strip on the left of a desktop
|
|
27
|
+
window — including the new Routing Map and Spend tabs — now use the full width of the window.
|
|
28
|
+
Nothing to enable; it's just fixed everywhere once the release lands.
|
|
29
|
+
|
|
30
|
+
## Summary of New Capabilities
|
|
31
|
+
|
|
32
|
+
- None — this is a layout bug fix. (It also adds a build-time guard so a future dashboard tab
|
|
33
|
+
can't reintroduce the same squished layout.)
|
|
34
|
+
|
|
35
|
+
## Evidence
|
|
36
|
+
|
|
37
|
+
`tests/unit/dashboard-panel-placement.test.ts` — 4 cases: rule present + spans grid, every
|
|
38
|
+
placement class actually declares grid-column, no bare after-main panel (negative control
|
|
39
|
+
verified: stripping one panel's class fails naming exactly that panel), matcher-anchor guard
|
|
40
|
+
(the slice skips CSS/JS mentions of `</main>`). Real-browser (headless Chromium) before/after
|
|
41
|
+
screenshots at 1280×800: content strip ~260px before, full-width after; 390×844 rendering is
|
|
42
|
+
byte-identical before vs after (placement-only change). All 106 dashboard-reading unit tests green.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Side-Effects Review — Dashboard responsive fix (.tab-panel placement + floor test)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `dashboard-responsive-fix`
|
|
4
|
+
**Date:** `2026-07-08`
|
|
5
|
+
**Author:** `Instar Agent (echo)`
|
|
6
|
+
**Second-pass reviewer:** `not required`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Fixes the "everything is squished to the side" dashboard bug (operator report with screenshots, topic 29723, 2026-07-08): fourteen tab panels declared after `</main>` in `dashboard/index.html` are direct `.app` grid children with no explicit grid placement, so the lone visible panel auto-places into the 280px sidebar column on desktop. The fix adds ONE shared `.tab-panel` CSS class (`grid-column: 1 / -1; min-width: 0`) applied to all fourteen panels (Integrated Being, PR Pipeline, Projects, Initiatives, Secrets, Commitments, Tokens, Resources, Blockers, LLM Activity, Routing Map, Spend, Evidence, Threadline), plus a regression floor test (`tests/unit/dashboard-panel-placement.test.ts`) that fails the build when a future after-main panel lacks a placement-carrying class. The pre-existing `.ph-root` per-tab fix is left untouched; its comment now points at the shared contract. Files touched: `dashboard/index.html`, `tests/unit/dashboard-panel-placement.test.ts`, `docs/specs/dashboard-responsive-fix.eli16.md`, this artifact, and a release fragment.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
No decision-point surface. This change is presentation-layer CSS/HTML plus a static test. It gates no information flow, blocks no actions, filters no messages, and constrains no agent behavior at runtime. (The new unit test constrains future COMMITS — the standard test-ratchet pattern — not runtime behavior.)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 1. Over-block
|
|
19
|
+
|
|
20
|
+
No block/allow surface at runtime — over-block not applicable to agent/user traffic. For the commit-time ratchet: the floor test could "over-block" a future legitimate panel that is genuinely out of normal flow (e.g. a new fixed-position overlay). Mitigation is built in: the `OUT_OF_FLOW_EXEMPT` list with a required justification comment, and the failure message names the exact panel and both resolution paths.
|
|
21
|
+
|
|
22
|
+
## 2. Under-block
|
|
23
|
+
|
|
24
|
+
The floor test keys on 4-space-indented `<div id=...>` openers in the after-`</main>` markup region (all 27 current top-level panels match this shape). A future panel authored at unconventional indentation, as a non-div element, or injected purely from JS would not be seen by the floor. Accepted: the regression vector this floor closes is the observed copy-paste pattern (14 real instances); the population-sanity assertion (≥20 openers visible) fails loudly if the matcher ever goes blind wholesale. Deeper enforcement (viewport smoke tests) belongs to the Dashboard UX Standard work tracked in the topic-29723 working brief. <!-- tracked: topic-29723 dashboard-ux-brief Increment 2 -->
|
|
25
|
+
|
|
26
|
+
## 3. Level-of-abstraction fit
|
|
27
|
+
|
|
28
|
+
Right layer. The bug is a CSS grid-placement defect; the fix is a shared CSS class at the layout layer where the sibling container classes (`files-container`, `jobs-container`, `systems-container`, `features-container`, `dropzone-container`) already solve the same problem the same way. The alternative — per-panel inline styles — is exactly the pattern that produced fourteen copies of the bug. No smarter existing gate applies (this is not decision logic).
|
|
29
|
+
|
|
30
|
+
## 4. Signal vs authority compliance
|
|
31
|
+
|
|
32
|
+
Compliant by vacuity at runtime: the change holds no blocking authority and produces no signal — it is inert presentation markup. The unit test is a build-time ratchet, the same class as every other test in `tests/unit/`; it holds commit-blocking authority through CI exactly like all tests do, with deterministic, human-readable failure output.
|
|
33
|
+
|
|
34
|
+
## 5. Interactions
|
|
35
|
+
|
|
36
|
+
- Interacts with `switchTab()` only passively: switchTab toggles inline `display`; the new class carries grid placement only, so show/hide behavior is unchanged.
|
|
37
|
+
- `.ph-root` panels keep their own placement + 760px prose width; the new rule does not apply to them (no double-fire; the floor test accepts either class).
|
|
38
|
+
- Mobile breakpoint (`@media max-width: 768px`) collapses `.app` to one column; `grid-column: 1 / -1` resolves identically there — verified byte-identical mobile rendering before vs after the change.
|
|
39
|
+
- No other rule targets `.tab-panel` (fresh class name; grep-verified single definition).
|
|
40
|
+
|
|
41
|
+
## 6. External surfaces
|
|
42
|
+
|
|
43
|
+
Visible change: dashboard tabs render full-width on desktop instead of squished — the operator-requested fix. No API change, no data change, no cross-agent surface, no timing/conversation-state dependency. Verified with real-browser (headless Chromium) before/after screenshots at 1280×800 and 390×844: desktop fixed; mobile rendering byte-identical to pre-change.
|
|
44
|
+
|
|
45
|
+
## 7. Multi-machine posture (Cross-Machine Coherence)
|
|
46
|
+
|
|
47
|
+
Machine-local BY DESIGN in the same sense as all dashboard markup: the HTML ships identically to every machine with the release; each machine serves its own copy. No replicated state, no machine-boundary URL, no one-voice notice surface. Both of the operator's machines get the fix as they pick up the release.
|
|
48
|
+
|
|
49
|
+
## 8. Rollback cost
|
|
50
|
+
|
|
51
|
+
Trivial: revert the commit (CSS class + class attributes + one test file). No data migration, no agent state, no config. A revert restores the prior (buggy) rendering and deletes the floor test with it.
|
|
@@ -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).
|