Skip to content

Derive project identity from package version and compiler revisions #94

Closed

Description

@ScriptedAlchemy

Summary

Stop requiring application authors to repeat the package version in
agent-bundle.config.ts and runtime registries. Derive release identity from
the project package, preserve Agent Bundle's existing source/config/model
revisions, and expose those distinct axes consistently in manifests, dev
status, runtime requests, and provenance.

This is a focused identity migration, not part of filesystem route discovery.

Problem

Agent Bundle currently requires plugin.version in config, while examples may
also restate name/version inside runtime application registries. At the same
time, ProjectContext already records source revision, config digest, model
digest, and source inputs. A static version in multiple authoring surfaces can
drift, while replacing semantic version with a development hash would conflate
release and source identity.

Contract

Reuse and extend the existing ProjectContext; do not introduce a parallel
identity object.

interface ProjectIdentity {
  packageName: string;
  packageVersion: string;
  sourceRevision: string;
  configDigest: string;
  modelDigest: string;
}

Rules:

  • package.json name/version are authoritative for packaged projects;
  • release artifacts and host manifests retain the semantic package version;
  • development status and generated manifests also expose the canonical source
    revision;
  • config/model digests remain separate compatibility/provenance axes;
  • a display label may render
    <packageVersion>+dev.<short-source-revision> without changing the canonical
    semantic version;
  • changing package.json invalidates the project context and source revision;
  • runtime registries and route modules never restate project identity;
  • release builds fail closed when package identity is missing or invalid;
  • a documented development-only fallback may exist for unpackaged scratch
    projects, but it cannot produce a release artifact.

Migration

  1. Read and validate package identity during project loading.
  2. Add derived identity to normalized config and generated manifests.
  3. Warn when plugin.version differs from package.json.
  4. Make plugin.version optional and prefer package identity.
  5. Remove duplicated runtime application identity during route migration.
  6. Deprecate and later remove plugin.version through the repository's normal
    breaking-change policy; this issue does not promise a fixed compatibility
    window.

Acceptance criteria

  • One packaged project declares its version only in package.json.
  • Build, inspect, Workbench, runtime context, and host manifests agree on
    package version, source revision, config digest, and model digest.
  • Editing source changes source revision without changing package version.
  • Editing package version changes package and source identity deterministically.
  • A conflicting legacy plugin.version fails or warns according to the active
    migration phase; it never silently wins.
  • A release build without valid package identity fails closed.
  • No application route or runtime registry repeats name/version.

Design references

Stack position

  • Can land independently of filesystem routes after current project loading.
  • #93 filesystem routes and #95 request context consume its derived identity when available but do not block initial implementation on the migration.

Full meta-framework stack

