# Edit Spec

> Edit a vigiles .spec.ts to change a compiled instruction file (CLAUDE.md / AGENTS.md) — add, modify, or remove a rule, section, command, or key file. Use whenever you need to change a CLAUDE.md/AGENTS.md that carries a vigiles hash (edit the spec, never the artifact), including adding a new enforce()/check()/guidance() rule.

- **Type:** Skill
- **Install:** `agentstack add skill-zernie-vigiles-edit-spec`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [zernie](https://agentstack.voostack.com/s/zernie)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [zernie](https://github.com/zernie)
- **Source:** https://github.com/zernie/vigiles/tree/main/skills/edit-spec
- **Website:** https://vigiles.sh

## Install

```sh
agentstack add skill-zernie-vigiles-edit-spec
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

Edit a `.spec.ts` file to update the project's instruction files. The spec is the source of truth — CLAUDE.md and AGENTS.md are compiled build artifacts that must not be edited directly.

## Arguments

$ARGUMENTS — What the user wants to change. Examples:

- "add a rule about always using the custom logger"
- "update the architecture section"
- "add src/services/auth.ts to key files"
- "add npm run lint to commands"
- "change the testing guidance"

## Instructions

### Step 1: Find the Spec

Look for spec files in the repo root:

- `CLAUDE.md.spec.ts` — source for CLAUDE.md
- `AGENTS.md.spec.ts` — source for AGENTS.md
- Any `*.spec.ts` matching instruction files

If no spec exists: if there's a hand-written `CLAUDE.md`, suggest the
`adopt-spec` skill; otherwise suggest `npx vigiles init` to scaffold one.

### Step 2: Read and Understand the Spec

Read the spec file. It's a TypeScript file that exports a `claude()` call with these fields:

```typescript
import { claude, enforce, guidance, check, every } from "vigiles/spec";

export default claude({
  // Optional: output target (defaults to "CLAUDE.md")
  target: "CLAUDE.md",
  // or multi-target:
  // target: ["CLAUDE.md", "AGENTS.md"],

  // Prose sections — become ## headings in compiled output
  sections: {
    positioning: "What this project does...",
    architecture: "How the codebase is structured...",
  },

  // File paths verified to exist at compile time
  keyFiles: {
    "src/index.ts": "Main entry point",
  },

  // Commands verified against package.json
  commands: {
    "npm run build": "Compile the project",
    "npm test": "Run all tests",
  },

  // Rules — three types
  rules: {
    // enforce() — backed by a linter rule, verified to exist AND be enabled
    "no-any": enforce(
      "@typescript-eslint/no-explicit-any",
      "Use unknown and narrow with type guards.",
    ),

    // check() — filesystem assertion run by vigiles
    "test-pairing": check(
      every("src/**/*.service.ts").has("{name}.test.ts"),
      "Every service must have tests.",
    ),

    // guidance() — prose only, no enforcement
    "research-first": guidance("Google unfamiliar APIs before implementing."),
  },
});
```

### Step 3: Make the Changes

Based on what the user asked for:

**Adding a rule** (this absorbs the old `generate-rule` skill):

- **Classify the rule** from the request:
  - `enforce()` — a linter rule can back it. Check the project's linter configs
    (ESLint, Ruff, Clippy, Pylint, RuboCop, Stylelint) for a matching rule; also
    consider an architectural tool (ast-grep, Dependency Cruiser, Steiger). If
    uncertain whether a rule exists, **ask the user** rather than guessing.
  - `check()` — a filesystem structural convention ("every X needs a Y"). Only
    for file-pairing; never for code content.
  - `guidance()` — can't be mechanically enforced (subjective conventions,
    process rules, migration context).
- For `enforce()`: use the real linter rule name (e.g. `eslint/no-console`,
  `@typescript-eslint/no-explicit-any`, `ruff/T201`).
- Add to the `rules` object with a kebab-case key derived from the intent,
  preserving alphabetical order if the existing rules are alphabetical. Import
  any new builders needed (e.g. `check` and `every` for the first `check()`).

**Updating a section:**

- Edit the string in `sections`. Sections are plain strings or tagged template literals with `file()`, `cmd()`, `ref()` for verified references
- Do NOT add `#` or `##` headers inside sections — they break the document structure

**Adding a key file or command:**

- Add to `keyFiles` or `commands`. The compiler verifies these exist at compile time
- For commands: must match a script in `package.json`
- For key files: must exist on disk

### Step 4: Compile

After editing the spec, run:

```bash
npx vigiles compile
```

This regenerates the compiled instruction file(s). Review the output for any errors:

- `stale-file` — a key file path doesn't exist
- `stale-command` — a command isn't in package.json
- `invalid-rule` — a linter rule doesn't exist or is disabled
- `section-has-header` — a section contains `#` headers (break into separate named sections)

### Step 5: Verify

```bash
npx vigiles lint
```

If the vigiles plugin is installed (`/plugin marketplace add zernie/vigiles` then `/plugin install vigiles@vigiles`, or `npx vigiles init`), the PostToolUse hook recompiles automatically after you save the spec.

## Important

- **Do what's asked; don't silently escalate enforcement.** Add the rule the user asked for. If making it an `enforce()` would need a linter-config edit or a plugin install (a cost), or if it could fail a clean CI, **say so and let the user choose** — don't change linter config or flip on strict / `workflow` gating on your own. A pure win (a rule that's already enabled) you can just apply. The `strengthen` skill owns `guidance()` → `enforce()` upgrades.
- **Never edit CLAUDE.md or AGENTS.md directly** — they have a vigiles hash comment and are build artifacts
- **The spec is TypeScript** — you get type checking, autocomplete, and verified references
- **`enforce()` rules are verified** — the compiler checks the rule exists AND is enabled in your linter config
- **Sections must not contain `#` or `##` headers** — use separate named sections instead

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [zernie](https://github.com/zernie)
- **Source:** [zernie/vigiles](https://github.com/zernie/vigiles)
- **License:** MIT
- **Homepage:** https://vigiles.sh

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-zernie-vigiles-edit-spec
- Seller: https://agentstack.voostack.com/s/zernie
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
