Repository navigation
Conversation
This was referenced Nov 7, 2026
- build_manifest.py exits 1, writing nothing, when it can't import PyYAML, instead of falling back to a subset parser that turned numbers into strings and dropped nested fields (which broke the Analyses page). It also stops, naming the file, on frontmatter that isn't a YAML mapping. The subset parser and the regex category fallback are gone. - The dashboard's manifest hooks run the builder through uv. manifest:safe keeps the committed manifest when the build can't run. - --check builds the manifest without writing it and exits 1 when the copy on disk differs anywhere but generated_at. A new CI job runs it on Linux under Python 3.11 and 3.14. - IDF comes from decimal's correctly rounded ln rather than math.log, which rounds as each platform's C library does; shared_terms break ties by term. - Overlap pairs stay in artifact order, so a one-skill edit rewrites only the scores it moves (#106's edit: 242 changed lines instead of 1,084). The drawer and the Duplicates view sort pairs by score themselves. - Tests: a builder without PyYAML, frontmatter types and errors, --check, overlap order, guards against the built-in sum() and math.log, and a Hypothesis property that overlaps ignore artifact and word order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anifest Python 3.15 has shipped (CPython is at 3.15.2), so the manifest job's newer entry moves from 3.14 to 3.15. The job's comment called its pair the oldest and newest Python the repo supports, which 3.14 no longer is. The test job already runs 3.15.2. On macOS, the committed manifest matches a fresh build under every Python from 3.11 to 3.15. --check printed a traceback when the file on disk held JSON that wasn't an object. It now says so and exits 1, and a test covers that case and invalid JSON. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#108 edited skills/policyengine-data/SKILL.md without rebuilding the manifest, so main's copy lacked that edit. Rebuilding adds the edited artifact, one new overlap pair and the 113 scores the edit moves, and updates repo_coverage. Built from the same corpus, main's builder and this branch's give the same 326 pairs and the same scores. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
force-pushed
the
manifest-pyyaml
branch
from
November 9, 2026 22:38
d7e187d to
cc0a9f7
Compare
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.
Closes the gaps #105 left in
scripts/build_manifest.pyand the dashboard's build hooks: its follow-up items 1 to 3, plus the diff-size problem #106 hit. Draft until CI passes on Linux and an independent review agrees.1. A missing PyYAML stops the build
main()prints how to run the script through uv and exits 1 before it writes anything.parse_frontmatterraises the same message for direct callers.parse_yaml_subset). Every frontmatter block in the repo's skills, agents, commands and analyses parses as a YAML mapping, so nothing needs it, and its output broke the Analyses page. The regex scan formetadata.categoryinload_skillsexisted only for that path, and no skill used it, so it went too.FrontmatterErrorthat names the file. Before, it dropped silently to the subset parser.dashboard/package.json,manifestrunsuv run python scripts/build_manifest.py.manifest:saferuns the same command and keeps the committed manifest when the build can't run.Before this PR,
/usr/bin/python3 scripts/build_manifest.py(macOS's Python 3.9.6, no PyYAML) exited 0. It wrote"child_poverty_pct_change": "-34.8"and"country": nullinto every analysis. Now:I ran the package.json scripts through bun, which runs the same script strings:
manifest, uv on PATHmanifest, no uv on PATHuv: command not found, exit 127, manifest untouchedmanifest:safe, no uv on PATHmanifest:safein a copy ofdashboard/alone/usr/bin/python32. CI checks that the manifest is fresh
--checkbuilds the manifest without writing it and compares it with the file on disk, withgenerated_atblanked in both. On a mismatch it prints the sections that differ, the first 200 diff lines and the command that fixes it, then exits 1. When the file on disk isn't valid JSON, or holds JSON that isn't an object, it says so instead of raising a traceback.manifestjob in.github/workflows/test.ymlruns--checkonubuntu-latestunder Python 3.11 and 3.15, the oldest and newest Python the repo supports. The existingtestjob already runs the suite under 3.15.compute_overlapsnow takes IDF from thedecimalmodule's correctly roundedln, notmath.log, which rounds however the platform's C library does. On macOS,math.logmisses the correctly rounded value for 44 of the 79,799 IDF ratios(n + 1) / (df + 1)with 2 ≤ n < 400. So a manifest built on a Mac could fail the Linux check whenever the artifact count hit one of those ratios. None of them occurs at today's 80 artifacts, so no score changes.manifestjobs report that the manifest I built on macOS matches a fresh build: under CPython 3.11.18 and 3.15.2 at the head, and under 3.11.18 and 3.14.10 at the first push. In a fresh clone, editing one skill without rebuilding makes the same command exit 1 and listartifacts, overlapsas the sections that differ.--checkmatches under Python 3.11.15, 3.12.14, 3.13.13, 3.14.7 and 3.15.2.shared_termsnow break exact ties by term, so their order never depends on where a word first appears in a text. On main's current corpus that reorders 7 of the 326 lists; in 3 of them a different term makes the 8-term cut.3. A test guards fsum
test_overlaps_never_use_builtin_sumswaps the built-insum(), asbuild_manifestsees it, for one that returns 1% more for floats, then checks thatcompute_overlapsreturns the same pairs. A manifest comparison would catch a return tosum()only on Python 3.11, wheresum([0.1] * 10)gives0.9999999999999999(3.12 on gives1.0). This test fails on every version.test_overlaps_never_use_the_c_librarys_logdoes the same formath.log.Mutation check: each of these edits to the builder makes its test fail:
sum()for the normsum()for the scoremath.logfor IDF--checkthat ignores contentRemoving only
main()'s PyYAML check changes nothing a user sees, sinceparse_frontmatterstill raises the same message, so that test still passes.test_check_fails_cleanly_on_a_malformed_manifestfails against this PR's first push, whose--checkraisedAttributeErroron a manifest holding[].4. Overlap diffs shrink
compute_overlapsno longer sorts pairs by score. They follow artifact order: bya, then byb.dashboard/src/data.tsexportsoverlapsByScore, a stable sort by score, andDrawer.tsx(first 8) andDuplicates.tsx(first 50) read it. A stable sort keeps tied scores in artifact order, the order the old manifest gave them, so both views show exactly what they showed before. I checked:policyengineskill's drawer: the same 8 pairs in the same order, three of them tied at 23%, checked the same two ways.repo_coveragechange. Built from the same corpus, main's builder and this branch's give the same 326 pairs and the same scores. The manifest diff changes about 3,900 lines, nearly all from reorderingoverlapsonce.5. Left out: the 6,000-character cap in
infer_target_repos47 of the 80 artifacts have bodies longer than 6,000 characters. Dropping the cap adds 66 artifact-to-repo links across 26 artifacts. It would also make a separate bug worse: aliases match as substrings. "SSI" inside "missing" tags 17 artifacts as policyengine-us, "PIP" inside "pipeline" tags 11 as policyengine-uk, and "GIS" inside "registry" or "legislative" tags others as policyengine-canada. Word-boundary aliases on their own remove 64 links. Both changes move
repo_coverageenough to need their own review, so they belong in a follow-up.Invariants
generated_at, whatever the hash seed (tests), the Python version from 3.11 to 3.15 (macOS runs of each; CI checks 3.11 and 3.15 on Linux), or the platform (CI on Linux against the manifest I built on macOS).--checknever writes.overlapslists each pair once,abeforeb, in artifact order.shared_termsdepend only on the words in the corpus, not on the order of artifacts or of words within a text (Hypothesis property test).sum()or the C library'slogrounds.Tests
uv run pytest --ignore=tests/test_skill_examples.py: 222 passed (Python 3.14.7, macOS). CI'stestjob runs the same suite under CPython 3.15.2 on Linux.tests/test_build_manifest.py: 19 passed under Python 3.11 too.bun run build(tsc -b && vite build) passes.Other PRs that touch the manifest
Rebase onto main and regenerate with
uv run python scripts/build_manifest.pyrather than hand-merging; this PR did that on top of #108. The open drafts #100 and #109 to #112 all change files that feed the manifest, so once this lands, the newmanifestcheck will fail each of them until it does the same.axiom: n/a: tooling (dashboard manifest builder, hooks and CI), no policy change.
🤖 Generated with Claude Code