Skip to content

Site updates - #193

Closed
ethancjackson wants to merge 125 commits into
mainfrom
site-updates
Closed

Site updates#193
ethancjackson wants to merge 125 commits into
mainfrom
site-updates

Conversation

@ethancjackson

Copy link
Copy Markdown
Collaborator

No description provided.

ethancjackson and others added 30 commits July 15, 2026 20:33
Pin the behaviour the domain-agnostic refactor must preserve:

- AdaptiveSkillStore save/load/render/backup contract and the
  confirmation_threshold store parameter (shared-lib test with a minimal
  concrete state).
- WtiStrategyState.build_markdown() renders the committed
  wti-strategy-trained artifact byte-identically (snapshot), plus the
  default oil skill name/title.
- The five strategy mutation tools' evidence governance: observation/
  hypothesis lifecycle, the graduation threshold guard, and the
  narrative-update rationale requirement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ainConfig

Promote the shared agentic engine so a new target series can be configured
without touching oil code, and drive the oil prompts/config from a single
`DomainConfig`. Pure refactor: no new features, no study driver.

Promoted to aieng/forecasting/methods/agentic/:
- strategy_state.py: generic `StrategyState` (+ Observation/Hypothesis/
  CalibrationCorrection/VersionEntry). Markdown title, default skill name, and
  frontmatter description are ClassVar params. Oil `WtiStrategyState` becomes a
  thin subclass pinning the WTI strings — committed SKILL.md renders identically.
- adaptive_skill_tools.py: `build_skill_tools(strategy_dir, state_type, ...)`
  generic over any StrategyState subclass. No import-time singletons. Oil
  skill_tools.py delegates and re-exports the sub-models; STORE/WTI_SKILL_TOOLS
  removed (unused outside docstrings).
- history.py: `compress_history` (was analyst_agent/agent.py); oil re-exports it.
- outputs.py: generic `ScenarioCard` / `ScenarioAgentForecastOutput` with the
  scenario-card numeric fields parameterized via `scenario_card_template_extra`.
  Oil `tasks.py` subclasses them, preserving `wti_range_60d`/`point_estimate_60d`
  and modality="discrete".
- domain.py: `DomainConfig` (identity, data/target, context-retrieval, strategy
  skill, skill dirs, vol-regime bands, tool bounds) plus render_* instruction
  templates and `build_analyst_config` / `build_adaptive_config`.

Oil implementation:
- energy_oil_forecasting/domain.py defines `OIL_DOMAIN`.
- analyst/adaptive/starter agent instructions now render from OIL_DOMAIN; the
  `build_wti_*` factories are thin delegating wrappers. Rendered oil prompts are
  byte-identical to the originals (verified against captured goldens).

Curriculum: `_vol_regime` vol bands extracted to a `bands` parameter with the
15/30/50 thresholds as `DEFAULT_VOL_REGIME_BANDS`.

Invariants held: oil agent.name / predictor_id strings unchanged; committed skill
artifacts render identically; nb05/nb06 import surfaces resolve. Regenerated the
concierge catalog/artifacts to index the new modules. __init__ re-exports the
promoted names; old oil import paths preserved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New PYSEC-2026 advisories against the locked versions fail CI's pip-audit
step on every branch (main last passed 2026-07-07, before publication).
Full test suite re-verified after the bump: 489 passed, 7 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
refactor(agentic): generalize agentic predictors via DomainConfig
Mirror the sampled-trajectory predictor: an optional covariate_series_ids
config field serialises labeled, cutoff-safe exogenous-series history into the
quantile-grid prompt (Context-is-Key §5.4). Default None keeps existing
target-only behaviour and predictor_id unchanged; covariate ids are recorded in
prediction metadata. Lets the workshop run llmp_qgrid and llmp_qgrid_cov as a
clean with/without-covariates pair.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New top-level workspace member (importable workshop_experiments) for the
workshop-paper + live-eval S&P 500 experiments — package + resumable CLI
runners, no notebooks. Contents:

- SP500_DOMAIN: an equity-index DomainConfig over the sp500_forecasting
  cumulative-log-return target (h=1/5/21 business days, ^GSPC via yfinance),
  general macro/market context (Fed, CPI, geopolitics, tech, yields, VIX) with
  no oil wording; news + code analyst configs via the PR-1 build_analyst_config.
- registry: named predictor factories (naive/ets/kalman/autoarima, lightgbm
  ±cov, llmp_qgrid ±cov, agent_news/agent_code) with model-encoding ids.
- specs: smoke (3), weekly 2025 backtest (52), weekly 2026 protected eval (24,
  h=21 resolves by mid-July), daily bonus layer (378), all CRPS-scored.
- runner: per-origin persist + resume + token/cost accounting; scoring rebuilds
  BacktestResults and reuses the sp500 leaderboard frames (no notebook/plot
  imports). CLI: ws-run-backtest / ws-score.
- tests: registry construction, spec load/validation, resume logic (fake
  predictor), and SP500_DOMAIN oil-free rendering; wired into CI.

README sketches how the stage-2b live daily harness builds on these primitives
(spec-less "today" origin, append-only log, deferred resolution).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Persisted per-origin predictions and leaderboard for sp500_ws_smoke
(naive/ets/autoarima x 3 origins x 3 horizons), plus per-predictor
accounting.json. Sanity: h=1 mean CRPS ~0.003 (ETS/ARIMA) vs ~0.012 (naive),
rising with horizon to ~0.02-0.03 at h=21 on the log-return scale. Yahoo/FRED
caches stay git-ignored under repo-root data/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(workshop): S&P 500 workshop_experiments foundation (stage 2a)
…deploy

Zero-backend static dashboard for the live S&P 500 forecasting experiment,
driven entirely by committed artifacts (the log is the database).

- monitor/DESIGN.md: view hierarchy (overview -> drill-down -> twins), curation
  policy verbatim.
