60 lines
3.6 KiB
Markdown
60 lines
3.6 KiB
Markdown
# Structural Contract — henxels Adoption (#138)
|
|
|
|
The repo's shape is machine-checkable. `henxels.yaml` (repo root) holds the
|
|
contract; `henxels sync` renders it into the `AGENTS.md` digest agents read;
|
|
`henxels check --all --plain` enforces it (exit 0 = green, 1 = red) and runs as
|
|
a CI lint-job step.
|
|
|
|
## What the contract governs
|
|
|
|
| Henxel | Scope | Rule |
|
|
| --- | --- | --- |
|
|
| Canaries registered in CI | `./src/rune/canary_*.py` | Custom statement `ci_runs_all_canaries` (in `henxels_checks.py`): every canary on disk must appear in `.gitea/workflows/ci.yml` |
|
|
| No secrets | whole repo | `no_secrets` — no credentials in tracked files |
|
|
| Plans | `./plans` | markdown only, kebab-case filenames |
|
|
| Docs | `./docs/*` | `.md`/`.yaml` only, except `docs/v1/**` and `docs/wiki/**` |
|
|
| File-size debt | `./src/rune` | `max_lines: 1200`, except the documented debt list below |
|
|
|
|
Warnings (non-blocking): near-duplicate file detection (the `shared/` vs
|
|
`src/rune/` copies and `backups/` snapshots are pre-existing debt the warning
|
|
correctly keeps visible).
|
|
|
|
## Debt table
|
|
|
|
Known violations, explicitly excepted in `henxels.yaml` instead of silently
|
|
ignored. Each entry lists the finding that forced the exception.
|
|
|
|
| File / spot | Rule | Finding | Disposition |
|
|
| --- | --- | --- | --- |
|
|
| `src/rune/rune_tui.py` | max_lines 1200 | 4231 lines (drafted exception) | except-listed; split is future work |
|
|
| `src/rune/rune_operator.py` | max_lines 1200 | 1265 lines (drafted exception) | except-listed; split is future work |
|
|
| `src/rune/local_tool_runtime.py` | max_lines 1200 | 506 lines — drafted as pre-emptive headroom, not currently over budget | except-listed (as drafted) |
|
|
| `src/rune/memory_store.py` | max_lines 1200 | 2171 lines (live finding) | except-listed; split is future work |
|
|
| `src/rune/curator.py` | max_lines 1200 | 1597 lines (live finding) | except-listed; split is future work |
|
|
| `src/rune/tool_executor.py` | max_lines 1200 | 1523 lines (live finding) | except-listed; split is future work |
|
|
| `src/rune/warm_router.py` | max_lines 1200 | 1292 lines (live finding) | except-listed; split is future work |
|
|
| `tests/test_gitea_provision.py` | no_secrets | flagged as hardcoded credential — actually synthetic fixture tokens (`plaintext-transport-test-secret` etc.) whose purpose is asserting tokens never leak | except-listed (false positive) |
|
|
| `src/rune/canary_native.py` | canary gate | tui_validator's import allowlist drifted from `rune_tui.py` (`from __future__ import annotations`, bare `import rune`) — 2 false-failures; validator fix is issue #139, not here | canary tolerates exactly those 2 messages (prints `⚠ known false-failure, #139`, does not count them); any other TUI error still fails the canary |
|
|
|
|
## How to add a rule
|
|
|
|
1. Prefer a built-in: `henxels catalogue` lists every statement (built-ins and
|
|
this repo's custom ones).
|
|
2. Add a henxel to `henxels.yaml`. Custom statements live in
|
|
`henxels_checks.py` (auto-loaded; a `.henxels/` folder of check modules also
|
|
works). Custom statements REQUIRE an `in:` scope — without one they never
|
|
fire.
|
|
3. Run `henxels check --all --plain` locally; fix findings cheaply or add an
|
|
explicit `except:` and a row to the debt table above.
|
|
4. `henxels sync` to refresh `AGENTS.md` and commit both together.
|
|
5. The contract must be green at birth: never merge a rule that fails on
|
|
master.
|
|
|
|
## Why no git hooks
|
|
|
|
Subagents work in throwaway worktrees (`/mnt/workdrive/rune` and siblings) and
|
|
commit there; a pre-commit hook would either miss those commits or block the
|
|
agent mid-flight. Enforcement is CI-only: the lint job runs
|
|
`henxels check --all --plain` on every push/PR, so the gate is the merge, not
|
|
the commit.
|