Environment manifest
Skill celestialdust/achilles-skills/skills/environment-manifest
Capture every external thing the autonomous run needs — API keys, MCP servers, services, runtime deps, test fixtures, accounts — as a typed-kind manifest with NO values and NO commands. Use during Spec right after the PRD lands, and again during Plan once slices exist. ALWAYS run this before an AFK/autonomous wave so preflight-readiness can refuse to start on a missing dependency. If you are about to paste a secret value or a check command into a config file, STOP and use this instead.From its SKILL.md
npx -y skills add celestialdust/achilles-skills --skill environment-manifestAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
10.4 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it
Purpose
Stage: Spec (pass 1, signed) + Plan (pass 2, appended). The autonomous Implement→Ship wave runs
AFK; the moment it hits a missing API key, an unprovisioned service, or a wrong runtime version, it fails
silently in the middle of a parallel wave. environment-manifest captures — declaratively, never executably —
every external thing the feature needs to run, so the value-blind preflight-readiness gate can refuse to start the
wave until each item is provisioned.
First principle: an environment need is data (a typed row), not code (a command). Encoding it as data
makes two whole classes of failure structurally impossible — a secret can't leak into a committed file
(there is nowhere to put a value), and an unreviewed shell string can't run unattended at the human→AFK
boundary (there is nowhere to put a command). You author the manifest; preflight-readiness checks it. Maker ≠ checker.
When to use / when to skip (depth: lite)
Use twice — two passes over one file:
- Pass 1 — Spec (interface-level, signed): right after
to-prdlandsprd.md. Capture the keys / MCPs / services the product needs. These rows are part of the single Spec gate sign-off. - Pass 2 — Plan (implementation-level, appended): after
plan-breakdownproduces slices. Append the fixtures / version-pins / accounts the implementation needs; these re-surface at the Verify barrier.
Skip only when a pure-refactor feature introduces zero external dependency — but still emit a signed
manifest with an explicit (no external dependencies) note so the gate is explicit and preflight-readiness has
something to read. Never leave the file absent: absence is ambiguous, an empty-signed manifest is a decision.
Inputs
- Pass 1 consumes
docs/features/<slug>/prd.md— sections Implementation Decisions (names services / MCPs / keys), Testing Decisions (names fixtures), Out of Scope (what NOT to provision). Refuse to run pass 1 ifprd.mdis absent — without the PRD you'd be guessing at the feature's needs. - Pass 2 consumes
docs/features/<slug>/plan.md+ its slices — to pick up impl-level needs (test fixtures, exact runtime versions, per-slice accounts) and tie each row to the slice id(s) that require it. - Never consumes a
.env, a secret store, or any live value. This skill reads intent, not secrets.
Process
- Locate the file.
docs/features/<slug>/environment.md. Pass 1 creates it; pass 2 appends. - Walk the source for external needs. From
prd.md(pass 1) /plan.md(pass 2), list everything the run touches outside the repo: keys, MCP servers, running services, language/tool versions, seed data, third-party accounts. - Classify each into exactly one kind (closed enum — see Kind playbook). If a need doesn't fit a kind, that's a signal you've mis-modeled it, not a license to invent a column.
- Write one row per need:
kind · name · purpose · required-by · pass · attest. No value. No command. - Mark un-probeable items with
manual: <yes/no question>inattest— the single amber escape hatch for things a value-blind prober can't check (paid quota remaining, a human-owned SaaS account). The question is human-readable, never executable. - Append-only after sign. Pass 2 never rewrites a row signed in pass 1; if a signed interface-level fact genuinely changed, add a new row and flag the supersession for re-sign — don't silently mutate a signed row.
- Set status.
draftuntil the Spec gate signs pass-1 rows →signed. - Do not probe. You author;
preflight-readinesschecks. Running a check here would duplicate preflight-readiness and tempt a command cell into existence.
The typed-kind manifest
Closed kind enum — these six, no others:
| kind | covers |
|---|---|
env-var | a named secret/config the process reads from the environment (e.g. POSTMARK_API_KEY) |
mcp | an MCP server the agent/app connects to (e.g. supabase) |
service | a running backing service (e.g. postgres, redis) |
runtime-dep | a language/tool/version the build needs (e.g. node>=20, pnpm) |
fixture | seed data / a test artifact (e.g. seed-users.json) |
account | a third-party account/tenant (e.g. stripe-test) |
Row schema — exactly these columns: | kind | name | purpose | required-by | pass | attest |
name— the identifier only (the env-var name, the MCP name, the service name). Never the value.purpose— one line: why the feature needs it.required-by— the PRD-namespaced slice id(s) (e.g.PWR-2) or the feature slug; ties the row toSTATE.md.pass—specorplan(which pass added the row).attest— blank = auto-probed bypreflight-readiness's per-kind value-blind prober;manual: <question>= un-probeable amber escape hatch.
Two columns that must never exist (security fail-safe):
- No
valuecolumn. Secrets are structurally unrepresentable — a key can never leak into this committed file because there is nowhere to put it. - No
command/verifycolumn. A free-text command cell is an unreviewed shell string thatpreflight-readinesswould run unattended at the AFK boundary. The reviewed prober-per-kind file inpreflight-readinessreplaces it. A new service is a new row, never a new command.
Example:
feature: password-reset
status: signed
## Manifest
| kind | name | purpose | required-by | pass | attest |
|-------------|-------------------|----------------------------------|-------------|------|--------|
| env-var | POSTMARK_API_KEY | send reset emails | PWR-1 | spec | |
| service | redis | store reset tokens with TTL | PWR-2 | spec | |
| mcp | supabase | user-table reads | PWR-1 | spec | |
| runtime-dep | node>=20 | crypto.webcrypto for token gen | PWR-1 | plan | |
| fixture | seed-users.json | known users for reset E2E | PWR-2 | plan | |
| account | stripe-test | billing webhook on reset (paid) | PWR-3 | plan | manual: is the stripe-test tenant funded this month? |
Kind playbook
- Read from
process.env/ the environment → env-var (name it; never paste it). - Talked to over MCP → mcp.
- A daemon/container that must be up → service.
- A version/tool the build assumes → runtime-dep (encode the constraint in
name, e.g.python>=3.11). - Data that must exist for a test to be meaningful → fixture.
- A tenant/login on a third-party platform → account (usually
manual:attested). If two kinds fit, pick the onepreflight-readinesscan check value-blind. If none fit, you've mis-modeled the need — re-read the PRD, don't add a column.
Rationalizations
- "I'll just drop the value in so
preflight-readinesscan check it." → No. The value is structurally unrepresentable on purpose;preflight-readinessprobes value-blind. A value here is a committed secret. - "A quick
curl/psqlverify command in a cell makes it runnable." → No. That runs unattended at the AFK boundary with no review. The prober-per-kind file is the reviewed replacement. - "This dep is weird, I'll add a
notes/typecolumn." → No. The enum is closed; a misfit is a modeling signal. - "It's un-probeable, so I'll skip the row." → No. Add it with
manual: <question>; a missing row is an invisible dependency that fails AFK. - "I'll just rewrite the signed Spec row during planning." → No. Append + flag for re-sign; signed facts are the Spec gate's contract.
- "Let me run the probe to be sure." → No. Maker ≠ checker; authoring and probing are separate skills.
Red flags — STOP
- A value, secret literal, token, password, or connection string appears in any cell.
- A column named
value,command,verify,cmd, or any shell string in a cell. - A
kindoutside{env-var, mcp, service, runtime-dep, fixture, account}. - You are about to run a command to check an item (that's
preflight-readiness's job). - Pass 2 edits/overwrites a row that pass 1 signed.
- The manifest is absent for a feature heading into a wave.
Verification (ending criteria)
docs/features/<slug>/environment.mdexists with a## Manifesttable and astatus:field.- Every row's
kindis one of the six enum values. - Greppable security check (load-bearing done-predicate): no column header matches
value|command|verify|secret|cmd; no cell contains a secret-shaped literal (sk_,AKIA,-----BEGIN, or a URL embedding credentials). - Every row has a non-empty
purposeandrequired-by. - Un-probeable rows carry
manual: <question>; all others leaveattestblank forpreflight-readiness. - Pass-1 (
pass: spec) rows are part of the Spec sign-off bundle;status: signedonly after that gate.
Outputs & handoff contract
- Emits
docs/features/<slug>/environment.md. - Stable sections consumers depend on: the
status:field and the## Manifesttable with the fixedkind · name · purpose · required-by · pass · attestcolumns. Consumer:preflight-readinessreads the Manifest, runs its per-kind value-blind prober per row, honorsmanual:attestations, and refuses the wave on any red / un-attested amber. - Contract rule: change the manifest's shape (a new kind, a renamed column) → update
preflight-readiness+ its prober registry in the same commit (a new kind needs a new prober file; OCP). - STATE.md update: the feature sits in
feature: specwhile pass-1 is unsigned; the plan-pass append happens whilefeature: plan. This skill creates no slice rows. - Per-stage handoff: the signed manifest is one of the 4–5 Spec-gate artifacts (intent + prd + acceptance
- environment [+ design contract when UI]); the next cold reader (
preflight-readiness) needs nothing but this file.
- environment [+ design contract when UI]); the next cold reader (
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.