clay-borg/.forgejo/workflows/ci.yml
tegwick fed422a3a3 T01: audit every InnerLoop rule, and make the checkable ones executable
41 rules classified executable / checkable / decorative, each tagged with
the failure class it catches. Counts: 11 executable, 22 checkable, 4
decorative (one of them dead policy).
Audit: history/260731-inner-loop-rule-audit.md

New tools/loop-lint.py makes 7 rules executable (tier declared, chaos
roll recorded, tier-L review trail, unmeasured-in-evidence, whole-file
loadability, reporting tools expose --self-test). It found three real
violations on its first run, none previously visible:

  - specs/ArchitectureBlueprint.md was 543 lines against a ~400 limit
    the loop has stated since v0.2 and never measured. Split at its own
    section boundaries into Blueprint (1-8) + Runtime (9-15).
  - tools/dep-weight.py and tools/rule-coverage.py had positive-control
    logic and no --self-test, so nothing verified the control worked.

Adding rule-coverage's self-test exposed a latent instance of the exact
class this workplan is about: if the spec regex stopped matching, rules
was empty, missing was empty, and the tool exited 0 reporting "0/0" --
a silent pass, in the tool that reports our headline AM-1 number. Both
tools now assert they found something before reporting.

Two demotions applied in the spec rather than left implicit: "structured
over prose" is marked guidance (nothing can check it), and the 8k/10k
token budget is struck through and marked DEAD POLICY pointing at T05.

The audit's uncomfortable finding: rule 13 (re-derive inherited numbers)
has no mechanical form, is deliberately left decorative, and caught the
LARGEST error in CB-WP-0002. That is a counter-example to this
workplan's own hypothesis. "A rule that cannot be executed is not a
rule" is wrong as stated; the defensible version is that such a rule
cannot be relied on to fire, so it must not be the only defence for a
class that matters.

Class coverage: harness-does-nothing has five executable rules;
trusted-arithmetic has ZERO and produced the largest single error.

make loop-lint and make self-tests wired into `make all` and CI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 09:16:00 +02:00

51 lines
2 KiB
YAML

name: ci
on:
push:
branches: [main]
pull_request:
jobs:
check:
runs-on: docker
container:
image: rust:1.97
steps:
- uses: actions/checkout@v4
- run: rustup component add rustfmt clippy
- run: cargo fmt --all --check
- run: cargo clippy --workspace --all-targets -- -D warnings
# The shipped runtime is a distinct configuration (AM-4a); it must
# compile and lint on its own, or the feature split rots.
- run: cargo clippy -p games-ground --no-default-features -- -D warnings
- run: cargo test --workspace
# No `|| test $? -eq 2`: cb-sim now fails on an unregistered game
# prefix and on a run that executed nothing. A silent skip is the
# failure this step exists to catch.
- run: cargo run -q -p cb-sim -- scenarios/ground/*.yaml
# AM-1: every numbered GR-rule is claimed by a scenario, and no
# scenario claims a rule the spec does not define.
- run: make coverage
# AM-4a/AM-4b: third-party source under audit, per configuration.
- run: make dep-weight
# Positive control for the cost collector (AC-5..AC-9). Does not
# gate on a dollar figure — transcripts are not present in CI — but
# proves the collector still detects the failures it claims to.
- run: make self-tests
# InnerLoop rules made executable (CB-WP-0003 T01). Fails on an
# overlong artifact, a survey missing its tier/chaos declaration, an
# approved tier-L survey with no review trail, `unmeasured` in an
# evidence table, or a reporting tool with no --self-test.
- run: make loop-lint
# InnerLoop v1.0 positive control, enforced rather than asserted in
# prose: --test runs every benchmark once, so a workload that
# stalls or produces the wrong event count fails the build instead
# of silently reporting throughput for work that never happened.
- run: cargo bench -p games-ground --bench synthetic -- --test