Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
2a9f19a
v0.5.0: AI instruction diagnostics engine
cleverhoods Apr 15, 2026
3813308
Fixing deploy.
cleverhoods Apr 15, 2026
a5ca2f4
Fix mypy and ruff errors for CI, remove invalid --no-update-check fro…
cleverhoods Apr 15, 2026
9a7e5c7
Fix action flags: remove -q, fix --exclude-dir to --exclude-dirs
cleverhoods Apr 15, 2026
b2cba71
Remove stale integration tests for removed features, add ONNX skip ma…
cleverhoods Apr 15, 2026
0d19b57
Gracefully handle missing ONNX model in mapper fallback paths
cleverhoods Apr 15, 2026
78c0587
Update integration tests for CombinedResult JSON schema
cleverhoods Apr 15, 2026
8828efb
Update action and summary for CombinedResult JSON schema
cleverhoods Apr 15, 2026
fc938bd
Rewrite test_summary.py for CombinedResult schema
cleverhoods Apr 15, 2026
e68f0b7
Fix action.yml YAML parse error — collapse multi-line Python to one line
cleverhoods Apr 15, 2026
6fc8ebe
Add parse_result.py for action score computation, fix --strict to exi…
cleverhoods Apr 15, 2026
0038aaf
Fix 9 remaining integration test failures for CombinedResult schema
cleverhoods Apr 15, 2026
4a337bc
Add CHANGELOG.md entry for 0.5.0
cleverhoods Apr 15, 2026
dda1f04
Bundle ONNX model in wheel via build hook, exclude HF cache metadata
cleverhoods Apr 15, 2026
00b304c
Fetch ONNX model before build in release workflow
cleverhoods Apr 15, 2026
7c3a7c2
Add wheel verification step before PyPI publish
cleverhoods Apr 15, 2026
8f26f21
Add post-publish smoke tests for pip, uvx, and npx install paths
cleverhoods Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
25 changes: 17 additions & 8 deletions .reporails/backbone.yml → .ails/backbone.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
version: 3
generator: manual
auto_heal: true
directive: >-
If any path, command, or classification in this file does not
match the project when accessed, update the entry and continue.

depends_on:
rules:
schemas: [rule, agent, package, levels]
artifacts: [levels, capability_levels]
depends_on: {}

agents:
claude:
main_instruction_file: CLAUDE.md
config: .claude/mcp.json
config: .claude/settings.json
mcp: .claude/mcp.json
skills: .claude/skills/
rules: .claude/rules/
sub_agents: .claude/agents/

modules:
core: src/reporails_cli/core/
interfaces: src/reporails_cli/interfaces/
formatters: src/reporails_cli/formatters/
bundled: src/reporails_cli/bundled/
templates: src/reporails_cli/templates/
rules: framework/rules/
schemas: framework/schemas/


bundled:
capability_patterns: src/reporails_cli/bundled/capability-patterns.yml
project_types: src/reporails_cli/bundled/project-types.yml

artifacts:
changelog: UNRELEASED.md
Expand All @@ -39,8 +45,8 @@ meta:
version_file: VERSION

skills:
check:
path: .claude/skills/check/
ails:
path: .claude/skills/ails/
entry: SKILL.md
qa:
path: .claude/skills/qa/
Expand All @@ -51,3 +57,6 @@ skills:
add-changelog-entry:
path: .claude/skills/add-changelog-entry/
entry: SKILL.md
bootstrap:
path: .claude/skills/bootstrap/
entry: SKILL.md
14 changes: 14 additions & 0 deletions .ails/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
default_agent: claude
exclude_dirs:
- fixtures
- research
- _archive
- _archived
- .venv
- docs
- framework
- .mypy_cache
- .ruff_cache
- .pytest_cache
disabled_rules:

7 changes: 4 additions & 3 deletions .claude/rules/checks-readonly.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
---
description: Bundled config protection — never modify without explicit instruction
paths: ["src/reporails_cli/bundled/**"]
---

# Bundled Config Files

NEVER modify bundled config files without explicit human instruction.
Leave `src/reporails_cli/bundled/capability-patterns.yml` unchanged unless the user explicitly asks for a modification. This file contains regex patterns for agent capability detection — it is CLI-owned orchestration logic, not a framework rule file under `framework/rules/`.

- `capability-patterns.yml` — Regex patterns for capability detection
## Discovery

These are CLI-owned orchestration logic, not framework rules.
Applies to files matching `src/reporails_cli/bundled/**` via `paths` frontmatter. Loaded automatically by Claude Code from `.claude/rules/`.
18 changes: 10 additions & 8 deletions .claude/rules/documentation.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
---
description: User-facing documentation — copy-pasteable commands, no aspirational content
paths: ["docs/*.md", "README.md"]
---

# User-Facing Documentation

These files are read by people, not coding agents.
Write `docs/*.md` and `README.md` for people, not coding agents. Commands must be copy-pasteable and working — use `ails check .` not `reporails check .`. Examples must reflect actual CLI behavior from `uv run ails --help`.

- These files are for user-facing documentation, not AI agent instructions
- Commands must be copy-pasteable and working (`ails check .`, not `reporails check .`)
- Examples must reflect actual CLI behavior
- Only document features that exist; remove references to unimplemented features
- Keep installation/usage sections current with pyproject.toml
- Use consistent terminology: "rules" not "checks" in user-facing text
- When fixing errors, make targeted edits — don't rewrite sections and lose valid content
- Keep installation and usage sections current with `pyproject.toml` version and dependencies
- Use "rules" not "checks" in user-facing text — consistent with CLI output from `uv run ails check`
- Only document features that exist in `src/reporails_cli/`. Remove references to unimplemented features.
- When fixing errors, make targeted edits — rewriting entire sections risks losing valid content

## Discovery

Applies to files matching `docs/*.md` and `README.md` via `paths` frontmatter. Loaded automatically by Claude Code from `.claude/rules/`.
13 changes: 7 additions & 6 deletions .claude/rules/instruction-file-style.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
---
description: Instruction file style — actionable content only, no meta-commentary
paths: ["CLAUDE.md", ".claude/rules/**"]
---

# Instruction File Style

When writing or editing CLAUDE.md or .claude/rules/*.md files:
Write `CLAUDE.md` and `.claude/rules/*.md` files for AI agent behavior, not user-facing documentation. Every line should be a directive (`Use ruff for formatting`), a constraint (`Do NOT modify .env`), or a concrete reference (`src/reporails_cli/core/pipeline.py`). Actionable content gives the model something to anchor on.

- These files are for AI agent behavior, not user-facing documentation
- State facts, commands, rules only
- No meta-commentary ("this section explains...", "as mentioned above...")
- Every line MUST be actionable or informative — passive filler wastes context tokens
- Avoid redundant context that wastes tokens
Remove meta-commentary like "this section explains..." or "as mentioned above..." from instruction files. Remove redundant context that restates what the file already says. These patterns waste context tokens without adding coupling.

## Discovery

Applies to files matching `CLAUDE.md` and `.claude/rules/**` via `paths` frontmatter. Loaded automatically by Claude Code from `.claude/rules/`.
13 changes: 7 additions & 6 deletions .claude/rules/specs.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
---
description: Spec file accuracy — specs must match implementation
paths: ["docs/specs/**"]
---

# Specification Files

Specs must accurately reflect the implementation.
Update `docs/specs/*.md` when changing behavior in `src/reporails_cli/core/`. Function signatures, return types, and interfaces in specs must match what `checks.py`, `rule_runner.py`, and `content_checker.py` actually implement.

- Update specs when changing code behavior
- Function signatures, return types, and interfaces must match code
- Remove features from specs when removing from code
- Add features to specs when adding to code
- No aspirational content - document what exists, not what might exist
Remove features from `docs/specs/` when removing them from `src/`. Add features to specs when adding them to code. Specs document what exists in the current codebase — not aspirational features or planned work.

## Discovery

Applies to files matching `docs/specs/**` via `paths` frontmatter. Loaded automatically by Claude Code from `.claude/rules/`.
15 changes: 10 additions & 5 deletions .claude/rules/writing-rules.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
---
description: Rule file authoring — format, scope, and constraints for .claude/rules/
paths: [".claude/rules/**"]
---

# Writing Rule Files

Rule files in `.claude/rules/` are loaded into Claude's context.
Rule files in `.claude/rules/` are loaded into Claude's context at session start.

## Format

Expand All @@ -21,7 +22,11 @@ paths: ["src/**/*.py"] # Optional: scope to specific files

