Repository navigation
feat: B4a search.fit breakdown cell, profiling-summary@2 exporter, Pages board, epic-1 table - #3
Merged
Conversation
…board (B4a)
- scripts/gaussian_x1/nautilus/search_fit_breakdown.py: re-homes
autofit_workspace_developer/searches_minimal/nautilus_profile.py as an
axis: breakdown cell. Times one af.Nautilus search.fit (exclusive
component wall: NN training, bound geometry, proposal sampling,
likelihood, checkpoint I/O, sampler bookkeeping, samples output,
visualisation, other) and re-runs the bare-sampler measurement as the
reproduction gate against the findings page (+-10 pp).
- results/gaussian_x1/nautilus/breakdown{,_bare_sampler}.json: laptop CPU
rows, median of 3 fresh fits.
- scripts/misc/tooling/build_catalogue.py: thin stdlib exporter to
dashboard/catalogue.json (profiling-summary@2), index.html and the
project badge feed state.json; --check and --validate-with PULSE.
- scripts/misc/test: stdlib-only tests; lint.yml runs them plus the
catalogue up-to-date + Pulse-validator check.
- .github/workflows/pages_dashboard.yml: publish dashboard/ to Pages and
dispatch pulse-refresh to PyAutoPulse.
- wiki/campaigns/search_fit_breakdown.md (findings, re-homed) and
search_fit_bottlenecks.md (epic-1 ranked table + likelihood_share).
Closes #2
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.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.
Summary
Search-extensibility B4a:
autofit_profilinggets its first measurement and becomes a PyAutoPulse producer. The Nautilussearch.fitanatomy fromautofit_workspace_developer/searches_minimal/is re-homed as abreakdowncell, run on the laptop CPU, published as a thinprofiling-summary@2catalogue with a Pages board and apulse-refreshdispatch, and epic 1's ranked bottleneck table is written up withlikelihood_sharefrom autofit_inference.Closes #2. Merge order: this PR first, then PyAutoPulse (the
fitregistry row reads the published catalogue), then the autofit_workspace_developer deletion PR.Per step
Contract read — Pulse
REFERENCE.mdv2 section,pulse/summary.py::classify, autolens_profilingbuild_catalogue.py(shape only) andpages_dashboard.yml, and the Mind recordcomplete/2026/10/pulse-refresh-project-identity.md.Breakdown cell —
scripts/gaussian_x1/nautilus/search_fit_breakdown.py. Monkey-patches the nautilus internals (NeuralNetworkEmulator.train,NautilusBound.compute,Sampler.sample_shell/evaluate_likelihood/write/write_shell_update/run) and PyAutoFit's output path (SearchUpdater._save_samples/_compute_latent_samples/_profile_and_summarize/visualize,NonLinearSearch.pre_fit_output/post_fit_output). It charges exclusive wall time through a stack timer (scripts/misc/profiling/exclusive_timer.py), so nested calls are never double-counted andother= wall − instrumented. There are two variants:search_fit: the fullaf.Nautilus(...).fit, written toresults/gaussian_x1/nautilus/breakdown.json.bare_sampler: the findings page's own bare-nautilus.Samplermeasurement re-run as the reproduction gate, written tobreakdown_bare_sampler.json. The cell exits 1 if NN training, bound geometry or likelihood fall outside ±10 pp of the findings page.Both use seed 1 and are deterministic in calls (7 501 and 16 400 likelihood calls in every repeat). Each is the median of 3 fresh fits. The findings prose is in
wiki/campaigns/search_fit_breakdown.md, with a new §0 for the re-measurement.Exporter —
scripts/misc/tooling/build_catalogue.py(stdlib, about 300 lines). It turnsresults/**/*.jsonintodashboard/catalogue.json,index.htmlandstate.json, with one setup per variant, onebreakdownrecord per component plus aruntimewall record, and an explicit selection for each. A zerocheckpoint_io(the bare sampler writes no checkpoint) becomes aninapplicableslot, not a zero record. Every record isunreviewed. Rendering is deterministic because the stamp is the newestmeasured_at. Use--checkfor staleness and--validate-with PULSEto run Pulse's ownclassify. Tests are inscripts/misc/test/.lint.ymlnow runs pytest plusbuild_catalogue.py --check --validate-with _pulse(PyAutoPulse checked out after ruff).Pages + dispatch —
.github/workflows/pages_dashboard.ymlmirrors autolens_profiling's workflow. It validates the catalogue with Pulse and the badge feed with Brainboard/_state.py, deploysdashboard/, then sendsrepository_dispatch: pulse-refresh(repo, sha,dashboard/catalogue.json) usingPAT_PYAUTOLABS. Without the secret it warns and exits 0.state.jsonusesorgan: autofit_profiling, following the project-feed identity in the Mind record.(PyAutoPulse PR, separate.)
Epic-1 table —
wiki/campaigns/search_fit_bottlenecks.md. Epic 2 is not opened.(autofit_workspace_developer PR, separate.)
Measured breakdown (laptop CPU,
DESKTOP-H143S82, WSL2 8 cores, numpy fp64, PyAutoFit911fe05e1= 2026.10.12.1+1, nautilus 1.0.5, n_live 200, n_networks 4, 1 core)Reproduction (bare sampler): wall 22.5 s (repeats 23.1/22.5/21.8). log Z −57.455, the same as the findings reference.
All three gated shares are within ±10 pp, so the cell exits 0.
search.fit (epic 1): wall 28.4 s (25.8/28.4/28.9), 7 501 calls. Shares of wall:
likelihood_sharecross-check: B3 Nautilus numpy has a median of 1.9 % (n=11), and Nautilus JAX CPU about 0.01 %.Pages status
Pages is enabled (
gh api repos/PyAutoLabs/autofit_profiling/pages -X POST -f build_type=workflowreturnedbuild_type: workflow,html_url: https://pyautolabs.github.io/autofit_profiling/). It is not live yet: the URL returns 404 untilpages_dashboard.ymlruns on main after this merges, because it triggers ondashboard/**pushes to main. I could not verify that the org secretPAT_PYAUTOLABSis visible to this new repo (reading org secrets needs admin:org). If it isn't, the deploy still succeeds and the dispatch step only warns. In that case, run Pulse'sdashboard_refresh.ymlby hand.Validator output (tail)
Decisions taken
nautilus.Sampler, while a PyAutoFitsearch.fitdiffers in three ways: it checkpoints (24.5 %), stops atn_eff=500(7 501 calls against 16 400), and has a cheaper per-call likelihood (about 43 µs throughFitnessagainst about 160 µs through the bare script'sinstance_from_vector). Its likelihood share (1.2 % sampler-internal) therefore cannot reproduce 14.3 %. The reproduction gate runs on the faithful bare-sampler variant, and thesearch_fitrow records its comparison as information only (gates_reproduction: false).search.fit. Its numbers stay quoted on the findings page.likelihood_sharesource.catalogue/search_catalogue.jsonhas nolikelihood_sharefield on main900648b5or onfeature/search-ext-b3-postmerge-fixes637713b2(it aggregates legs by task). The per-run values come from autofit_inferencedashboard/summary.json(inference-summary@1) at637713b253ab149f87a08ea0b02fcb009b4aa24e. The values are identical on main.config/general.yamlonly disables the workspace version check, so the cell measures what a user'ssearch.fitpays. Visualisation is PyAutoFit's search-level default; there is no custom Analysis visualiser.validation: unreviewed, withqualified: truebecause provenance is complete. Pulse never judges, and the profiling conductor has not reviewed these numbers.producer_revision: null. The catalogue is committed alongside the rows it describes, so no self-referencing SHA is possible.generated_atis the newestmeasured_at, which keeps--checkdeterministic.runtimerecord (metric: wall) and components arebreakdownrecords. Shares are not catalogue records, because a breakdown unit must bes. They are shown onindex.htmland in the result rows.status: greenwith a neutral headline. It reads "baseline only, not a verdict", and the Brain cockpit reads the Pulse organ feed, not this one.Tests
pytest -q scripts/misc/test: 11 passed. The exclusive timer has 4 tests. The exporter has 7, including the committed catalogue being current, the committed rows validating with the Pulse reader, and the Pulse reader refusing a broken unit.ruff check .andruff format --check .are clean.build_catalogue.py --check --validate-with ../PyAutoPulsereportsok.board/_state.py dashboard/state.jsonreportsstate: ok.🤖 Generated with Claude Code