dev
← All ADRs

Project Layout for Instantiated Projects

ACCEPTEDEngine2026-05-30

Context

autograph needs a standard filesystem layout that clearly separates concerns and enforces the 3-layer security model. The layout must accommodate: an engine (submodule), resolved packages (West), a workspace for the agent, secrets, and host-side configuration.

The layout must be intuitive for both the operator (who navigates the root) and the agent (who sees only its mounted volumes).

Options considered

Option A - Flat structure

Everything at the root: src/, engine/, deps/, env/, docs/, Taskfiles.

  • Advantage: Simple, familiar
  • Disadvantage: No clear security boundary. The agent would need per-directory mount rules. Hard to reason about what's L1 vs L2.

Option B - Workspace-centric (chosen)

A dedicated workspace/ directory that IS the agent's L1. Everything outside it is L2 or L3.

  • Advantage: The security model maps directly to the filesystem. workspace/ = L1 (RW), everything else = L2 (RO) or L3 (not mounted). Simple Docker volume config.
  • Disadvantage: One extra level of nesting. The operator must cd workspace/ to see source code.

Option C - Container-centric

No workspace directory. The container mounts are the abstraction layer (mount only specific directories as RW).

  • Advantage: No nesting on host
  • Disadvantage: The security model lives only in Docker config, not visible in the filesystem. Harder to reason about and audit.

Decision

Option B - Workspace-centric.

The workspace/ directory is the physical manifestation of L1. This makes the security model visible in the filesystem structure itself, not just in Docker configuration.

Consequences

Standard layout

my-project/                          # Project root (Git repo)
├── .git/
├── .gitignore
├── Taskfile.yaml                    # Single operator entry point (L2)
├── Taskfile.d/                      # Task definitions by concern (L2)
├── Taskfile.env.yaml                # Environment variables (L2)
│
├── engine/                          # Git submodule → autograph (L2)
│   ├── Taskfile.yaml
│   ├── infra/docker/
│   ├── deps/                        # Engine's own deps (West recursive)
│   │   ├── manifest/west.yml
│   │   └── modules/
│   └── docs/
│
├── deps/                            # Project West workspace (L2)
│   ├── .west/
│   ├── manifest/west.yml
│   └── modules/
│
├── env/                             # Secrets + runtime (L3)
│   ├── .env
│   └── logs/
│
├── workspace/                       # Agent working area (L1 - RW)
│   ├── AGENTS.md
│   ├── agent/                       # Project-specific agent config
│   │   ├── attitudes/
│   │   └── skills/
│   ├── env.template/
│   ├── docs/
│   ├── delivery/
│   ├── infra/
│   ├── src/
│   └── exchange.dev.tmp/
│       └── proposed/
│
├── exchange.lab.tmp/                # Metalab exchange
│   └── proposed/
│
└── .augr/                           # Reserved for future local state

Mapping to security layers

Filesystem path Layer Agent access
workspace/ L1 Read-Write
engine/, deps/, Taskfile*, .git/ L2 Read-Only
env/ L3 Not mounted

Trade-offs

  • The operator interacts with the root level (Taskfiles, engine, env)
  • The agent interacts with workspace/ exclusively (plus RO references)
  • Source code lives in workspace/src/ (one level deeper than typical projects)
  • This nesting is the price for a filesystem-visible security model