
strengthen
Upgrade a vigiles spec's guidance() rules to enforce() — scan the guidance rules in a CLAUDE.md/AGENTS.md spec and find existing linter rules (ESLint, Ruff, Clippy, Pylint, RuboCop, Stylelint) that back them. Use when asked to strengthen, harden, or make vigiles rules enforceable; NOT for general linting or fixing lint errors.
- Installs
- 2.1K
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/zernie/vigiles --skill strengthen- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads strengthen automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Scan spec files for guidance() rules and suggest enforce() replacements backed by real linter rules.
Principle: auto the free wins, nudge for the costs
The dividing line is cost, not strictness. A guidance() → enforce() swap where the linter rule already exists and is enabled is a pure win — free, reversible, no false-positive risk — so apply it (Tier 1 below). Anything that costs something — editing linter config, installing a plugin, or a change that could fail a clean CI — is the user's call: present it with the tradeoff spelled out and let them choose (Tiers 2–4). Never silently edit config, install a dependency, or escalate the repo into strict gating. This is the init enforcement model (structural = on by default, workflow/strict = opt-in) applied at edit time.
Instructions
Step 0: Choose Mode
Ask the user:
Auto or interactive?
- Auto — I'll apply all safe changes (direct replacements where the rule is already enabled), commit, and show you the diff. Risky changes (require config edits or plugin installs) go in a summary for you to review.
- Interactive — I'll present each suggestion and you pick which ones to apply.
Default to interactive if the user doesn't specify.
Step 1: Discover What's Installed
Run npx vigiles generate types to get the full list of enabled linter rules in the project. Read .vigiles/generated.d.ts to see every rule available across all detected linters.
Note which linter prefixes appear in the generated types (e.g., EslintRule, RuffRule). You'll only need reference docs for detected linters.
Step 2: Find All Guidance Rules
Find all .spec.ts files in the project (**/*.md.spec.ts). For each file, identify every guidance() rule.
Step 3: Match Against Generated Types (Fast Path)
For each guidance rule, check if an enabled rule in .vigiles/generated.d.ts directly matches. This is the fast, deterministic path — no doc reading needed.
Look for:
- Exact rule name in text — guidance says "no-console" and
no-consoleis in EslintRule - Semantic match — guidance says "don't use console.log" and
no-consoleis available - Rule description match — guidance says "unused variables" and
no-unused-varsor@typescript-eslint/no-unused-varsis available
If a match is found and the rule is in the generated types (meaning it's already enabled), this is a direct replacement — no config changes needed.
Step 4: Read Linter Docs (Slow Path)
For guidance rules that didn't match in Step 3, read the linter reference docs for the project's detected linters:
- ESLint →
../linter-docs/eslint.md - Stylelint →
../linter-docs/stylelint.md - Ruff →
../linter-docs/ruff.md - Pylint →
../linter-docs/pylint.md - RuboCop →
../linter-docs/rubocop.md - Clippy →
../linter-docs/clippy.md
Only read docs for linters the project actually uses. Skip docs for linters with no rules in generated types.
Check the plugin tables and decision matrices. The guidance text may describe a pattern covered by:
- A plugin rule that's installed but not enabled
- A plugin that's not installed yet
- A
no-restricted-*config pattern (see Step 4b)
Step 4b: no-restricted-* Patterns
Many guidance rules can be enforced via built-in linter config without a custom rule. This is the most common strengthen pattern — "don't do X" maps to a restriction config.
ESLint:
// "Don't import from internal modules"
"no-restricted-imports": ["error", {
patterns: [{ group: ["src/internal/*"], message: "Use the public API." }]
}],
// "Don't call console.log"
"no-restricted-syntax": ["error", {
selector: 'CallExpression[callee.object.name="console"]',
message: "Use the project logger."
}],
// "Don't use moment.js"
"no-restricted-imports": ["error", {
paths: [{ name: "moment", message: "Use dayjs instead." }]
}],
Ruff:
# "Don't use os.system"
[tool.ruff.lint.flake8-tidy-imports.banned-api]
"os.system".msg = "Use subprocess.run instead."
RuboCop:
# "Don't use puts in production" — if Rails/Output doesn't fit
Custom/NoPuts:
Enabled: true
When suggesting a no-restricted-* change:
- Show the exact config edit needed (which file, which section)
- Show the
enforce()rule that references it - Note that this changes linter config, not just the spec
Step 5: Present Suggestions
Group the output into tiers:
Tier 1: Direct replacements (rule already enabled — zero risk)
// Before
"no-console": guidance("Use structured logger instead of console.log"),
// After
"no-console": enforce("eslint/no-console", "Use structured logger instead of console.log"),
Tier 2: Config-backed (rule exists but needs config options)
// Spec change:
"no-moment": enforce("eslint/no-restricted-imports", "Use dayjs instead of moment."),
// Config change needed (eslint.config.mjs):
"no-restricted-imports": ["error", {
paths: [{ name: "moment", message: "Use dayjs instead." }]
}],
Tier 3: Plugin install needed
"cognitive-complexity": guidance("Keep functions simple")
→ Install eslint-plugin-sonarjs, enable sonarjs/cognitive-complexity
→ enforce("eslint/sonarjs/cognitive-complexity", "Keep functions simple")
Tier 4: No match (stays as guidance — candidate for a future rule-synthesis skill)
"research-first": guidance("Google unfamiliar APIs first.")
→ No linter rule can enforce this. Stays as guidance for now.
→ (Custom-rule synthesis is planned but not yet shipped.)
Step 6: Apply Changes
In auto mode:
- Apply all Tier 1 changes (edit spec files, replace
guidance()withenforce()) - Run
npm run build && npx vigiles compileto verify each change compiles - If any compilation fails, revert that specific change and report the error
- Commit all successful changes
- Present Tier 2-4 as a summary for the user to review
In interactive mode:
- Present all tiers
- Ask the user which suggestions to apply
- For approved Tier 2 changes: edit the linter config, then edit the spec
- Run
npm run build && npx vigiles compileto verify - If compilation fails, report the error and revert
For Tier 4 (no match): Tell the user these rules stay as guidance — custom-rule synthesis is a planned skill, not yet available.
FAQ
What does the strengthen skill do?
Upgrade a vigiles spec's guidance() rules to enforce() — scan the guidance rules in a CLAUDE.md/AGENTS.md spec and find existing linter rules (ESLint, Ruff, Clippy, Pylint, RuboCop, Stylelint) that back them. Use when asked to strengthen, harden, or make vigiles rules enforceable; NOT for general linting or fixing lint errors.
How do I install strengthen?
Run npx skills add https://github.com/zernie/vigiles --skill strengthen in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/strengthen/ (personal) or .claude/skills/strengthen/ (project).
Which AI agents can use strengthen?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is strengthen safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains strengthen?
It is published by zernie in zernie/vigiles. It has 2,071 recorded installs.
More from zernie/vigiles
edit-spec
zernie/vigiles
Edit a vigiles .spec.ts to change a compiled instruction file (CLAUDE.md / AGENTS.md) — add, modify, or remove a rule, section, command, or file pointer (including a request to add a "key file" — the keyFiles field is deprecated). 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.
test-harness
zernie/vigiles
Install vigiles and test a Claude Code harness — hooks, skills, agents, settings, CLAUDE.md — by picking the right tier (unit / deterministic / eval) and writing a test that passes. Use to check that a hook fires or blocks, that a skill triggers, that injected context lands; or to observe a run — which tools it called, whether it stayed inside its declared allowed-tools, what files and side effects it produced, how to intercept a call without executing it.
linter-docs
zernie/vigiles
Deep linter reference for authoring or debugging a vigiles enforce() rule — plugin tables, AST selectors, type-aware rules, auto-fix, and edge cases for ESLint, Ruff, Pylint, RuboCop, Stylelint, and Clippy. Use when you need the exact rule name or config for a specific linter, not for running a linter. (JVM/Go linters — detekt, ktlint, Checkstyle, golangci-lint — and Cedar have no deep-dive file yet; their reference lives in docs/linter-support.md.)
adopt-spec
zernie/vigiles
Adopt a typed .spec.ts for an existing hand-written CLAUDE.md — start from the file you already have, non-destructively
debug-my-harness
zernie/vigiles
Diagnose why an agent harness misbehaved by reading the local flight-recorder ledger (.vigiles/runs.jsonl) — which skills fired or got hijacked, which hooks blocked or wrongly allowed, which subagent tool-contract violations happened, and how a skill's trigger rate moved. Use when asked why a skill stopped firing, why a hook didn't block, why the wrong skill ran, or to debug/investigate what the harness actually did. NOT for writing new rules (use strengthen) or editing the spec (use edit-spec).
deep-research
zernie/vigiles
Use when the user asks to research a topic in depth, map a competitive/market landscape, run a multi-source investigation, or "fan out" parallel research agents — anything where many findings must be gathered and then NOT lost. Enforces durable, detail-preserving research (write full findings to disk; keep a full appendix beside the synthesis).
Popular code quality & workflow skills
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
improve-codebase-architecture
mattpocock/skills
Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
handoff
mattpocock/skills
Compact the current conversation into a handoff document for another agent to pick up.
domain-modeling
mattpocock/skills
Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or recording or editing an ADR.
codebase-design
mattpocock/skills
Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.
diagnosing-bugs
mattpocock/skills
Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.