- monitor/data-contract.md + monitor/schemas/*.schema.json: versioned JSON Schema
  interface (prediction, resolution, leaderboard, gap-log, mutation-event records
  + manifest & forecast-bundle envelopes) with append-only file layout.
- monitor/site/: working prototype (plain HTML/ES modules/CSS, no build, no CDN).
  Overview (leaderboard heatmap, cumulative-CRPS lines, gap log) and single-forecast
  drill-down (predictive-distribution fan vs realized + agent rationale + curated
  trace + Langfuse id) built; twins & calibration stubbed. Charts hand-built SVG
  per the dataviz skill; responsive; light/dark via prefers-color-scheme; MOCK DATA
  banner keyed on generated_by.
- monitor/site/data/: ~58-trading-day mock fixtures conforming to the schemas.
- monitor/tools/generate_mock_data.py: deterministic fixture generator.
- monitor/validate_fixtures.py: schema validation (standalone + pytest).
- .github/workflows/deploy-monitor.yml: validate fixtures, then deploy site to Pages.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(monitor): experiment monitor — data contract + static dashboard + Pages deploy
…tputs

Two defects surfaced by the workshop LLM smoke run:

1. The workshop registry hardcoded the full covariate panel, but the data
   service skips covariates that are unavailable upstream (gold, delisted
   on FRED) — every *_cov predictor failed asking for an unregistered
   series. The runner now filters the panel against the service's
   registered series and threads it through build_predictor; *_cov
   factories reject an empty panel with a clear message.

2. make_json_schema_response_format stripped additionalProperties
   unconditionally (required for the proxy's Gemini response_schema
   route), which OpenAI strict mode rejects — all gpt-* structured
   completions failed. The wrapper is now model-aware: OpenAI-family
   models keep the schema verbatim; all other models keep the legacy
   stripped form. All six call sites pass their model through.

Verified live on the 3-origin smoke: gpt-5.4/gpt-5.5 now pass both
variants; gemini flash-lite unchanged; covariate runs 9/9 across models.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3-origin smoke, quantile-grid target-only + covariate variants, all six
candidate proxy models (gemini flash-lite-3.1/flash-3.5, claude
sonnet-4-6/opus-4-7, gpt-5.4/5.5). 108 persisted predictions, zero
failures post-fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(llmp): covariate panel filtering + OpenAI-strict structured outputs
Adds the `ws-live-run` umbrella CLI and the `workshop_experiments.live`
package that runs one trading-day cycle: trading-day check -> predict ->
resolve -> aggregate -> commit + push, guarded by a single-run lockfile.

- live_config.yaml: the deployed ladder (6 conventional + 12 LLMP + 4
  agent rungs), horizons 1/5/21, 17:30 America/Toronto submission, retry
  policy, and log/aggregate paths. Model lists are config, not code.
- Records conform exactly to monitor/schemas; the three writer invariants
  (standard grid, monotonic quantiles, point==q50) are enforced pre-write.
  curated_trace_summary carries tool names + query titles only.
- Resolver reuses properscoring CRPS over the stored quantile grid.
- Aggregates are deterministic (generated_at derived from the log's latest
  timestamp) and validated against the schemas before writing; the monitor
  validator is refactored into an importable `validate_instance` while
  keeping the standalone script working.
- Gaps are logged per method and never backfilled; non-session days exit
  cleanly. `--dry-run`, `--no-push`, and `--simulate` (offline, no API) are
  wired; simulate is exercised end to end as a CI pytest.
- ops/: launchd plist template + install/inspect/health-check docs (not
  installed).

Offline tests cover schema conformance, CRPS math, aggregate determinism,
gap policy, and the lockfile. Full suite + pre-commit are green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Orchestrator ruling on the stage-2b taxonomy question: never overload the
public `model` field as a variant label. The `method` enum now carries one
value per deployed rung — naive, ets, kalman, autoarima, lightgbm,
lightgbm_cov, llm_process, llm_process_cov, agent_news, agent_code — plus
adaptive_frozen / adaptive_learning as stage-2c forward declarations.
`model` is null for conventional methods and holds the plain backing-model
id for LLM/agent rungs (no "+cov" suffixes anywhere). Leaderboard cells key
on (method, model, horizon), unique again with per-rung methods.

- schemas: prediction + resolution method enums; gap_log scope example.
- data-contract.md: 1.1.0, enum documentation, changelog, and the
  "curated_trace_summary populated when available" limitation note.
- harness: config.py taxonomy mapping (agent predictor ids become
  sp500_agent_news__<model> / sp500_agent_code__<model>), SCHEMA_VERSION,
  aggregate method order, records.py limitation docs.
- monitor: generate_mock_data.py emits the per-rung ladder (18 rows);
  fixtures regenerated and validated; site config.js method
  order/labels/colors (families share a hue, labels disambiguate).

Made pre-deployment: no live artifact ever carried 1.0.0 method values.
Full suite (569 passed) + pre-commit green; simulate end-to-end unchanged
(45 predictions / 21 gaps / 30 resolutions).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(live): stage 2b — live daily forecasting harness + data contract 1.1.0
…stage 2c)

Implements workshop stage 2c on top of the live harness + data contract 1.1.0.

SP500 adaptive domain wiring (workshop_experiments/adaptive/):
- SP500_ADAPTIVE_DOMAIN extends SP500_DOMAIN with the pipeline/strategy/
  governance skill dirs; Sp500StrategyState brands the seed artifacts.
- Equity-generalized seed skills: sp500-strategy (seed), fetch-yfinance,
  vol-regime (VIX bands), trend-projection, meta-learning. Oil skills untouched.
- RESEED semantics: trained variants are seeded by copy; the seed is never mutated.

Study driver (ws-study, non-notebook, resumable): Phase A Study Hall over a
sticky session with the §4 agenda as suggested directions and distill
checkpoints every N turns; Phase B Residency postmortems over worst-N-by-CRPS +
control origins. Pluggable session so it builds/tests offline; dry-run default.

Live twins + tiered gates:
- adaptive_frozen / adaptive_learning rungs wired into live_config.yaml +
  live/config.py (kept out of the stateless ladder; deploy later).
- GatePolicy over the mutation tools: tier-1 observations pass; tier-2
  hypotheses use the k-confirmation machinery with a weekly rate limit; tier-3
  behavioral changes enter a shadow champion/challenger (adopt iff mean CRPS not
  worse over M origins). Circuit breaker freezes adaptation when the learner's
  trailing-21d CRPS exceeds 1.15x the frozen twin's.
- Every adoption/rejection/freeze writes a schema-conforming mutation_event; the
  aggregate step collates them into mutations.json for the monitor's twins view.
- Frozen twin is genuinely read-only (no mutation tools; read-only gate raises).
- Bounded reflection step feeds the gate through gated tools.

Retrospective before/after eval (ws-adaptive-eval): untrained vs Phase-A vs
Phase-A+B arms on the 2026 weekly spec via the runner; tested with a fake
predictor. All spend-bearing commands default to dry-run and require --run.

Tests (offline, no network): gate state machine, shadow adopt/reject, circuit
breaker, mutation_event schema conformance, frozen-twin enforcement, RESEED,
origin selection, twin config expansion, study driver resume, aggregate wiring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(adaptive): stage 2c — study driver, live twins, tiered gates
35/36 agent predictions first-pass (news+code x gemini-3.5/sonnet-4-6);
the one transient failure resumed cleanly. Leaderboard scored across all
16 rung-model combinations (n=3, sanity only).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The end-to-end simulate test hardcoded prediction/gap/resolution counts
that broke whenever the committed smoke store grew. Expectations are now
computed from per-(rung, origin, horizon) fixture existence, so adding
smoke-backed rungs or filling a previously failed origin cannot break CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
chore(workshop): agent smoke artifacts + scored smoke leaderboard
The live harness writes ``curated_trace_summary.tool_calls`` from
prediction metadata, but the agent predictor path never surfaced a
structured tool-call list, so public summaries were always empty.

Wire the capture end to end:

- AdkTextRunner records each tool invocation during a run as a curated
  ``{"tool", "title"}`` entry (``last_tool_calls``). Titles are curated at
  capture time: search_web -> query (truncated to 120 chars), code
  execution -> ``"python (N lines)"`` (never the body), other tools ->
  the tool name. The list is capped at 50 entries defensively.
- AgentPredictor threads ``last_tool_calls`` into each prediction's
  metadata under ``tool_calls`` (only when non-empty; absence is
  tolerated downstream).
- The live records writer reads the capture's ``title`` key (legacy
  ``query_title`` still accepted) and maps it to the schema's
  ``query_title`` field.

Tests cover capture ordering, truncation, the defensive cap, per-run
reset, metadata threading, and that a record built from tool_calls
metadata validates against prediction.schema.json.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Smoke store now complete: 144/144 predictions across all 16 rung-model
combinations (the transient code x sonnet failure at 2025-10-13 h=21b,
resumed via the store's skip-cached path: predicted=1 cached=8).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(agentic): capture curated tool-call summaries for the public monitor
chore(workshop): complete the smoke store (144/144)
The experiment monitor must not be published to a public GitHub Pages URL
until Vector Institute publication approval lands. Drop the `push` trigger
from deploy-monitor.yml so no commit to `main` can silently publish the site;
keep `workflow_dispatch` so a deploy is one deliberate click away once
approved. Document local serving (`python -m http.server` from monitor/site)
as the supported viewing mode meanwhile, and record the two steps to re-enable
automatic deploys after sign-off.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Git author/committer dates are client-supplied and forgeable, so they cannot
back the paper's claim that commit history proves submission times. Add a
server-side trust anchor and document the model:

- New workflow attest-live-log.yml: on push to main touching the live log path
  (mirrors log_dir in live_config.yaml), cut an idempotent GitHub Release tagged
  attest/<UTC date>-<short sha> whose server-set created_at is the anchor; body
  lists the head SHA and changed log files. permissions: contents: write.
- HONESTY.md documents what an auditor checks (Release created_at vs. the
  record's submission_timestamp, expected within minutes; commit dates
  explicitly NOT the anchor), the existence-by-time limitation, and
  OpenTimestamps as a future strengthening. Linked from the ops README and
  monitor/DESIGN.md's curation/honesty section.
- gitops.commit_message now embeds the UTC submission timestamp in the subject
  (@ <ts>) as a human-readable cross-check; threaded through the CLI run steps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ul cap

Trace analysis of the 3-origin smoke found code agents looping 30+ times with
~2-minute model generations over a growing context (up to ~26 min wall), while
the sandbox executions themselves were fast (1-7 s). Address the loop, not the
data the agent may access — nothing here changes what information is available.

Instruction: add render_code_exec_supplement(domain) to the shared lib — a
workstyle supplement telling the agent code execution is for short, focused
analysis bursts (diagnostics/rolling stats/calibration, not heavy ML), to plan
and batch into ~4-6 executions, and to print compact numeric summaries rather
than dump raw frames. Appended in build_sp500_code_config only (news/bootcamp
paths unaffected).

Defensive cap: new AgentConfig.max_tool_iterations (None by default) threads
through build_analyst_config and AgentPredictor into AdkTextRunner, which bounds
the run with ADK's RunConfig.max_llm_calls. On the limit, the runner catches
LlmCallsLimitExceededError (raised before the next LLM call, so the session is
clean) and issues one final, uncapped "submit now with what you have" turn on
the same session — a capped run still resolves to a valid structured forecast
instead of a hard mid-loop kill. build_sp500_code_config opts in at a generous
12; oil call sites keep current behavior for a cherry-pick-friendly shared-lib
diff.

Tests: workstyle guidance present for code config only; cap opt-in (12 for code,
None for news, overridable); runner graceful-final-turn path, final-turn
instruction, max_llm_calls bounding, no-final-turn-under-cap, and uncapped
current-behavior path (mocked runner per existing patterns).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(ops): Pages hold, release-based submission attestation, code-agent efficiency
Pivot the workshop experiments' primary target to the S&P/TSX Composite
(^GSPTSE) for the Canada-focused live forecasting experiment. The S&P 500
machinery is left fully intact for retrospective use.

- data_tsx.py: leak-safe TSX target (close-to-close cumulative log returns at
  h=1/5/21) plus an 11-covariate panel, mirroring the sp500 lag-1-business-day +
  conservative-release pattern. Panel is FRED-free: Yahoo market factors (VIX
  level/return, WTI CL=F, gold GC=F, USD/CAD, S&P 500, US 10Y ^TNX) and StatCan
  Canadian macro (BoC policy rate + GoC 10Y from table 10-10-0139-01, CPI MoM,
  unemployment). Unavailable covariates degrade with a warning (strict=False).
- domain_tsx.py: TSX_DOMAIN with a Canadian equity-index analyst persona,
  Canadian-macro context-retrieval + search queries, tsx-strategy skill name,
  and empirically-calibrated realized-vol regime bands (below the SPX/VIX bands).
- registry.py: tsx_* variants of every rung (naive->agents) with tsx-distinct
  predictor ids (tsx_ws variant tag, tsx_analyst_* agent names) and tsx_* groups.
- specs.py + specs/tsx_ws_*.yaml: smoke / 2025 backtest / 2026 eval / daily specs.
  Smoke origins (Nov 3/10/17 2025) are TSX sessions, clear of Thanksgiving.
- run_backtest.py / score.py: select the TSX service + panel from the spec's
  target family so one CLI serves both S&P 500 and TSX.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ethancjackson and others added 26 commits July 20, 2026 10:48
…luation case

The retrospective structurally motivates a forward live experiment: the pro-agent
findings (break-time value, divergence-as-alarm) rest on ~one regime event/year
that two dozen origins cannot confirm, and no offline protocol fully firewalls a
web-reading model from the future it is scored against. The conclusion now makes
that case explicitly and ends on it, keeping the practitioner takeaways. Motivation,
not announcement: no dashboard, cadence, or commit-log — the binding no-live-
announcement rule holds. Also softened the section 4 close so it hands off to the
ending instead of pre-empting it (revertable if undesired).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
blog(part-2): retitle Coda to "What's next", conclude on the live-evaluation case
…width

- fig1: drop the mid-figure flow arrows that landed inside the panels
- fig5: off-scale note on its own header line; even title/subtitle rhythm
- fig6: lift subtitles and the n<=24 caveat clear of the chart frames
- fig4: widen the source caption to span all three subplots

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Statistical corrections (recomputed on the published n=24 population):
- REMOVE the unsupported claim that divergence predicts the tree's own error
  (rho=0.32, p=0.13 on n=24; it had been computed on n=22 where it looked
  significant). Now reported explicitly as not significant.
- All statistics restated as rho/p/n on one canonical population, with a
  plain-language gloss of what rho and p mean on first use.
- Replace the uncited 'one-day forecasting is purely a calibration game' with a
  claim our own leaderboard supports (2% spread at h=1, direction near chance).

Structure:
- Fold LLMP into 'The numbers-only ladder' as its final rung, before the results
  figures, so the figures no longer show LLMP before it is introduced. Adds the
  programmatic-vs-agentic framing that Part 2 turns on.
- Credit David Duvenaud (Vector Institute) as senior author of the LLMP paper.
- Cite ALMA (arXiv:2602.07755) alongside ADAS and the Darwin Godel Machine.
- Judge rubric as a three-bullet list, verbatim from scenario_judge.py.
- Per-part figure numbering: Part 1 Figures 1-6 (fig0 was unnumbered, so every
  number shifted), Part 2 Figures 1-7 incl. the new sentinel flagship slot.

Editorial: market forecasting named as deliberately hard; covariate panel
defended (WTI/gold are front-month futures, VIX is options-implied; term
structure is the fair gap); futures-skill extension noted; softened Part 1
close and Part 2 conclusion; sentinel-in-a-mixed-pipeline as the practical
takeaway; repo CTA with bootcamp origin and fork nudge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… to what survives scrutiny

New Figure 4 (fig7_sentinel_bands): both methods' 10-90 prediction intervals
across the 24 protected-window origins, realized return overlaid, war window
shaded. Tree spans a 1.7x width range end to end; agent spans 3.5x, median
1.63x the tree, peaking at 3.00x at origin 2026-03-16.

Statistical scrutiny of the flagship width claim (rho=0.52, p=0.010, n=24):
- Excluding the war window it does NOT hold (rho=0.27, p=0.35) - the
  association is carried almost entirely by that one event.
- Weekly origins with a 21-business-day horizon overlap ~80%, so the 24 points
  are nearer five independent observations; a block permutation respecting that
  gives p from 0.009 to 0.166 depending on block size.
- Median width ratio inside the war window (1.60) is NOT elevated versus quiet
  weeks (1.64) - so 'the agent widens at the break' was wrong. It runs
  consistently wider and spikes at the trough.

Prose and figure title corrected accordingly; the sentinel framing is now
presented as a hypothesis worth testing rather than an established finding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ing supports

Audited the two claims not yet stress-tested, plus the paired code-agent win.
All three are weaker than written, for the same underlying reason: 24 weekly
origins at a 21-business-day horizon overlap ~80%, giving roughly five
independent observations containing a single regime event.

- War/quiet split: the -11% break-window edge is carried by ONE origin (85% of
  the total gain; drop it and it falls to -2%), and the agent records the worse
  score on 6 of the 10 break origins (Wilcoxon p=0.70). Reframed as one avoided
  blowup rather than a dependable break-time edge.
- Divergence-gated router: the <2% margin is not distinguishable from chance —
  ~28% of random gates of the same size do at least as well, paired p=0.94.
  Reframed accordingly; no longer presented as beating both baselines.
- Code agent 18/24: sign test p=0.011, but Wilcoxon p=0.11 and a block
  permutation respecting the overlap gives p~0.40, on a 3.1% mean margin. No
  longer called the study's only significant paired win.

Conclusion reframed per Ethan: complementarity (conventional methods carrying
the base rate, an agentic layer watching for regime change) presented as a
direction worth exploring and explicitly not a demonstrated result.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… finding, scoreboard folded into the window-limit narrative, ending lands on the leakage/power squeeze

- Adaptive section 618 -> ~275 words; Figure 7 (fig4_adaptive_prepost) removed
  from the post (script/PNG left on disk); Part 2 now has 6 figures, numbering
  already contiguous 1-6.
- 'The same scoreboard' 1,855 -> ~1,330: kept the changing-of-the-guard walk,
  the code agent's h=1 rank-2, the war/quiet split as description, and the
  width-vs-median contrast; the p-value enumerations and router battery are now
  one clear sentence each.
- 'What's next' rewritten to end on the two-sided squeeze: you cannot buy
  statistical power with history when the forecaster may have memorized the
  history — divergence framed as a pre-registrable hypothesis, not a finding.
- Part 2: 4,544 -> 3,675 words.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…11 scripts migrated, captions absorb the moved text, renderer fails on captionless images

- _blogdata.py: font-size ladder (FS, 10pt floor) pushed into rcParams; numbered
  figure_title helper; one savefig for both parts at 220 dpi that refuses
  figure-level text below the axes block (the footnote idiom), refuses any text
  under the floor, and asserts saved width <= 1.02x figsize x 220dpi — the
  tight-bbox inflation that shrank fig4 (part-1, +9.2%) and the combined
  leaderboard (part-2, +19.6%) is now unrepresentable. Both are fixed (0.895,
  1.016).
- All 11 live figure scripts migrated: PNGs keep only title/axes/legend/marks
  plus decode-required text; interpretation, attribution, and hedging moved to
  the markdown captions. Scripts print CAPTION: lines at save time so computed
  values are never hand-transcribed.
- Truncated axes stay honest standalone: the divergence inset's zoomed start is
  encoded in break glyphs + tick label; the leaderboard's off-scale floors are
  chevron marks with true values.
- post.md captions updated per the one-paragraph *...* contract; CAPTIONS.md in
  both parts rewritten, re-keyed by reading-order Figure N, receiving the
  provenance strings deleted from the scripts.
- _render.py now exits non-zero when an <img> paragraph is not followed by an
  <em> caption paragraph (previously emitted a captionless image and exited 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rter

Part 1:
- Opening retitled 'From public leaderboards to a single series'; both
  'series you actually care about' phrasings and the 'series *you* picked'
  sentence removed.
- LLMP framing tidied per comment: the ladder is now the 'fixed-context
  ladder' — LLMP acknowledged as not strictly numbers-only (series
  description, can condition on any text supplied in advance at inference);
  agents are separated because agency to seek information or self-study was
  the hypothesis under test.

Part 2:
- Futures-market paragraph dropped entirely (panel already carries
  front-month futures).
- Router negative result compressed to the suggested framing: interesting,
  but this window lacks the statistical power to tell if it is a real
  mechanism — reported as an idea, not an edge.
- Sentinel reframed as the production-pipeline alert: agent runs alongside
  conventional forecasters, divergence raises an alert that triggers deeper
  investigation or a human expert with a stake in the target.
- Figure 5 caption notation unified (all values ×10⁻³ once).
- 'The trees' nickname for the LightGBM models replaced throughout
  (prose, captions, alt text).
- Repo CTA reframed as an invitation to extend the process.

Part 1: 2,463 words; Part 2: 3,685 (net −76). Both parts re-rendered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Blog final pass: review-comment resolution, compression to the honest narrative, and the chrome-out figure system
Addresses Ali's feedback that the posts read as AI-assisted. Rewrote both
parts against the learn-day lecture transcripts to match how Ethan actually
sounds: plainer declaratives, honest hedging, and his own phrases ("honest
evaluation", "earn their place") kept.

Removed throughout: all em-dashes, "not X, but Y" antithesis constructions,
chiasmus/aphorisms, dramatic sentence fragments, mid-prose bold, and
emphasis italics. Stylized headings simplified ("The staircase", "The rung
that has to read", "The referee"). All numbers, figures, links, tables, and
the caption convention are unchanged; dist/ re-rendered via render.sh.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Humanize blog voice: match Ethan's spoken tone, remove AI-isms
Bring in the architecture atlas, strategy guides, and the BoC analyst-prompt
fix. Keep this fork's domain-templated WTI agent; the shared renderer still
needs the same search_web-only-when-tooled split, which follows next.

Co-authored-by: Cursor <cursoragent@cursor.com>
Port origin VectorInstitute#184 into the shared DomainConfig renderer: the base
instruction is tool-free, and news/code/tool factories append a
search supplement. Basic WTI configs were still being told to call a
tool they do not have.

Co-authored-by: Cursor <cursoragent@cursor.com>
Give the live-evaluation fork a public face distinct from the origin
atlas: a landing page that frames the repo as a bootcamp project, with
both posts assembled from the existing blog renderer.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ethancjackson
ethancjackson deleted the site-updates branch August 24, 2026 19:01
@ethancjackson
ethancjackson restored the site-updates branch August 24, 2026 19:02
@ethancjackson
ethancjackson deleted the site-updates branch August 24, 2026 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant