Pin the AVE side of six crosswalks to the tree each count was read at - #194
Merged
chaksaray merged 2 commits intoAug 22, 2026
Merged
Conversation
… count was read at Six endpoints across six crosswalk files state a record_count with no commit pinning the tree that count describes, so a reader cannot re-derive the number without counting the upstream corpus by hand. All six are the AVE side, and AVE is this repository, so each one pins to a commit on main. ave-to-ast10 source, clawscan target and skillspector target state 56 and pin 38b6cf0, which is the commit that brought records/ to 56. cfgaudit target states 70 and 51 static and pins 71b3e53. nova-proximity and ramparts targets state 76 and 57 static and pin a97254d. Every pin was chosen by reading the tree rather than by picking a nearby tag or branch head: at each commit, the number of records/AVE-*.json files equals the stated record_count and the number of records whose detection_stage is static_detection equals the stated static_record_count. The derivation was checked first against semia-to-ave, which already carries a pin, and it reproduces both of that file's numbers exactly. Each commit is an ancestor of main and was taken from main's own history. Where a count is unchanged across a run of commits, the pin names the commit that established it rather than an arbitrary later one in the same run, so the choice is reproducible from the history instead of being a preference.
… not under url check_declared_unpinnable_has_no_repository read only the url field, so it refuted a false unpinnable declaration when the repository happened to sit under that one key and missed it otherwise. That is a fact about where an author put a link, not about the declaration. The endpoint definition sets additionalProperties true, and two sides in this repository already carry a repository somewhere other than url: the AST10 side of ave-to-ast10 carries its OWASP project page under url and its repository under github, and the ClawScan side carries the repository under url and the project site under site. The AST10 side is the concrete miss. Declaring it unpinnable would pass the offline check, and the network probe would agree for the same reason, because it probes the project page and correctly finds no history behind it. A false declaration would read as clean twice. The check now scans every field on the endpoint and names the field it found, which is the same contract its docstring already stated: an exemption nobody can check is not a declaration. No endpoint in the repository declares itself unpinnable today, so no verdict changes. Both new tests fail without the widening and pass with it.
This was referenced Aug 20, 2026
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.
This is step 2 of the sequence on #126, the backfill. It pins the AVE side of every crosswalk that states a record count, and it fixes a hole in the check that guards the unpinnable declaration. Two things I told you in #126 were wrong, and both are corrected here rather than left for review to find.
The first is the count. I said four crosswalks. It is six endpoints across six files, and the repository's own validator says so on a clean checkout of main. Running python scripts/validate_crosswalks.py before this change prints six warnings: ave-to-ast10.json source, cfgaudit-to-ave.json target, clawscan-to-ave.json target, nova-proximity-to-ave.json target, ramparts-to-ave.json target, and skillspector-to-ave.json target. The two I missed are nova-proximity and ramparts, both added after I wrote the plan and both stating a count of 76. Had the backfill covered only the four I named, step 3 would have hard-failed the moment you made the field required, on two files nobody had looked at. After this change the same command prints nine ok lines and zero warnings.
The second is worse, because it was the part of the plan you singled out. I said ave-to-ast10.json would declare itself unpinnable, on the reasoning that the OWASP AST10 project is a published site with no repository to pin. The warning on that file is not on the AST10 side at all. It is on the source, and the source is AVE, which is this repository, which has a history and pins like any other. So the unpinnable declaration I described was never needed there. Worse, if it had been written on the side I claimed it belonged to, it would have been false: the AST10 endpoint carries a
githubvalue of https://github.com/OWASP/www-project-agentic-skills-top-10 alongside its owasp.org project page. That means the example I gave you of the three outcome design meeting a real non pilot case does not exist. This backfill contains six real commits and zero unpinnable declarations, and the first live use of that declaration is still ahead of us.That second error also exposed a hole in the check, which is the other commit here.
check_declared_unpinnable_has_no_repositoryreads only theurlfield. The endpoint definition setsadditionalProperties: true, so a side may describe itself with as many URL bearing fields as it needs, and two sides in this repository already do: AST10 carries its project page under url and its repository under github, and ClawScan carries the repository under url and its project site undersite. A check reading one key of an open ended object refutes a false declaration only when the repository happens to sit under the key it looks at, which is a fact about where an author put a link rather than anything about the declaration. The network probe reaches the same wrong verdict by a different route: it would probe the owasp.org page, correctly find no history behind it, and emit the note saying the declaration is unrefuted. A false declaration would have read as clean twice, and the endpoint it would have read as clean on is the exact one my plan proposed to declare. The docstring on that check already states the contract it was missing, that an exemption nobody can check is not a declaration but the box anything awkward gets put in, so this is the check meeting its own stated bar rather than a new requirement. It now scans every field on the endpoint and names the field it found. No endpoint in the repository declares itself unpinnable today, so no verdict changes anywhere. Both new tests fail without the widening and pass with it, which I checked by reverting the script and rerunning.On how the pins were chosen, I have taken your correction and it is the better statement. The failure on #160 was not that develop was the wrong branch. It was presenting a commit as verified history without confirming where it came from. So every pin here was read rather than inferred. All six are the AVE side, so all six are commits in this repository, which makes them checkable without leaving the tree. The ave-to-ast10 source, the clawscan target and the skillspector target state 56 and pin 38b6cf0, the commit that brought records/ to 56. The cfgaudit target states 70 records and 51 static and pins 71b3e53. The nova-proximity and ramparts targets state 76 and 57 static and pin a97254d. At each of those commits the number of records/AVE-*.json files equals the stated
record_count, and the number of records whosedetection_stageis static_detection equals the statedstatic_record_count. I checked that derivation first against semia-to-ave.json, which already carries a pin, and it reproduces both of that file's numbers exactly, so the method was proved on a case you had already accepted before I applied it to six you had not. Each commit was taken out of main's own history and each is an ancestor of main.One detail worth stating rather than leaving implicit. Where a stated count is unchanged across a run of commits, more than one tree re-derives it, and I cannot know which one was actually in front of whoever generated the crosswalk. Rather than pick one and present it as the tree that was read, each pin names the commit that established the count, which is the one commit in that run identifiable from the history instead of chosen. Every crosswalk's generated date falls inside the run its pin opens.
There is a third thing, which is not an error in the plan but does affect the change you are about to write, so it is better said now than discovered by your CI. I simulated step 3 two ways against the backfilled corpus. Promoting the field into the required list on the endpoint definition outright fails four more endpoints, all of them tool sides that state no record count and were therefore never covered by the warning: the AST10 side of ave-to-ast10, and the cfgaudit, ClawScan and SkillSpector sides of their files. Scoping the requirement to endpoints that state a count leaves all nine files green. SkillSpector is the one we already agreed has no resolvable version upstream, so the blunt form would reopen that. I did not pin those four, because guessing which upstream tree a tool crosswalk was read against is exactly the move your #160 correction rules out, and if you want them pinned it is a separate piece of work with real reading behind it. Which form step 3 takes is your call, and this backfill closes the count scoped form completely.
The repository's three validators and the test suite all pass on this branch. The record validator reports all 80 records valid, with the six pre-existing researcher attribution warnings unchanged. The crosswalk validator reports 9 of 9 valid with no warnings, down from six. The fixture checker reports all 80 records have positive and negative fixtures. The test suite passes 341 tests, up from 339.
The two commits are separate and the second one stands alone, so if you would rather review the check widening as its own pull request I will split it out and rebase this down to the six line backfill. I kept them together because the hole in the check is what my own plan walked into, and reading them apart loses why the widening is worth having.