Activity

  1. added
    enhancementNew feature or request
    meta-frameworkAgent Bundle compiler-coupled meta-framework
    runtimeRuntime context, state, rendering, or execution
    on Aug 31, 2026
  2. ScriptedAlchemy commented on Sep 1, 2026

    @ScriptedAlchemy
    OwnerAuthor

    Stages 1-2 landed in #121 (merge e8908cc), the reconciled superset of #117 and #115 (#117 could not be reopened after a post-closure rebase force-push, so the identical branch landed as #121).

    Delivered (stages 1-2):

    • packageName/packageVersion derived from the project's package.json, validated (npm name rules incl. reserved names, strict semver 2.0.0), carried as optional axes on NormalizedMetadata/ProjectContext, and exposed distinctly in artifact manifests, inspect output, and dev status DTOs (SourceStatus, ArtifactEpoch, agent API wire, workbench client decoders).
    • Precedence: package.json is authoritative for the release axes; plugin.version authors only the native plugin version and a mismatch reports the AB4008 warning. Invalid identity is a diagnostic, never a crash: AB4009 invalid npm name, AB4010 invalid semver, AB4011 unusable package.json (unparsable or symlinked outside the project root).
    • Missing package version stays a normal dev state with the labeled 0.0.0-dev.<short-revision> display fallback; no new required fields.
    • G9 respected: plugin.name remains the host-native slug, never derived from the npm package name.
    • Proofs: audiobook-curator derives one version source with no AB4008; unversioned examples show the labeled fallback; direct AB4008/AB4009/AB4010/AB4011 tests; manifest round-trip; conscious pin flips in normalization and overview e2e tests. Changeset: minor.

    Remaining (stage 3): making plugin.version optional and release fail-closed behavior.

  3. ScriptedAlchemy commented on Sep 2, 2026

    @ScriptedAlchemy
    OwnerAuthor

    Stage 3 landed in #270 (merge 09067f6), together with #237's build-time constant.

    • plugin.version is now optional: omitted → derived from package.json (migration step 4); declared → still authoritative for the host-facing version during the migration, with AB4008 staying a warning (step 3 policy unchanged).
    • Release fail-closed: agent-bundle build refuses a project with neither an authored plugin.version nor a valid package.json version with the new AB4013 error before anything compiles. dev/inspect/validate keep the labeled 0.0.0-dev.<short-revision> fallback — the documented development-only state that can never produce a release artifact.
    • Compiled surfaces join the agreeing set via agent-bundle/meta (Infer plugin version from package.json and expose a build-time version constant to plugin code #237): build, inspect, dev status, host manifests, and compiled Node + browser bundles all report the same identity axes.
    • examples/audiobook-curator now declares its version only in package.json (the acceptance-criteria proof project).

    Remaining for this issue: migration step 5 (remove duplicated runtime application identity during route migration — tracked with the #93/#95 route work) and step 6 (deprecate and eventually remove plugin.version per the normal breaking-change policy). Leaving open for those.

  4. ScriptedAlchemy commented on Sep 2, 2026

    @ScriptedAlchemy
    OwnerAuthor

    Completed the final #94 migration steps in #322 (squash merge 0e3c444a).

    Already complete before this PR

    Final remaining scope delivered

    • Migration step 5: compiled MCP App routes consume compiler-stamped agent-bundle/meta identity rather than restating name/version. The prebuilt RSC example now declares 1.0.0 in package.json, omits plugin.version, and shares one host slug/package-derived version across its config, MCP server, runtime registry, and App bootstrap.
    • Migration step 6: AgentBundlePluginConfig.version is now formally @deprecated; docs direct new projects to package.json and preserve removal through the normal breaking-change policy with no promised fixed window.
    • Added a minor changeset.

    Evidence

    • pnpm typecheck — green
    • pnpm lint — green (0 errors, 0 warnings)
    • MCP App example build + contract integration — green; emitted App contains mcp-app-example@1.0.0, no legacy mcp-app-status-panel, and no unresolved agent-bundle/meta
    • RSC example typecheck/build — green; build manifest reports package name @agent-bundle/rsc-agent-runtime-demo, package version 1.0.0, and source validation passed
    • RSC host-artifact suite — 5/5 green

    All acceptance owned by #94 is now complete; closing.

  5. added a commit that references this issue on Sep 3, 2026
  6. ScriptedAlchemy commented on Sep 3, 2026

    @ScriptedAlchemy
    OwnerAuthor

    Closed-issue re-audit (G3) — PARTIAL → fixed in #372 (squash ccb9cd18a).

    Verified on origin/main: plugin.version is @deprecated (packages/agent-bundle/src/core/types.ts:23); AB4008–AB4011 emit from config/validate.ts:1654-1660 and AB4013 from config/validate.ts:1705; packageName/packageVersion ride ProjectContext (core/project-context.ts:33-52); agent-bundle/meta is exported; examples/audiobook-curator and examples/rsc-agent-runtime declare their version only in package.json; docs/diagnostics.md §Release identity documents the deprecation.

    What did not match the closing claim "docs direct new projects to package.json": the headline configs in README.md and docs/framework-mode.md, and all three create-agent-bundle templates, still authored plugin.version: '0.1.0' — every scaffolded project started on the deprecated field. #372 removes it from both docs and the templates (package.json 0.1.0 is the single source; a scaffolded minimal project validates with zero diagnostics and inspect reports version: "0.1.0" derived from packageVersion), adds a per-template scaffold test pinning "no version: in the config, 0.1.0 in package.json" (packages/create-agent-bundle/tests/scaffold.test.ts), and ships a create-agent-bundle patch changeset. Evidence: scaffold tests 23/23, scaffold-packed.e2e (minimal template auto-installs and passes its own check without plugin.version) ✓, CI green on #372.

    Remaining by design: examples/hooks-and-scripts, mcp-app, and skills-starter keep plugin.version because their package.json has no version (dropping it would trip AB4013); worktree-proximity declares both, in agreement (no AB4008).

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

    enhancementNew feature or requestmeta-frameworkAgent Bundle compiler-coupled meta-frameworkruntimeRuntime context, state, rendering, or execution

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions