Packages: research & manifest design (turian-package.json + ADR)

Part of the Plugin & Package System epic #20 (closed). Phase 1 (foundation/MVP).

Goal

Define the contract for everything else in the epic: the package manifest format and the conceptual model. No build/runtime code ships here — this is research + a written specification + an ADR. Every other issue in the epic consumes the decisions made here.

Why first

Discovery (#C), build integration (#B/#D/#E/#F), the CLI (#G) and the editor panel (#H) all read/write the manifest. Locking its shape first prevents churn.

Terminology to ratify (carry into the ADR)

Term Meaning
OAP (.oap) The cooked, runtime asset container the game ships/streams (already exists — editor/AssetPackager.zig, open_asset_package dep). Already supports manifests, inter-package deps, DLC/mod overlays.
Package The authoring/distribution unit: a manifest + any mix of assets, Zig source, native libs, plugins. This epic.
Module A Zig compilation unit (b.addModule) — the Unity asmdef equivalent. Already used per user script (script_N_mod in editor/GameCodegen.zig).
Plugin The runtime/editor registration entry point a Package exposes (registers components/systems/services, or editor panels via #4 (closed)).

A Package may be asset-only, source, native, or hybrid (the normal case). An asset-only package can ship its assets as loose files (cooked into the project game.oap at build) or as a prebuilt .oap (DLC/mod overlay).

Key research questions

  1. How much do we delegate to Zig's package manager? build.zig.zon + zig fetch already give us content-addressed hashing, transitive resolution, hash-pinning (the lockfile), and .path (local) / git+https (remote) deps. The recommendation entering this issue is: delegate dependency resolution / conflict / cycle / lock to Zig, and keep the Turian manifest for engine-integration metadata only. Validate or refute this.
  2. What can a manifest NOT express that asmdef does, and do we need it (public/private API, editor/runtime split)?
  3. Survey and write up takeaways from: Zig package manager, Unity UPM + Assembly Definition Files, Godot addons + Asset Library, Unreal plugins, Cargo, npm.

Proposed manifest (starting point — refine in the issue)

A turian-package.json (JSON per project convention — not ZON) at the package root, alongside a normal build.zig.zon for source/native packages (so Zig's fetcher works unchanged):

{
  "name": "com.acme.platformer-kit",   // reverse-DNS, globally unique
  "version": "1.2.0",                   // semver
  "author": "Acme",
  "description": "...",
  "license": "MIT",
  "engine_compat": ">=0.16 <0.18",      // Turian engine version range
  "types": ["asset", "source"],         // any of asset|source|native|plugin
  "assets": ["assets"],                 // asset dirs (relative to package root)
  "modules": [                          // exported Zig modules (source pkgs)
    { "name": "platformer", "root": "src/root.zig" }
  ],
  "native": [                           // native pkgs
    { "name": "physx", "kind": "static", "lib": "lib/{target}/libphysx.a", "include": "include" }
  ],
  "plugin": { "register": "platformer", "entry": "registerPlugin" }, // optional
  "dependencies": {                     // mirrors/maps to build.zig.zon deps
    "com.acme.core-utils": "^1.0.0"
  }
}

Decide: is dependencies authoritative, or is build.zig.zon authoritative and this a view? (Leaning: build.zig.zon authoritative for source/native; this manifest authoritative for asset-only packages that have no build.zig.zon.)

Tasks

  • Survey UPM / asmdef / Godot / Unreal / Cargo / npm / Zig PM; write a comparison table of what translates to a Zig engine
  • Decide the Zig-PM delegation boundary (what Turian owns vs. what build.zig.zon owns)
  • Specify the turian-package.json schema (field-by-field, with types and validation rules)
  • Specify the project-side record of installed packages (see #B — likely lives in the project's build.zig.zon + a thin index)
  • Define GUID-collision and asset-virtual-path namespacing policy across packages (consumed by #D)
  • Define the engine-compat check semantics
  • Write docs/decisions/000X-package-system.md (ADR) capturing all of the above
  • Define a minimal example package layout to be used by #D/#E test fixtures

Acceptance criteria

  • ADR merged in docs/decisions/ with the ratified terminology table and Zig-PM delegation boundary.
  • turian-package.json schema documented field-by-field with validation rules.
  • A concrete example package directory layout is specified (used as the fixture for later issues).
  • GUID/virtual-path collision policy is written down.

Dependencies

None. This unblocks all other epic issues.

Out of scope

Any code. (Manifest parser is #C.)