Skip to content

Commit ed5f3c7

Browse files
mikolalysenkoclaude
andcommitted
Gradle hosted/vendored: review round 1 fixes
Hosted: - A rescan sets the pom and module entries of an existing suffixed verification component, so a component written before the service served the suffixed .module gains it (Gradle fails verification of the .module it then downloads otherwise). - A new patch of the same GAV drops the replaced patch's verification component when it is still as written (else redirect_gradle_verification_component_left). - Locks and strictly versions above the base are no longer conflicts (decision 3): only versions at or below the base refuse. - The fallback snippet follows the owned script's rules (rewrite only selectors admitting the base, reject only candidates at or below it, no strictly / implementation line) instead of forcing every request down to the patched base. - New redirect_gradle_dynamic_selector_pinned: a dynamic or range selector admitting the base is pinned like a lock; docs no longer promise VEX withholding for unlocked builds. - Discovery re-runs the planner's build- and GA-level refusals (settings classpath, unresolved includeBuild, Android/KMP, classifier, exclusiveContent), so a build changed after the scan stops attesting. Vendored: - The verification-file revert is line-ending blind (autocrlf checkouts left the patched jar hash behind and broke the upstream build). - Classifier jars the tree serves get their upstream sha256 in an existing verification file (no .asc is served). - A non-UTF-8 gradle-index.tsv is unreadable, not absent: the revert of one patch no longer unwires every other. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent d69a672 commit ed5f3c7

7 files changed

Lines changed: 820 additions & 188 deletions

File tree

‎crates/socket-patch-cli/CLI_CONTRACT.md‎

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,19 +1757,27 @@ The script routes the suffixed version to its Socket repository with
17571757
`exclusiveContent`, substitutes every request whose selector admits the base (direct,
17581758
transitive, ranges, dynamic and rich versions), rejects every other candidate at or
17591759
below the base, and fails the build (`socket-patch: … resolved …`) if anything still
1760-
resolves there; it also checks the jar's sha256 against the index. Versions above the
1761-
base resolve (a newer upstream fix); `vex` then withholds the attestation until a
1762-
rescan. Detached configurations (`configurations.detachedConfiguration`) are not
1763-
reached.
1760+
resolves there; it also checks the jar's sha256 against the index. A request whose
1761+
selector does not admit the base (an explicit newer version, a lock or `strictly` above
1762+
the base, a transitive bump) is left alone and resolves above the base (a newer
1763+
upstream fix is never downgraded); `vex` withholds the attestation when a lock entry
1764+
records such a version, and otherwise judges the installed suffixed copies. A dynamic
1765+
or range selector that admits the base is pinned like a lock: it resolves the patched
1766+
version even after a newer upstream release appears (the Socket repository lists no
1767+
versions), reported as `redirect_gradle_dynamic_selector_pinned`. Detached
1768+
configurations (`configurations.detachedConfiguration`) are not reached.
17641769

17651770
A dep is **confirmed** (`redirected`, attested) only when the final files hold the
17661771
socket-patch script, the live apply line with the current digest in every target
17671772
settings file, the index row, and the suffixed version in every lock entry of the GA
17681773
(`confirmed_gradle_uuids`); anything else is not counted. `list`, `vex`, `rollback`,
17691774
`remove`, `vendor` and `repair` discover hosted Gradle pins from the index under the
17701775
same rules (a settings-classpath lock naming the GA, a stale digest, a custom
1771-
`lockFile`, a non-Socket URL or a lock at another version is `patched_ref_invalid`,
1772-
no reference). `rollback` / `remove` restore without the network: lock entries back to
1776+
`lockFile`, a non-Socket URL, a lock at another version, or any build- or GA-level
1777+
refusal of the planner holding now — a settings-classpath declaration, an
1778+
`includeBuild` it cannot follow, an Android / KMP plugin, a classifier request, a user
1779+
`exclusiveContent` rule — is `patched_ref_invalid`, no reference). `rollback` /
1780+
`remove` restore without the network: lock entries back to
17731781
the base, the row out of the index, the verification component out when it is still
17741782
exactly what the planner wrote (else `gradle_verification_component_left`), and the
17751783
owned files and apply lines once no row is left.
@@ -1781,7 +1789,9 @@ eject (`vendor` over hosted pins) snapshots every Gradle wiring file before it
17811789
restores, so a failed vendor step rolls the whole build back byte-exact.
17821790

