Skip to content

Tracking: hosted rewriters behind one HostedRewriter trait with a per-dependency outcome #1075

Description

[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: E31.

Kind: tracking. Source: review §2.1 and Part 3.7 recommendation 2; register E31.

Problem

Verified on main 05ecc6e. Hosted mode has no rewriter abstraction. Each rewriter is a free function fn(&BTreeMap<String,String>, &[DepOverride], &mut RewriteResult), and each one reports which patches it pinned by writing to its own field of a shared struct.

  • RewriteResult now holds 27 per-ecosystem uuid sets (20 at the review): for example confirmed_cargo_uuids, refused_pdm_uuids, yarn_berry_uuids, vlt_foreign_uuids, gradle_uuids, confirmed_sbt_uuids and refused_sbt_uuids. There are four meanings, spelled ad hoc per ecosystem:
    • owned: this rewriter decides the uuid (yarn_berry_, python_lock_, hatch_, gradle_);
    • confirmed: the pin landed;
    • refused: the rewriter declined it;
    • foreign: vlt_foreign_, plus bundled_skipped_.
  • merge_group_delta destructures and extends every field by hand.
  • engine::confirm is 225 lines. It is an ordered chain of 25 ProbeStep outcomes keyed on purl prefixes, pdm_drives(files), vlt_drives, binary_bun, sbt::maven_confirmation and those sets. Precedence is encoded only by the order of the ifs (vlt before binary bun, pdm before hatch, sbt before Gradle).
  • The CLI reads four of the sets directly (scan/hosted.rs#L1215, #L1245-L1246, #L1339). vex/discover/gradle.rs and upstream/gradle.rs also reach into the Gradle sets.
  • rewriter_groups is a hand-wired Vec<Box<dyn Fn>> of 11 groups. Each rewriter filters its own deps with string compares (ecosystem == "…": 12 in redirect/mod.rs, 15 in hosted/engine.rs).

Adding an ecosystem to hosted mode still means editing these parallel tables:

  • formats::registry::REGISTRY;
  • upstream::format_of and restore_pass;
  • engine::file_ecosystem;
  • memory::select::classify;
  • roots::UNSUPPORTED_MARKERS;
  • rewriter_groups;
  • the RewriteResult fields, merge_group_delta and confirm().

The sbt support added in #690 shows the cost: two new sets, new fields in merge_group_delta, and a three-way sbt/Gradle/pom precedence block inside confirm().

Symptoms

Impact: every hosted ecosystem change touches the same three hot spots, which serializes concurrent hosted PRs on mod.rs and engine.rs.

Target design

pub enum DepStatus { Confirmed, Refused, Foreign, Skipped }
pub struct Outcome { files, binary_files, edits, warnings, per_dep: BTreeMap<String /*uuid*/, (Rewriter, DepStatus)> }
pub trait HostedRewriter {
    fn id(&self) -> Rewriter;
    fn ecosystem(&self) -> Ecosystem;
    fn drives(&self, files: &FileSet) -> bool;      // pdm/vlt/uv/sbt "driver" rules
    fn rewrite(&self, files: &FileSet, deps: &[&DepOverride]) -> Outcome;
}
  • confirm() becomes: if the driving rewriter for the candidate's ecosystem reported a status, use it, otherwise use the needle probe.
  • The CLI reads Outcome accessors, never per-ecosystem fields.

Checklist (each item one PR)

Dependencies

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)priority:p3refactorStructural change: duplicated code or logic, missing abstraction, layering, dead code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions