Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 0 additions & 78 deletions .claude/settings.json

This file was deleted.

7 changes: 1 addition & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ test-results/
*.old

# Instance-specific development files (not committed)
.claude/plan.md
.claude/todos.md
.claude/review.md
.claude/skills/
.agents/

# codevoyant context store — in-repo .codevoyant is a symlink to ~/.codevoyant/<project-slug>/; never commit it
Expand All @@ -103,8 +99,7 @@ test-results/
# codevoyant snippets store (in-project fallback — never commit generated snippets)
.codevoyant/snippets/

# Claude Code agent state
.claude/worktrees/
# Codevoyant agent state
.memsearch/

# Generated / untracked assets
Expand Down
18 changes: 11 additions & 7 deletions .mise-tasks/vendor-assets
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
# the whole source dir is copied; when present the listed entries are the
# minimum set that must be vendored — any other file under the source is also
# vendored, so a file added to the shared source propagates automatically. The
# vendored set for each target is recorded in skills/vendor.manifest.json so
# --check can flag (and vendor can clean) a previously-vendored copy whose file
# is no longer in the source or the allowlist.
# vendored set for each (asset, target) pair is recorded in
# skills/vendor.manifest.json (key "<asset>::<target>") so --check can flag
# (and vendor can clean) a previously-vendored copy whose file is no longer in
# the source or the allowlist — without one asset's cleanup deleting files
# vendored into the same target dir by another asset.
#
# The Agent Skills standard scopes every skill to its own directory: file
# references are relative and one level deep, and there is no cross-skill
Expand Down Expand Up @@ -228,10 +230,12 @@ for name, asset in assets.items():
targets = resolve_targets(name, asset)
files = asset.get("files")
if files:
managed = sorted(set(files) | set(source_relfiles(src)))
# `files` is an exclusive filter per the documented contract ("copy only
# these") — tests and other source-dir residents stay in skills/shared/.
managed = sorted(set(files))
for t in targets:
files_targets.add(t)
prev = set(manifest.get(t, []))
prev = set(manifest.get(f"{name}::{t}", []))
stale = sorted(prev - set(managed))
if mode == "check":
for f in managed:
Expand All @@ -252,7 +256,7 @@ for name, asset in assets.items():
if os.path.lexists(os.path.join(root, d)):
remove_path(d)
print(f"removed stale: {d}")
manifest[t] = managed
manifest[f"{name}::{t}"] = managed
else:
for t in targets:
if mode == "check":
Expand All @@ -262,7 +266,7 @@ for name, asset in assets.items():
print(f"vendored: {src} -> {t}")

if mode != "check":
manifest = {t: v for t, v in manifest.items() if t in files_targets}
manifest = {k: v for k, v in manifest.items() if "::" in k and k.split("::", 1)[1] in files_targets}
save_manifest(manifest)

sys.exit(fail)
Expand Down
2 changes: 1 addition & 1 deletion .releaserc.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
[
"@semantic-release/exec",
{
"prepareCmd": "echo ${nextRelease.version} > version.txt && node scripts/sanitize-changelog.js"
"prepareCmd": "echo ${nextRelease.version} > version.txt && mise run changelog:sanitize"
}
],
[
Expand Down
File renamed without changes.
5 changes: 2 additions & 3 deletions docs/.vitepress/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ export default defineConfig({
// Root-level files
"README.md",
"CHANGELOG.md",
"CLAUDE.md",
"AGENTS.md",
// Internal dirs
".claude/**",
".memsearch/**",
".codevoyant/**",
".memsearch/**",
// Shared skill assets (source of truth for vendored templates/scripts — not docs pages)
"skills/shared/**",
// Non-recipe skills (exclude entirely)
Expand Down
2 changes: 1 addition & 1 deletion docs/skills/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Checks for: required sections (per template order), prescribed Mermaid diagram t

### retcon -- author the whole docs/ tree from the codebase

The only `docs` command that writes real content. `retcon` reads the code, scaffolds each doc the same way `new` does, then replaces every `@agent` marker with accurate prose, diagrams, and tables. It first handles existing docs: it moves them to `docs/legacy/`, confirms their facts against the code, and carries those facts forward (asking before carrying machine-generated content). It finishes by validating every doc's `globs` against the real code tree.
The only `docs` command that writes real content. `retcon` reads the code, scaffolds each doc the same way `new` does, then fills the contract surface — tables, mermaid diagrams, runnable code samples, constrained `## Requirements`, and `## References` — replacing each `@agent` marker it consumes. It never writes prose elsewhere (see the prose policy, `references/prose-policy.md`): sections marked `<!-- @human: … -->` keep their marker untouched until a person writes them. It first handles existing docs: it moves them to `docs/legacy/`, confirms their facts against the code, and carries those facts forward (asking before carrying machine-generated content). It finishes by validating every doc's `globs` against the real code tree.

```bash
/docs retcon # author the whole docs/ tree
Expand Down
25 changes: 25 additions & 0 deletions docs/skills/loop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: loop
---

# loop

Repeat a task until its objective is met or a max iteration count is reached. A loop is not a saved artifact like a flow — `/loop` creates a tracking doc and runs immediately, with every iteration executed by a single background loop agent that performs the task and judges the objective.

## Usage

```bash
/loop fix the failing lint errors --until "mise run lint exits 0" --max 5
/loop keep triaging the backlog --until "all P0 issues are closed" --check "gh issue list --label P0 --state open | wc -l | grep -qx 0"
/loop continue the earlier pass --resume fix-lint-errors
```

- **task** (required) — what to repeat each iteration: a skill command, shell command, or agent instruction.
- **--until** (required) — the objective: the verifiable condition that ends the loop, phrased as an outcome.
- **--max N** (default 3) — the hard upper bound; the loop stops at N iterations even if the objective is not met.
- **--check <command>** (optional) — a deterministic check that exits 0 when the objective is met; when present it overrides the agent's verdict.
- **--resume <slug>** — continue an existing loop's tracking doc instead of starting a new one.

## How a run works

Each invocation writes `.codevoyant/loops/{slug}/loop.md` — the tracking doc holding the task, objective, check, bound, status, and one row per iteration — then runs: for each iteration it spawns one `loop-agent` background agent that performs the task and strictly judges the objective from the actual repo state (never from its own claim). On a MET verdict (or a zero-exit `--check`) the loop stops with status `complete`; at the bound it stops with `max-reached`. If an iteration needs input, the question is escalated to the user and the same iteration re-runs without consuming the bound twice.
4 changes: 3 additions & 1 deletion docs/skills/pr.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ Read a PR/MR diff and generate AI-authored inline comments. Comments are terse (

Reviews evaluate the change against its **stated intent** first — does the diff actually deliver the PR/MR's purpose end-to-end (tracing the headline use case), not just whether the code is clean? A well-formed change that fails its intent is flagged `BLOCKING`.

Assesses the change with **four subagents in parallel**, one per dimension, then merges their findings into one review:
Runs deterministic pre-checks (CI status, commit-convention consistency, and a static-analysis floor), then assesses the change with **five subagents in parallel** — one per dimension — plus a **claim-checker**, and merges all findings into one review:

- **Intent-match** — does the diff deliver the stated intent (from the description, linked issue, or executed spec plan) end-to-end? A well-formed change that fails its intent is `BLOCKING`.
- **Unnecessary changes** — a dedicated **slop-detector**: scope creep, stray edits, dead/commented code, accidental reverts, stochastic churn (random renames, reordering, reformatting), boilerplate, debug leftovers, dependency creep. Findings prefixed `Slop:`. A prevalent problem with agentic coding.
- **Code quality** — a **code-quality-auditor** judges the added/edited code against the relevant codevoyant skill (`typescript`, `python`, `react`, `svelte`, `sveltekit`, …) or the language/framework standard. Findings prefixed `Quality:`.
- **Docs freshness** — a **docs-freshness-checker** decides whether docs should have been updated. By default review stays read-only: stale docs are reported as a `Docs:` finding recommending `/docs update`. Pass `--update-docs` to opt in to having the pass run `/docs update` and refresh docs during the review. Findings prefixed `Docs:`.
- **Adversarial hunt** — a **red-team-adversary** tries to break the change: failure modes, edge cases, negative paths, mutation-mindset test review, STRIDE on security surfaces. Findings prefixed `Adversarial:` — `BLOCKING` only when they carry a concrete input/expected/observed scenario.
- **Claim check** — a **claim-checker** verifies the PR/MR body's claims (Changes bullets, Validation checklist, stated behavior) against the diff. Findings prefixed `Claim:`.

```bash
/pr review # draft the review directly on the PR/MR
Expand Down
4 changes: 3 additions & 1 deletion docs/skills/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Specification-driven development — create structured plans from requirements,

Explore requirements and produce a multi-phase implementation plan with objectives, design decisions, and per-phase specs. Every task carries the **complete, ready-to-write code** it will produce. Before `new` reports a plan ready, a mandatory code-completeness gate scans every task and rejects stubs, placeholder markers, omitted code, and prose-only descriptions; it reruns after repairs and fails closed if literal code cannot be resolved. `--validate` still adds the broader multi-agent validation pass.

Enumerable sets in the objective or intent are **tabulated**: rote replacements, target sets to search or touch, and enumerated requirement lists each get a row-per-item table under `.codevoyant/spec/{plan}/tables/`, enumerated from the codebase (never from memory), with every requirement row carrying an Intent ref back to `intent.md`. A completeness gate re-runs each table's enumeration, checks every intent item appears in a row and every row is owned by exactly one task, and fails the plan on any dropped item, orphan row, or drift.

Two ways to give the objective:

- **Inline objective** — a description; planning starts immediately.
Expand All @@ -32,7 +34,7 @@ Two ways to give the objective:

`--branch` and `--worktree` are independent — each does one thing, and neither implies the other. `--branch` creates or switches to a branch (bare: derived from the plan slug; with a name: that name). `--worktree` creates a worktree (bare: `.codevoyant/worktrees/<branch>`; with a path: that path). Both delegate to the shared `/git worktree` routine.

`--persistent` is an **experimental** doc-aware mode: docs are written first, every phase is scoped to the doc globs it may write, and cross-module interaction happens only through documented public interfaces. It requires valid docs in the repo (`docs/` with `globs:` frontmatter plus an architecture index or a component doc with a public API/interface section); `new` refuses to plan blind otherwise. See the skill's `references/doc-aware.md` for the full model.
`--persistent` is an **experimental** doc-aware mode: docs are written first, every phase is scoped to the doc globs it may write, and cross-module interaction happens only through documented public interfaces. Cross-module changes are discouraged by default (Rule 7): a phase that must write across module boundaries has to call the crossing out with a reason and a rejected restructure, and the executor refuses uncalled-out crossings. It requires valid docs in the repo (`docs/` with `globs:` frontmatter plus an architecture index or a component doc with a public API/interface section); `new` refuses to plan blind otherwise. See the skill's `references/doc-aware.md` for the full model.

Pass a Linear, GitHub, or GitLab issue URL as the first argument to pre-fill requirements from the issue title, description, and comments.

Expand Down
5 changes: 5 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ shfmt = "latest"
gh = "latest"
glab = "latest"
"npm:skills-ref" = "0.1.5"
"npm:@mermaid-js/mermaid-cli" = "11.16.0"

# ==============================================================================
# DOCS
Expand Down Expand Up @@ -49,6 +50,10 @@ run = "cat version.txt"
description = "Run semantic-release to version and update changelog"
run = ".mise-tasks/upversion"

[tasks."changelog:sanitize"]
description = "Escape bare HTML tags in CHANGELOG.md after generation"
run = "node scripts/sanitize-changelog.js"

# ==============================================================================
# SKILLS
# ==============================================================================
Expand Down
2 changes: 1 addition & 1 deletion skills/docs/references/docs-review-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ To re-review after manual edits:
/docs review {path} -- regenerates this report
```

**Severity types:** `STRUCTURE` (missing/malformed section), `DIAGRAM` (missing/wrong diagram type), `LANGUAGE` (language-guide or STE violation), `REFERENCE` (missing References section or entries), `COVERAGE` (missing/duplicate `globs` coverage or API-boundary violation — see `references/coverage-and-api.md`), `GLOB` (a doc's `globs` matches no real paths, or a discovered component has no owning doc — from `validate`).
**Severity types:** `STRUCTURE` (missing/malformed section), `DIAGRAM` (missing/wrong diagram type), `LANGUAGE` (language-guide or STE violation), `REQUIREMENTS` (a requirement in `## Requirements` violates R1–R7 of `references/requirements-guidance.md`), `REFERENCE` (missing References section or entries), `PROSE` (LLM prose outside the prose-policy allowance — not in a `<!-- -->` comment, not in `## Requirements`, not in `## References`, not a minimal artifact label; see `references/prose-policy.md`), `COVERAGE` (missing/duplicate `globs` coverage or API-boundary violation — see `references/coverage-and-api.md`), `GLOB` (a doc's `globs` matches no real paths, or a discovered component has no owning doc — from `validate`).

**Principles:**
- Each replacement preserves all surrounding human-authored text. The replacement block contains ONLY the text that changes, not the entire file.
Expand Down
11 changes: 9 additions & 2 deletions skills/docs/references/language-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,12 @@ When updating existing docs, preserve human-authored text. Change only text that
8. **Slop vocabulary** (STE slop table): leverage, utilize, ensure, in order to, functionality, enables you to, allows you to, is designed to, aims to, dive into, delve into, robust, powerful, comprehensive, seamlessly, facilitate, streamline, and/or, etc. → the plain replacement from the ruleset.
9. **Condition-first** (STE 5.4): a sentence where `if`/`when` stands after the command ("Increase the timeout if the network is slow" → "If the network is slow, increase the timeout").
10. **Procedural imperative** (STE 5.3): in a procedural section, an instruction written as a statement instead of an imperative.

For each violation, record `type: LANGUAGE`, `current_text` = the exact offending sentence, `replacement_text` = the minimal rewrite that fixes only that violation, `rationale` = the rule number/name. Never rephrase working prose for style.
11. **R1 no-impl-terms** (requirements-guidance): a `## Requirements` bullet naming an endpoint, route, class, function, table, SQL, UI widget, or file path as if it were the requirement.
12. **R2 survive-change** (requirements-guidance): a requirement whose wording would need to change if the implementation changed.
13. **R3 fit-criterion** (requirements-guidance): a Functional requirement with no observable outcome or measurable success condition.
14. **R4 smells** (requirements-guidance): subjective language, ambiguous adverbs/adjectives, superlatives, totality terms, baseline-less comparatives in a requirement.
15. **R5 invariant** (requirements-guidance): an implementation invariant stated as a Functional requirement.
16. **R6 source** (requirements-guidance): a domain claim with neither `Source:` nor `[ASSUMPTION — unvalidated]`.
17. **R7 verbs** (requirements-guidance): a requirement using should/would/can instead of the template's prescribed verbs.

For each violation, record `type: LANGUAGE` (checks 1–10) or `type: REQUIREMENTS` (checks 11–17, applied only inside `## Requirements` sections), `current_text` = the exact offending sentence, `replacement_text` = the minimal rewrite that fixes only that violation, `rationale` = the rule number/name. Never rephrase working prose for style.
11 changes: 11 additions & 0 deletions skills/docs/references/mermaid-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,17 @@ stateDiagram-v2
- Use `[*]` for entry/exit states
- Avoid showing error states unless they have transitions back to valid states

## Artifact quality gate

`scripts/validate_artifacts.py` enforces these rules on every generated doc (retcon blocks on failures; review and validate report them). One pinned renderer decides what "valid" means: `mmdc` at mermaid-cli 11.16.0 (PATH, else `npx -y @mermaid-js/mermaid-cli@11.16.0`).

- Every mermaid fence must render (parse failures are blocking).
- Sequence diagrams: ≤8 participants. Graphs/flowcharts: ≤12 nodes. Split larger diagrams.
- Node labels break lines with `<br/>`, never a literal `\n`.
- Tables carry a separator row and no unfilled `{placeholder}`-only rows.

The semantic caps come from the C4 review checklist: large diagrams carry too much cognitive load to be read; split by focus instead.

## When NOT to Use a Diagram

- Simple 2-step flows (just use prose or a bullet list)
Expand Down
2 changes: 2 additions & 0 deletions skills/docs/references/ml-examples.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# ML examples — boundaries and requirements

> The functional-vs-non-functional-vs-invariant rule taught here is generalized to all templates in `references/requirements-guidance.md` (R5). The examples below remain the ML-flavored worked subset.

Worked examples for the ml-model, data-pipeline, and experiment templates. The rule that matters most: how a class operates is an implementation invariant, never a functional requirement.

## Module boundaries
Expand Down
Loading
Loading