Conversation
Umbrella design (signals-wiki-unification) plus six sequenced workstream specs: storage relocation (B), migrate framework (C), command/agent/skill unification (D), drift scope (E), agent model overrides (F), Cobra migration (A).
Storage path constants move from .claude/project/ to docs/wiki/: signalsFile -> docs/wiki/scan.md (no YAML frontmatter), prevFile -> tmp/.scan.prev.md. ScanWithOptions no longer emits frontmatter; idempotency and Stale compare raw body directly. LinkifyFiles points at the docs/wiki/ router (index.md) and flat domain files, excluding scan.md/CLAUDE.md/index.md. tree.go skips docs/wiki/scan.md so the dump does not appear in its own tree. Workstream B / CP1 of signals-wiki unification.
… ref Doctor signals/refs checks adapt to the relocated layout: router at docs/wiki/index.md, ref @docs/wiki/index.md, domain files flat under docs/wiki/ (orphan enumeration excludes index.md/scan.md/CLAUDE.md by basename). fix.go --fix wires @docs/wiki/index.md. Workstream B / CP2 of signals-wiki unification.
…rol blocks Relocate every storage path in the inferrer template to docs/wiki/: router docs/wiki/index.md (OKF type: Index + <wiki-type>repo</wiki-type>, <scan-sha> via git hash-object, <wiki-schema>1</wiki-schema>), flat domain files docs/wiki/<domain>.md (OKF type: Domain), scan docs/wiki/scan.md, prev tmp/.scan.prev.md, @-ref @docs/wiki/index.md. New Step 8c bootstraps docs/wiki/CLAUDE.md steering (idempotent, never clobbers). Wiki-output mode reads <tmp>/docs/wiki/scan.md. Agent name unchanged (signals). Bundle regenerated. Workstream B / CP3 of signals-wiki unification.
signals-gate stages docs/wiki/index.md + domains (excludes raw scan.md); refresh-signals relocates scan/router/@-ref paths and moves steering to docs/wiki/CLAUDE.md (OKF type: Steering, create-if-absent); refresh-wiki member-detection prose -> docs/wiki/index.md; cliusage scan/show/linkify descriptions name docs/wiki paths; golden test updated. Bundle + rendered commands regenerated. Workstream B / CP4 of signals-wiki unification.
frontmatterTypeToClass maps type: Index -> index and type: Domain -> domain; app.css adds --c-index/--c-domain palette vars (light+dark); layout.html registers index/domain in atomicCyTypeColors + typeNames so the dynamic legend and node coloring pick them up. docs/wiki/ signals docs now render as first-class typed nodes in atomic serve. Workstream B / CP5 of signals-wiki unification.
git mv .claude/project/signals.md -> docs/wiki/index.md and 9 domain files -> docs/wiki/<domain>.md; deterministic-signals.md -> docs/wiki/ scan.md (regenerated). Add OKF frontmatter (Index/Domain/Steering), index.md control blocks (<wiki-type>/<scan-sha>/<wiki-schema>), bootstrap docs/wiki/CLAUDE.md steering. Rewire @-ref to @docs/wiki/index.md, fix depth-3 -> depth-2 relative links, drop obsolete .gitignore prev path, exclude docs/wiki/ from the VitePress site. Doctor refs PASS. Workstream B / CP6a of signals-wiki unification.
README signals diagram, docs/reference/signals-workflow.md +
wiki-workflow.md, and the atomic-help detection probe + state-files tour
now name docs/wiki/{index,scan}.md and the docs/wiki/CLAUDE.md steering
file. Rendered atomic-help + bundle regenerated.
Workstream B / CP6b of signals-wiki unification.
docs/wiki/ is generated signals output (router, domains, scan, steering), not source. Including it made the scan self-referential: the <scan-sha> hash written into index.md changed index.md's blob SHA, changing the tree, so 'atomic signals stale' returned exit 1 forever. Skip the whole docs/wiki/ dir, mirroring the already-skipped .claude/project/. Workstream B / CP6c of signals-wiki unification.
Regenerate docs/wiki/scan.md against the final tree (docs/wiki/ now excluded) and stamp <scan-sha> to match. atomic signals stale is fresh.
parseRouterDomains used an inTable flag that flipped false on the first prose line after '## Domains' — but the router has an intro paragraph before the table, so zero domains parsed and every real domain file was falsely flagged as an orphan. Switch to section-based scanning: enter on '## Domains', exit on the next '## ' heading, parse only table rows in between. Workstream B / CP6d of signals-wiki unification.
parseRouterDomains read the Detail column as cols[4], but domain one-liners may contain unescaped pipes (the serve row: md|code, [page|system]), shifting the split. Detail is always the last content column and pipe-free, so read cols[len(cols)-2]. Workstream B / CP6e of signals-wiki unification.
Unifies per-repo signals storage under docs/wiki/ with OKF frontmatter and the <wiki-type>/<scan-sha>/<wiki-schema> control blocks — the foundation for the signals/wiki unification. - scan -> docs/wiki/scan.md (no frontmatter), prev -> tmp/.scan.prev.md - router -> docs/wiki/index.md (type: Index + control blocks), @-ref'd - domains -> flat docs/wiki/<domain>.md (type: Domain) - steering -> docs/wiki/CLAUDE.md (type: Steering) - doctor, inferrer, signals-gate, cliusage, serve graph relocated - this repo migrated; docs/wiki/ excluded from scan tree + VitePress site Agent name and /refresh-signals kept (workstream D renames).
New atomic/internal/migrate package: Migration{TargetVersion,Scope,Up}
type, ordered Registry, and Run() that applies steps with TargetVersion
semver-greater than the recorded version in ascending order, stop-on-
error, empty recorded treated as a 0.0.0 floor, caller slice not mutated.
Adds exported selfupdate.CompareSemver(a,b) as the canonical compare
(malformed inputs floored to 0.0.0) so migrate reuses semver parsing
instead of duplicating it.
Workstream C / C1 of signals-wiki unification.
Add the [install] TOML table: version (semver) + [install.artifacts] per-kind lists (agents/commands/skills/output-styles/rules). knownSchemaKeys accepts install.* without unknown-key warnings; install keys are machine- written (not surfaced in 'atomic config list'). checks_config validates install.version as semver via the reused selfupdate.IsValidSemver; a config with no [install] table is valid (pre-framework state). Workstream C / C2 of signals-wiki unification.
On a non-dry-run install: write [install].version + [install.artifacts] to config.toml (per-kind target lists), and prune artifacts present in the prior manifest but absent from the current bundle (pure PruneDiff + deny-by-default batched confirm seam; Ctrl+C/non-interactive = decline, never an install failure). Only install.artifacts entries are ever prune-eligible, so user-added files are untouchable. uninstall.go scopes removal to the manifest (nil = pre-framework fallback). Workstream C / C3 of signals-wiki unification.
… hook New 'atomic migrate' verb: no flags = install-scope (config [install]. version anchor); --repo reads/writes the <wiki-schema> block in the repo's docs/wiki/index.md; --realm runs install-scope then prompts per member repo (non-interactive/abort = skip, never auto-migrate). First registered step relocates .claude/project/signals* -> docs/wiki/ — resumable (completion sentinel <wiki-type> written last), idempotent (moveFile skips already-moved, refuses to clobber an existing target), atomic content writes. runUpdate runs install-scope migrations after the artifact refresh (warn-not-fatal). cliusage registers migrate (A1 clean). Workstream C / C4 of signals-wiki unification.
Doctor check 12 (migrate): when config [install].version is older than the running binary, WARN to run 'atomic migrate' (artifacts/migrations behind the binary); PASS when [install] is absent (pre-framework) or the binary is 'dev'. /atomic-help lists 'atomic migrate [--repo|--realm]' in the binary topic + maintenance tour; docs/guides/install.md gains a Migrations section (update auto-runs steps; migrate --repo/--realm). Workstream C / C5 of signals-wiki unification.
Versioned, replayable migration framework backed by install state in
config.toml [install].
- migrate package: Migration{TargetVersion,Scope,Up} + ordered Registry
+ semver-ordered Run (exported selfupdate.CompareSemver)
- config [install].version + [install.artifacts] schema v2
- install writes the manifest; prune removes dropped artifacts (data-safe
batched confirm); uninstall scopes to install.artifacts
- atomic migrate verb (--repo reads <wiki-schema>, --realm fans out with
per-repo confirm); first step relocates signals -> docs/wiki/ (resumable,
idempotent, refuses to clobber); atomic update auto-runs install-scope
migrations
- doctor check 12 nudges when binary newer than [install].version
Rename the inferrer agent (template + rendered) and update every dispatch site (signals-gate, autopilot, subagent-implementation, refresh-wiki, atomic-setup, atomic-help, CLAUDE.md). The agent's system prompt gains an imperative authoritative-steering clause: read docs/wiki/CLAUDE.md and treat it as authoritative before inferring. Stale embedded bundle copy pruned. Bundle regenerated. Workstream D (CP2+CP4) of signals-wiki unification.
/refresh-wiki is now the single refresh verb for both repo and realm
scope (Step 0 detects <wiki-type>). The atomic-wiki skill is a thin
router (95 lines); the full per-scope pipelines live in
skills/atomic-wiki/references/{repo,realm}.md. atomic-wiki-inferrer is
thinned to detect scope, read the installed reference
($HOME/.claude/skills/atomic-wiki/references/<scope>.md), and execute —
caller-context interface (mode/first_run/changed_range) preserved.
/refresh-signals removed (template + rendered + embedded). Bundle
regenerated with the new references.
Workstream D (CP1+CP3) of signals-wiki unification.
Three-case detection: not-a-repo + wiki/ -> realm; repo + no wiki/ -> repo; repo + wiki/ -> ask (default repo on cancel). Writes the machine-managed <wiki-type> block into claude.local.md if present else CLAUDE.md; idempotent (replace in place). Lets the inferrer/skill-router detect scope without guessing. Workstream D (CP5) of signals-wiki unification.
…ripple wiki.go classifyMembers now classifies a member repo as indexed by docs/wiki/index.md (new, primary) OR .claude/project/signals.md (legacy, back-compat) — realm scans detect both migrated and un-migrated members. doctor fix.go @-ref block heading renamed to 'Project wiki'. README, docs/reference/*, and design/spec surfaces ripple /refresh-signals -> /refresh-wiki and atomic-signals-inferrer -> atomic-wiki-inferrer (historical rename descriptions keep the old name where accurate). Workstream D (CP6) of signals-wiki unification.
One refresh verb, one inferrer agent, one skill-router.
- /refresh-signals folded into /refresh-wiki (single verb, repo + realm
via <wiki-type> detection)
- atomic-signals-inferrer renamed to atomic-wiki-inferrer (+ authoritative
docs/wiki/CLAUDE.md steering clause)
- atomic-wiki skill is a thin router; per-scope pipelines in
skills/atomic-wiki/references/{repo,realm}.md (read from the installed
$HOME/.claude location at runtime)
- atomic-setup writes the <wiki-type> scope marker
- wiki.go realm detection recognizes docs/wiki/index.md (+ legacy)
- README, docs/reference, CLAUDE.md ripple
The committed docs/wiki/scan.md is the canonical incremental-diff baseline (git diff HEAD -- docs/wiki/scan.md); tmp/.scan.prev.md is a no-git fallback. New Step 2b decision tree picks full vs incremental: no index.md -> full; <scan-sha> tiebreaker (committed scan.md blob sha != stored last-infer sha) -> full; large delta -> full; else incremental scoped to changed paths. Agent gains an optional scope: incremental|full caller override. No new staleness mechanism — reconciles with atomic signals stale and changed_range. Workstream E of signals-wiki unification.
SPA fallback serves the embedded dist for every non-API, non-carried GET; layout.html, search_page.go (minus relocated normalizeSearchSrc), the old assets/ dir, htmx.min.js, and all HTML-fragment handler paths and tests are deleted; renderers emit plain hrefs; app.css pruned of htmx selectors; graph-gates retargeted to the React shell (10/10 via the restored #btn-graph). Fixes two latent frontend bugs surfaced by the harness: null nav-group items crash and AtomicGraphUI never being installed.
Reference, atomic-serve spec (spec-currency amendment with Superseded line), and serve wiki domain file rewritten to the shipped SPA truth; corrects the graph-live-reload overstatement.
Playwright screenshot sweep of every screen surfaced six launch bugs: the code modal rendered permanently (hardcoded .open class + Ark keeping closed content mounted under .code-modal-box's display:flex — now lazyMount/unmountOnExit + state-driven class); the SPA landing hardcoded README.md, unreachable realm index (/api/page/ now resolves the landing server-side); /code/schema 500-flashed at realm roots (fetch now waits for member resolution); the editorial fonts (Newsreader/Inter/JetBrains Mono) were never carried into index.html; every page lacked the page-content-inner width/padding wrapper; and the palette's Combobox.Positioner floated results over the footer (now in-flow).
Groups (Realm/Repos/Knowledge/...) become top-level TreeView branches — collapsible with chevrons, expanded by default — instead of static headings over per-group mini-trees; restores the pre-cutover summary.nav-group visual contract on the branch controls.
…yout Rail/breadcrumb tolerate Go nil-slice JSON nulls (server now emits [] too — the null crash on link-less pages); left nav gains VSCode-style file icons and indent guides; /api/external memoized by realm fingerprint (6s walk now cached) and the page groups entries by domain; rail properties stack key-over-value instead of the cramped two-column split; markdown tables scroll horizontally inside the content column.
Extension-routed glyphs from the tree-shakeable @FortAwesome icon-data packages (brands markdown, solid file-code/image/csv/pdf/lines, folder for directory targets) rendered via a plain svg — no icon font, no react wrapper; FileIcon ships as the first ui/ barrel primitive.
Ark's Combobox.Root wrapper div broke the modal's flex column, leaving the results list unconstrained — the wrapper now participates in the column (flex:1, min-height:0) so .search-results scrolls inside 70vh.
Each member mirrors the Buckets pattern: an index leaf (the landing target) plus nested subtrees of the member's docs/ markdown and the realm-side wiki/repos/<name>/ pages; members with nothing to expand stay flat leaves.
Deep-nested entries no longer wrap into tall slivers — nav items and branch labels are nowrap with 120px minimum label room, and #nav-pane scrolls horizontally to reveal the overflow.
Member-repo docs authored against a different nesting depth (e.g. ../../../src/x.ts from gui/docs/wiki/) climb past their true target; repairOverClimbedRelative strips the ../ run and probes the remainder against each ancestor of the page's directory, deepest first. Applied in both resolveMarkdownLink (rail edges) and resolvePageHref (body hrefs) so the two stay in agreement; genuinely dead targets stay broken.
…tialiasing Hover highlight/dim, the preview card, and node drag now engage only while Shift is held — plain mouse is pan/zoom + click, so dense zoomed regions pan instead of grabbing nodes and the graph no longer fades on every mouse pass. On-canvas hint added; graph-gates harness updated to hold Shift for its drag/hover gates. Vendored cosmos point shader patched (documented in provenance): the fixed 0.9 smoothing band gave ~0.2px of edge AA at 8-14px points — visibly jagged circles. Replaced with fwidth()-based one-pixel band.
… switch crash) Points now shrink with zoom-out — pointSizeScale ramps linearly from full size (at 2.5x the mount's fit zoom) down to a 4px floor, anchored per-dataset like the zoom floor; hit targets scale with it since the same uniform feeds the GPU pick passes. The Docs|Code switch insertBefore crash was graph-core removing the React-owned loading <p> (clearLoading), corrupting React's sibling anchors for the keyed mount container. clearLoading now hides instead of removing (resetLoading re-shows per mount), and legend + hint mount into the keyed graph container — destroyed wholesale on switch — not #main-pane. Gate harness waits for the loading element hidden, not detached.
With Shift held, the first click on a node pins its neighborhood highlight — it survives mouse-out and Shift release so relationships can be studied hands-free; a second Shift-click on the same node opens its modal. Plain click still opens directly. Unpinned by background click, pinning another node, or legend-hiding the pinned type. applyHighlightState() is the single resolver (pin > shift-hover > clear); transient hover/edge highlights fall back to the pin instead of clearing. debugState() exposes pinned/hover/shift for probes.
F-1 apiSearchStreamCodeEvent comment aligned with behavior (Results always populated). F-2 root Makefile gains a frontend delegate. F-3 SearchPalette and CodeModal fetch per-branch with typed generics — the union-generic-then-cast pattern is gone. F-4 /api/code/schema returns 200 + degraded on a not-indexed member instead of 500 (soft-state convention; spec contract row amended, frontend renders the message). F-5 realm-self-index scenarios ported from the deleted htmx tests to JSON assertions (api_code_realm_test.go).
serve.md: document the Shift-gated graph interaction model (camera by default, Shift for highlight/drag, Shift-click pin then open) and zoom-scaled node sizes, in both the docs- and code-graph sections. contributing.md: pre-commit hook is four stages (frontend dist rebuild added) and a new section covers the Bun workspace, the committed embedded dist, and the make frontend / bun test / CI drift gate.
feat!(serve): React + TypeScript SPA frontend, replacing the htmx shell
Concepts gains the resolution-ladder section; getting-started a pi setup note; install the auto-migration behavior; README a multi-harness row; conventions the harness-relative path caveat.
String literals in host code naming SQL objects (Kysely selectFrom,
GORM Table, mapping declarations, annotations) previously produced no
graph edge to the .sql-defined object. Identifier-shaped literals are
now harvested as speculative refs and matched at resolution time
against indexed tables/views/procs/SQL functions -> references edges
with provenance string-match and confidence in Edge.Metadata. A 28-name
query-builder/declaration-DSL callee vocabulary (CalleeExpr, Go/TS/
Python harvesters) upgrades confidence; columns match only anchored
(qualified table.col, or bare names scoped to a function's matched
table). A fragment tier tokenizes builder-arg SQL fragments
(where("name = ?"), order-DESC, comma lists) and resolves tokens one
confidence notch lower. Unmatched refs are deleted; nodes are never
minted from strings.
Validated on taxgentic (2836 edges) and an 18-language probe corpus.
Known limits documented: no view-column nodes; Elixir/Erlang harvest
deferred (follow-up filed).
[pi.agent.<name>] model/thinking overrides merge global + repo config (repo wins per field) into a versioned JSON envelope with structured diagnostics, so the Pi agent reads tiers through the binary instead of parsing TOML itself. [pi] is opaque to unrelated config writes.
* fix(ci): install bun in test job and isolate frontend test state go generate now runs the bun frontend build (frontend_dist.go), but the test job never installed bun -> every next push failed at Generate bundle. Two flaky frontend tests were cross-file module-state leaks: window.__railCy left registered by MiniGraph.test.tsx, and loadScript's promise cache poisoned with a rejected entry by Rail/Page suites. Per-file afterEach resets plus a central reset in setup.testing.ts. * fix(ci): deterministic Rail script-load stub and spec S5 table shape The Rail suite relied on happy-dom rejecting vendor script loads synchronously — an implementation detail that doesn't hold on CI, where the unstubbed MiniGraph load chain rode past the 5s test timeout. Stub script creation + cytoscape factory for the whole suite; count only /rail/ fetches in refetch assertions. Also reshape the sql-string-match spec checkpoint table to the S5-required columns. * fix(ci): mock MiniGraph in Rail suite; strip PATH in profile subprocess test Strategist RCA: the Rail timeout was macrotask-timer starvation — RTL's own 1s waitFor timer never fired — caused by unmounting MiniGraph while its FetchEngine request (retry+dedupe, no AbortController) was inflight. Rail tests only assert panel state, so MiniGraph is mocked out (covered in its own suite); page.resolved emits act-wrapped; CP2 script-stub scaffolding removed. Profile subprocess test strips PATH so detectors probe no real tools — bazel's cache writes into the temp HOME raced t.TempDir cleanup on CI.
Adds an optional per-agent effort (low/medium/high/xhigh/max) alongside model under a harness-namespaced [claude.agents.<name>] block, applied to the installed agent frontmatter at install time and immediately on 'atomic config agents'. model accepts a tier alias or a bare Claude Code model id; validation is lenient. Drift between config and installed agents is detected by the existing doctor install-integrity check and repaired by 'atomic doctor --fix'. pi's block is renamed [pi.agent] -> [pi.agents] for symmetry (config key only; applying pi overrides stays the pi extension's job). No back-compat shim: neither block had shipped in a release.
… verbs Buckets now carry a code-generated ## Docs listing of their own topics, and the realm index a ## Buckets listing of every bucket, both spliced into XML-delimited managed regions (<bucket-docs>, <wiki-bucket-list>) so user prose around them survives regeneration. Listings derive from a six-key frontmatter contract (title, type, description, tags, status written by the author; created stamped at scaffold time); frontmatter-free files still list under ### Unindexed. atomic wiki scan rebuilds every region non-fatally. New verbs: atomic wiki bucket doc <bucket> <slug> [--router] scaffolds a topic (router adds a <slug>/ subtree for breakout subtopics), skill <bucket> scaffolds a per-bucket .claude/skills/<bucket>-management/ skill, index [<bucket>] forces a rebuild. Adds a shared managed-region splice primitive and migrates the legacy HTML-comment-bounded ## Members section onto it (position-preserving, skips on an unpaired marker rather than risk a half-migrated document).
* fix: stop C5 @-ref check flagging email domains validate config C5 parsed the domain half of any user@host.tld in CLAUDE.md prose as an @-ref and FAILed on it not resolving. Guard on the char preceding @: skip when it's an email local-part character. RE2 has no lookbehind, so the check runs at match time. Refs #159 * fix: redact PII in /report-issue before posting Both report-issue commands reproduced pasted context verbatim into a public GitHub issue — issue #159 itself leaked real emails and a domain. Add a shared privacy partial: scrub PII, secrets, and third-party identifiers to placeholders while keeping technical signal, and preview the full body for explicit confirmation before gh issue create. Refs #159 * chore(signals): refresh after #159 fixes
* fix(wiki): resolve summary repo dir from scan block atomic wiki stale reconstructed a member's directory from its summary file's own path, which never stripped .md and discarded any parent directory of the member. The derived path did not exist, git rev-parse failed, and the fail-safe branch emitted STALE summary before the reflects_rev comparison was ever reached — so three of the four member-location x summary-layout shapes could never report fresh, and affected realms stayed permanently dirty. Resolve each summary back to its Member and use Member.Path, the value scan recorded. Falls back to base-name matching for members that have graduated to indexed and carry an empty SummaryPath alongside a leftover summary file; anything still unresolved reports stale as before. Fixes #157 * chore(signals): refresh after wiki-stale-summary-resolution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v6 breaking release: 136 commits on
next.Breaking
~/.claude/.atomic/→~/.atomic/; automatic first-run migration (rename + compat symlink). (Make CLI-managed paths configurable; move user state to ~/.atomic #150).claude/worktrees/(Claude Code's native home).atomic-commit→atomic-git-discipline,atomic-prose→atomic-writing,atomic-setup→setup-wiki,atomic-improve→retrospective-learning. (Rename four artifacts: atomic-commit, atomic-prose, atomic-setup, atomic-improve #124)Harness-agnostic paths (#150)
harness.dirconfig key routes all repo-local state (.pi/...vs.claude/...).ATOMIC_HARNESSenv >PI_CODING_AGENT=true>CLAUDECODE=1> config > default — mixed Claude/pi machines work with zero config.@-refs.Features
/quick-fix— implement→review loop without the planning phase.atomic repo init— idempotent.claude/scaffolding with nested.gitignore.atomic template <name>— document skeletons for the authoring commands..claude/atomic.tomlignore globs for the code-intel index (+ doctor category 13).Merging triggers release-please for the major bump (
feat!/fix!commits present).