Structural contract layer: adopt henxels with retroactive application #138

Closed
opened 2026-09-05 01:36:57 +01:00 by conductor · 4 comments
Owner

Plain summary — what and why

The repo needs a machine-checkable structural contract using henxels — a repo-level harness that keeps every agent (and human) writing files in the right place, with the right names, registered in the right lists. Today our structure conventions live in the controller's memory, not in the repo: a fresh agent in a worktree has no in-repo steerage, and structural mistakes are caught by luck.

Concrete example of the hole this closes: our CI uses an explicit test-file list. When an implementer adds tests/test_new_feature.py but forgets to register it in .gitea/workflows/ci.yml, CI stays green while the test silently never runs (observed finding, general-153 review of #105). A contract rule makes that failure impossible by accident: henxels check fails with an instruction — "register tests/test_new_feature.py in .gitea/workflows/ci.yml" — instead of silence.

Example

$ henxels check --all
✗ "Every test file is registered in CI" — tests/test_new_feature.py is missing from .gitea/workflows/ci.yml
    → add it to the pytest file list, or remove the file

Technical details

WHAT

  1. henxels.yaml contract encoding the repo's CURRENT structure: placement rules (canaries are src/rune/canary_*.py, orchestration modules in src/rune/orchestration/, docs per subsystem in docs/), naming rules, required files, repo-wide no-secrets rule, file-size awareness (warn level for known debt like rune_tui.py).
  2. Custom statement ci_lists_all_tests in henxels_checks.py: every tests/test_*.py must appear in .gitea/workflows/ci.yml.
  3. AGENTS.md digest committed (henxels mirrors the contract into it) — in-repo steerage for any agent.
  4. CI step running henxels check --all in Gitea Actions.
  5. Retroactive application: run henxels check --all against the existing tree; cheap findings fixed in this stage, structural debt documented at warn level (findings = migration plan, per henxels' governing-an-existing-repo mode).

WHY S#: closes the silent-CI-omission gap (general-153); gives the repo in-repo agent steerage (AGENTS.md digest); anti-scatter protection for docs/; forge-agnostic so it survives the Forgejo port. Research: full primary-source read of benquemax/henxels (README, commit history, v0.12.0) completed 2026-09-04 — tool is MIT, actively maintained, dogfooded; empty-contract trap already fixed upstream with executable-example tests.

FILES: henxels.yaml, henxels_checks.py, .henxels/, AGENTS.md, .gitea/workflows/ci.yml, docs/structural-contract.md, plan file.

ACCEPTANCE: henxels check --all exits 0 on the enforced set with the contract's rules matching current reality; planted-violation test proves the custom statement bites (fails when a test file is unregistered, passes when registered); CI step green on the runner; AGENTS.md digest present and committed; retroactive sweep findings recorded (fixed or warn-documented).

DEPENDENCIES: none — new tool, no existing module changes.

Pipeline requirements checklist

  • TDD red→green for the custom statement (planted violation)
  • ruff check + format on new Python files
  • Spec gate PASS (independent reviewer)
  • Quality gate Approved (independent reviewer)
  • Full-suite regression green
  • henxels check --all green (enforced set)
  • Closed with formatted comment + refs
## Plain summary — what and why The repo needs a machine-checkable structural contract using **henxels** — a repo-level harness that keeps every agent (and human) writing files in the right place, with the right names, registered in the right lists. Today our structure conventions live in the controller's memory, not in the repo: a fresh agent in a worktree has no in-repo steerage, and structural mistakes are caught by luck. **Concrete example of the hole this closes:** our CI uses an explicit test-file list. When an implementer adds `tests/test_new_feature.py` but forgets to register it in `.gitea/workflows/ci.yml`, CI stays green while the test silently never runs (observed finding, general-153 review of #105). A contract rule makes that failure impossible by accident: `henxels check` fails with an instruction — "register tests/test_new_feature.py in .gitea/workflows/ci.yml" — instead of silence. ## Example ``` $ henxels check --all ✗ "Every test file is registered in CI" — tests/test_new_feature.py is missing from .gitea/workflows/ci.yml → add it to the pytest file list, or remove the file ``` ## Technical details **WHAT** 1. `henxels.yaml` contract encoding the repo's CURRENT structure: placement rules (canaries are `src/rune/canary_*.py`, orchestration modules in `src/rune/orchestration/`, docs per subsystem in `docs/`), naming rules, required files, repo-wide no-secrets rule, file-size awareness (warn level for known debt like rune_tui.py). 2. Custom statement `ci_lists_all_tests` in `henxels_checks.py`: every `tests/test_*.py` must appear in `.gitea/workflows/ci.yml`. 3. AGENTS.md digest committed (henxels mirrors the contract into it) — in-repo steerage for any agent. 4. CI step running `henxels check --all` in Gitea Actions. 5. **Retroactive application**: run `henxels check --all` against the existing tree; cheap findings fixed in this stage, structural debt documented at warn level (findings = migration plan, per henxels' governing-an-existing-repo mode). **WHY S#**: closes the silent-CI-omission gap (general-153); gives the repo in-repo agent steerage (AGENTS.md digest); anti-scatter protection for docs/; forge-agnostic so it survives the Forgejo port. Research: full primary-source read of benquemax/henxels (README, commit history, v0.12.0) completed 2026-09-04 — tool is MIT, actively maintained, dogfooded; empty-contract trap already fixed upstream with executable-example tests. **FILES**: `henxels.yaml`, `henxels_checks.py`, `.henxels/`, `AGENTS.md`, `.gitea/workflows/ci.yml`, `docs/structural-contract.md`, plan file. **ACCEPTANCE**: `henxels check --all` exits 0 on the enforced set with the contract's rules matching current reality; planted-violation test proves the custom statement bites (fails when a test file is unregistered, passes when registered); CI step green on the runner; AGENTS.md digest present and committed; retroactive sweep findings recorded (fixed or warn-documented). **DEPENDENCIES**: none — new tool, no existing module changes. ## Pipeline requirements checklist - [ ] TDD red→green for the custom statement (planted violation) - [ ] ruff check + format on new Python files - [ ] Spec gate PASS (independent reviewer) - [ ] Quality gate Approved (independent reviewer) - [ ] Full-suite regression green - [ ] henxels check --all green (enforced set) - [ ] Closed with formatted comment + refs
conductor added the infrastructure label 2026-09-05 01:36:58 +01:00

⚠️ Priority gate: this issue has no priority. Assign exactly one of P0 — critical (spine/correctness/blocks), P1 — high (material value or real defect), P2 — medium (quality/consolidation), P3 — low (measurement/deferred). An issue without a priority is not filed.

⚠️ **Priority gate:** this issue has no priority. Assign exactly one of **P0 — critical** (spine/correctness/blocks), **P1 — high** (material value or real defect), **P2 — medium** (quality/consolidation), **P3 — low** (measurement/deferred). An issue without a priority is not filed.
gitea-actions Bot added the bugcustodianmemory labels 2026-09-05 01:37:06 +01:00

⚠️ Priority gate: this issue has no priority. Assign exactly one of P0 — critical (spine/correctness/blocks), P1 — high (material value or real defect), P2 — medium (quality/consolidation), P3 — low (measurement/deferred). An issue without a priority is not filed.

⚠️ **Priority gate:** this issue has no priority. Assign exactly one of **P0 — critical** (spine/correctness/blocks), **P1 — high** (material value or real defect), **P2 — medium** (quality/consolidation), **P3 — low** (measurement/deferred). An issue without a priority is not filed.
conductor added P1 — high and removed memorycustodianbug labels 2026-09-05 01:37:32 +01:00

⚠️ Priority gate: this issue has no priority. Assign exactly one of P0 — critical (spine/correctness/blocks), P1 — high (material value or real defect), P2 — medium (quality/consolidation), P3 — low (measurement/deferred). An issue without a priority is not filed.

⚠️ **Priority gate:** this issue has no priority. Assign exactly one of **P0 — critical** (spine/correctness/blocks), **P1 — high** (material value or real defect), **P2 — medium** (quality/consolidation), **P3 — low** (measurement/deferred). An issue without a priority is not filed.
gitea-actions Bot added the bugcustodianmemory labels 2026-09-05 01:37:41 +01:00
Author
Owner

Plain summary — what was delivered

The repo now carries a machine-checkable structural contract (henxels): henxels.yaml (5 rules in plain English), a custom CI-completeness check, an agent-readable AGENTS.md digest, and a CI step that fails any push breaking the shape. Applied retroactively: 4 canaries that were silently never running in CI are now registered, file-size debt is documented instead of invisible, and near-duplicate files are flagged.

Technical details

Implementation commits: 89516e4 (plan) → 11d5f94 (implementation) → b17e1a6 (quality-gate discharges). Branch structural-contract.

What the contract enforces:

  1. Every src/rune/**/canary_*.py must be registered in .gitea/workflows/ci.yml (custom statement ci_runs_all_canaries) — closes the silent-CI-omission class (general-153 finding); 4 unregistered canaries found and fixed retroactively (query_memory, unbounded, full_system, native).
  2. No secrets in tracked files (repo-wide; one documented except for synthetic fixture tokens in test_gitea_provision.py).
  3. Plans are kebab-case markdown; top-level docs are md/yaml.
  4. File-size ratchet (1200 lines, recursive) — 6 known giants except-listed in a documented debt table (docs/structural-contract.md); new giants are caught.

Gates: Spec PASS 10/10 (general-168); Quality Approved with minors (general-169) — all 5 Importants discharged in b17e1a6 (subdir canary blindspot closed with recursive scopes, red-green proven; tolerance pinned by test; henxels==0.12.0 exact pin + redundant CI install removed; AGENTS.md digest freshness enforced by test — the umbrella rule made mechanical; max_lines made recursive + dead allowance dropped). Minors 6-13 accepted and documented in the plan tail.

Tests: contract tests 5 → 9 (red→green proven at each step); full suite 461 → 470 passed + 84 subtests, zero regressions. henxels check --all --plain exit 0. ruff clean on new files.

CI: lint job runs henxels check --all --plain (pinned via [dev] extra); canary job covers all 15/15 canaries (structurally proven by test).

Pins / follow-ups: #139 (tui_validator allowlist fix) will also remove the canary_native tolerance + its pin test; digest-sync via henxels sync now machine-enforced; future umbrella-style rules can use henxels must_be_in_sync/changed_with primitives.

## Plain summary — what was delivered The repo now carries a machine-checkable structural contract (**henxels**): `henxels.yaml` (5 rules in plain English), a custom CI-completeness check, an agent-readable `AGENTS.md` digest, and a CI step that fails any push breaking the shape. Applied **retroactively**: 4 canaries that were silently never running in CI are now registered, file-size debt is documented instead of invisible, and near-duplicate files are flagged. ## Technical details **Implementation commits**: `89516e4` (plan) → `11d5f94` (implementation) → `b17e1a6` (quality-gate discharges). Branch `structural-contract`. **What the contract enforces**: 1. Every `src/rune/**/canary_*.py` must be registered in `.gitea/workflows/ci.yml` (custom statement `ci_runs_all_canaries`) — closes the silent-CI-omission class (general-153 finding); 4 unregistered canaries found and fixed retroactively (query_memory, unbounded, full_system, native). 2. No secrets in tracked files (repo-wide; one documented except for synthetic fixture tokens in test_gitea_provision.py). 3. Plans are kebab-case markdown; top-level docs are md/yaml. 4. File-size ratchet (1200 lines, recursive) — 6 known giants except-listed in a documented debt table (docs/structural-contract.md); new giants are caught. **Gates**: Spec PASS 10/10 (general-168); Quality Approved with minors (general-169) — **all 5 Importants discharged in `b17e1a6`** (subdir canary blindspot closed with recursive scopes, red-green proven; tolerance pinned by test; henxels==0.12.0 exact pin + redundant CI install removed; AGENTS.md digest freshness enforced by test — the umbrella rule made mechanical; max_lines made recursive + dead allowance dropped). Minors 6-13 accepted and documented in the plan tail. **Tests**: contract tests 5 → 9 (red→green proven at each step); full suite **461 → 470 passed + 84 subtests**, zero regressions. `henxels check --all --plain` exit 0. ruff clean on new files. **CI**: lint job runs `henxels check --all --plain` (pinned via [dev] extra); canary job covers all 15/15 canaries (structurally proven by test). **Pins / follow-ups**: #139 (tui_validator allowlist fix) will also remove the canary_native tolerance + its pin test; digest-sync via `henxels sync` now machine-enforced; future umbrella-style rules can use henxels `must_be_in_sync`/`changed_with` primitives.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: conductor/rune#138