Skip to content

fix(lint): burn down the kanon-lint debt baseline and delete it - #86

Merged
forkwright merged 1 commit into
mainfrom
fix/57-lint-debt-burndown
Aug 9, 2026
Merged

fix(lint): burn down the kanon-lint debt baseline and delete it#86
forkwright merged 1 commit into
mainfrom
fix/57-lint-debt-burndown

Conversation

@forkwright

Copy link
Copy Markdown
Owner

What was wrong

kanon lint carried 18 pre-existing violations against hamma main (11 in .kanon-lint-baseline.toml, 7 unbaselined), blocking kanon gate --stamp — no PR could earn the Gate-Passed trailer required by gate-attestation. The baseline entries carry remove_after = "2026-08-13"; an expired non-empty baseline makes kanon lint return an error and stop linting entirely, which also blocks the gate.

What changed

Resolves every entry in .kanon-lint-baseline.toml plus the 7 unbaselined violations, so the baseline can be deleted rather than extended:

  • Crate rename (NAMING/no-owner-prefix):hamma-coremitos. The old name prefixed the parent fleet repo; mitos (Greek mitos, "loom-thread") keeps the family's weaving vocabulary (hamma "knot", dictyon "net", histos "loom"). Every hamma_core:: / hamma-core path across dictyon, docs, and CI comments moves with it; CHANGELOG.md is untouched (historical record).
  • File-too-long (RUST/file-too-long):wire.rs (1288 lines) splits into wire/{mod,support,tests}.rs; config.rs and types.rs each split into <name>/{mod,tests}.rs, moving their test modules into sibling files — the same pattern control.rs and noise.rs already use in this crate. Cross-module helpers land as pub(super) fns called via support::.
  • RUST/indexing-slicing:parse_server_key_response now uses response.get(body_start..) instead of &response[body_start..].
  • RUST/no-silent-result-swallow:hex_encode no longer routes through fmt::Write (whose Result on a String can never actually be Err, which is what made let _ = a swallow); it writes nibbles through a checked lookup table instead.
  • RUST/no-debug-derive-on-public-types (RegisterRequest, MapRequest, Node, PeerChange): each flagged struct's only "secret-shaped" fields are public-key hex (already carrying field-level plain-string-secret ignores) or, for RegisterRequest, the already-redacting AuthInfo::Debug the derive calls into — kanon:ignore with a NOTE recording why, mirroring the existing plain-string-secret convention in this same file.
  • COMMENTS/deflection-without-tracking:RegisterRequest::followup's doc reworded off the trigger phrase "Follow-up" (the field names a real protocol continuation URL, not deferred work).
  • RUST/primitive-for-domain-id:Hostinfo::backend_log_id is now a BackendLogId newtype (#[serde(transparent)]) instead of a bare String, with every construction site (mitos, dictyon, both test suites) updated.
  • RUST/non-exhaustive-enum:PeerRemoval gains #[non_exhaustive]; dictyon's one exhaustive match over it (PeerRemovalIndex::build) gets the required wildcard arm.
  • RUST/config-deny-unknown-fields:DnsConfig mirrors Tailscale's wire DNSConfig response type, not a local operator config — denying unknown fields would make dictyon reject a MapResponse the day a conforming server adds a DNS field. kanon:ignore with a NOTE recording the forward-compatibility rationale.
  • YAML/missing-concurrency:gate-attestation.yml deliberately carries no concurrency block (the reusable it calls already declares one; a second one under the same key self-cancels, per that file's own WHY comment). Suppressed via .kanon-lint-ignore rather than "fixed" into a regression.
  • OIKOS/private-content: the internal kanon.lan forge hostname is redacted to a <kanon-forge-host> placeholder across CONTRIBUTING.md (3 sites); the one occurrence that was purely restating "the forge is unreachable" drops the hostname entirely instead of adding a fourth placeholder.
  • WRITING/identity-fluff: drops "sovereign"/"sovereignty" from README.md (thumos's description, the histos hardware-attestation phase heading and its Phase C entry) in favor of concrete descriptions of what those extensions do.

Verification

Not restated with a Gate-Passed trailer on this commit; CI on this PR (fmt, check, clippy, nextest, kanon lint) is the verifier per the current op-pause convention on this repo.

Refs #57

Resolves every entry in .kanon-lint-baseline.toml plus the 7 unbaselined
violations kanon lint carried outside it, so the baseline (due to
hard-fail on 2026-08-13) can be deleted rather than extended.
Crate rename (NAMING/no-owner-prefix): hamma-core -> mitos. The old name
prefixed the parent fleet repo; mitos (Greek mitos, "loom-thread") keeps
the family's weaving vocabulary (hamma "knot", dictyon "net", histos
"loom") and reads as the raw material those crates knot and weave from.
Every use hamma_core:: / hamma-core path across dictyon, docs, and CI
comments moves with it; CHANGELOG.md is untouched (historical record).
File-too-long (RUST/file-too-long): wire.rs (1288 lines) splits into
wire/{mod,support,tests}.rs; config.rs and types.rs each split into
<name>/{mod,tests}.rs, moving their test modules into sibling files --
the same pattern control.rs and noise.rs already use in this crate.
Cross-module helpers land as pub(super) fns called via `support::`.
RUST/indexing-slicing: parse_server_key_response now uses
response.get(body_start..) instead of &response[body_start..].
RUST/no-silent-result-swallow: hex_encode no longer routes through
fmt::Write (whose Result on a String can never actually be Err, which is
what made `let _ =` a swallow); it writes nibbles through a checked
lookup table instead.
RUST/no-debug-derive-on-public-types (RegisterRequest, MapRequest, Node,
PeerChange): each flagged struct's only "secret-shaped" fields are public
key hex (already carrying field-level plain-string-secret ignores) or,
for RegisterRequest, the already-redacting AuthInfo::Debug the derive
calls into -- kanon:ignore with a NOTE recording why, mirroring the
existing plain-string-secret convention in this same file.
COMMENTS/deflection-without-tracking: RegisterRequest::followup's doc
reworded off the trigger phrase "Follow-up" (the field names a real
protocol continuation URL, not deferred work).
RUST/primitive-for-domain-id: Hostinfo::backend_log_id is now a
BackendLogId newtype (#[serde(transparent)]) instead of a bare String,
with every construction site (mitos, dictyon, both test suites) updated.
RUST/non-exhaustive-enum: PeerRemoval gains #[non_exhaustive]; dictyon's
one exhaustive match over it (PeerRemovalIndex::build) gets the required
wildcard arm.
RUST/config-deny-unknown-fields: DnsConfig mirrors Tailscale's wire
DNSConfig response type, not a local operator config -- denying unknown
fields would make dictyon reject a MapResponse the day a conforming
server adds a DNS field. kanon:ignore with a NOTE recording the
forward-compatibility rationale.
YAML/missing-concurrency: gate-attestation.yml deliberately carries no
concurrency block (the reusable it calls already declares one; a second
one under the same key self-cancels, per that file's own WHY comment).
Suppressed via .kanon-lint-ignore rather than "fixed" into a regression.
OIKOS/private-content: the internal kanon.lan forge hostname is redacted
to a <kanon-forge-host> placeholder across CONTRIBUTING.md (3 sites);
the one occurrence that was purely restating "the forge is unreachable"
drops the hostname entirely instead of adding a fourth placeholder.
WRITING/identity-fluff: drops "sovereign"/"sovereignty" from README.md
(thumos's description, the histos hardware-attestation phase heading and
its Phase C entry) in favor of concrete descriptions of what those
extensions do.
Refs #57
@forkwright
forkwright merged commit 8c420f3 into mainAug 9, 2026
10 checks passed
@forkwright
forkwright deleted the fix/57-lint-debt-burndown branch August 9, 2026 00:37
forkwright added a commit that referenced this pull request Aug 15, 2026
… lint-debt gap (#91)
## What was wrong
`kanon lint` carried one live violation on `main`:
`SHELL/unpinned-action` on
`.github/workflows/gate-attestation.yml:88` — the reusable-workflow call
to
`forkwright/.github/.github/workflows/hybrid-gate.yml` used a mutable
`@main`
ref instead of a pinned commit SHA. The gate fails on any warning by
default,
so this alone blocked `kanon gate --stamp` for every PR.
## Re-verified premise, corrected
The literal 12-entry `.kanon-lint-baseline.toml` this issue was filed
against
(`remove_after = "2026-08-13"`) no longer exists on `main` — PR #86
(merged
2026-08-09) already resolved every one of those entries plus 7
unbaselined
findings and deleted the baseline file. `kanon lint .` against a fresh
`origin/main` checkout confirms this: none of the original rule families
(`RUST/file-too-long`, `RUST/indexing-slicing`,
`NAMING/no-owner-prefix`,
`RUST/no-silent-result-swallow`, `RUST/no-debug-derive-on-public-types`,
`COMMENTS/deflection-without-tracking`, `RUST/primitive-for-domain-id`,
`RUST/non-exhaustive-enum`, `RUST/config-deny-unknown-fields`) fire
anymore.
`crates/hamma-core` is `crates/mitos` now, so the specific
`NAMING/no-owner-prefix` entry this issue's follow-up note asked about
is
already gone with it — nothing left to carry forward in a new baseline.
What #86 did *not* catch was `SHELL/unpinned-action` on the
reusable-workflow
call itself, which is the one violation still blocking the gate today.
This
PR closes that gap so #57's actual acceptance criterion — `kanon lint .`
clean on main — is met, with no baseline file needed at all.
## What changed
- **`SHELL/unpinned-action`:** pin
`forkwright/.github/.github/workflows/hybrid-gate.yml`
to its current `main` SHA (`df92942bcc41cc7ffd0339b75b2f01e52269d0ef`),
matching the convention already used by `typikon` and `thumos` (SHA + a
trailing `# main` comment, plus a WHY comment documenting the refresh
command).
- **Adjacent drift, same class:** `.kanon-lint-ignore` still carried
`RUST/pub-visibility:crates/dictyon/src/control.rs` and `.../noise.rs`
from
before both modules split into `control/mod.rs` / `noise/mod.rs` (the
same
split `wire.rs` already went through, whose ignore entry is already a
glob). The stale entries matched no file and silently suppressed
nothing;
`kanon lint` warned about both on every run. Re-globbed to match the
current layout.
## Verification
```
$ kanon lint .
0 error(s), 0 warning(s), 0 info (9 suppressed)
$ kanon gate --tier nobuild
PASS config check
PASS advisory ignore parity
PASS derive check (deterministic)
PASS fleet-names freshness
PASS cargo fmt
PASS kanon lint
ok light gate passed — push to the forge for authoritative clippy + nextest + verifier
```
`--tier nobuild` is the local-verifiable slice (zero rustc invocations,
per
this box's compile-on-CI-only posture); `cargo build`/clippy/nextest run
on
this PR's GitHub Actions checks, which is what actually gates merge.
No Rust source changed — YAML and `.kanon-lint-ignore` only.
Closes#57
---------
Co-authored-by: forkwright <cody@forkwright.com>
forkwright added a commit that referenced this pull request Aug 26, 2026
#120)
## Finding
Two live docs-drift defects.
`_llm/current_state.toml` hadn't been touched since 2026-05-25 (3
commits total,
`git log --follow`) and still carried an unfilled
`<canonical-state-doc>/STATE.md`
template placeholder in `source_docs`. The same broken placeholder was
copy-pasted
into `_llm/architecture.toml`, `_llm/decisions.toml`, and
`_llm/glossary.toml`
(4 sites total, `grep -rn canonical-state-doc`).
`README.md`'s Status paragraph named issue #20 ("Phase 3 audit: missing
PeersChangedPatch...") as the "current audit backlog" topic set. #20
closed
2026-05-25T19:46:08Z. Of the issues open when the underlying finding was
written,
neither #65 nor #67 was named, and a third (#61, open since 2026-07-21)
wasn't
caught either — issue numbers embedded in prose go stale the moment the
tracker
moves, independent of whether anyone remembers to update the doc.
## Evidence
- `git log -1 --format='%ci %h' -- _llm/current_state.toml` →
`2026-05-25 ... 3b5b82b`
while the file said `updated = "2026-05-01"`.
- Since that commit: `crates/hamma-core` renamed to `crates/mitos` (#86,
landed
2026-08-08 per `git log --diff-filter=A -- crates/mitos/Cargo.toml`),
`crates/dictyon/src/wire.rs` split into `wire/mod.rs`, PR #58 cut the
v0.2.0
changelog (2026-07-28), and 100+ PRs merged after that (`git log
--oneline
3b5b82b..origin/main | wc -l`).
- `grep -rn "canonical-state-doc" .` → 4 hits, all `_llm/*.toml`.
- The placeholder was never a mystery token: hamma's own README
auto-metadata
block already resolves it — `Planning state: projects/hamma/STATE.md` —
and
`gh api repos/forkwright/kanon/contents/projects/hamma/STATE.md`
confirms the
file exists. `_llm/*.toml` now point at the same target via the full URL
hamma's own `CLAUDE.md` already uses for this cross-repo link
(`https://github.com/forkwright/kanon/blob/main/projects/hamma/STATE.md`).
- `gh issue list --repo forkwright/hamma --state closed` → #20 closed
2026-05-25T19:46:08Z. `gh issue list --repo forkwright/hamma --state
open` →
#61 (2026-07-21), #65 (2026-07-21), #67 (2026-07-21), #118 (2026-08-26,
opened
today) — none is #20's topic set.
## Why this matters
`_llm/*.toml` is the corpus other agents and tools read instead of
re-deriving
repo state from scratch; a doc that's been silently wrong for three
months
defeats that purpose worse than no doc at all, since it reads as
authoritative.
A broken placeholder that's been copy-pasted across four files is the
same
defect four times, not four defects. README's Status section is the
first thing
a human or agent reads; naming a closed issue as "the current backlog"
points
readers at the wrong problem set entirely.
## Desired correction
Refresh `_llm/current_state.toml`'s `summary`, `current_phase`,
`updated`, and
`recent[]`/`open_threads[]` against present-day repo state; point every
`<canonical-state-doc>` placeholder at the real STATE.md; stop naming
specific
issue numbers in README's Status prose and point at the tracker instead.
**Done when:** `grep -rn "canonical-state-doc\|map deltas, zstd
framing"` returns
nothing, and `_llm/current_state.toml`'s `updated` field and
`open_threads[]`
reflect the tree at merge time. Both hold in this PR — see the diff.
## Note (out of scope, flagged for the right owner)
`forkwright/kanon`'s `projects/hamma/STATE.md` — the doc `_llm/*.toml`
now
points at — is itself stale in a worse way than what this PR fixes: its
frontmatter claims `last_updated: 2026-08-15` but its body still says
`Version:
v0.1.0 (unreleased)`, references `crates/hamma-core` (renamed
2026-08-08, before
the claimed update date), and says "No dictyon code touched since
2026-04-13"
against 100+ merged PRs. That's a `forkwright/kanon` planning-doc
defect, not a
`forkwright/hamma` one — this PR doesn't touch it, since kanon is a
shared
planning tree outside this lane's scope.
Co-authored-by: forkwright <cody@forkwright.com>
Sign up for freeto 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.

1 participant

@forkwright