Skip to content

Decide vendor mechanism: how downstream consumers ingest canonical #93

@lezama

Description

@lezama

Problem

The convergence audit (#77) step 7 says "vendor canonical via git subtree" — but that decision deserves an explicit discussion before any downstream consumer commits to a path. Different mechanisms have different versioning/maintenance/contribution properties, and the project should pick one and document it before adopters diverge.

Three plausible mechanisms

A. git subtree

Downstream pulls canonical's main (or a tagged ref) into a subdirectory of its own repo, e.g. mu-plugins/agents-api/ for a host plugin. Periodic git subtree pull refreshes the subtree.

  • Pros: Simple to set up. Source is in the consumer's working tree, easy to grep/debug. Contributors can fix things in-place and push back via git subtree push. Works without composer or any package manager.
  • Cons: Subtree commits clutter the consumer's history. Pinning is by-commit, not by semver. Easy to forget the pull cadence. Push-back has rough edges (stale subtree state can cause spurious diffs).

B. Composer dependency

Canonical publishes a Composer package; consumers composer require automattic/agents-api. Optionally autoload via composer.json's autoload.classmap so the WP-style class-wp-agent-*.php files load through composer's classmap (since the filename convention doesn't follow PSR-4).

  • Pros: Standard PHP versioning + semver. Lockfile guarantees reproducibility. composer update cadence is familiar. Multiple consumers of the same canonical version get the same bytes.
  • Cons: Requires consumers to have composer in their toolchain (most do, but this is a new dep for some). Vendored code in vendor/ is harder to grep + edit-in-place during debugging. WordPress-shaped projects don't always use composer for runtime code (only build-time).

C. Manual periodic sync

Maintainer of each consumer hand-syncs canonical changes into their tree on whatever cadence they want, with no tooling enforcement.

  • Pros: Maximum flexibility. No tooling required.
  • Cons: Drift is the default failure mode. No reproducibility across consumers. Effectively the current state, which is what we're trying to escape.

Decisions to make

  1. Default mechanism — pick one as the documented happy path. Adopters can deviate but should understand they're going off-script.
  2. Versioning policy — semver tags? Date-based? Just "latest main"?
  3. Push-back convention — does git subtree push from a consumer back to canonical happen, or are all canonical changes via direct PRs against this repo? (Strongly suggest the latter — keeps history clean.)
  4. Lockfile / pin policy — does canonical ship a recommended pin commit/tag for each release? Do consumers track that?

Recommendation

B (Composer) with semver tags, no push-back from consumers (canonical changes happen as direct PRs here). Reasons:

  • Composer is standard tooling for PHP plugin authors. Familiar workflow.
  • Lockfiles + semver give consumers explicit control over upgrade timing — important for high-traffic hosts that need to pin during incidents.
  • Eliminates the "who pushes back" ambiguity. All canonical changes flow through this repo's PR review.
  • Doesn't preclude vendoring on top — a consumer can still composer install --prefer-dist into a tracked path if they want it in-tree.

Subtree (A) is a fine secondary path for consumers that don't want composer in their toolchain. Canonical should document both, with composer as the recommended default.

Acceptance criteria

  • README has a "Consuming canonical" section documenting the recommended mechanism + tags + pin policy.
  • composer.json shipped with canonical at the root, name: automattic/agents-api, autoload set up for the WP-style filenames (probably classmap, since class-wp-agent-*.php doesn't follow PSR-4).
  • First semver tag cut (v0.1.0 or similar) so adopters have a stable target.
  • (Optional) MIGRATION.md showing the convergence path for a host with an existing extracted runtime.

AI assistance

  • AI assistance: Yes
  • Tool(s): Claude Code (Opus 4.7)
  • Used for: Surveying the three mechanisms against typical PHP/WordPress consumer workflows and drafting the decision criteria.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions