Skip to content

fix(hk): drop five restated check_first defaults - #332

Merged
wenzowski merged 2 commits into
mainfrom
claude/rules-engine-defaults-research-lbzrbg
Aug 12, 2026
Merged

wenzowski merged 2 commits into
mainfrom
claude/rules-engine-defaults-research-lbzrbg

Conversation

@wenzowski

Copy link
Copy Markdown
Contributor

Follow-on from the rules-engine defaults census (CLOUD-381). Two small changes; the research itself lives in Linear, per the repo's rule 7.

hk.pkl: five restated check_first defaults removed

check_first already defaults true at the pinned v1.54.0 (pkl/Config.pkl:515), so all five assignments restated a default rather than overriding one. The cargo-fmt comment was the harmful part: it explained the behaviour as though the step were opting into it, so a reader checking whether the fixer skips a clean tree found a rationale for a line that changed nothing.

.claude/rules/toolchain.md already states the principle for exactly these steps — upstream's globs and check_first are upstream's authority, and re-declaring them here is a second authority for something upstream already tests.

This is the same class the census found across ten tools: a config that restates a default is indistinguishable from one that overrides it, and the reader cannot tell which layer decided. Nine of ten surveyed tools cannot answer "which layer set this value?" at all.

Memory: which survey tools reach the evidence

Two findings that each cost a wasted call to discover and are not inferable from the tool descriptions:

  • Scholar Gateway is Wiley-only and near-useless for software engineering — two on-topic articles across 24 passages over two queries. Consensus returned the field's standard results on the first try.
  • GitHub reaction counts are unreachable for repos outside button-inc/batten; add_repo on a survey target is declined by the permission classifier. Shallow clones still work, so reading source is unaffected — only the issue-reaction channel is closed, and a survey's evidence plan has to name signals the environment can actually produce.

Verification

mise run verify green after rebase. mise run pkl-check hk.pkl evaluates cleanly; the gate steps whose check_first was removed (shfmt, taplo-format, pkl-format, prettier, cargo-fmt) all run in verify, so their behaviour under the inherited default is exercised by this run rather than asserted.


Generated by Claude Code

@wenzowski
wenzowski marked this pull request as ready for review August 11, 2026 20:27
@wenzowski
wenzowski force-pushed the claude/rules-engine-defaults-research-lbzrbg branch 2 times, most recently from 69a3c36 to 18a4125 Compare August 11, 2026 20:35
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #332 (comment) by @​wenzowski.

Trying to fast forward main (6569aeb) to claude/rules-engine-defaults-research-lbzrbg (18a4125).

Target branch (main):