## Constraints

- One concern per file (e.g., access control separate from styling)
- Keep under 500 lines — everything consumes tokens
- Use descriptive filenames (`api-validation.md` not `rules1.md`)
- Add `paths` frontmatter to scope rules to relevant files; omit for global rules
- Keep each `.claude/rules/*.md` file focused on one concern — access control separate from styling, testing separate from documentation
- Keep files under 500 lines — every line consumes context tokens
- Use descriptive filenames like `api-validation.md` not `rules1.md`
- Add `paths` or `globs` frontmatter to scope rules to relevant files under `src/`, `tests/`, or `docs/`. Omit for global rules.

## Discovery

Applies to files matching `.claude/rules/**` via `paths` frontmatter. Loaded automatically by Claude Code from `.claude/rules/`.
2 changes: 1 addition & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path // .tool_input.filePath // empty' | grep -q 'src/reporails_cli/bundled/' && echo '{\"decision\": \"block\", \"reason\": \"Bundled config files (levels.yml, capability-patterns.yml) must not be modified without explicit human instruction. These are CLI-owned orchestration logic.\"}' && exit 2 || exit 0"
"command": "jq -r '.tool_input.file_path // .tool_input.filePath // empty' | grep -q 'capability-patterns\\.yml' && echo '{\"decision\": \"block\", \"reason\": \"capability-patterns.yml is CLI-owned orchestration logic. Do not modify without explicit human instruction.\"}' && exit 2 || exit 0"
}
]
}
Expand Down
62 changes: 16 additions & 46 deletions .claude/skills/add-changelog-entry/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,27 @@ description: Add a changelog entry to UNRELEASED.md

# /add-changelog-entry

Automatically add a changelog entry to PROJECT_ROOT/UNRELEASED.md.

## Instructions

1. Check git diff or recent file modifications
2. Determine the area from the file path:
- interfaces/cli/ → [CLI]
- core/ → [CORE]
- bundled/ → [BUNDLED]
- formatters/ → [FORMATTERS]
- README.md → [DOCS]
- CLAUDE.md, backbone.yml, .claude/, .reporails/ → [META]
3. Determine the category:
- New files/content → Added
- Modified existing → Changed
- Marked as deprecated/obsolete → Deprecated
- Removed content → Removed
- Bug fixes → Fixed
- Security-related changes → Security
Add a changelog entry to `UNRELEASED.md` based on recent changes.

## Process

1. Run `git diff` or check recent file modifications to determine what changed
2. Determine the **area** from the file path:
- `src/reporails_cli/interfaces/cli/` → `[CLI]`
- `src/reporails_cli/core/` → `[CORE]`
- `src/reporails_cli/bundled/` → `[BUNDLED]`
- `src/reporails_cli/formatters/` → `[FORMATTERS]`
- `README.md`, `docs/` → `[DOCS]`
- `CLAUDE.md`, `.ails/backbone.yml`, `.claude/` → `[META]`
3. Determine the **category**: Added (new files/content), Changed (modified existing), Deprecated, Removed, Fixed (bug fixes), Security
4. Write a concise description (3-7 words)
5. Append to UNRELEASED.md under the correct category section
6. Create the category section if it doesn't exist
5. Append to `UNRELEASED.md` under the correct `### [Category]` section — create the section if it doesn't exist

