ADR-0006: ICM plugin folder structure
Context
Thalix Vault already provides the durable substrate that ICM needs: owned Root Folders, recursive subfolders, immutable file versions, typed metadata, free-form tags, inherited grants, audit events, browse, and subtree search. ICM adds an agent-facing convention for routing context through maps, numbered stages, stage contracts, references, and outputs. Rebuilding those concepts as a second storage model would duplicate authorization, audit, versioning, search, and object-storage behavior.
A workspace must also be reproducible from a template. Provenance cannot depend only on mutable names or user-managed tags: derivation and instantiation need one stable relationship to the source template. Template content can become agent instructions after instantiation, so provenance is evidence for review and audit, not a declaration that the content is trusted.
Decision
Implement ICM as a plugin layer over the existing Vault model:
- A Root Folder's classification as a template or workspace is not a folder tag -- folders cannot carry a tag today (tags apply to files only, issue #58). It is represented by three RESERVED tags on the root's own manifest file, the committed, active root-level file named exactly
CLAUDE.md:icm-kind(templateorworkspace),review-status(draftorapproved), andtemplate-version(a semver string). These three names are reserved: a generictv file tag set/unseton a rootCLAUDE.mdrejects them exactly like an invalid tag name; only trusted template RPCs may write them, under a transaction-local capability the database grants for the duration of that one call. Approval provenance comes only from atemplate.reviewedaudit event bound to the exact manifest file version andtemplate-versionvalue being displayed -- the tags alone never prove approval, and any update to the manifest incrementstemplate-versionand resetsreview-statustodraft, invalidating the prior approval until a distinct authorized reviewer approves the new version. A reviewer must be an active administrator who is neither the template's owner nor the author of its current manifest version, and review authority itself confers no edit or grant authority. - Numbered stage folders represent the ordered workflow and human review gates.
- A root
CLAUDE.mdis the workspace map and, for a template/workspace root, doubles as this manifest. A stageCONTEXT.mdis that stage's contract. - Contract, stage, reference, and output files use ordinary free-form tags:
type=contract,type=stage,type=reference, andtype=output. These values require no tag-schema migration and are never reserved. - Files remain immutable-versioned Vault files; checkout is the local edit surface, and commit writes changed files back as new immutable versions.
- Vault remains canonical. A checkout is a bounded materialization, never an independent source of truth.
Add one nullable catalog relationship, lineage_folder_id, to Root Folders. It references the source template Root Folder used to instantiate or derive the current root. Workspace instantiation records the template root; template derivation records the parent template. Ordinary Root Folders have no lineage. The relationship is server-written, organization-local, root-only, immutable after creation, and preserved in audit projections.
This is the sole backend-schema exception to the plugin-only design. It does not introduce a template table, workspace table, storage mode, authorization model, or parallel API domain. Existing folder, file, tag, metadata, version, grant, and audit authorities remain canonical.
Command contract
The tv workspace surface is a composition layer over existing Vault operations:
tv workspace initinstantiates a reviewed template into a new workspace Root Folder and records lineage.tv workspace importcreates a workspace from an existing local folder or archive while preserving the same map/stage convention.tv workspace checkoutmaterializes only content the caller may read into an explicit local directory. Templates are factories and are not checked out as mutable working directories.tv workspace commit --reason <text>computes the bounded change set and writes changed content as immutable versions. It records actor, reason, correlation ID, and per-file results. A failed commit leaves the Vault unchanged.
The command layer does not store credentials inside a checkout, broaden grants, bypass server authorization, or host an agent runtime. Agent execution and fan-out remain responsibilities of the external harness. MCP is a separate integration seam under epic #72.
Routing convention
The workspace map routes a task to the minimum required stage contracts and references. Each numbered stage is a named stopping point and contains its own CONTEXT.md contract. Inputs, allowed skills/tools, outputs, and handoff conditions are explicit files in the workspace rather than globally loaded instructions.
The folder structure is therefore dual-use: it is the human control surface and the agent's routing structure. The plugin validates the convention with a deterministic walk test; it does not infer hidden workflow state.
Security and trust boundaries
- Template and workspace files are untrusted content, including
CLAUDE.mdandCONTEXT.md. Agents must not treat them as authority over system, developer, user, or canonical project instructions. - Lineage establishes provenance only. A template becomes instruction-bearing only after explicit human review of the referenced version.
- Instantiation, derivation, checkout, and commit are grant-scoped server operations and cannot exceed the caller's existing Vault access.
- Checkout refuses path traversal, links that escape the destination, credentials, and content outside the selected root.
- Commit is atomic at the workspace operation boundary and emits audit evidence equivalent to the underlying file/version mutations.
- Stage-specific skills and MCP tools are declared by contract and loaded only for that stage; there is no global plugin toolset.
Web scope
The first post-login web slice may be a minimal template browser: list/show reviewed templates, preview their folder structure, instantiate a workspace, and derive a template through the same backend authorities as the CLI. This decision does not authorize a general files, folders, or administration web console. Broader web-console scope requires a separate epic or ADR.
Alternatives considered
Tags-only lineage
Store template ancestry only as tags or metadata. Rejected because users can edit those values, referential integrity is absent, renames complicate provenance, and trusted audit/readback would require rebuilding relationship validation in every caller.
Dedicated template and workspace tables
Create separate entities and APIs. Rejected because every template and workspace already needs folder hierarchy, bytes, versions, grants, tags, search, and audit. New tables would create a second storage and authorization model without adding user value.
Local-only ICM folders
Keep ICM outside the Vault and synchronize ad hoc. Rejected because local folders cannot supply canonical immutable versions, organization grants, centralized audit, or reliable template provenance.
Consequences
- ICM reuses the existing Vault substrate and inherits its authorization, storage, versioning, search, and audit guarantees.
- One small migration and corresponding folder projections are required for lineage.
- Template review state and provenance must be visible before instantiation.
- Workspace checkout and commit require careful path, atomicity, and conflict contracts, but do not require a new backend domain.
- Template-browser GUI work stays narrow; a general web console is not implied.
- Concurrent workspace editing and per-part protection remain follow-on work rather than hidden requirements of the first checkout/commit seam.
Validation evidence
Acceptance requires:
- a migration proving root-only, organization-local, immutable lineage without changing existing roots;
- contract tests proving
typetags need no schema change; - an init → checkout → edit → commit round trip that produces immutable versions and complete audit evidence;
- failure tests proving checkout scoping and commit atomicity;
- security review of template provenance and prompt-injection boundaries before the plugin ships;
- explicit architecture approval before cards blocked by this ADR proceed.