17831791
Refusals write nothing for the dep and are followed by `redirect_gradle_manual_snippet`
1784-
(a per-DSL `exclusiveContent` snippet with the suffixed version):
1792+
(a per-DSL snippet applying the owned script's rules for this dep: `exclusiveContent`
1793+
for the suffixed version, every request whose selector admits the base rewritten to it,
1794+
and every other candidate at or below the base rejected; it declares no dependency):
17851795

17861796
| Code | Cause |
17871797
|---|---|
@@ -1795,20 +1805,25 @@ Refusals write nothing for the dep and are followed by `redirect_gradle_manual_s
17951805
| `redirect_gradle_vendored_conflict` | The GA is vendored (`.socket/vendor/gradle-index.tsv`); `vendor --revert` first. |
17961806
| `redirect_gradle_settings_classpath` | The GA is on a settings-script classpath (declared, or named in any `settings-gradle.lockfile`), which resolves before the script runs. |
17971807
| `redirect_gradle_classifier_declared` | A declaration requests a classifier the Socket repository does not serve. |
1798-
| `redirect_gradle_range_declared` | A `strictly` constraint excludes the patched base version. |
1808+
| `redirect_gradle_range_declared` | A `strictly` constraint excludes the patched base version and admits nothing above it. |
17991809
| `redirect_gradle_exclusive_content_conflict` | A user `exclusiveContent` rule routes the group to another repository. |
18001810
| `redirect_gradle_version_conflict` | The index already pins the GA at another base, or two patches pin it in one run. |
1801-
| `redirect_gradle_lock_conflict` | A lock entry names the GA at a version that is neither the base nor the suffixed one; re-lock (`--write-locks`) first. |
1811+
| `redirect_gradle_lock_conflict` | A lock entry names the GA below the base (and not at the suffixed version); re-lock (`--write-locks`) first. A lock above the base is a newer upstream release the pin lets resolve, not a conflict. |
18021812
| `redirect_gradle_verification_unparseable` | `gradle/verification-metadata.xml` cannot be edited. |
18031813

18041814
Warnings on a confirmed run: `redirect_gradle_detached_configs_unguarded` (always:
1805-
detached configurations are not reached), `redirect_gradle_unscanned_build_logic`
1815+
detached configurations are not reached), `redirect_gradle_dynamic_selector_pinned` (a
1816+
declaration's dynamic or range selector admits the base, so it stays on the patched
1817+
version while the patch is in place), `redirect_gradle_verification_component_left`
1818+
(a replaced patch's verification component was edited by hand, so it is kept; an
1819+
unedited one is removed with its row), `redirect_gradle_unscanned_build_logic`
18061820
(build logic the graph could not follow, so a declaration, lock or repository there
18071821
is unchecked) and `redirect_gradle_module_metadata_unavailable` (the grant carries no
18081822
`mavenModuleSha256`: the Socket repository serves no suffixed `.module`, so Gradle
18091823
falls back to the pom and the upstream module's variants and capabilities are not
18101824
applied). When it does, the suffixed `.module` and its digest go into the
1811-
verification component. File edits in `rewrittenFiles` / the edit list carry the kinds
1825+
verification component, also on a rescan of a component written before the service
1826+
served it. File edits in `rewrittenFiles` / the edit list carry the kinds
18121827
`redirect_gradle_hosted_index`, `redirect_gradle_hosted_script`,
18131828
`redirect_gradle_gitattributes`, `redirect_gradle_settings_apply`,
18141829
`redirect_gradle_lock_entry` and `redirect_gradle_verification_component`. The
@@ -1838,7 +1853,10 @@ A root holding both `pom.xml` and a Gradle build vendors both in one ledger entr
18381853
(#395); either half refusing writes nothing. A derived
18391854
`.socket/vendor/gradle/<group-path>/<artifact>/maven-metadata.xml` keeps range,
18401855
prefix and rich selectors on the vendored version (#511). Existing pgp-only
1841-
verification entries get a `sha256` beside them (#487). The owned script, index,
1856+
verification entries get a `sha256` beside them (#487), and so do the classifier jars
1857+
the tree serves (a declared classifier, the IDE sources): the vendored repository
1858+
serves no signatures, so each gets its upstream `sha256` unless its entry already
1859+
holds a checksum. The owned script, index,
18421860
derived metadata and `.gitattributes` are compared line-ending blind (#429). Ledger
18431861
fragments use the kinds `gradle_settings_fragment`, `gradle_verification_fragment`,
18441862
`gradle_derived_metadata`, `jvm_owned_file`, `jvm_vendor_tree`, `jvm_created_dir`

0 commit comments

Comments
 (0)