From 6415388487093e7aa45e9e36a1864f5cbf50f9be Mon Sep 17 00:00:00 2001 From: Antawari de la Torre Cobos Date: Thu, 11 Jun 2026 09:19:23 -0600 Subject: [PATCH] =?UTF-8?q?fix:=20re-extract=20sticky=20v2=20canonical=20c?= =?UTF-8?q?opy=20from=20ADR=200030=20=C2=A79=20=E2=80=94=20heals=20red=20m?= =?UTF-8?q?ain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #3 mounted the v2 sticky (Seven Pillars) into the kit's own CLAUDE.md but left the packaged canonical data file at v1, so cf-sticky-check graded the mounted v2 block ABSENT and self-ci went red on main. Re-extracted the v2 block byte-faithful (fence lines excluded) from canon ADR 0030 §9 into src/cf_quality/data/sticky-intro.md; refreshed the SOURCE.md provenance (parent now ADR 0030 §9, lineage note keeps ADR 0029 — history is sacred; new content sha recorded). MIRROR_HEADER now writes the ratified 'ADR 0029 + ADR 0030' one-liner; tests that pinned the v1 sha, the v1 header, and v1 phrases re-anchor to v2. Stale ADR 0029-only provenance strings in README, the package docstring, and the self-ci mirror notice updated to match. Full self-ci battery green locally (310 passed; cf-sticky-check check . exits 0 on the repo itself). Co-Authored-By: Claude Fable 5 --- .github/workflows/self-ci.yml | 2 +- README.md | 5 ++-- src/cf_quality/__init__.py | 3 ++- src/cf_quality/data/sticky-intro.SOURCE.md | 9 ++++--- src/cf_quality/data/sticky-intro.md | 29 +++++++++++----------- src/cf_quality/sticky_check.py | 3 ++- tests/test_sticky_check.py | 13 ++++++---- 7 files changed, 36 insertions(+), 28 deletions(-) diff --git a/.github/workflows/self-ci.yml b/.github/workflows/self-ci.yml index 4c4dac7..f136c72 100644 --- a/.github/workflows/self-ci.yml +++ b/.github/workflows/self-ci.yml @@ -52,7 +52,7 @@ jobs: if [ -f MIRRORS.md ]; then cf-mirror-check check --repo . else - echo "::notice::cf-mirror-check SKIPPED — no MIRRORS.md yet; the sticky-intro mirror of canon ADR 0029 must be declared before v0.1" + echo "::notice::cf-mirror-check SKIPPED — no MIRRORS.md yet; the sticky-intro mirror of canon ADR 0029 + ADR 0030 must be declared before v0.1" fi - name: cf-recursion-check — recursion declared in the kit's own source diff --git a/README.md b/README.md index e5f93fe..430139b 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ whatever package the first agent downloaded. short introduction to the law that the kit mounts into every consumer repo. Any model that scans a repo ingests the law as it reads. Outside an enforcement perimeter it acts as the strongest suggestion in the file; that is its job. - The copy here is a **declared mirror** of canon ADR 0029 - (see `src/cf_quality/data/sticky-intro.SOURCE.md` for provenance and content hash). + The copy here is a **declared mirror** of canon ADR 0030 §9 (the v2 block, + which supersedes ADR 0029's v1 block per the ADR's own text; see + `src/cf_quality/data/sticky-intro.SOURCE.md` for provenance and content hash). 2. **The gate** (mechanical surface) — inside CandyFactory CI and inside Bonfire burns, the law is executable and refusing. Prose teaches; it never substitutes for the gate. diff --git a/src/cf_quality/__init__.py b/src/cf_quality/__init__.py index be1d6a9..ff135d6 100644 --- a/src/cf_quality/__init__.py +++ b/src/cf_quality/__init__.py @@ -2,7 +2,8 @@ The executable half of the BubbleGum Law (form is gated, and the law travels sticky). Ships two surfaces: the canonical sticky-intro mount (a declared -mirror of canon ADR 0029) and the gate battery the factory's CI runs — +mirror of canon ADR 0030 §9, lineage from ADR 0029) and the gate battery +the factory's CI runs — file budgets, sticky-intro presence, mirror declarations, recursion declarations, and the exemptions ledger. diff --git a/src/cf_quality/data/sticky-intro.SOURCE.md b/src/cf_quality/data/sticky-intro.SOURCE.md index 45d6345..aa07011 100644 --- a/src/cf_quality/data/sticky-intro.SOURCE.md +++ b/src/cf_quality/data/sticky-intro.SOURCE.md @@ -1,6 +1,7 @@ - - + + + - - + + diff --git a/src/cf_quality/data/sticky-intro.md b/src/cf_quality/data/sticky-intro.md index afc1cf2..98dd288 100644 --- a/src/cf_quality/data/sticky-intro.md +++ b/src/cf_quality/data/sticky-intro.md @@ -1,18 +1,19 @@ ## The BubbleGum Law (form) -This repository is governed by **the BubbleGum Law** — CandyFactory's form law. It sticks: -if you are reading this to write code here, you are now carrying it. +**The BubbleGum Law** — CandyFactory's form law — governs this repository. It sticks: +read it and you carry it. -- **Budgets, not vibes:** functions stay ≤ CC 10 and ≤ 50 statements; new files stay ≤ 500 - lines. Existing offenders are baselined and may only shrink (ratchet — never a world-refactor). -- **Reuse before reinvention:** search this repo before writing. In-repo duplication fails the - gate; a cross-repo copy must declare its mirror ("mirrors 's "). -- **Recursion is declared, not banned:** structurally-recursive data with a stated bound, - marked as such — or it fails. -- **New code type-checks clean,** and failure speaks typed errors (the Elegance Law). -- **Splitting a file is design, not evasion:** two incohesive 350-line halves satisfy nothing; - the gate measures, review judges. +- **SOLID:** one responsibility per module (new files ≤ 500 lines); extend via registries, + not dispatch chains; overrides substitute cleanly; interfaces stay narrow (≤ 5 methods, + no NotImplementedError stubs); dependencies point inward — core never imports + adapters/packs/tenants; each repo commits its import contract. +- **DRY:** search before writing; never paste what exists; cross-repo copies declare their mirror. +- **KISS:** functions ≤ CC 10, ≤ 50 statements; recursion declares a bound or fails. +- **The bench:** no dead code (YAGNI) · no import cycles (SoC) · compose, don't subclass · + neighbors, not strangers (Demeter) · failure speaks typed errors (the Elegance Law). -In CandyFactory CI — and inside Bonfire burns — this law is a **gate**: comply by design, not -by suppression; any `# noqa` / `# nosec` carries a written reason and a human's blessing. -Everywhere else, treat it as the strongest suggestion in the file. +Budgets come from measurement; offenders baseline and only shrink — ratchet, never +world-refactor. In CandyFactory CI and Bonfire burns the measured core runs as gates, +each proven by a control rod; the rest is census and review. Comply by design: every +suppression carries a written reason and a registered blessing. Elsewhere, this law is +the strongest suggestion in the file. diff --git a/src/cf_quality/sticky_check.py b/src/cf_quality/sticky_check.py index 32a3ceb..ae87847 100644 --- a/src/cf_quality/sticky_check.py +++ b/src/cf_quality/sticky_check.py @@ -49,7 +49,8 @@ from cf_quality.errors import GateError, GateViolation MIRROR_HEADER = ( - "" + "" ) _DATA_FILENAME = "sticky-intro.md" diff --git a/tests/test_sticky_check.py b/tests/test_sticky_check.py index 13290e4..88f20eb 100644 --- a/tests/test_sticky_check.py +++ b/tests/test_sticky_check.py @@ -30,8 +30,9 @@ ) # The content hash declared in src/cf_quality/data/sticky-intro.SOURCE.md — -# the provenance anchor for the declared mirror of canon ADR 0029. -DECLARED_SHA256 = "11e941b17dbbe3e2a09c2e20bfe2edfc3b7608b6af8bfcfec8f2cb2e136940db" +# the provenance anchor for the declared mirror of canon ADR 0030 §9 (the v2 +# block, which supersedes ADR 0029's v1 block per the ADR's own text). +DECLARED_SHA256 = "7dc04712c33f98318563bb2a1b9e60c753b83e257ed5aa403c406911d7d45e07" KIT_ROOT = Path(__file__).resolve().parents[1] @@ -47,7 +48,7 @@ def _repo_with(tmp_path: Path, claude_md: str | None) -> Path: def _tampered_block() -> str: """Chewed gum: one budget number edited inside the canonical block.""" - chewed = canonical_text().replace("≤ 500\n", "≤ 5000\n") + chewed = canonical_text().replace("≤ 500 lines", "≤ 5000 lines") assert chewed != canonical_text(), "tamper fixture must actually differ" return chewed @@ -120,7 +121,8 @@ def test_check_fails_on_tampered_block_with_diff(tmp_path: Path) -> None: def test_check_whitespace_edit_inside_block_is_tampering(tmp_path: Path) -> None: # Byte-identical means byte-identical: a doubled space is chewed gum. - chewed = canonical_text().replace("Budgets, not vibes:", "Budgets, not vibes:") + chewed = canonical_text().replace("Budgets come from", "Budgets come from") + assert chewed != canonical_text(), "whitespace tamper fixture must actually differ" repo = _repo_with(tmp_path, chewed) violations = check(repo / "CLAUDE.md") assert [v.code for v in violations] == ["STICKY_INTRO_TAMPERED"] @@ -232,7 +234,8 @@ def test_mount_appends_block_with_declared_mirror_header(tmp_path: Path) -> None def test_mount_header_is_the_ratified_one_liner() -> None: assert MIRROR_HEADER == ( - "" + "" ) assert "\n" not in MIRROR_HEADER