## Format

```markdown
### [Category]
- [Area]: [Description]
```

## Categories

Added, Changed, Deprecated, Removed, Fixed, Security

## Areas

- [CLI] – CLI interface (interfaces/cli/)
- [CORE] – Core domain logic
- [BUNDLED] – Bundled config (levels.yml, capability-patterns.yml)
- [FORMATTERS] – Output formatters
- [DOCS] – README, general documentation
- [META] – CLAUDE.md, backbone.yml, repo structure

## Example

```markdown
### Added
- [CORE]: Semantic rule caching support

### Changed
- [FORMATTERS]: Updated compact output format
- [Area]: Description
```

Do not ask for confirmation. Just do it.
Append directly without asking for confirmation.
5 changes: 5 additions & 0 deletions .claudeignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ build/
# IDE & editor
.idea/

# Research corpus — contains 4600+ CLAUDE.md and 6700+ .claude/rules/ files
# from third-party repos. Without this exclusion, Claude Code loads them as
# project instructions, contaminating every session.
research/data/corpus/

# Environment & secrets
.env
.env.local
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,5 @@ jobs:
- name: Unit tests
run: uv run poe test_unit

- name: Download rules
run: uv run python -c "from reporails_cli.core.init import download_rules, download_recommended; download_rules(); download_recommended()"

- name: Integration tests
run: uv run poe test_integration
103 changes: 103 additions & 0 deletions .github/workflows/post-publish-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Post-publish smoke test

on:
workflow_run:
workflows: ["Release"]
types: [completed]

jobs:
smoke-pypi:
name: "Smoke: pip install from PyPI"
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Wait for PyPI propagation
run: |
for i in 1 2 3 4 5 6; do
if pip install reporails-cli --dry-run --quiet 2>/dev/null; then break; fi
echo "Waiting for PyPI propagation (attempt $i)..."
sleep 30
done

- name: Install from PyPI
run: pip install reporails-cli

- name: Verify ails command exists
run: |
which ails
ails version

- name: Verify ONNX model bundled
run: |
python -c "
from reporails_cli.bundled import get_models_path
onnx = get_models_path() / 'minilm-l6-v2' / 'onnx' / 'model.onnx'
assert onnx.exists(), f'ONNX model missing: {onnx}'
print(f'OK: {onnx.stat().st_size / 1024 / 1024:.0f} MB')
"

- name: Smoke check
run: |
mkdir /tmp/smoke-project
echo "# Test Project" > /tmp/smoke-project/CLAUDE.md
ails check /tmp/smoke-project -f json

smoke-uvx:
name: "Smoke: uvx ephemeral install"
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: Wait for PyPI propagation
run: |
for i in 1 2 3 4 5 6; do
if uvx reporails-cli version 2>/dev/null; then break; fi
echo "Waiting for PyPI propagation (attempt $i)..."
sleep 30
done

- name: Verify uvx runs ails
run: uvx reporails-cli version

- name: Smoke check
run: |
mkdir /tmp/smoke-project
echo "# Test Project" > /tmp/smoke-project/CLAUDE.md
uvx reporails-cli check /tmp/smoke-project -f json

smoke-npx:
name: "Smoke: npx @reporails/cli"
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
with:
node-version: "20"

- uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: Wait for npm propagation
run: |
for i in 1 2 3 4 5 6; do
if npx --yes @reporails/cli version 2>/dev/null; then break; fi
echo "Waiting for npm propagation (attempt $i)..."
sleep 20
done

- name: Verify npx runs ails
run: npx --yes @reporails/cli version

- name: Smoke check
run: |
mkdir /tmp/smoke-project
echo "# Test Project" > /tmp/smoke-project/CLAUDE.md
npx --yes @reporails/cli check /tmp/smoke-project -f json
Loading
Loading