R76.P1 Audit — κ Rule Engine Phase 1 Deep Task Breakdown
Step 1 of 5 (audit → contract → packet → implement → verify) for R76.P1.
Scope bound. This task produces spec/prompt content only. No κ code is written in R76; Phase 1 κ implementation officially begins at R81 per
docs/5-time/roadmap.md. The output of R76.P1 goes into the task-prompts directory for future rounds to execute against.
1. Current state of Phase 1 in task-breakdown.md
Source: docs/guides/implementation/task-breakdown.md lines 457–593.
As of main e455b00a, the Phase 1 κ section already has 10 sub-tasks filled across 4 groups. Mapped below, with the gap analysis against the task-breakdown commissioned by R76.P1:
| Group in file | Existing sub-tasks | Existing file target prefix | Status in file | Gap vs R76.P1 target |
|---|---|---|---|---|
| P1.1 — Integer Math Library | P1.1.1 (Basis Point Arithmetic), P1.1.2 (Determinism Verification Harness) | src/rules/integer-math.{ext} + tests |
Complete, 2 entries | Keep. Rename file path from src/rules/ → src/domains/rules/ to match Phase 0 convention. |
| P1.2 — DSL Parser | P1.2.1 (Lexer/Tokenizer), P1.2.2 (Parser → AST), P1.2.3 (AST Validator) | src/rules/lexer.{ext}, parser.{ext}, validator.{ext} |
Complete, 3 entries | Keep. Same directory rename. Add Chevrotain reference in P1.2.2. |
| P1.3 — Deterministic Interpreter | P1.3.1 (Core Evaluation Loop), P1.3.2 (Built-in Functions), P1.3.3 (State Access Layer) | src/rules/engine.{ext}, builtins.{ext}, state-access.{ext} |
Complete, 3 entries (the task-prompt spec in R76.P1 lists only 2, but 3 is correct — the third is the state-access layer from the extraction §10) | Keep all 3. Document the third as additive over the R76.P1 prompt’s “2 tasks” figure. |
| P1.4 — Rule Versioning | P1.4.1 (Version Hash Computation), P1.4.2 (Rule Migration) | src/rules/versioning.{ext}, migration.{ext} |
Complete, 2 entries | Reshape: R76.P1’s group plan designates P1.4 = Admission Layer and P1.5 = Governance / Rule Versioning. The existing P1.4 is genuinely about rule versioning. Solution: keep both entries and renumber to P1.5.1 / P1.5.2, then fill in a new P1.4 — Admission Layer with 3 sub-tasks (admission evaluator at α’s tool-lock stage, typed denial reasons, admission budgets). |
| Missing | P1.4 Admission Layer | TBD | Not filled | Fill (new). Covers admission layer at α’s tool-lock stage — inputs, outputs, denial taxonomy, budget enforcement. 3 sub-tasks: P1.4.1 admission evaluator, P1.4.2 typed denial reasons, P1.4.3 budget/quota enforcement. |
| Missing | P1.5 Governance / Rule Versioning | TBD | Not filled | Populate by moving the two existing “P1.4” entries into a renamed P1.5 group and adding one new entry: P1.5.3 — Activation Epoch + Rollback. That brings P1.5 to 3 entries (version hash + migration + activation/rollback) aligned to π governance touch-points from rule-engine.md §Rule versioning. |
Headline gap summary
- task-breakdown.md already lists 10 P1 sub-tasks, grouped as P1.1 (2) + P1.2 (3) + P1.3 (3) + P1.4 rule-versioning (2).
- R76.P1 deliverable requires ≥20 sub-tasks across 5 groups. Doubling the sub-task count requires restructuring P1.4 (renumber to P1.5 then populate a new Admission Layer P1.4) and expanding the interior of every group with the next layer of extraction-informed sub-tasks.
- Target final shape (this task delivers): P1.1 (3) + P1.2 (4) + P1.3 (4) + P1.4 (4 admission) + P1.5 (5 governance+versioning) = 20 sub-tasks total.
Concrete text changes planned for task-breakdown.md
- Rename section headers: keep
### P1.4 — Rule Versioningonly as a historical anchor; add a new### P1.4 — Admission Layerabove or in place of it, renumber the existing “P1.4.1/P1.4.2” to P1.5.1/P1.5.2, and add P1.5.3 — Activation Epoch + Rollback. - Add
### P1.5 — Governance / Rule Versioningsection containing P1.5.1 (Version Hash Computation — from existing P1.4.1), P1.5.2 (Rule Migration — from existing P1.4.2), P1.5.3 (Activation Epoch + Rollback — new). - Add two more granular sub-tasks in P1.1 (P1.1.3 — BPS Constants + Overflow Protection) plus existing P1.1.1 / P1.1.2.
- Add one sub-task in P1.2 (P1.2.4 — Rule Loader / Registry) plus existing P1.2.1 / P1.2.2 / P1.2.3.
- Add one sub-task in P1.3 (P1.3.4 — Policy Gating / Pre-guards) plus existing P1.3.1 / P1.3.2 / P1.3.3.
- Populate P1.4 — Admission Layer with 4 sub-tasks: P1.4.1 (Admission Evaluator), P1.4.2 (Denial Reason Taxonomy), P1.4.3 (Admission Budgets / Evaluation Budget), P1.4.4 (Tool-Lock Integration Spec).
Count after the rewrite: 3 + 4 + 4 + 4 + 5 = 20 sub-tasks (≥20 target met, with headroom of zero — we commit to exactly 20).
2. Key design invariants (from docs/3-world/physics/laws/rule-engine.md)
Lifted verbatim from the spec — every P1.x sub-task must preserve these:
- 64-bit signed integer arithmetic only. Floats are forbidden. Every numeric operation uses basis points:
10000 = 100%,1 = 0.01%. Floor rounding for all division; floor is monotone under composition. - Forbidden operations in rule bodies: clock reads, randomness (except via VRF inputs), floating-point arithmetic, side effects, external I/O (file, HTTP).
- First-match-wins evaluation.
ruleset.sorted_by_specificity()thenfor rule in ruleset: if guard_matches: apply_effects; break. No fallthrough. - Specificity ordering: (a) guard term count descending, (b) declaration order. Ties refuse boot (load-time error).
- Atomic effects: all three land in a single logical event or none do (transactional at the β layer).
- Evaluation budget:
MAX_INTEGER_OPS = 10_000,MAX_CALL_DEPTH = 16,MAX_ARG_COUNT = 8. Overruns returnADMISSION_DENIED(reason="budget:<which>"). - Rule version hash:
SHA-256(canonical_serialization(all_rules) || engine_version). Participates in θ consensus votes ((round_id, merkle_root, rule_version_hash)) and ι fork ids. - Test corpus parity requirement: π governance requires
h_old == h_newfor every corpus event both versions admit, and the divergence set matches the proposal’s declared scope. Divergence outside declared scope auto-fails π proposal. - Constitutional axioms AX-01–AX-07 (see
../constitution.md) bound what κ may be asked to evaluate. Load-time rejection on violation. - Collect-then-apply mutation pattern. Evaluation produces a mutation list; mutations apply atomically after all rules run. No side effects during evaluation.
- AST cap: max 10,000 nodes per rule per the extraction §5.
- Two-phase evaluation: (1) guard block, (2) effects block. Effects only fire if guard matched.
3. Chevrotain + EBNF grammar points
From CLAUDE.md §1: “Chevrotain is spec-only for Phase 1+ (κ).” Library choice ratified in ADR-006.
EBNF highlights (grammar union from concept doc §DSL grammar + extraction §1)
Two overlapping but slightly different grammars are on file. The concept doc (rule-engine.md) defines a narrow expression language; the extraction (kappa-rule-engine-extraction.md §1) defines a broader expression grammar covering OrExpr / AndExpr / NotExpr / Comparison / Additive / Multiplicative / Unary / Primary. P1.2 prompts must cite both and commit to the extraction’s broader form as Phase 1’s contract target — it’s the richer superset.
Key grammar productions Phase 1 must implement:
rule = "rule" IDENTIFIER "{" GuardBlock EffectBlock "}"GuardClause = ( Expression | "else" ) "->" ActionAction = "admit" | "reject" STRINGEffectCall = IDENTIFIER "(" ArgList ")"Variable = "$" DotPath— variables begin with$, deref via.INTEGER = DIGIT { DIGIT }— no floats, no hex literals, no underscore separators- Keyword list:
rule,guards,effects,when,then,if,else,and,or,not,true,false,admit,reject,admission,transition,consequence,promotion
Chevrotain-specific notes for prompts
Phase 1 sub-task prompts must:
- Target Chevrotain as the lexer + parser library (one dependency, two artifacts).
- Not invent a hand-rolled parser — historical reason Chevrotain was chosen per ADR-006.
- Exercise Chevrotain’s error recovery (
recoveryEnabled: true) to fulfill the “reports first 5 errors, doesn’t crash on malformed input” acceptance criterion in P1.2.2. - Pin Chevrotain version in
package.jsonat P1.2.1 landing time.
4. Rough mapping — 20 sub-tasks → Phase 1 files in src/domains/rules/
Phase 0 established the src/domains/<axis>/ convention (tasks → domains/tasks/, trail → domains/trail/, proof → domains/proof/, etc.). κ Phase 1 follows the same pattern.
| Sub-task | Phase 1 output file (convention) | Tests |
|---|---|---|
| P1.1.1 Basis Point Arithmetic | src/domains/rules/integer-math.ts |
src/domains/rules/__tests__/integer-math.test.ts |
| P1.1.2 Determinism Verification Harness | (test-only) | src/domains/rules/__tests__/determinism.test.ts |
| P1.1.3 BPS Constants + Overflow Protection | src/domains/rules/bps-constants.ts |
src/domains/rules/__tests__/bps-constants.test.ts |
| P1.2.1 Lexer / Tokenizer | src/domains/rules/lexer.ts |
src/domains/rules/__tests__/lexer.test.ts |
| P1.2.2 Parser (Tokens → AST) | src/domains/rules/parser.ts |
src/domains/rules/__tests__/parser.test.ts |
| P1.2.3 AST Validator | src/domains/rules/validator.ts |
src/domains/rules/__tests__/validator.test.ts |
| P1.2.4 Rule Loader / Registry | src/domains/rules/registry.ts |
src/domains/rules/__tests__/registry.test.ts |
| P1.3.1 Core Evaluation Loop | src/domains/rules/engine.ts |
src/domains/rules/__tests__/engine.test.ts |
| P1.3.2 Built-in Functions | src/domains/rules/builtins.ts |
src/domains/rules/__tests__/builtins.test.ts |
| P1.3.3 State Access Layer | src/domains/rules/state-access.ts |
src/domains/rules/__tests__/state-access.test.ts |
| P1.3.4 Policy Gating / Pre-guards | src/domains/rules/policy-gate.ts |
src/domains/rules/__tests__/policy-gate.test.ts |
| P1.4.1 Admission Evaluator | src/domains/rules/admission.ts |
src/domains/rules/__tests__/admission.test.ts |
| P1.4.2 Denial Reason Taxonomy | src/domains/rules/denial-reasons.ts |
src/domains/rules/__tests__/denial-reasons.test.ts |
| P1.4.3 Admission Budgets | src/domains/rules/budget.ts |
src/domains/rules/__tests__/budget.test.ts |
| P1.4.4 Tool-Lock Integration Spec | src/domains/rules/tool-lock-adapter.ts |
src/domains/rules/__tests__/tool-lock-adapter.test.ts |
| P1.5.1 Version Hash Computation | src/domains/rules/versioning.ts |
src/domains/rules/__tests__/versioning.test.ts |
| P1.5.2 Rule Migration | src/domains/rules/migration.ts |
src/domains/rules/__tests__/migration.test.ts |
| P1.5.3 Activation Epoch + Rollback | src/domains/rules/activation.ts |
src/domains/rules/__tests__/activation.test.ts |
| P1.5.4 Canonical Serialization | src/domains/rules/canonical.ts |
src/domains/rules/__tests__/canonical.test.ts |
| P1.5.5 Test Corpus Parity Harness | src/domains/rules/parity-harness.ts |
src/domains/rules/__tests__/parity-harness.test.ts |
Final shape: 20 sub-tasks, each with one source file + one test file (except P1.1.2 which is test-only — 19 source files + 20 test files).
5. Out-of-scope confirmation for R76.P1
- No κ TypeScript code written in this PR.
- No modification to
src/anywhere. - No ADR changes (ADR-005 / ADR-006 untouched).
- No δ Phase 1.5 content (R76.P2’s turf).
- No roadmap edits (R76.P3’s turf).
- No edits to
.agents/or.claude/skill surfaces.
Deliverables in this PR touch only docs/guides/implementation/task-breakdown.md (Phase 1 section rewrite), docs/guides/implementation/task-prompts/p1.1-kappa-rule-engine.md (new), docs/guides/implementation/task-prompts/index.md (new entry), and the four chain docs at docs/{audits,contracts,packets,verification}/r76-p1-kappa-planning-*.md.
6. References
- Concept:
docs/3-world/physics/laws/rule-engine.md - Extraction:
docs/reference/extractions/kappa-rule-engine-extraction.md - Spec targets (still spec-only at R76):
docs/spec/s10-admission.md,docs/spec/s11-rule-engine.md,docs/spec/s12-dsl.md - ADRs:
docs/architecture/decisions/ADR-002-vrf-implementation.md,docs/architecture/decisions/ADR-006-dsl-grammar.md - Roadmap anchor:
docs/5-time/roadmap.md(Phase 1 starts R81) - Pattern reference:
docs/guides/implementation/task-prompts/p0.3-beta-task-pipeline.md,docs/guides/implementation/task-prompts/p0.5-delta-router.md,docs/guides/implementation/task-prompts/index.md
Audit complete — proceed to contract.