Skip to main content

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 .stet repos 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 .stet packs).

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).