dev
← All ADRs

Metalab Mode Architecture

ACCEPTEDEngine2026-08-31

Context

autograph defines three operating modes (prod, dev, metalab). Dev mode is implemented via pkg.agent. Prod mode is the absence of autograph scaffolding. Metalab mode - working on autograph itself from within an autographed project - has been designed but not yet implemented.

The current autograph.lab is a proto-metalab: an ad-hoc environment where autograph is developed without using autograph's own infrastructure. Once metalab mode exists as a package, the lab is superseded.

The inversion model

Metalab mode is a literal inversion of dev mode volume wiring:

  • Dev mode: the agent works on the project (L1 mutable) while autograph is frozen infrastructure (L2 frozen)
  • Metalab mode: the agent works on autograph sources (L1 mutable) while the project is frozen context (L2 frozen)

Volume wiring: dev vs. metalab

Host path Dev agent Metalab agent Content
${AUGR_PATH_WORKSPACE} L1 (mutable) L2 (frozen) Source code, docs, delivery, exchange
${AUGR_PATH_ROOT}/Taskfile.yaml + Taskfile.d/ L2 (frozen) L2 (frozen) Project task definitions
${AUGR_PATH_ENGINE}, ${AUGR_PATH_DEPS} L2 (frozen) L1 (mutable) Autograph sources (engine + packages)
env/, Docker socket L3 (inaccessible) L3 (inaccessible) Secrets, orchestration

Requirements

The metalab mode must:

  1. Run simultaneously with dev mode (parallel containers, no interference)
  2. Apply the full security model (cap_drop ALL, no-new-privileges, isolated network, resource limits)
  3. Share the existing Phoenix instance (mode-tagged observability)
  4. Be activatable as an optional package in any autographed project

Terminology: Shadow

Status: embryonic concept - not yet implemented.

In this ADR, "shadow" refers to the autograph sources as seen by the metalab agent through its L1 volume mounts. It is not a copy or a sync mechanism - it is the result of mounting the same source directories with different access levels depending on the mode.

The exact shape of the shadow (which directories, how they are structured, whether a preparation step is needed) is not yet defined. The current autograph.lab workspace - with its instances/ containing full git clones - is the closest existing approximation, but it predates the package system and was not designed with the 3-layer security model in mind.

Open questions for implementation:

  • What host directories are mounted as L1 in the metalab container?
  • Does the metalab agent see individual package repos, a unified workspace, or something else?
  • How does shadow initialization interact with West-resolved modules (which strip .git)?
  • Can the shadow reuse existing instance directories, or does it need its own?

These questions will be resolved during implementation (E15 tickets T02–T03).

Options considered

Option A - Standalone package depending on `pkg.agent`

autograph.pkg.metalab is a separate package with its own augr.pkg.yml, compose.yaml, and Taskfile. It depends on pkg.agent for the base Docker image and shared infrastructure (Phoenix). No code duplication - real dependency.

  • Advantage: Clean separation of concerns. Independent lifecycle. Clear contract. Each package has a single responsibility.
  • Advantage: Pioneers inter-package dependency in autograph - opportunity to validate the pattern.
  • Disadvantage: Requires solving package-to-package dependency at the engine level (West does not support this natively).

Option B - Extend `pkg.agent` with a metalab profile

Single package, AUGR_MODE=dev|metalab env var. Compose uses profiles for different containers. Shared Dockerfile, parameterized entrypoint.

  • Advantage: Zero duplication. Single source of truth. Simpler dependency graph.
  • Disadvantage: pkg.agent becomes more complex. Two concerns in one package. Mode leakage risk. Harder to test independently.

Decision

Option A - Standalone package.

autograph.pkg.metalab is a separate package that depends on pkg.agent. The dependency is managed at the engine level for v0:

  1. The engine's west.yml declares both packages as core dependencies
  2. Both are resolved during augr:install
  3. diagnos validates both are present
  4. Docker-level dependency via FROM (shared base image) and depends_on (Phoenix)

This approach is chosen because:

  • It preserves single-responsibility per package
  • It creates the opportunity to pioneer and validate inter-package dependency in autograph
  • It avoids complexity creep in pkg.agent, which is already feature-complete for dev mode
  • Extraction from a monolithic package is always harder than composition of separate ones

