Commit Graph
14 Commits
Author SHA1 Message Date
bdeshi 8dc6746684 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.
2026-08-01 02:23:36 +06:00
bdeshi 7a08fccc42 gate that the staged tree builds, not just the working tree
Earned by a real mistake this session: `web.Handler` gained a parameter, its
caller in cmd/ was updated in the working tree, and `git add internal docs` left
that caller out. verify.sh was green throughout, because every gate looks at the
files on disk rather than at the commit being made. The result was a commit that
did not compile — the kind of thing git bisect trips over for as long as the repo
exists. I rewrote the two local commits rather than adding a fix-up on top.

The check builds a throwaway checkout of the index via `git write-tree`, so it
cannot touch the real index or working tree, and it only runs when something is
staged. Proved both directions: staging a signature change without its caller
fails, a clean tree passes.

Eighth gate defect found by running the harness against real work rather than
reasoning about it — and the first that was a missing gate rather than a wrong one.
2026-08-01 02:23:36 +06:00
bdeshi d40c53778b gate the raw-HTML default instead of remembering it
Since Arc 1 the latent list has carried "raw HTML is omitted only because
goldmark's default omits it". Shortcodes were the trigger, and they came and went
without needing unsafe mode — a call renders a theme template (ADR-0036). So the
right close is not a note saying we got away with it, but a gate: verify.sh now
fails on WithUnsafe in any non-comment line under cmd/ or internal/.

Proved both directions before keeping it. The first version also failed on the
comment in render.go that explains the rule — a gate that fires on its own
documentation is one nobody keeps, so it now skips comment lines. That is the
seventh gate defect found by running against real code rather than reasoning
about it.

The latent row is gone rather than reworded, and the untrusted-boundary row says
which half is now mechanism and which half still isn't.
2026-08-01 02:23:35 +06:00
bdeshi 97b01bea05 harness: a standing advisory is a defect
The %w advisory counted every fmt.Errorf without %w, including calls that create
an error rather than wrap one — so it fired permanently on correct code. It now
looks for a call that passes an err and drops the %w, which is the actual rule.

Recorded the general form in the loop's Verify step and in HARNESS.md: a warning
that fires on correct code and keeps firing is a defect in the check or the code,
resolved in that change. Two advisories have now been narrowed after firing on
code the harness itself mandates, and the count creeping from one to two was the
only signal either time.

verify.sh is at zero warnings, which is what makes the next one legible.
2026-08-01 02:23:34 +06:00
bdeshi b3ffa21fdf harness: flag any only in exported signatures
The advisory fired on stringList(v any), which reads the open page object that
ADR-0002 mandates — so its false-positive rate was total, and a warning that is
always wrong teaches you to skim warnings. conventions.md bans interface{} as an
API escape hatch, which is what the check now looks for: any or interface{} in an
exported func or method signature. Verified by adding an exported func Do(x any)
and watching it fire, then reverting.
2026-08-01 02:23:34 +06:00
bdeshi c6d5b4abb7 harness: say which settings file the exemption means
The exemption is Claude Code's permission list, not "settings files". khosra will
have its own configuration and none of it is exempt: the engine's settings live in
the site root and the engine validates them, while scripts/budgets.env and
everything else under scripts/ and .claude/ stays gated. Verified by touching
budgets.env and watching the coupling gate fail.
2026-08-01 02:23:34 +06:00
bdeshi c87fed697b harness: fail an untidy go.mod
go get marks a module indirect until something imports it, and the allowlist
check only inspects direct requires — so an unapproved dependency could sit in
go.mod unnoticed. Demonstrated: adding github.com/google/uuid passed the
allowlist check and was caught only by this gate.
2026-08-01 02:23:34 +06:00
bdeshi 28face98d6 harness: permissions changes owe no HARNESS.md note
The coupling gate treated every path under .claude/ as mechanism, so editing the
pre-approved command list demanded an explanation of a machine that had not
changed. HARNESS.md already calls settings.json a convenience — if its schema
changed the harness would still work, you would just get more prompts — so the
gate now exempts that one file and nothing else.

Carries the settings.json edit that exposed it.
2026-08-01 02:23:34 +06:00
bdeshi 0314179ec2 keep the build queue in an uncommitted .scratch/
The queue is a working plan, not a record: git log already carries what landed on
each step, so committing the plan duplicates it and invites the two to disagree.
.scratch/ is gitignored and skipped by the gate the way ideas/ and reference/ are,
so exploratory files there need not compile.

state.md keeps a conditional pointer rather than a path it cannot promise: if the
scratch file is absent, the log is the plan.
2026-08-01 02:23:34 +06:00
bdeshi 0dacf71c87 harness: three gate fixes found by running against real code
The allowlist parser stripped only whole-line comments, so an entry carrying the
reason it exists — the format allowed-deps.txt documents — failed the gate and
would have blocked every dependency ever added.

The interface{}/any advisory printed a line number instead of a filename when
only one file matched, because grep -n omits the name for a single file, and it
matched the word "any" in prose comments.

"Nesting past 4" fired at four tabs, which a closure inside a function reaches
unaided.
2026-08-01 02:23:34 +06:00
bdeshi c468cf24c3 rename the project to khosra, initialise the module
Naming is free before a module is published, a URL is shared, or a binary is
deployed; every day it waits costs more. Swept every form: module path, binary,
cmd/ directory, KHOSRA_SITE, the feature-loop skill directory, and the prose in
earlier ADRs — which describe this project under its old name, not a different
project. Recorded as ADR-0030.

go mod init lands here rather than with the first feature because the module
path is what the rename is about. x/text and yaml.v3 are required but not yet
imported, so both are indirect and no direct dependency is claimed yet.
2026-08-01 02:23:34 +06:00
bdeshi 39dcb8cc34 harness: soften two gates that would have taught --no-verify
The test-coupling gate failed comment-only and gofmt-only .go diffs, which
ship no behaviour and owe no test. Bypassing it would have cost every gate at
once, so it now compares added and removed lines with comments, blanks and
whitespace runs stripped: equal sets mean nothing happened. A new .go file is
never exempt.

The exported-doc-comment check is now a warning. No gate can tell
"// Load loads." from a useful sentence, so as a hard failure its cheapest
satisfaction was exactly the noise conventions.md calls worse than nothing.
Package comments and ADR citations in code stay hard.

Also fills in state.md's verified-against line and drops a stray blank line
left in roadmap.md by an earlier gate test.
2026-08-01 02:23:34 +06:00
bdeshi 581d6c08ee harness: withdraw five pre-code ADRs to deferred ideas
Twenty-seven ADRs existed before a line of Go. Five specified the shape of
unbuilt mechanisms — cache validity, declared types, the settings cascade,
taxonomies, extras — which breaks the rule against abstraction before a
second concrete use, in prose where the counters cannot see it. They move to
ideas/deferred-decisions.md as recorded intent and return shaped by whatever
implements them.

Citations retargeted throughout; where one was decoration the rule now stands
on its own reasoning. Type declarations and the cascade drop to [spec] with
the MVP behaviour stated instead, so the first prompts have less to build.
conventions.md names http.ServeMux as the router, closing a hole that invited
hand-rolling a path splitter. The ADR gate now checks a number is registered
in the log rather than headed by an entry, so withdrawals resolve and invented
numbers still fail. Two architecture invariants corrected: identity no longer
implies a required language suffix, and the duplicated permalink clause is gone.
2026-08-01 02:23:33 +06:00
bdeshi 54c14a20be init 2026-07-30 00:34:18 +06:00