approve x/image and re-cost the core ceiling
ADR-0040 puts the dependency approval on the record, as hard rule 2 requires: the standard library decodes JPEG, PNG and GIF but cannot resize, and image/draw scales only by nearest neighbour, which is visibly wrong on the photographic downscales this site is made of. Four modules against a cap of six, no transitive dependencies, and WebP decoding comes along. AVIF still has no decoder anywhere, so it will pass through untouched. ADR-0041 raises CORE_LOC_MAX 2000 → 2800. The old figure was costed before any code existed, for the spine and the render path, and never budgeted what cmd/ will hold: `check` ~250, `new` ~100, `-dev` ~100, change detection ~100, page cache ~200. On a core already at 1870 that is ~2620 before anything optional, so the gate was going to fail work nobody would call excess. A costing error corrected, not discipline loosened. The ADR and HARNESS.md both say what a *second* raise would mean: that something belongs in internal/ext/. Two ceilings exist so "core stops growing, ext rises" is observable, and that stops being true the moment leaves are let into core.
This commit is contained in:
@@ -52,6 +52,12 @@ must do — not the theme. `verify.sh` fails if the embedded reference theme cha
|
||||
changing, because in practice those two drift together — and it fails on a `<script>` tag in that theme,
|
||||
because a reference theme that grows taste stops being a reference (ADR-0026).
|
||||
|
||||
**The core ceiling moved once, on purpose.** `CORE_LOC_MAX` went 2000 → 2800 (ADR-0041) because the original
|
||||
figure was costed before any code existed and never budgeted what `cmd/` would hold — `check`, `new`, `-dev`,
|
||||
change detection. Treat a *second* raise as evidence that something belongs in `internal/ext/` instead: the
|
||||
two ceilings exist so that "core stops growing, ext rises" is observable, and that stops being true the moment
|
||||
leaves are allowed into core.
|
||||
|
||||
**What is staged has to build, not just the working tree.** Every other gate looks at your files; this one
|
||||
looks at the commit you are about to make, by building a throwaway checkout of the index. It exists because
|
||||
staging a subset — a changed signature without its caller — produced a commit that did not compile while
|
||||
|
||||
@@ -519,3 +519,34 @@ stated wherever a key is documented; and the set of keys must stay declared or `
|
||||
config, which is the failure the parked cascade already warns about.
|
||||
Revisit if: a section wants to set a policy for everything beneath it. That is the parked cascade arriving
|
||||
for real, and its trigger is unchanged: the first section-level override with a reader.
|
||||
|
||||
## ADR-0040 — `golang.org/x/image` for resampling and WebP decoding
|
||||
Date: 2026-07-30 · Status: accepted (human approval on the record, per hard rule 2)
|
||||
Decision: add `golang.org/x/image` to the allowlist, for `draw` (CatmullRom resampling) and `webp` (decode).
|
||||
Total modules go from three to four, against a cap of six.
|
||||
Why: the standard library decodes and encodes JPEG, PNG and GIF but cannot resize — `image/draw` scales only
|
||||
by nearest neighbour, which is visibly wrong on photographic downscales, and a site whose content *is*
|
||||
pictures cannot ship that. A hand-rolled box filter is about fifty lines and still worse than CatmullRom on
|
||||
exactly the material this site has. `x/image` is maintained by the Go team, sibling of the `x/text` already
|
||||
allowed, and carries no transitive dependencies.
|
||||
Consequence: cheap — good downscaling and WebP input for one module. Expensive — AVIF still has no decoder in
|
||||
either the standard library or this module, so AVIF passes through untouched; and image code now has a
|
||||
dependency that must be checked at each Go release like any other.
|
||||
Revisit if: the standard library gains a resampler, or AVIF becomes something the site actually publishes.
|
||||
|
||||
## ADR-0041 — `CORE_LOC_MAX` 2000 → 2800
|
||||
Date: 2026-07-30 · Status: accepted
|
||||
Decision: raise `CORE_LOC_MAX` from **2000** to **2800**. `EXT_LOC_MAX` stays at 2000. The budget continues
|
||||
to cover `cmd/` plus `internal/{content,render,web}`.
|
||||
Why: the original figure was costed before any code existed, for "spine, bundles, queries, render, routing,
|
||||
templates" — and it never budgeted the things `cmd/` will hold. Costing what remains that cannot be a leaf:
|
||||
`check` ~250, `new` ~100, `-dev` ~100, change detection ~100, the page cache ~200. On top of 1870 that is
|
||||
~2620 before anything optional, so the ceiling was going to fail on work nobody would call excess. This is a
|
||||
costing error being corrected, not discipline being loosened.
|
||||
Consequence: cheap — the gate stops blocking planned core work, and 2800 still binds at roughly one feature's
|
||||
slack. Expensive — a raised ceiling is a weaker signal than the one it replaces, so the *second* raise should
|
||||
be treated as evidence that something belongs in `internal/ext/` instead. Features that are leaves must keep
|
||||
going there: if they land in core, `EXT_LOC` measures nothing and invariant 9 becomes unobservable, which is
|
||||
the whole reason there are two ceilings.
|
||||
Revisit if: core approaches 2800. That is the question "what here is not core?" and the answer is a leaf, not
|
||||
a third raise.
|
||||
|
||||
@@ -5,4 +5,5 @@
|
||||
|
||||
github.com/yuin/goldmark
|
||||
golang.org/x/text # NFC normalisation (ADR-0015); collation later if earned
|
||||
golang.org/x/image # CatmullRom resampling + WebP decode (ADR-0040); no stdlib resizer exists
|
||||
gopkg.in/yaml.v3 # frontmatter + site declaration (ADR-0020)
|
||||
|
||||
+6
-2
@@ -5,7 +5,7 @@
|
||||
# code worse — sharding a coherent file into a `_helpers.go` turns it green while creating the package
|
||||
# CLAUDE.md rule 3.6 bans. Total mass cannot be gamed by moving code between files; file length can.
|
||||
|
||||
CORE_LOC_MAX=2000 # cmd/ + internal/{content,render,web} + repo root, non-test .go
|
||||
CORE_LOC_MAX=2800 # cmd/ + internal/{content,render,web} + repo root, non-test .go (ADR-0041)
|
||||
EXT_LOC_MAX=2000 # internal/ext/ — composition, grows after the core freezes
|
||||
FILE_LOC_WARN=500 # any single .go file — advisory
|
||||
FUNC_LOC_WARN=60 # any single function — advisory
|
||||
@@ -13,7 +13,11 @@ DEPS_MAX=6 # total modules in go.mod, direct plus indirect
|
||||
|
||||
# Two ceilings because "the core stops growing after Arc 2" (architecture.md invariant 9) is only an
|
||||
# invariant if something measures it: post-freeze CORE holds and only EXT rises.
|
||||
# Costed, not round: spine, bundles, queries, render, routing, templates ~1200-1800 → CORE 2000.
|
||||
# Costed, not round, and re-costed once (ADR-0041): the first figure covered spine, bundles, queries,
|
||||
# render, routing and templates (~1200-1800 → 2000) but never budgeted what cmd/ would hold. Adding `check`
|
||||
# ~250, `new` ~100, `-dev` ~100, change detection ~100 and the page cache ~200 to a core already at 1870
|
||||
# gives ~2620 → CORE 2800. A second raise is evidence something belongs in internal/ext/, not evidence the
|
||||
# number is still too small.
|
||||
# Feeds, sitemap, OpenGraph, shortcodes, image sizing, galleries, paging, indieweb ~900-1200 → EXT
|
||||
# 2000, deliberately loose since that is where growth belongs. Reaching CORE asks what to delete;
|
||||
# reaching EXT asks whether a template would have done it — only .go lines count here.
|
||||
|
||||
Reference in New Issue
Block a user