ADR-0017: Composable, Importable .stet Configuration
Status
Proposed / exploring. Captured during ideation on 2026-07-04; the config format and the import model were decided that session (marked DECIDED). Extends ADR-0015 (topology) and ADR-0005 (YAML workflows). Revisit for promotion after the core loop (SPEC-0001..0003) is standing.
Context and Problem Statement
The .stet topology (ADR-0015) defines where the three primitives (Agents, Skills,
Verbs) live and how the user/org/project levels compose. Two things are still
undecided: the format the configs are written in, and whether a .stet can build
on another arbitrary .stet — so friends can base theirs on yours, and orgs can
import packs from other orgs or vendors.
Decisions
DECIDED — YAML is the config format
All primitive configs (Agents, Skills, Verbs, and the workflow definitions of ADR-0005) are authored in YAML: human-readable, diffable, reviewable, and ubiquitous — consistent with the "configs are software artifacts" framing.
DECIDED — .stet repos can import other .stet repos
A .stet may declare imports of other .stet repositories by reference. Imported
primitives join the resolution stack, turning the fixed user→org→project topology
(ADR-0015) into an open dependency graph: your local tiers sit on top of imported
bases. This is the extends/module/tap pattern (ESLint shareable configs, Terraform
modules, Homebrew taps) applied to agents/skills/verbs — and a distribution channel:
vendor packs, community verb packs, a friend's curated setup.
Resolution with imports
- Local overrides imported. Your own tiers (project/org/user) take precedence over imported definitions; imports are a base layer you extend.
- Deterministic conflicts. Among multiple imports, declared order decides; diamond conflicts and transitive imports resolve deterministically; cycles are detected and broken.
- Pins still win. A pinned local/higher-tier definition (ADR-0015) cannot be overridden by an import; an import itself may be pinned.
Supply-chain safety (the hard part)
Importing a .stet imports executable intent for AI agents — agents that run code,
skills that instruct them, verbs that trigger workflows. A malicious/compromised import
is prompt-injection-as-a-dependency. This is a real, novel attack surface. The
defenses compose from existing decisions:
- Pinned refs (lockfile). Imports resolve to a pinned SHA/tag by default — no silent upstream drift; reproducible and the first supply-chain control.
- Review-on-import via the recursion. Adding/bumping an import is a PR to your
.stet, reviewed/voted/trajectory-tracked (ADR-0014) — you review the diff of what you import; upstream updates surface as a reviewable dispatch (Dependabot-like). - Sandbox (ADR-0003) contains imported agents' execution.
- Secret-scan/redaction gate (ADR-0011) applies to imported config.
- Org pins/allowlist (ADR-0015) let an org forbid an import from overriding a mandate.
DECIDED — Trust via required signed refs (downstream-enforced)
An import pins a SHA; downstream policy can require that the pinned commit/tag be GPG-signed by an allowed signer. Enforcement is downstream — the importer / org sets the policy as a pinnable org setting (ADR-0015) — so Stet is not a central trust authority: it verifies git's existing signatures rather than running its own PKI. The verification hook is signature-agnostic (GPG is the default; SSH-key and Sigstore/gitsign signatures are also verifiable), so the policy reduces to "a verified signature from an allowed signer." This reuses the same "let downstream enforce" philosophy as pinning: decentralized trust, provenance-tracked.
Residual gap: git signing proves a ref was signed, not whose keys to trust — managing the allowed-signer trust root (key/identity distribution, rotation, revocation) is the remaining work; forge identity (ADR-0007) is a candidate root.
Why it fits
- Good, because it makes Stet config a shareable ecosystem, not a per-user silo — vendor packs, community bases, "fork my setup."
- Good, because import lifecycle (add/bump/review) rides the existing review/vote/ trajectory machinery; supply-chain review is just the normal loop.
- Good, because YAML keeps every primitive human-diffable and reviewable.
Open questions
- Transitive imports — depth, re-export semantics, and how deep the supply-chain surface goes.
- Allowed-signer trust root — GPG-signed refs are required by downstream policy (see Supply-chain safety); open: how allowed-signer keys/identities are distributed, rotated, and revoked, and whether forge identity (ADR-0007) is the root.
- Import allowlists — org-level control over which source repos (and which signers) may be imported.
- Update cadence & notification — how upstream bumps are surfaced and throttled.
- Private-repo auth for imports (forge credentials, ADR-0007).
- Licensing/attribution of imported/vendor config.
- Marketplace/discovery — how importable
.stetrepos are found (future).
Consequences (tentative)
- Introduces an import/dependency resolver layered under the topology resolver (ADR-0015), with pinned refs (a lockfile) and cycle detection.
- Turns supply-chain review into the normal stet loop; trust is git-native signed refs required by downstream (org) policy, leaving allowed-signer key management as the residual hardening.
- Opens a distribution/ecosystem surface (vendor and community
.stetpacks).
More Information
Extends ADR-0015 (topology) and ADR-0005 (YAML). Precedents: ESLint/tsconfig
extends, Terraform modules, Ansible Galaxy, Homebrew taps. Security substrate:
ADR-0003 (sandbox), ADR-0011 (scan/redaction), ADR-0014 (review/vote), ADR-0015 (pins).