Site updates - #193
Closed
ethancjackson wants to merge 125 commits into
Closed
Conversation
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>
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.