Inter-package dependency (v0)

West has no native concept of "module A depends on module B." For v0, the engine manifest manages co-presence explicitly. The engine "knows" that metalab needs agent and declares both. This is documented with comments in the manifest.

Future evolution: add a requires field to augr.pkg.yml that the engine's diagnos validates. West remains a transport/clone tool; dependency intelligence lives in the autograph engine layer.

.git access (v0 stance)

The metalab agent's workspace contains autograph repos with full git history. This means .git directories are in L1 (mutable). This is a known limitation for v0.

Mitigations:

  • AGENTS.md and attitudes instruct the agent to never directly commit
  • Operator remains the git authority
  • Pre-commit hooks provide a safety net

Future fix (to be designed once metalab is self-sustaining):

  • Split mounts: .git as L2 (RO), worktree as L1 (RW)
  • Git proxy layer (intercepts git commands, requires operator approval)

Taskfile security breach (v0 - must be addressed early)

This is a security flaw. In dev mode, Taskfiles are L2 (frozen) - the agent cannot modify the infrastructure that runs it. In metalab mode, since ${AUGR_PATH_ENGINE} and ${AUGR_PATH_DEPS} are mounted L1 (mutable), the Taskfiles inside them become mutable too. The metalab agent can technically edit the Taskfiles that define its own lifecycle tasks.

The risk is partially mitigated by the fact that task runs on the host, not inside the container - the agent cannot execute modified Taskfiles directly. But the files are writable, which violates the security model formally.

Target fix: Automatic duplication of package Taskfiles into an aggregated, convention-based location. The metalab agent works on source Taskfiles (L1, mutable) but the active Taskfiles used by the host are separate copies (not mounted in the container, or mounted L2). This follows the same pattern as exchange.dev.tmp/proposed/ - the agent edits a working copy, the operator validates and activates.

Concretely, this would enable a proper workflow for Taskfile modifications:

  1. Metalab agent edits Taskfiles in the source packages
  2. A dedicated task (e.g., augr:metalab:apply-taskfiles) aggregates and deploys them
  3. Operator reviews the diff before activation
  4. Container restart picks up the new Taskfiles

This mechanism should be designed and implemented as a priority once the basic metalab container is functional.

Consequences

Positive

  • Any autographed project gains the ability to improve autograph itself
  • The reactive environment vision is formalized: projects are both consumers and contributors
  • The lab (proto-metalab) can be retired once metalab mode is proven in seed
  • Clear architectural pattern for future package-to-package dependencies

Negative / Risks

  • Inter-package dependency is a new pattern - must be validated carefully
  • .git in L1 is a security compromise accepted for v0
  • Taskfiles in L1 are a security breach - the metalab agent can modify the infrastructure that orchestrates it. Must be addressed early (see dedicated section above).
  • Shadow initialization requires solving the West/.git bridge (West strips .git from resolved modules)
  • Two agent containers running simultaneously doubles resource consumption

Deferred concerns

Concern Priority Rationale Tracking
Taskfile aggregation for metalab High Security breach: agent can edit active Taskfiles E15 (early follow-up)
.git access hardening High Metalab must be self-sustaining first Future epic
Testing metalab changes against the project Medium Separate evaluation concern, v0 = basic loop only Future epic or E13 extension
Event bus for prompt routing between agents Low Needs experimentation, depends on event-bus maturity brainstorm-event-system.md
requires field in augr.pkg.yml Low Needs engine-level implementation in diagnos Draft ticket in E15
Registry / upstream contribution flow Low Depends on metalab v0 being functional E15.T06 or future epic
Shadow design (structure, init, lifecycle) - Embryonic concept, to be resolved during T02–T03 E15.T02, E15.T03

Implementation notes

  • Task namespace: augr:pkg:metalab:* (prepare, build, shell, chat, forge, sync, clean, logs)
  • Container name: augr_metalab_agent
  • Network: dedicated isolated network (no route to dev-agent network or application networks)
  • Phoenix: shared instance, sessions tagged with mode identifier
  • The metalab agent gets its own AGENTS.md focused on working on autograph, not the project