vigiles 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.json +46 -0
- package/.claude/settings.local.json +8 -0
- package/.claude-plugin/hooks/post-edit.sh +34 -0
- package/.claude-plugin/hooks/pre-edit.sh +40 -0
- package/.claude-plugin/hooks/session-start.sh +38 -0
- package/.claude-plugin/marketplace.json +14 -0
- package/.claude-plugin/plugin.json +47 -0
- package/.github/workflows/ci.yml +81 -0
- package/.prettierignore +1 -0
- package/.vigiles/generated.d.ts +205 -0
- package/CLAUDE.md +95 -0
- package/CLAUDE.md.spec.ts +142 -0
- package/CONTRIBUTING.md +121 -0
- package/LICENSE +21 -0
- package/README.md +377 -0
- package/action.yml +25 -0
- package/dist/action.d.ts +7 -0
- package/dist/action.d.ts.map +1 -0
- package/dist/action.js +180 -0
- package/dist/action.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1267 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.test.d.ts +2 -0
- package/dist/cli.test.d.ts.map +1 -0
- package/dist/cli.test.js +650 -0
- package/dist/cli.test.js.map +1 -0
- package/dist/compile.d.ts +101 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +503 -0
- package/dist/compile.js.map +1 -0
- package/dist/evolve.d.ts +132 -0
- package/dist/evolve.d.ts.map +1 -0
- package/dist/evolve.js +599 -0
- package/dist/evolve.js.map +1 -0
- package/dist/freshness.d.ts +67 -0
- package/dist/freshness.d.ts.map +1 -0
- package/dist/freshness.js +244 -0
- package/dist/freshness.js.map +1 -0
- package/dist/freshness.test.d.ts +2 -0
- package/dist/freshness.test.d.ts.map +1 -0
- package/dist/freshness.test.js +356 -0
- package/dist/freshness.test.js.map +1 -0
- package/dist/generate-types.d.ts +34 -0
- package/dist/generate-types.d.ts.map +1 -0
- package/dist/generate-types.js +381 -0
- package/dist/generate-types.js.map +1 -0
- package/dist/inline.d.ts +58 -0
- package/dist/inline.d.ts.map +1 -0
- package/dist/inline.js +142 -0
- package/dist/inline.js.map +1 -0
- package/dist/inline.test.d.ts +5 -0
- package/dist/inline.test.d.ts.map +1 -0
- package/dist/inline.test.js +152 -0
- package/dist/inline.test.js.map +1 -0
- package/dist/linters.d.ts +38 -0
- package/dist/linters.d.ts.map +1 -0
- package/dist/linters.js +588 -0
- package/dist/linters.js.map +1 -0
- package/dist/proofs.d.ts +272 -0
- package/dist/proofs.d.ts.map +1 -0
- package/dist/proofs.js +622 -0
- package/dist/proofs.js.map +1 -0
- package/dist/proofs.test.d.ts +9 -0
- package/dist/proofs.test.d.ts.map +1 -0
- package/dist/proofs.test.js +952 -0
- package/dist/proofs.test.js.map +1 -0
- package/dist/spec.d.ts +258 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +113 -0
- package/dist/spec.js.map +1 -0
- package/dist/spec.test.d.ts +2 -0
- package/dist/spec.test.d.ts.map +1 -0
- package/dist/spec.test.js +1222 -0
- package/dist/spec.test.js.map +1 -0
- package/dist/types.d.ts +101 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +10 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +286 -0
- package/dist/validate.js.map +1 -0
- package/dist/validate.test.d.ts +2 -0
- package/dist/validate.test.d.ts.map +1 -0
- package/dist/validate.test.js +531 -0
- package/dist/validate.test.js.map +1 -0
- package/docs/agent-setup.md +85 -0
- package/docs/agent-workflows.md +103 -0
- package/docs/comparison.md +71 -0
- package/docs/freshness.md +124 -0
- package/docs/inline-mode.md +119 -0
- package/docs/linter-support.md +166 -0
- package/docs/spec-format.md +194 -0
- package/eslint.config.mjs +79 -0
- package/examples/CLAUDE.md +54 -0
- package/examples/CLAUDE.md.spec.ts +65 -0
- package/examples/SKILL.md +50 -0
- package/examples/SKILL.md.spec.ts +57 -0
- package/fixtures/example-project/CLAUDE.md +11 -0
- package/fixtures/example-project/package.json +9 -0
- package/fixtures/example-project/src/index.ts +3 -0
- package/fixtures/example-project/src/utils.test.ts +2 -0
- package/fixtures/example-project/src/utils.ts +3 -0
- package/logo.png +0 -0
- package/package.json +42 -0
- package/research/adoption-strategy.md +111 -0
- package/research/agent-integration.md +145 -0
- package/research/ai-code-quality.md +197 -0
- package/research/code-search-for-agents.md +313 -0
- package/research/competitive-landscape.md +163 -0
- package/research/doc-freshness.md +516 -0
- package/research/executable-specs.md +368 -0
- package/research/feature-ideas.md +464 -0
- package/research/formal-proofs-for-agents.md +338 -0
- package/research/fp-for-agent-harness.md +150 -0
- package/research/fp-for-deterministic-ai.md +131 -0
- package/research/self-evolving-specs.md +298 -0
- package/schemas/claude-md-strict.yml +18 -0
- package/schemas/claude-md.yml +6 -0
- package/schemas/skill-strict.yml +12 -0
- package/schemas/skill.yml +5 -0
- package/skills/audit-feedback-loop/SKILL.md +76 -0
- package/skills/edit-spec/SKILL.md +131 -0
- package/skills/enforce-rules-format/SKILL.md +71 -0
- package/skills/generate-logo/SKILL.md +102 -0
- package/skills/generate-rule/SKILL.md +90 -0
- package/skills/linter-docs/clippy.md +241 -0
- package/skills/linter-docs/eslint.md +384 -0
- package/skills/linter-docs/pylint.md +288 -0
- package/skills/linter-docs/rubocop.md +277 -0
- package/skills/linter-docs/ruff.md +187 -0
- package/skills/linter-docs/stylelint.md +247 -0
- package/skills/migrate-to-spec/SKILL.md +124 -0
- package/skills/pr-to-lint-rule/SKILL.md +97 -0
- package/skills/strengthen/SKILL.md +168 -0
- package/src/action.ts +214 -0
- package/src/cli.test.ts +914 -0
- package/src/cli.ts +1631 -0
- package/src/compile.ts +691 -0
- package/src/evolve.ts +781 -0
- package/src/freshness.test.ts +449 -0
- package/src/freshness.ts +299 -0
- package/src/generate-types.ts +448 -0
- package/src/inline.test.ts +206 -0
- package/src/inline.ts +164 -0
- package/src/linters.ts +739 -0
- package/src/proofs.test.ts +1314 -0
- package/src/proofs.ts +849 -0
- package/src/spec.test.ts +1471 -0
- package/src/spec.ts +427 -0
- package/src/types.ts +117 -0
- package/src/validate.test.ts +701 -0
- package/src/validate.ts +381 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# Self-Evolving Specification System
|
|
2
|
+
|
|
3
|
+
Design document for vigiles's self-evolving spec system. Specs mutate, proofs verify, only valid mutations survive. The system improves itself deterministically — AI proposes changes, algorithms prove correctness.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Core Insight
|
|
8
|
+
|
|
9
|
+
vigiles already proves things at compile time: file references exist, linter rules are enabled, commands are in package.json. But these are **static assertions about the world**. The next frontier is **dynamic assertions about the spec itself** — proofs that the specification system is evolving correctly over time.
|
|
10
|
+
|
|
11
|
+
The key principle: **LLM proposes, deterministic algorithm disposes.** AI agents suggest spec mutations (new rules, strengthened enforcement, merged sections). A suite of proof algorithms verifies each mutation before it's accepted. No mutation enters the spec without passing every proof.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────┐
|
|
19
|
+
│ AI Agent │
|
|
20
|
+
│ (proposer) │
|
|
21
|
+
└──────┬──────┘
|
|
22
|
+
│ proposes mutation
|
|
23
|
+
▼
|
|
24
|
+
┌─────────────┐
|
|
25
|
+
│ Evolution │
|
|
26
|
+
│ Engine │
|
|
27
|
+
└──────┬──────┘
|
|
28
|
+
│ applies mutation to spec
|
|
29
|
+
▼
|
|
30
|
+
┌────────────────────────┐
|
|
31
|
+
│ Proof Suite │
|
|
32
|
+
│ │
|
|
33
|
+
│ ┌──────────────────┐ │
|
|
34
|
+
│ │ Monotonicity │ │ ← rules only strengthen;
|
|
35
|
+
│ │ Lattice │ │ removals require allowlist
|
|
36
|
+
│ ├──────────────────┤ │
|
|
37
|
+
│ │ NCD Similarity │ │ ← no NEW duplicate pairs
|
|
38
|
+
│ │ Distance │ │ (pre-existing dups ignored)
|
|
39
|
+
│ ├──────────────────┤ │
|
|
40
|
+
│ │ Fixed-Point │ │ ← compilation converges
|
|
41
|
+
│ │ Convergence │ │
|
|
42
|
+
│ ├──────────────────┤ │
|
|
43
|
+
│ │ Bloom Filter │ │ ← token overlap vs surviving
|
|
44
|
+
│ │ Index │ │ rules only (excludes removed)
|
|
45
|
+
│ ├──────────────────┤ │
|
|
46
|
+
│ │ Property-Based │ │ ← invariants hold under
|
|
47
|
+
│ │ Testing │ │ random mutations
|
|
48
|
+
│ └──────────────────┘ │
|
|
49
|
+
└────────────┬───────────┘
|
|
50
|
+
│ all proofs pass?
|
|
51
|
+
▼
|
|
52
|
+
┌─────────────┐
|
|
53
|
+
│ Merkle DAG │ ← append to tamper-evident history
|
|
54
|
+
│ History │
|
|
55
|
+
└──────┬──────┘
|
|
56
|
+
│
|
|
57
|
+
▼
|
|
58
|
+
┌─────────────┐
|
|
59
|
+
│ Accept │ → new spec version
|
|
60
|
+
└─────────────┘
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Proof Algorithms
|
|
66
|
+
|
|
67
|
+
### 1. Monotonicity Lattice (Rule Strength Ordering)
|
|
68
|
+
|
|
69
|
+
Rules form a lattice ordered by enforcement strength:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
enforce (1) ← strongest: backed by external linter
|
|
73
|
+
│
|
|
74
|
+
guidance (0) ← weakest: prose only
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Monotonicity proof**: Given spec version N and proposed version N+1, for every rule that exists in both versions, its strength in N+1 must be ≥ its strength in N. Weakening requires an explicit `allowWeaken` flag. **Removing** a rule is also a violation unless the rule ID is in `allowWeaken` — otherwise a bare `remove` mutation could pass on neutral fitness and silently delete constraints.
|
|
78
|
+
|
|
79
|
+
This is a **partial order** — rules can be added freely, but existing rules can only move UP the lattice (guidance → enforce). Catches the silent regression where someone downgrades an enforced rule or deletes it entirely.
|
|
80
|
+
|
|
81
|
+
The lattice extends to coverage: the set of enforced rule IDs in N+1 must be a superset of N's enforced IDs (minus any explicit allowlist).
|
|
82
|
+
|
|
83
|
+
**Algorithm**: O(n) comparison of rule maps. For each rule ID present in both versions, compare ordinal values.
|
|
84
|
+
|
|
85
|
+
### 2. Normalized Compression Distance (Rule Deduplication)
|
|
86
|
+
|
|
87
|
+
NCD is an information-theoretic metric that approximates Kolmogorov complexity:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
NCD(x, y) = (C(xy) - min(C(x), C(y))) / max(C(x), C(y))
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Where C() is the compressed size (using zlib/gzip). Range: [0, 1+ε] where 0 = identical information content, 1 = maximally different.
|
|
94
|
+
|
|
95
|
+
**Use case**: Detect semantically similar rules that should be merged. Two rules about "no console.log" and "use structured logger instead of console" have low NCD because they share information content — even though they use different words.
|
|
96
|
+
|
|
97
|
+
**Why NCD over cosine similarity or embeddings?**
|
|
98
|
+
|
|
99
|
+
- Deterministic — same input always produces same output
|
|
100
|
+
- No model dependency — works offline, no API calls
|
|
101
|
+
- Language-agnostic — works on any string content
|
|
102
|
+
- Theoretically grounded — approximates the universal similarity metric (Li et al. 2004)
|
|
103
|
+
|
|
104
|
+
**Threshold**: NCD < 0.3 suggests near-duplication. NCD < 0.5 suggests related content worth reviewing.
|
|
105
|
+
|
|
106
|
+
### 3. Fixed-Point Convergence
|
|
107
|
+
|
|
108
|
+
Specs can trigger recompilation (e.g., a rule that references a generated file). The compilation must converge — running the compiler repeatedly must reach a fixed point where the output stops changing.
|
|
109
|
+
|
|
110
|
+
**Algorithm**: Iterate compilation up to N times (default 10). At each step, hash the output. If hash[i] === hash[i-1], fixed point reached. If after N iterations no fixed point, the spec is **divergent** — report the cycle.
|
|
111
|
+
|
|
112
|
+
**Formal basis**: This is the discrete analog of Banach's fixed-point theorem. The compiler is a contraction mapping on the space of markdown documents (most compilations reduce or preserve information). Convergence is guaranteed when the compiler is contractive.
|
|
113
|
+
|
|
114
|
+
**Practical check**: Most specs converge in 1 iteration (compilation is idempotent). Specs that reference their own output (self-referential) may take 2-3 iterations. Specs that never converge have a bug.
|
|
115
|
+
|
|
116
|
+
### 4. Bloom Filter Index
|
|
117
|
+
|
|
118
|
+
A space-efficient probabilistic data structure for approximate set membership.
|
|
119
|
+
|
|
120
|
+
**Use case**: Fast pre-filtering for rule similarity. Before computing expensive NCD comparisons (O(n²) for n rules), use a Bloom filter to quickly identify candidate pairs that share tokens.
|
|
121
|
+
|
|
122
|
+
**Parameters**:
|
|
123
|
+
|
|
124
|
+
- m = bit array size (calculated from desired false positive rate)
|
|
125
|
+
- k = number of hash functions (optimal: k = (m/n) × ln2)
|
|
126
|
+
- FPR ≈ (1 - e^(-kn/m))^k
|
|
127
|
+
|
|
128
|
+
For 1000 rules with 1% false positive rate: m ≈ 9,586 bits (~1.2 KB), k = 7.
|
|
129
|
+
|
|
130
|
+
**Hash functions**: FNV-1a with k different seeds. Fast, good distribution, no crypto overhead.
|
|
131
|
+
|
|
132
|
+
### 5. Merkle DAG History
|
|
133
|
+
|
|
134
|
+
Every spec version is a node in a content-addressed DAG:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
interface HistoryNode {
|
|
138
|
+
hash: string; // SHA-256 of this node's content
|
|
139
|
+
parentHash: string; // hash of previous version (or "genesis")
|
|
140
|
+
specHash: string; // hash of the compiled spec
|
|
141
|
+
mutation: Mutation; // what changed
|
|
142
|
+
proofs: ProofResult[]; // which proofs were run and passed
|
|
143
|
+
timestamp: number;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Properties**:
|
|
148
|
+
|
|
149
|
+
- **Tamper-evident**: Changing any node invalidates all descendant hashes
|
|
150
|
+
- **Append-only**: New versions append to the DAG, never modify history
|
|
151
|
+
- **Verifiable**: Anyone can recompute the hash chain and verify integrity
|
|
152
|
+
- **Branchable**: Fork the DAG for parallel spec evolution (e.g., different teams)
|
|
153
|
+
|
|
154
|
+
**Verification**: Walk the chain from any node to genesis, recomputing hashes. If any hash mismatches, the history was tampered with.
|
|
155
|
+
|
|
156
|
+
### 6. Property-Based Testing
|
|
157
|
+
|
|
158
|
+
Generate random valid mutations and verify that invariants hold across all of them.
|
|
159
|
+
|
|
160
|
+
**Invariants**:
|
|
161
|
+
|
|
162
|
+
- **Idempotency**: Compiling a spec twice produces identical output (hash equality)
|
|
163
|
+
- **Monotonic coverage**: Adding a rule never decreases coverage percentage
|
|
164
|
+
- **Hash stability**: The hash of unchanged content is stable across compilations
|
|
165
|
+
- **Serialization roundtrip**: spec → JSON → spec produces equivalent result
|
|
166
|
+
|
|
167
|
+
**Mutation generators**:
|
|
168
|
+
|
|
169
|
+
- Add random guidance/enforce rule
|
|
170
|
+
- Strengthen random `guidance → enforce`
|
|
171
|
+
- Remove random rule
|
|
172
|
+
- Reorder rules
|
|
173
|
+
- Modify rule text
|
|
174
|
+
|
|
175
|
+
**Shrinking**: When an invariant fails, binary-search the mutation sequence to find the minimal failing case. Start with N mutations, try N/2, etc.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Evolution Engine
|
|
180
|
+
|
|
181
|
+
### Mutation Operators
|
|
182
|
+
|
|
183
|
+
| Operator | Input | Output | Proof Required |
|
|
184
|
+
| ------------ | ---------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
185
|
+
| `add` | rule definition | spec + new rule | NCD (no _new_ duplicate pairs), bloom (vs surviving rules) |
|
|
186
|
+
| `remove` | rule ID | spec − rule | Monotonicity (rejects unless rule in `allowWeaken`) |
|
|
187
|
+
| `strengthen` | rule ID + linterRule | `guidance → enforce` | Monotonicity (always passes by definition) |
|
|
188
|
+
| `weaken` | rule ID + justification | `enforce → guidance` | Monotonicity (requires `allowWeaken`) |
|
|
189
|
+
| `merge` | two source IDs + merged rule | sources removed, merged rule added | Sources allowlisted for this call; merged rule must be ≥ strongest source; bloom excludes removed IDs |
|
|
190
|
+
| `reword` | rule ID + new text | updated rule text | NCD (no new duplicate pair introduced) |
|
|
191
|
+
|
|
192
|
+
Two rule kinds today (`enforce`, `guidance`) — the earlier `check` kind
|
|
193
|
+
was dropped. Strength ordering is `guidance < enforce`.
|
|
194
|
+
|
|
195
|
+
### Fitness Function
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
fitness(spec) = coverage × (1 - redundancy) × (1 - budget_pressure)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Where:
|
|
202
|
+
|
|
203
|
+
- **coverage** = enforced rules / total rules — fraction with teeth
|
|
204
|
+
- **redundancy** = fraction of rule pairs below the NCD threshold — penalizes duplication
|
|
205
|
+
- **budget_pressure** = tokens_used / max_tokens — penalizes bloat
|
|
206
|
+
|
|
207
|
+
Higher fitness = better spec. Range: [0, 1].
|
|
208
|
+
|
|
209
|
+
### Selection Protocol
|
|
210
|
+
|
|
211
|
+
1. AI agent proposes a mutation
|
|
212
|
+
2. Evolution engine applies mutation to produce candidate spec
|
|
213
|
+
3. Run full proof suite on candidate
|
|
214
|
+
4. If all proofs pass AND fitness(candidate) ≥ fitness(current): **accept**
|
|
215
|
+
5. If proofs fail: **reject** with diagnostic (which proof failed, why)
|
|
216
|
+
6. Append accepted mutation to Merkle history
|
|
217
|
+
|
|
218
|
+
This is a **hill-climbing** algorithm with proof-based constraints. The proofs prevent invalid moves; the fitness function guides toward better specs.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Self-Evolution Loop
|
|
223
|
+
|
|
224
|
+
The full loop for autonomous spec improvement:
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
1. Agent analyzes codebase (linter violations, PR comments, test failures)
|
|
228
|
+
2. Agent proposes mutation: "Add enforce('eslint/no-floating-promises')"
|
|
229
|
+
3. Evolution engine:
|
|
230
|
+
a. Apply mutation to spec
|
|
231
|
+
b. Run proof suite:
|
|
232
|
+
- Monotonicity: ✓ (adding a rule, not weakening)
|
|
233
|
+
- NCD: ✓ (no NEW near-duplicate pair vs baseline)
|
|
234
|
+
- Fixed-point: ✓ (compilation converges in 1 iteration)
|
|
235
|
+
- Bloom filter: ✓ (no token overlap against surviving rules)
|
|
236
|
+
c. Compute fitness: 0.73 → 0.76 (improvement)
|
|
237
|
+
d. Accept mutation
|
|
238
|
+
4. Append to Merkle history with proof receipts
|
|
239
|
+
5. Recompile spec → new CLAUDE.md
|
|
240
|
+
6. Commit with evolution metadata
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The agent can run this loop continuously. Each iteration is deterministically verified. The spec gets better over time without human intervention — but every change is auditable and reversible.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Implementation
|
|
248
|
+
|
|
249
|
+
### Core Modules
|
|
250
|
+
|
|
251
|
+
| Module | Purpose | Key Exports |
|
|
252
|
+
| -------------------- | ---------------- | ------------------------------------------------------------------------------------------ |
|
|
253
|
+
| `src/proofs.ts` | Proof algorithms | `MonotonicityLattice`, `ncd`, `BloomFilter`, `fixedPoint`, `MerkleHistory`, `propertyTest` |
|
|
254
|
+
| `src/evolve.ts` | Evolution engine | `EvolutionEngine`, mutations, fitness, selection |
|
|
255
|
+
| `src/proofs.test.ts` | Proof tests | Comprehensive test suite for all algorithms |
|
|
256
|
+
|
|
257
|
+
### Dependencies
|
|
258
|
+
|
|
259
|
+
All algorithms use only Node.js built-ins:
|
|
260
|
+
|
|
261
|
+
- `node:crypto` — SHA-256 for Merkle hashing
|
|
262
|
+
- `node:zlib` — gzip for NCD compression
|
|
263
|
+
- No external dependencies added
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Theoretical Foundations
|
|
268
|
+
|
|
269
|
+
| Algorithm | Theory | Complexity | Reference |
|
|
270
|
+
| ----------------------- | ------------------------------------------------------ | ---------------------------------- | ------------------------------------------------------- |
|
|
271
|
+
| Monotonicity lattice | Order theory, lattice algebra | O(n) per comparison | Davey & Priestley, "Introduction to Lattices and Order" |
|
|
272
|
+
| NCD | Kolmogorov complexity, information theory | O(n log n) per pair (compression) | Li et al. 2004, "The Similarity Metric" |
|
|
273
|
+
| Fixed-point convergence | Banach fixed-point theorem, discrete dynamical systems | O(k × compile_time) | Granas & Dugundji, "Fixed Point Theory" |
|
|
274
|
+
| Bloom filter | Probabilistic data structures | O(k) per insert/query | Bloom 1970, "Space/Time Trade-offs in Hash Coding" |
|
|
275
|
+
| Merkle DAG | Cryptographic hash chains, content addressing | O(n) verification | Merkle 1987 |
|
|
276
|
+
| Property-based testing | QuickCheck, fuzzing theory | O(n × m) for n tests × m mutations | Claessen & Hughes 2000 |
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## What This Enables
|
|
281
|
+
|
|
282
|
+
1. **Autonomous spec improvement** — AI agents propose changes, proofs verify them, no human in the loop for routine improvements
|
|
283
|
+
2. **Auditable evolution** — Every change has a Merkle proof chain back to genesis
|
|
284
|
+
3. **Regression prevention** — Monotonicity lattice catches silent weakening
|
|
285
|
+
4. **Deduplication** — NCD + Bloom filter catch redundant rules before they bloat the spec
|
|
286
|
+
5. **Convergence guarantee** — Fixed-point analysis catches pathological self-referential specs
|
|
287
|
+
6. **Robustness testing** — Property-based testing finds edge cases humans miss
|
|
288
|
+
7. **Cross-project learning** — Bloom filter indices can be shared across projects for fast rule discovery without sharing actual content
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Open Questions
|
|
293
|
+
|
|
294
|
+
1. **Multi-agent convergence** — When multiple agents propose mutations concurrently, how to merge? CRDTs for spec evolution?
|
|
295
|
+
2. **Fitness landscape visualization** — Can we render the fitness landscape to help humans understand spec quality?
|
|
296
|
+
3. **Transfer learning** — Can Bloom filter indices from mature projects accelerate new project bootstrap?
|
|
297
|
+
4. **Formal verification** — Could we encode the monotonicity lattice in a proof assistant (Lean, Coq) for machine-checked proofs?
|
|
298
|
+
5. **Adversarial robustness** — Can a malicious agent craft mutations that pass all proofs but degrade spec quality in subtle ways?
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Strict schema for CLAUDE.md — enforces consistent template structure.
|
|
2
|
+
# See https://github.com/jackchuka/mdschema for full syntax
|
|
3
|
+
|
|
4
|
+
structure:
|
|
5
|
+
- heading:
|
|
6
|
+
pattern: "# .+"
|
|
7
|
+
optional: true
|
|
8
|
+
allow_additional: true
|
|
9
|
+
children:
|
|
10
|
+
- heading: "## Commands"
|
|
11
|
+
- heading: "## Architecture"
|
|
12
|
+
optional: true
|
|
13
|
+
- heading: "## Rules"
|
|
14
|
+
optional: true
|
|
15
|
+
|
|
16
|
+
heading_rules:
|
|
17
|
+
no_skip_levels: true
|
|
18
|
+
max_depth: 4
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Strict schema for SKILL.md — enforces frontmatter fields and heading depth.
|
|
2
|
+
# See https://github.com/jackchuka/mdschema for full syntax
|
|
3
|
+
|
|
4
|
+
frontmatter:
|
|
5
|
+
fields:
|
|
6
|
+
- name: "description"
|
|
7
|
+
required: true
|
|
8
|
+
- name: "name"
|
|
9
|
+
required: false
|
|
10
|
+
|
|
11
|
+
heading_rules:
|
|
12
|
+
max_depth: 4
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: audit-feedback-loop
|
|
3
|
+
description: Scan the current repo and score its feedback loop maturity for AI-assisted development
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Scan the current repository and score its feedback loop maturity for AI-assisted development.
|
|
8
|
+
|
|
9
|
+
## Instructions
|
|
10
|
+
|
|
11
|
+
Analyze this repository and score its **feedback loop maturity** using the levels below. Check for each signal, then output a summary report.
|
|
12
|
+
|
|
13
|
+
### Maturity Levels
|
|
14
|
+
|
|
15
|
+
**Level 0 — Vibes**
|
|
16
|
+
No CI config, no linter rules, no CLAUDE.md. The AI agent is flying blind.
|
|
17
|
+
|
|
18
|
+
**Level 1 — Guardrails**
|
|
19
|
+
Has CI + standard linters, but no custom rules. The agent gets basic feedback but can't learn project-specific conventions.
|
|
20
|
+
|
|
21
|
+
**Level 2 — Architecture as Code**
|
|
22
|
+
Has custom lint rules, CLAUDE.md rules have enforcement annotations. The agent gets rich, project-specific feedback.
|
|
23
|
+
|
|
24
|
+
**Level 3 — The Organism**
|
|
25
|
+
Has CI + custom rules + screenshot/visual tests + observability + scheduled agent tasks. The entire development loop is instrumented.
|
|
26
|
+
|
|
27
|
+
### Signals to Check
|
|
28
|
+
|
|
29
|
+
Scan the repository for the following and note which exist:
|
|
30
|
+
|
|
31
|
+
1. **CI Configuration**: Look for `.github/workflows/`, `.circleci/`, `Jenkinsfile`, `.gitlab-ci.yml`, `bitbucket-pipelines.yml`, `.travis.yml`, etc.
|
|
32
|
+
2. **Linter Config** (language-aware):
|
|
33
|
+
- **JS/TS**: `eslint.config.*`, `.eslintrc*`, `biome.json`, `.prettierrc*`, `deno.json`
|
|
34
|
+
- **Python**: `pyproject.toml` (look for `[tool.ruff]`, `[tool.pylint]`, `[tool.flake8]`), `setup.cfg`, `.flake8`, `ruff.toml`
|
|
35
|
+
- **Rust**: `clippy.toml`, `.clippy.toml`, `rustfmt.toml`
|
|
36
|
+
- **Go**: `.golangci.yml`, `.golangci.yaml`
|
|
37
|
+
- **Ruby**: `.rubocop.yml`
|
|
38
|
+
- **Java/Kotlin**: `checkstyle.xml`, `pmd.xml`, `detekt.yml`
|
|
39
|
+
3. **Custom Lint Rules**: Look for custom plugins, rule directories, or inline rule definitions in linter configs
|
|
40
|
+
- JS/TS: `eslint-plugin-*`, `eslint-rules/` directories
|
|
41
|
+
- Python: custom Ruff/Pylint plugins, AST-based checks
|
|
42
|
+
- Rust: custom Clippy lints
|
|
43
|
+
- Go: custom analyzers
|
|
44
|
+
4. **CLAUDE.md**: Check if `CLAUDE.md` exists at the repo root
|
|
45
|
+
5. **CLAUDE.md Enforcement**: Check if using vigiles v2 specs (`CLAUDE.md.spec.ts` exists) or v1 annotations (`**Enforced by:**` in CLAUDE.md). v2 specs = higher maturity.
|
|
46
|
+
6. **Type-Safe Specs**: Check for `CLAUDE.md.spec.ts` or `*.spec.ts` files — indicates typed spec compilation via vigiles v2
|
|
47
|
+
7. **Generated Types**: Check for `.vigiles/generated.d.ts` — indicates linter rules are type-checked at authoring time
|
|
48
|
+
8. **Screenshot/Visual Tests**: Look for Playwright (`playwright.config.*`), Cypress (`cypress.config.*`), Chromatic, Percy, BackstopJS configs
|
|
49
|
+
9. **Observability**: Search for imports/usage of `@sentry/`, `dd-trace`, `@datadog/`, `newrelic`, `@opentelemetry/`, `sentry_sdk`, `structlog`, `tracing` (Rust), `opentelemetry` in source files
|
|
50
|
+
10. **Scheduled Agent Tasks**: Look for cron patterns in CI configs, `.github/workflows/` with `schedule:` triggers, or references to scheduled Claude Code tasks
|
|
51
|
+
|
|
52
|
+
### Output Format
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
## Feedback Loop Audit
|
|
56
|
+
|
|
57
|
+
**Repository:** <repo name>
|
|
58
|
+
**Primary language(s):** <detected languages>
|
|
59
|
+
**Score: Level X — <Name>**
|
|
60
|
+
|
|
61
|
+
### Signals Found
|
|
62
|
+
- [x] CI Configuration: <details>
|
|
63
|
+
- [ ] Custom Lint Rules: not found
|
|
64
|
+
- [x] CLAUDE.md: found, 5 enforced / 2 guidance / 1 missing
|
|
65
|
+
...
|
|
66
|
+
|
|
67
|
+
### Recommendations
|
|
68
|
+
1. <Most impactful next step to level up>
|
|
69
|
+
2. <Second recommendation>
|
|
70
|
+
3. <Third recommendation>
|
|
71
|
+
|
|
72
|
+
### How to Level Up
|
|
73
|
+
<Specific, actionable advice for reaching the next maturity level>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Be specific about file paths and what you found. Give actionable recommendations tailored to the project's language and toolchain.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: edit-spec
|
|
3
|
+
description: Edit a vigiles spec file to update instruction files (CLAUDE.md, AGENTS.md)
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
argument-hint: <what to change — e.g., "add a rule about error handling" or "update the testing section">
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
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.
|
|
9
|
+
|
|
10
|
+
## Arguments
|
|
11
|
+
|
|
12
|
+
$ARGUMENTS — What the user wants to change. Examples:
|
|
13
|
+
|
|
14
|
+
- "add a rule about always using the custom logger"
|
|
15
|
+
- "update the architecture section"
|
|
16
|
+
- "add src/services/auth.ts to key files"
|
|
17
|
+
- "add npm run lint to commands"
|
|
18
|
+
- "change the testing guidance"
|
|
19
|
+
|
|
20
|
+
## Instructions
|
|
21
|
+
|
|
22
|
+
### Step 1: Find the Spec
|
|
23
|
+
|
|
24
|
+
Look for spec files in the repo root:
|
|
25
|
+
|
|
26
|
+
- `CLAUDE.md.spec.ts` — source for CLAUDE.md
|
|
27
|
+
- `AGENTS.md.spec.ts` — source for AGENTS.md
|
|
28
|
+
- Any `*.spec.ts` matching instruction files
|
|
29
|
+
|
|
30
|
+
If no spec exists, suggest: `npx vigiles setup`
|
|
31
|
+
|
|
32
|
+
### Step 2: Read and Understand the Spec
|
|
33
|
+
|
|
34
|
+
Read the spec file. It's a TypeScript file that exports a `claude()` call with these fields:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { claude, enforce, guidance, check, every } from "vigiles/spec";
|
|
38
|
+
|
|
39
|
+
export default claude({
|
|
40
|
+
// Optional: output target (defaults to "CLAUDE.md")
|
|
41
|
+
target: "CLAUDE.md",
|
|
42
|
+
// or multi-target:
|
|
43
|
+
// target: ["CLAUDE.md", "AGENTS.md"],
|
|
44
|
+
|
|
45
|
+
// Prose sections — become ## headings in compiled output
|
|
46
|
+
sections: {
|
|
47
|
+
positioning: "What this project does...",
|
|
48
|
+
architecture: "How the codebase is structured...",
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
// File paths verified to exist at compile time
|
|
52
|
+
keyFiles: {
|
|
53
|
+
"src/index.ts": "Main entry point",
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
// Commands verified against package.json
|
|
57
|
+
commands: {
|
|
58
|
+
"npm run build": "Compile the project",
|
|
59
|
+
"npm test": "Run all tests",
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
// Rules — three types
|
|
63
|
+
rules: {
|
|
64
|
+
// enforce() — backed by a linter rule, verified to exist AND be enabled
|
|
65
|
+
"no-any": enforce(
|
|
66
|
+
"@typescript-eslint/no-explicit-any",
|
|
67
|
+
"Use unknown and narrow with type guards.",
|
|
68
|
+
),
|
|
69
|
+
|
|
70
|
+
// check() — filesystem assertion run by vigiles
|
|
71
|
+
"test-pairing": check(
|
|
72
|
+
every("src/**/*.service.ts").has("{name}.test.ts"),
|
|
73
|
+
"Every service must have tests.",
|
|
74
|
+
),
|
|
75
|
+
|
|
76
|
+
// guidance() — prose only, no enforcement
|
|
77
|
+
"research-first": guidance("Google unfamiliar APIs before implementing."),
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Step 3: Make the Changes
|
|
83
|
+
|
|
84
|
+
Based on what the user asked for:
|
|
85
|
+
|
|
86
|
+
**Adding a rule:**
|
|
87
|
+
|
|
88
|
+
- Determine the type: `enforce()` if a linter rule exists, `check()` for filesystem conventions, `guidance()` for prose-only
|
|
89
|
+
- For `enforce()`: find the actual linter rule name (e.g., `eslint/no-console`, `@typescript-eslint/no-explicit-any`, `ruff/T201`)
|
|
90
|
+
- Add to the `rules` object with a descriptive key
|
|
91
|
+
|
|
92
|
+
**Updating a section:**
|
|
93
|
+
|
|
94
|
+
- Edit the string in `sections`. Sections are plain strings or tagged template literals with `file()`, `cmd()`, `ref()` for verified references
|
|
95
|
+
- Do NOT add `#` or `##` headers inside sections — they break the document structure
|
|
96
|
+
|
|
97
|
+
**Adding a key file or command:**
|
|
98
|
+
|
|
99
|
+
- Add to `keyFiles` or `commands`. The compiler verifies these exist at compile time
|
|
100
|
+
- For commands: must match a script in `package.json`
|
|
101
|
+
- For key files: must exist on disk
|
|
102
|
+
|
|
103
|
+
### Step 4: Compile
|
|
104
|
+
|
|
105
|
+
After editing the spec, run:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx vigiles compile
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This regenerates the compiled instruction file(s). Review the output for any errors:
|
|
112
|
+
|
|
113
|
+
- `stale-file` — a key file path doesn't exist
|
|
114
|
+
- `stale-command` — a command isn't in package.json
|
|
115
|
+
- `invalid-rule` — a linter rule doesn't exist or is disabled
|
|
116
|
+
- `section-has-header` — a section contains `#` headers (break into separate named sections)
|
|
117
|
+
|
|
118
|
+
### Step 5: Verify
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npx vigiles check
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
If the PostToolUse hook is installed (via `npx skills add zernie/vigiles`), compilation happens automatically after you save the spec.
|
|
125
|
+
|
|
126
|
+
## Important
|
|
127
|
+
|
|
128
|
+
- **Never edit CLAUDE.md or AGENTS.md directly** — they have a vigiles hash comment and are build artifacts
|
|
129
|
+
- **The spec is TypeScript** — you get type checking, autocomplete, and verified references
|
|
130
|
+
- **`enforce()` rules are verified** — the compiler checks the rule exists AND is enabled in your linter config
|
|
131
|
+
- **Sections must not contain `#` or `##` headers** — use separate named sections instead
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: enforce-rules-format
|
|
3
|
+
description: Validate that all rules have proper enforcement classification (enforce/check/guidance)
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Validate that every rule in the project's instruction files has a proper enforcement classification, and fix any that are missing.
|
|
8
|
+
|
|
9
|
+
## Instructions
|
|
10
|
+
|
|
11
|
+
### Step 1: Detect Format
|
|
12
|
+
|
|
13
|
+
Check which format the project uses:
|
|
14
|
+
|
|
15
|
+
**v2 (spec-based):** Look for `CLAUDE.md.spec.ts` or any `*.spec.ts` files. If found, this is a v2 project — rules must use `enforce()`, `check()`, or `guidance()`.
|
|
16
|
+
|
|
17
|
+
**v1 (hand-written):** Look for `CLAUDE.md`, `AGENTS.md`, `.cursorrules`. If found without a spec file, this is a v1 project — rules need `**Enforced by:**` or `**Guidance only**` annotations.
|
|
18
|
+
|
|
19
|
+
### Step 2: Validate
|
|
20
|
+
|
|
21
|
+
**For v2 specs:**
|
|
22
|
+
|
|
23
|
+
The TypeScript type system already prevents unannotated rules — you can't create a rule without calling `enforce()`, `check()`, or `guidance()`. So focus on:
|
|
24
|
+
|
|
25
|
+
1. Do `enforce()` rules reference real linter rules? Run `npx vigiles compile` to check.
|
|
26
|
+
2. Are there guidance rules that COULD be `enforce()`? Check linter configs for matching rules.
|
|
27
|
+
3. Are there `check()` assertions that could be delegated to a linter? Suggest `enforce()` instead.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx vigiles compile
|
|
31
|
+
npx vigiles discover
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**For v1 hand-written files:**
|
|
35
|
+
|
|
36
|
+
Scan for `###` headings. Each must have one of:
|
|
37
|
+
|
|
38
|
+
- `**Enforced by:** \`linter/rule-name\``
|
|
39
|
+
- `**Guidance only** — reason`
|
|
40
|
+
- `<!-- vigiles-disable -->`
|
|
41
|
+
|
|
42
|
+
Report missing annotations with a summary table.
|
|
43
|
+
|
|
44
|
+
### Step 3: Fix Issues
|
|
45
|
+
|
|
46
|
+
For each issue found:
|
|
47
|
+
|
|
48
|
+
1. Check the project's linter configuration for matching rules
|
|
49
|
+
2. Suggest `enforce("linter/rule")` (v2) or `**Enforced by:** \`linter/rule\`` (v1)
|
|
50
|
+
3. If no linter rule exists, suggest `guidance()` (v2) or `**Guidance only**` (v1)
|
|
51
|
+
4. **Ask the user** before making changes
|
|
52
|
+
|
|
53
|
+
### Step 4: Suggest Migration
|
|
54
|
+
|
|
55
|
+
If the project uses v1 format, suggest migrating to v2 specs for type safety:
|
|
56
|
+
|
|
57
|
+
> Your rules could benefit from type-safe specs. Run the `migrate-to-spec` skill to convert your CLAUDE.md to a typed .spec.ts file.
|
|
58
|
+
|
|
59
|
+
### Step 5: Verify
|
|
60
|
+
|
|
61
|
+
Run the appropriate command:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# v2
|
|
65
|
+
npx vigiles compile && npx vigiles check
|
|
66
|
+
|
|
67
|
+
# validate
|
|
68
|
+
npx vigiles check
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Report the validation result.
|