commit 6569aeb303e942642dd22feab96f221c67f7027e (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:02:59 2026 +0000

    feat(rules)!: rename the command kind's `run` column to `check`, reserve `fix`
    
    House style §9 specifies the `command` rule kind as a check/fix duality: an
    inspection-only `check` is the gate — the only side enforcement ever runs — and
    an optional mutating `fix` repairs what it condemned. The shipped `Rule` carried
    one `run` column, which does not express the split.
    
    §2 declares no back-compatibility surface and no deprecation aliases, so every
    config written against `run` becomes a breaking migration later. Today the key
    appears in no shipped config at all — only fixtures, tests and the README — so
    the rename costs nothing. It will not stay that way.
    
    `fix` parses and is executed by nothing: serialised fix execution is a
    capability this engine does not have. `enforce` refuses a row declaring one
    rather than running the check side and silently ignoring the repair, which would
    report green over work nobody did. Reserving the key now means an author who
    writes it is writing the final spelling.
    
    `run` survives as a refusal-only field, the shape `OverrideConfig::
    min_batten_version` already uses: "unknown field `run`" reads as a typo, where
    this is a rename with one specific fix, and the refusal has to carry it
    (CLOUD-122). It is deliberately outside `Rule::columns` — that census classifies
    the columns a kind may carry, and no kind carries this one.
    
    Both refusals are exit 1, not the exit 2 the issue's §5/§7 asked for. §7 makes 2
    the policy verdict — a violation found in the repository, or a mediated call
    denied — while a config naming a key or a capability this build does not have is
    the config-or-usage class. §5 spells the structurally identical sibling refusal
    (a rule the read-only half cannot honestly run) as exit 1, and `run_static` has
    implemented it that way since CLOUD-170; the issue's §3 describes that same
    landed refusal as exit 2, which is falsified by the code it describes. Emitting
    2 here would also make an engine gap read to a harness as a policy deny, which
    is what the structural fail-open exists to prevent.
    
    Refs: CLOUD-215

Pull request (claude/rules-engine-defaults-research-lbzrbg):

commit 18a41258b7326b718980d160064bb4f4634a6cba (pull_request/claude/rules-engine-defaults-research-lbzrbg)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:13:21 2026 +0000

    fix(hk): drop five restated check_first defaults
    
    check_first already defaults true at the pinned v1.54.0
    (pkl/Config.pkl:515), so all five assignments restated a default rather
    than overriding one. The cargo-fmt comment was the harmful part: it
    explained check_first's behaviour as though the step were opting into it,
    so a reader checking whether the fixer skips a clean tree found a
    rationale for a line that changed nothing.
    
    Same class the rules-engine defaults census (CLOUD-381) found across ten
    tools: a config that restates a default is indistinguishable from one
    that overrides it, and the reader cannot tell which layer decided.
    .claude/rules/toolchain.md already states the principle for exactly these
    steps -- upstream globs and check_first are upstream's authority, and
    re-declaring them here is a second authority for something upstream
    already tests.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01P1xT4aa59k7kKPCDXq7y3d

Can't fast forward main (6569aeb) to claude/rules-engine-defaults-research-lbzrbg (18a4125). main (6569aeb) is not a direct ancestor of claude/rules-engine-defaults-research-lbzrbg (18a4125). Branches appear to have diverged at 18bb416:

* 18a41258b7326b718980d160064bb4f4634a6cba fix(hk): drop five restated check_first defaults
* e428ef4b099869c7c26e772ff9085ffc7866dcc2 docs(memory): record which survey tools reach the evidence (CLOUD-381)
| * 6569aeb303e942642dd22feab96f221c67f7027e feat(rules)!: rename the command kind's `run` column to `check`, reserve `fix`
|/  
* 18bb41610d628560c9babe07224ae6c30478c81c ci(hooks): remind once when the instruction surface moves under a running session

commit 18bb41610d628560c9babe07224ae6c30478c81c
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:29:23 2026 +0000

    ci(hooks): remind once when the instruction surface moves under a running session
    
    A session loads its hook wiring and reads its instruction files once, at start.
    When the contract then changes on `main`, the running session keeps executing the
    old one with no signal that it drifted: `issue-guard` landed mid-session and a
    live session readied a PR whose branch and commits carried no `CLOUD-<n>` key,
    because that hook was never in that session's wiring.
    
    `contract-drift` hashes the tracked contract surface (`AGENTS.md`,
    `.claude/rules`, `.claude/settings.json`, `hk.pkl`, `mise-tasks`) in one
    `git hash-object` pass — 63 files, 8ms — keyed per session under `.git/`, and
    names the paths that moved. Silence is the default; a change-set is reported once,
    because reporting overwrites the snapshot. Pointer-only: paths and a count, never
    a byte of the file, since a reminder carrying the new text is a mirror and a
    mirror is cleared by reading the hook instead of the file.
    
    Not `PreToolUse`, which the Ready block specified: that event's only model-facing
    channel is exit 2, which blocks the call, and CLOUD-97 and CLOUD-219 each ruled a
    deny out independently. `PostToolBatch` documents `additionalContext` firing
    "before the next model request", which is the same instant as "before the next
    lifecycle step"; `SessionStart` seeds the snapshot before any tool runs, since an
    autonomous session's first batch is routinely fetch+rebase and a snapshot written
    after it would record the drift as its baseline.
    
    Measured while building it: the `PostToolBatch` entry took effect within the
    session that added it, so the channel works and the premise is narrower than the
    title reads. The reminder therefore tells the agent to check whether a new hook is
    loaded rather than asserting it cannot be.
    
    Refs: CLOUD-187

Rebase locally, and then force push to claude/rules-engine-defaults-research-lbzrbg.

@wenzowski
wenzowski force-pushed the claude/rules-engine-defaults-research-lbzrbg branch from 18a4125 to ee03e26 Compare August 11, 2026 20:43
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #332 (comment) by @​wenzowski.

Trying to fast forward main (6947232) to claude/rules-engine-defaults-research-lbzrbg (ee03e26).

Target branch (main):

commit 6947232b13bc17174986a0e3bfe528d848617519 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:57:59 2026 +0000

    perf(hk): glob batten-check and macos-link-check, and gate the glob's honesty
    
    `hk check` ran three steps unconditionally, because a step with no `glob` is
    never skipped. `batten-check` is `cargo run -p batten -- check`, so every
    commit paid a debug build whatever it touched: 9.47s cold from a fresh clone
    (CLOUD-212 run 1, D8) against 0.16s for the cheapest gate in the same run, and
    133-141ms warm, forever.
    
    The glob is the union of what `batten check` ACTUALLY reads, which is not the
    two things the obvious reading gives. Read at run_check_with in
    crates/batten/src/lib.rs, it evaluates every `[[rule]]` over that rule's own
    glob — and those reach outside crates/, to mise.toml, .github/workflows/*.yml
    and tests/*.bats — plus `budget::measure_all`, because a declared budget is a
    gate under `check` and not only under `policy budget` (CLOUD-50). That last one
    makes AGENTS.md and .serena/project.yml genuine inputs, so "a Markdown-only
    change cannot change this verdict" is false for the most-edited Markdown file
    in the repo, and a glob written from the obvious reading would have switched
    the gate off for it. Cargo.toml and Cargo.lock are in because the task uses
    `cargo run` deliberately, to judge the engine and the config as the pair that
    ships.
    
    `macos-link-check` globs the manifests alone: its predicate is `cargo metadata
    --filter-platform` over the resolved graph, and nothing else can move that
    graph. `no-docs-tree` deliberately keeps no glob — its input is the whole
    index, including a docs/ path an earlier commit left behind, and at ~95ms that
    is affordable.
    
    Deriving batten-check's list from batten.toml by hand makes hk.pkl a second
    authority over a set the config already defines, and a second authority narrows
    silently: add a rule whose glob names a new path and the step stops running for
    commits that touch only it, with nothing going red. So the glob ships with its
    mechanism (non-negotiable 2). `mise run batten-glob-check` is a pure function
    of the two committed files — every rule glob and every declared budget path
    must be covered verbatim or subsumed by a `P/**` entry, and a config it can
    parse nothing out of is exit 2 rather than a vacuous pass.
    
    Selection is asserted as data, never as a timing: `hk check --plan --json`
    prints each step's status without running it, and tests/hk-selection.bats pins
    both directions over the repository's own hk.pkl — README.md skips
    batten-check, AGENTS.md does not.
    
    Refs: CLOUD-224

Pull request (claude/rules-engine-defaults-research-lbzrbg):

commit ee03e267de19aa0acaf645a69270c6cff8f67cd4 (pull_request/claude/rules-engine-defaults-research-lbzrbg)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:13:21 2026 +0000

    fix(hk): drop five restated check_first defaults
    
    check_first already defaults true at the pinned v1.54.0
    (pkl/Config.pkl:515), so all five assignments restated a default rather
    than overriding one. The cargo-fmt comment was the harmful part: it
    explained check_first's behaviour as though the step were opting into it,
    so a reader checking whether the fixer skips a clean tree found a
    rationale for a line that changed nothing.
    
    Same class the rules-engine defaults census (CLOUD-381) found across ten
    tools: a config that restates a default is indistinguishable from one
    that overrides it, and the reader cannot tell which layer decided.
    .claude/rules/toolchain.md already states the principle for exactly these
    steps -- upstream globs and check_first are upstream's authority, and
    re-declaring them here is a second authority for something upstream
    already tests.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01P1xT4aa59k7kKPCDXq7y3d

Can't fast forward main (6947232) to claude/rules-engine-defaults-research-lbzrbg (ee03e26). main (6947232) is not a direct ancestor of claude/rules-engine-defaults-research-lbzrbg (ee03e26). Branches appear to have diverged at 6569aeb:

* ee03e267de19aa0acaf645a69270c6cff8f67cd4 fix(hk): drop five restated check_first defaults
* 544ffba28c92fd72540fc7ee0e71adf535b6deb4 docs(memory): record which survey tools reach the evidence (CLOUD-381)
| * 6947232b13bc17174986a0e3bfe528d848617519 perf(hk): glob batten-check and macos-link-check, and gate the glob's honesty
|/  
* 6569aeb303e942642dd22feab96f221c67f7027e feat(rules)!: rename the command kind's `run` column to `check`, reserve `fix`

commit 6569aeb303e942642dd22feab96f221c67f7027e
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:02:59 2026 +0000

    feat(rules)!: rename the command kind's `run` column to `check`, reserve `fix`
    
    House style §9 specifies the `command` rule kind as a check/fix duality: an
    inspection-only `check` is the gate — the only side enforcement ever runs — and
    an optional mutating `fix` repairs what it condemned. The shipped `Rule` carried
    one `run` column, which does not express the split.
    
    §2 declares no back-compatibility surface and no deprecation aliases, so every
    config written against `run` becomes a breaking migration later. Today the key
    appears in no shipped config at all — only fixtures, tests and the README — so
    the rename costs nothing. It will not stay that way.
    
    `fix` parses and is executed by nothing: serialised fix execution is a
    capability this engine does not have. `enforce` refuses a row declaring one
    rather than running the check side and silently ignoring the repair, which would
    report green over work nobody did. Reserving the key now means an author who
    writes it is writing the final spelling.
    
    `run` survives as a refusal-only field, the shape `OverrideConfig::
    min_batten_version` already uses: "unknown field `run`" reads as a typo, where
    this is a rename with one specific fix, and the refusal has to carry it
    (CLOUD-122). It is deliberately outside `Rule::columns` — that census classifies
    the columns a kind may carry, and no kind carries this one.
    
    Both refusals are exit 1, not the exit 2 the issue's §5/§7 asked for. §7 makes 2
    the policy verdict — a violation found in the repository, or a mediated call
    denied — while a config naming a key or a capability this build does not have is
    the config-or-usage class. §5 spells the structurally identical sibling refusal
    (a rule the read-only half cannot honestly run) as exit 1, and `run_static` has
    implemented it that way since CLOUD-170; the issue's §3 describes that same
    landed refusal as exit 2, which is falsified by the code it describes. Emitting
    2 here would also make an engine gap read to a harness as a policy deny, which
    is what the structural fail-open exists to prevent.
    
    Refs: CLOUD-215

Rebase locally, and then force push to claude/rules-engine-defaults-research-lbzrbg.

@wenzowski
wenzowski force-pushed the claude/rules-engine-defaults-research-lbzrbg branch 2 times, most recently from a2a471d to 0214abf Compare August 11, 2026 20:59
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #332 (comment) by @​wenzowski.

Trying to fast forward main (b642e2d) to claude/rules-engine-defaults-research-lbzrbg (0214abf).

Target branch (main):

commit b642e2dd35304790923f2a63bbbf0f9f68c9b4c2 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:47:33 2026 +0000

    perf(ci): run the shell suite in parallel, since it is the pole of the gate
    
    `hk` runs two chains concurrently, and the shell one was the longer by 133s:
    on run 31531728503 the cargo chain's last step finished 166s into `mise run
    ci`, while `test:bats` ran to 247.01s of the step's 298.87s. 800 tests, one at
    a time. `verify` runs the same gate, so a `land` lap paid it twice.
    
    That put it in the exponent of the lap economics. A lap dies whenever `main`
    moves under it, so with mean inter-land gap 487s the expected CI runs per
    landed PR is e^(L/G) — which is why shortening the lap is the one lever that
    cuts latency and the bill together rather than trading one for the other.
    
    Measured here: 248s serial -> 72.73s, 808 tests, same assertions, nothing
    skipped or sampled. The remaining pole is the cargo chain at 166s.
    
    `rush` rather than GNU parallel, which bats would otherwise look for: GNU
    parallel ships as a source tarball with no aqua/ubi/release coordinate, so it
    cannot be a [tools] key at all, and an `apt-get install` in ci.yml is the
    second-authority drift `ci-tools-check` exists to refuse. rush is prebuilt per
    platform, so `mise.lock` holds a checksum for every platform this repo
    installs on.
    
    Across files, never within one. The suites that model lock and race behaviour
    are precisely the ones a within-file schedule would interleave with their own
    setup, and across-files is already enough — the largest file is 49 of 808
    tests, so the schedule is not tail-bound.
    
    Two things ship with it:
    
    - `tests/attribution-check.bats` built its end-to-end fixture in the real
      worktree and the real index. Serially that was invisible; in parallel it is
      a race against the sibling case that reads the same tracked set, plus
      .git/index.lock contention. It now builds a throwaway repo, which is the
      convention issue-guard.bats already set.
    - A speed-up is the kind of fix that rots silently — drop the flag and
      everything still passes, just slower, and `timeout-check`'s 3.4x headroom
      absorbs a return to serial without a red build. So the invocation is now a
      gate over mise.toml: serial is an exit code, not a slower Tuesday.
    
    Refs: CLOUD-386

Pull request (claude/rules-engine-defaults-research-lbzrbg):

commit 0214abf8f8e82f7c103026c06b91db3706859023 (pull_request/claude/rules-engine-defaults-research-lbzrbg)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:13:21 2026 +0000

    fix(hk): drop five restated check_first defaults
    
    check_first already defaults true at the pinned v1.54.0
    (pkl/Config.pkl:515), so all five assignments restated a default rather
    than overriding one. The cargo-fmt comment was the harmful part: it
    explained check_first's behaviour as though the step were opting into it,
    so a reader checking whether the fixer skips a clean tree found a
    rationale for a line that changed nothing.
    
    Same class the rules-engine defaults census (CLOUD-381) found across ten
    tools: a config that restates a default is indistinguishable from one
    that overrides it, and the reader cannot tell which layer decided.
    .claude/rules/toolchain.md already states the principle for exactly these
    steps -- upstream globs and check_first are upstream's authority, and
    re-declaring them here is a second authority for something upstream
    already tests.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01P1xT4aa59k7kKPCDXq7y3d

Can't fast forward main (b642e2d) to claude/rules-engine-defaults-research-lbzrbg (0214abf). main (b642e2d) is not a direct ancestor of claude/rules-engine-defaults-research-lbzrbg (0214abf). Branches appear to have diverged at 5532160:

* b642e2dd35304790923f2a63bbbf0f9f68c9b4c2 perf(ci): run the shell suite in parallel, since it is the pole of the gate
| * 0214abf8f8e82f7c103026c06b91db3706859023 fix(hk): drop five restated check_first defaults
| * dec785f4ecfdf4152dda95fa006783ad695d973d docs(memory): record which survey tools reach the evidence (CLOUD-381)
|/  
* 55321601f0fb1cf8e5d9c5a97129e36b11df62fb chore(deps): drop dev-dependencies that duplicate the normal ones

commit 55321601f0fb1cf8e5d9c5a97129e36b11df62fb
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:04:52 2026 +0000

    chore(deps): drop dev-dependencies that duplicate the normal ones
    
    `serde_json` was listed in both `[dependencies]` and `[dev-dependencies]`, and
    so were `flate2`, `tar` and `toml` — the identical redundancy, in the same
    table, filed as one bullet because one of the four was noticed. A normal
    dependency is already in scope for every test target, so all four entries
    declared nothing; the comment above them explained a provision-suite need that
    `[dependencies]` had long since covered.
    
    `jsonschema` stays: it is the one crate the tests link and the shipped binary
    does not.
    
    Predicate is the Ready block's — the crate and its test targets still build.
    
    Refs: CLOUD-217

Rebase locally, and then force push to claude/rules-engine-defaults-research-lbzrbg.

@wenzowski
wenzowski force-pushed the claude/rules-engine-defaults-research-lbzrbg branch from 0214abf to 026fe22 Compare August 11, 2026 21:05
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #332 (comment) by @​wenzowski.

Trying to fast forward main (98aceb0) to claude/rules-engine-defaults-research-lbzrbg (026fe22).

Target branch (main):

commit 98aceb05393d0fdfc91d977603ae486cf34e1b7f (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 19:14:30 2026 +0000

    feat(bench): measure the token economics instead of asserting them
    
    The adoption claim is token economics, and the differentiator is that ours is
    reproducible: anyone can say they are cheaper, we ship the harness that produces
    the number from committed inputs with no credential and no network.
    
    `mise run token-bench` executes what `bench/tokens/workloads.toml` declares and
    prices it with what `bench/tokens/method.toml` declares — no price, divisor,
    re-run coefficient or workload is baked into the program, because a constant
    written into a benchmark's code is a number nobody re-derives. Every arm runs
    three times and is compared byte-for-byte; an arm that is not byte-stable is
    reported as such rather than averaged, since byte-stability is the property the
    cache claim rests on.
    
    `mise run token-bench-check` is the mechanism that makes "reproducible"
    checkable: it regenerates the table into scratch and diffs it byte-for-byte, and
    it re-reads the published bytes for the honesty predicate — a figure without
    workload, baseline, run count and method is refused, and so is a capability
    reporting "not measured" with no reason. The gate re-reads the artifact rather
    than trusting the generator, which is what a program checking its own arithmetic
    would not do.
    
    Two capabilities carry a measured figure; `log-handle` reports "not measured"
    because the capability is not shipped, and the cross-session cache hit rate
    reports "not measured" because it needs a live provider credential and is a
    property of the world rather than of this commit. Neither borrows a magnitude
    from its neighbour. No aggregate is published: averaging across capabilities
    needs a workload mix nobody here has measured.
    
    `build-warning` is the honest one — Batten wins it by 1.47x, and the saving is
    exactly the discarded `tail` window rather than the log, which `exec` tees in
    full by design.
    
    Named `token-bench` rather than `bench`: CLOUD-207's `mise run bench` measures
    batten's invocation cost and landed under that name first. Two benchmarks with
    two subjects need two names, so the later and more specific one moves, and
    `bench/tokens/` leaves room for the sibling's own inputs beside it.
    
    Refs: CLOUD-119

Pull request (claude/rules-engine-defaults-research-lbzrbg):

commit 026fe22bdcf8109221c06c09fc1516bb42f4b3d5 (pull_request/claude/rules-engine-defaults-research-lbzrbg)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:13:21 2026 +0000

    fix(hk): drop five restated check_first defaults
    
    check_first already defaults true at the pinned v1.54.0
    (pkl/Config.pkl:515), so all five assignments restated a default rather
    than overriding one. The cargo-fmt comment was the harmful part: it
    explained check_first's behaviour as though the step were opting into it,
    so a reader checking whether the fixer skips a clean tree found a
    rationale for a line that changed nothing.
    
    Same class the rules-engine defaults census (CLOUD-381) found across ten
    tools: a config that restates a default is indistinguishable from one
    that overrides it, and the reader cannot tell which layer decided.
    .claude/rules/toolchain.md already states the principle for exactly these
    steps -- upstream globs and check_first are upstream's authority, and
    re-declaring them here is a second authority for something upstream
    already tests.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01P1xT4aa59k7kKPCDXq7y3d

Can't fast forward main (98aceb0) to claude/rules-engine-defaults-research-lbzrbg (026fe22). main (98aceb0) is not a direct ancestor of claude/rules-engine-defaults-research-lbzrbg (026fe22). Branches appear to have diverged at b642e2d:

* 026fe22bdcf8109221c06c09fc1516bb42f4b3d5 fix(hk): drop five restated check_first defaults
* 86be1162e61b96631c8952fcd570933891838449 docs(memory): record which survey tools reach the evidence (CLOUD-381)
| * 98aceb05393d0fdfc91d977603ae486cf34e1b7f feat(bench): measure the token economics instead of asserting them
|/  
* b642e2dd35304790923f2a63bbbf0f9f68c9b4c2 perf(ci): run the shell suite in parallel, since it is the pole of the gate

commit b642e2dd35304790923f2a63bbbf0f9f68c9b4c2
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:47:33 2026 +0000

    perf(ci): run the shell suite in parallel, since it is the pole of the gate
    
    `hk` runs two chains concurrently, and the shell one was the longer by 133s:
    on run 31531728503 the cargo chain's last step finished 166s into `mise run
    ci`, while `test:bats` ran to 247.01s of the step's 298.87s. 800 tests, one at
    a time. `verify` runs the same gate, so a `land` lap paid it twice.
    
    That put it in the exponent of the lap economics. A lap dies whenever `main`
    moves under it, so with mean inter-land gap 487s the expected CI runs per
    landed PR is e^(L/G) — which is why shortening the lap is the one lever that
    cuts latency and the bill together rather than trading one for the other.
    
    Measured here: 248s serial -> 72.73s, 808 tests, same assertions, nothing
    skipped or sampled. The remaining pole is the cargo chain at 166s.
    
    `rush` rather than GNU parallel, which bats would otherwise look for: GNU
    parallel ships as a source tarball with no aqua/ubi/release coordinate, so it
    cannot be a [tools] key at all, and an `apt-get install` in ci.yml is the
    second-authority drift `ci-tools-check` exists to refuse. rush is prebuilt per
    platform, so `mise.lock` holds a checksum for every platform this repo
    installs on.
    
    Across files, never within one. The suites that model lock and race behaviour
    are precisely the ones a within-file schedule would interleave with their own
    setup, and across-files is already enough — the largest file is 49 of 808
    tests, so the schedule is not tail-bound.
    
    Two things ship with it:
    
    - `tests/attribution-check.bats` built its end-to-end fixture in the real
      worktree and the real index. Serially that was invisible; in parallel it is
      a race against the sibling case that reads the same tracked set, plus
      .git/index.lock contention. It now builds a throwaway repo, which is the
      convention issue-guard.bats already set.
    - A speed-up is the kind of fix that rots silently — drop the flag and
      everything still passes, just slower, and `timeout-check`'s 3.4x headroom
      absorbs a return to serial without a red build. So the invocation is now a
      gate over mise.toml: serial is an exit code, not a slower Tuesday.
    
    Refs: CLOUD-386

Rebase locally, and then force push to claude/rules-engine-defaults-research-lbzrbg.

@wenzowski
wenzowski force-pushed the claude/rules-engine-defaults-research-lbzrbg branch 2 times, most recently from 59af6d3 to f7f7810 Compare August 11, 2026 21:17
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski

Copy link
Copy Markdown
Contributor Author

Triggered from #332 (comment) by @​wenzowski.

Trying to fast forward main (42319f4) to claude/rules-engine-defaults-research-lbzrbg (f7f7810).

Target branch (main):

commit 42319f43bfdff5cdb654394d2504d1ac173cb024 (HEAD -> main, origin/main)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:44:36 2026 +0000

    ci(stop-posture): one flagging-verb set across the worth/bears openers
    
    `HEDGES` gave its two openers different verb sets — `worth
    (noting|flagging)` beside `bears (noting|mentioning)` — so `mentioning`
    was a flagging verb to this file under one opener and unknown under the
    other. Nothing distinguished them; the split was an accident of how the
    alternation was written.
    
    Measured, one sentence per row: `worth naming` and `worth mentioning`
    were silent while `bears mentioning` fired. The first of those is a
    witnessed miss. The CLOUD-347..356 audit closed its report with "One
    open thread worth naming: the census … never interrogated host
    settings" — a real finding that reached chat and nothing else, and
    became CLOUD-380 only because a human asked. Nothing else covered it
    either: `stop-guard` consults `finding-sink-check` precisely when this
    rule is silent, and that gate needs a `path:line` citation the sentence
    does not carry, so the turn's one advisory slot was never claimed.
    
    One shared `FLAG_VERB` set now, every entry either witnessed (`naming`)
    or already in the file (`noting`, `flagging`, `mentioning`). `calling
    out` stays out and is asserted to stay out: unwitnessed and not already
    present, which is the line between completing an inflection and
    inventing a phrase list. The `I would flag` / `I should note` family
    keeps `(flag|note)` — "I would name that" is not natural flagging.
    
    Not the unmeasured-literal mistake CLOUD-323 and CLOUD-326 forbid:
    those govern a new SHAPE, while this is inflection completion inside a
    construction already measured at 3/3, which this gate's own header
    sanctions and its own history already did once.
    
    Refs: CLOUD-387

Pull request (claude/rules-engine-defaults-research-lbzrbg):

commit f7f781044b020d927551c3f8030aedce07d351ae (pull_request/claude/rules-engine-defaults-research-lbzrbg)
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 20:13:21 2026 +0000

    fix(hk): drop five restated check_first defaults
    
    check_first already defaults true at the pinned v1.54.0
    (pkl/Config.pkl:515), so all five assignments restated a default rather
    than overriding one. The cargo-fmt comment was the harmful part: it
    explained check_first's behaviour as though the step were opting into it,
    so a reader checking whether the fixer skips a clean tree found a
    rationale for a line that changed nothing.
    
    Same class the rules-engine defaults census (CLOUD-381) found across ten
    tools: a config that restates a default is indistinguishable from one
    that overrides it, and the reader cannot tell which layer decided.
    .claude/rules/toolchain.md already states the principle for exactly these
    steps -- upstream globs and check_first are upstream's authority, and
    re-declaring them here is a second authority for something upstream
    already tests.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01P1xT4aa59k7kKPCDXq7y3d

Can't fast forward main (42319f4) to claude/rules-engine-defaults-research-lbzrbg (f7f7810). main (42319f4) is not a direct ancestor of claude/rules-engine-defaults-research-lbzrbg (f7f7810). Branches appear to have diverged at 87ed397:

* f7f781044b020d927551c3f8030aedce07d351ae fix(hk): drop five restated check_first defaults
* cb6a27d8af552e6fe7c0edd9f927f0db1701632f docs(memory): record which survey tools reach the evidence (CLOUD-381)
| * 42319f43bfdff5cdb654394d2504d1ac173cb024 ci(stop-posture): one flagging-verb set across the worth/bears openers
|/  
* 87ed39733221612abd4f99ce64c5f93e773439d4 fix(verify): refuse to receipt a HEAD whose bytes were not the ones validated

commit 87ed39733221612abd4f99ce64c5f93e773439d4
Author: Claude <noreply@anthropic.com>
Date:   Tue Aug 11 18:56:29 2026 +0000

    fix(verify): refuse to receipt a HEAD whose bytes were not the ones validated
    
    `verify` runs every gate over the WORKING TREE and then writes a receipt keyed
    to HEAD. Nothing asserted the two agree, so a dirty tree could attest a commit
    nobody verified: the receipt is written, `verified` matches it, `ready-guard`
    accepts it, and CI runs a commit that was never the thing that passed.
    
    Measured 2026-08-09 landing CLOUD-269 — a backgrounded `land` compiled a
    mid-edit snapshot and reported `verify failed on c5bfe05`, a commit containing
    none of that code. That direction is loud and self-correcting; the mirror is
    silent, and it is the one this closes.
    
    `mise-tasks/tree-clean` is the predicate: `git --no-optional-locks status
    --porcelain --untracked-files=normal`, exit 1 with a count and the porcelain
    lines as pointers, exit 2 when it cannot look. Untracked-but-not-ignored counts
    as dirty — decided, not omitted — because `cargo test` auto-discovers
    `crates/batten/tests/*.rs` and the bats suite globs `tests/*.bats`, so a new
    untracked file is run by `verify` with zero tracked-file change. Ignored paths
    are excluded structurally.
    
    Wired into `[tasks.verify]` at both ends of the window: in `depends` so a dirty
    tree fails in seconds rather than after ~170s, and in the body — the
    load-bearing one, since `depends` completes before a tree can be dirtied
    mid-run. Not an hk step: `pre-commit` runs over a tree that is dirty by
    definition. `land` inherits it through `verify` and re-implements nothing.
    
    Refs: CLOUD-277

Rebase locally, and then force push to claude/rules-engine-defaults-research-lbzrbg.

@wenzowski
wenzowski force-pushed the claude/rules-engine-defaults-research-lbzrbg branch from f7f7810 to d20b282 Compare August 12, 2026 05:17
claude added 2 commits August 12, 2026 05:27
Scholar Gateway is Wiley-only and returned two on-topic articles across 24
passages; Consensus returned the field's standard results on the first try.
GitHub reaction counts are unreachable for repos outside button-inc/batten,
so the planned reception signal needs reachable substitutes named up front.

Both cost a wasted call to discover on the rules-engine defaults census and
neither is inferable from the tool descriptions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P1xT4aa59k7kKPCDXq7y3d
check_first already defaults true at the pinned v1.54.0
(pkl/Config.pkl:515), so all five assignments restated a default rather
than overriding one. The cargo-fmt comment was the harmful part: it
explained check_first's behaviour as though the step were opting into it,
so a reader checking whether the fixer skips a clean tree found a
rationale for a line that changed nothing.

Same class the rules-engine defaults census (CLOUD-381) found across ten
tools: a config that restates a default is indistinguishable from one
that overrides it, and the reader cannot tell which layer decided.
.claude/rules/toolchain.md already states the principle for exactly these
steps -- upstream globs and check_first are upstream's authority, and
re-declaring them here is a second authority for something upstream
already tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P1xT4aa59k7kKPCDXq7y3d
@wenzowski
wenzowski force-pushed the claude/rules-engine-defaults-research-lbzrbg branch from d20b282 to cebd9d2 Compare August 12, 2026 05:29
@sonarqubecloud

Copy link
Copy Markdown

@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski
wenzowski merged commit cebd9d2 into main Aug 12, 2026
7 checks passed
@wenzowski
wenzowski deleted the claude/rules-engine-defaults-research-lbzrbg branch August 12, 2026 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants