[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.
Kind: tracking. Source: review Part 5.4 ("XML: eight hand-rolled scanners"), Maven/Gradle half; register E10. The NuGet half is #594.
Problem
On main @ 045d7ec, pom.xml is read or edited by seven independent scanners. Each has its own rules for comments, CDATA, profiles, plugin <dependencies>, <exclusions> and tag boundaries:
| # |
Where |
Used by |
Comments / CDATA |
Scoping |
| 1 |
formats/maven/mod.rs#L55-L104 parse_pom (+ blank_non_markup, open_tags, elements L212-L304) |
VEX discovery, restore gate |
both blanked, offsets kept |
skips build/reporting/pluginRepositories/distributionManagement, profiles and <exclusions> |
| 2 |
patch/redirect/mod.rs#L6052-L6099 MAVEN_DEPENDENCY_BLOCK_RE + maven_tag_inner_range; insert_maven_repository / insert_maven_dependency_management L6510-L6545 |
hosted rewrite |
none |
none; first <groupId> in the block wins (an exclusion's, if it comes first) |
| 3 |
patch/redirect/upstream/maven.rs#L59-L111 `dep_matches`, `dm_sections`; [`modules` L221-L233](https://github.com/SocketDev/socket-patch/blob/045d7ec783d788bf3c5a1310724b51e09fb6505d/crates/socket-patch-core/src/patch/redirect/upstream/maven.rs#L221-L233)`` |
upstream restore |
none |
none (reuses #2's regex) |
| 4 |
vendor/maven_repo.rs#L1519-L1625 find_wireable_anchor, comment_spans, profiles_spans; declares_modules / strip_xml_comments / real_open_tag L1660-L1706 |
vendored single-pom |
comments only |
profiles only |
| 5 |
vendor/jvm/maven_reactor.rs#L1638-L1712 mask + Doc::parse (a nested tree with parent links) |
vendored reactor |
comments, CDATA, PIs |
full tree |
| 6 |
vendor/jvm/maven_reactor.rs#L2189-L2330 scan_pom_project (a port of depscan's maven-pom-scan.ts), in the same file as #5 |
suffixed upstream pom |
comments, CDATA, PIs |
project children |
| 7 |
crawlers/maven_crawler.rs#L80-L240 line scanner parse_pom_group_artifact_version; vex/product.rs#L218-L300 parse_pom_xml / xml_element_texts |
crawler, VEX product |
per-line / own |
own |
The writers (#2, #3, #4) never use the readers (#1, #5), so a writer can edit an element the reader says does not exist, and the reverse.
Symptoms
#259 (hosted edits commented-out, plugin and profile markup), #342 (a second <repositories> / <dependencyManagement> when the existing one is self-closed or commented), #683 (<exclusions> first: the direct literal isn't matched), #260 (confirmation by substring, so the scan and VEX disagree), and #716 (two declares_modules disagree, so a single-module EAR pom is refused).
Impact: the symptoms above are open bugs, and each comes from a scanner that the other modes don't share. Each fix today has to be made two or three times.
Target design
One masked element scanner in formats::maven. Comments, CDATA and PIs are blanked with offsets kept, the result is a tree with parent links (the shape of maven_reactor::Doc), and scope queries are built on it (project-level vs profile vs build/plugin, <exclusions> excluded). Readers (VEX, crawler, product) and splicing writers (hosted, restore, vendored, reactor) locate elements through it. Writers keep their own byte-splices; only the locating is shared.
Checklist (one PR each)
Out of scope: line-ending policy for inserted blocks (#273; E16), Maven model semantics (parents, BOM imports, profile activation).
Acceptance criteria
Dependencies
Not blocked. Overlaps E26 (two Maven backends) and E38 (product probes). #690 (sbt/Mill) touches maven_reactor.rs and maven_crawler.rs, so land the move child after it.
[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.
Kind: tracking. Source: review Part 5.4 ("XML: eight hand-rolled scanners"), Maven/Gradle half; register E10. The NuGet half is #594.
Problem
On main @
045d7ec,pom.xmlis read or edited by seven independent scanners. Each has its own rules for comments, CDATA, profiles, plugin<dependencies>,<exclusions>and tag boundaries:formats/maven/mod.rs#L55-L104parse_pom(+blank_non_markup,open_tags,elementsL212-L304)<exclusions>patch/redirect/mod.rs#L6052-L6099MAVEN_DEPENDENCY_BLOCK_RE+maven_tag_inner_range;insert_maven_repository/insert_maven_dependency_managementL6510-L6545<groupId>in the block wins (an exclusion's, if it comes first)patch/redirect/upstream/maven.rs#L59-L111`dep_matches`, `dm_sections`; [`modules` L221-L233](https://github.com/SocketDev/socket-patch/blob/045d7ec783d788bf3c5a1310724b51e09fb6505d/crates/socket-patch-core/src/patch/redirect/upstream/maven.rs#L221-L233)``vendor/maven_repo.rs#L1519-L1625find_wireable_anchor,comment_spans,profiles_spans;declares_modules/strip_xml_comments/real_open_tagL1660-L1706vendor/jvm/maven_reactor.rs#L1638-L1712mask+Doc::parse(a nested tree with parent links)vendor/jvm/maven_reactor.rs#L2189-L2330scan_pom_project(a port of depscan'smaven-pom-scan.ts), in the same file as #5crawlers/maven_crawler.rs#L80-L240line scannerparse_pom_group_artifact_version;vex/product.rs#L218-L300parse_pom_xml/xml_element_textsThe writers (#2, #3, #4) never use the readers (#1, #5), so a writer can edit an element the reader says does not exist, and the reverse.
Symptoms
#259 (hosted edits commented-out, plugin and profile markup), #342 (a second
<repositories>/<dependencyManagement>when the existing one is self-closed or commented), #683 (<exclusions>first: the direct literal isn't matched), #260 (confirmation by substring, so the scan and VEX disagree), and #716 (twodeclares_modulesdisagree, so a single-module EAR pom is refused).Impact: the symptoms above are open bugs, and each comes from a scanner that the other modes don't share. Each fix today has to be made two or three times.
Target design
One masked element scanner in
formats::maven. Comments, CDATA and PIs are blanked with offsets kept, the result is a tree with parent links (the shape ofmaven_reactor::Doc), and scope queries are built on it (project-level vs profile vs build/plugin,<exclusions>excluded). Readers (VEX, crawler, product) and splicing writers (hosted, restore, vendored, reactor) locate elements through it. Writers keep their own byte-splices; only the locating is shared.Checklist (one PR each)
declares_modulescopy (bug, can start now)<dependency>/<repositories>/<dependencyManagement>through the masked, scoped scan (can start now)build_repo_edit(comment_spans/profiles_spans/find_outside) onto the same scan; the vendored half of Maven pom rewrites add a second <repositories> or <dependencyManagement> section when the existing one is self-closed or has a comment before <dependencies>, so Maven refuses the pom #342maven_reactor::{mask, Doc}intoformats/maven(mechanical), rebuildparse_pomandscan_pom_projecton it, and deleteblank_non_markup/open_tags/elements/scan_*parse_pom_group_artifact_versionandvex/product.rsparse_pom_xmlread throughformats::maven(coordinate with E38)verification-metadata.xml(gradle.rsmask_xml_comments/xml_attr/xml_elements) and NuGet (Read and splice nuget.config through formats::nuget in hosted, vendored and restore #594) share the masking primitive (a smallformats::xml)Out of scope: line-ending policy for inserted blocks (#273; E16), Maven model semantics (parents, BOM imports, profile activation).
Acceptance criteria
grep -rn '"<!--"' crates/socket-patch-core/srcfinds no pom-specific comment handling outsideformats/maven_reactortests,vex::discover::maventests ande2e_vendor_jvm_buildstay greenDependencies
Not blocked. Overlaps E26 (two Maven backends) and E38 (product probes). #690 (sbt/Mill) touches
maven_reactor.rsandmaven_crawler.rs, so land the move child after it.