Skip to content

grund 0.8.0

Choose a tag to compare

@github-actions github-actions released this 11 Aug 12:32
· 2698 commits to main since this release

Added

  • §DF-conversation-link-target: the local-conversation link form is now a Markdown link whose label is the bare citation and whose target is an absolute URI, and the addressing scheme is a per-machine choice — the new user-configuration key [reference] conversation_target and its flag grund integrations --write --conversation-target <target>, accepting file (default), path, web, vscode, vscodium, and cursor (§FS-config.3.1, §FS-integrations.4.3). This reverses the plain-path:line form recorded days earlier: that form rested on the one row of the §DF-neural-link-generation matrix carrying no observation of its own — Claude Code linkifying file_path:line_number — which failed its first click-test on 2026-08-11, while an absolute-URI Markdown link worked on the first try under file:, vscodium:, and https: (matrix rows 12–14; row 1's recorded failure was a relative target all along). The form is gated per agent: Claude receives every target, Codex receives web only — its renderer shows a local destination in place of the label, erasing the citation — and every unverified agent keeps path, the form it already had, so the gate can never make a surface worse. path remains available as the explicit opt-out. Schema: the AGENTS.md init block bumps to v6 and the grund integrations agent-guidance block to v3; run grund init and grund integrations --write to refresh. Note that a CLAUDE.md that is a symlink to AGENTS.md resolves to the canonical entrypoint and therefore keeps the plain form (§FS-init.2.3.4.17). The Codex half of the gate was then click-tested on 2026-08-11 and held (matrix row 15): its TUI never hides a destination behind a label — a file: target replaces the citation with a cwd-relative location, while vscodium: and https: append the URL in parentheses and only https: is clickable — so an editor scheme there costs a long inline URL and buys no click, and web stays its one natively clickable form. Pi was click-tested the same day and earned a third profile (matrix row 16): its labels always survive, and its clicks come from the terminal's URL matcher rather than from Pi — pi-tui hides a URL behind its label only when it identifies a hyperlink-capable terminal and otherwise prints text (url) — so file and web are usable there under either outcome and editor schemes are not. PR #45.

  • §FS-integrations.4.4 / §DF-conversation-link-target.2.5: add per-agent overrides of the conversation target. One machine reads several agents and the click-tests say they do not render alike, so [reference.agents.<agent>] in the user configuration is a partial of the machine-wide keys, shallow-merged over them — a key present under an agent replaces the base for that agent, an absent key inherits it, and there is no per-agent default to unset. grund integrations --write --agent codex --conversation-target web records one, leaving the base every other agent inherits byte-for-byte alone. This makes the pairing the evidence points at expressible: Claude on an editor scheme, Codex on web, from one config. An override sets the request and the §DF-conversation-link-target.2.4 gate still sets the verdict, so no key can instruct a form recorded as erasing citations on that surface. A flatter conversation_target_by_agent map of scalars was considered and rejected: it is smaller for exactly one overridable key and degenerates into parallel maps tied together by naming convention as soon as there is a second. Every written instruction target now also names the form it received and why when that is not what was asked for (link → path; vscodium unverified here) — behavior §FS-integrations.4.3 already specified and the implementation did not yet do, which left an override, a gate downgrade, and an unread key indistinguishable from the outside. PR #45.

  • §FS-init.2.3.4.17: grund init now reports a Claude entrypoint that is a symlink to AGENTS.md when the repository commits [reference] conversation = "link". A symlink resolves to the canonical target, so one file carries the block for every agent — and that file is the one Codex reads, where the linked form is recorded as erasing the citation, so it must keep the plain location. The linked form therefore cannot reach Claude through a symlinked entrypoint, and until now nothing said so: the sentence was simply absent on the one agent the opinion was mostly written for, which is indistinguishable from the feature not working. The run emits one note: line naming the symlink and pointing at grund init --claude. It is a report, not a finding — nothing is rewritten and the exit code is untouched. InitOutput gains a notes field. PR #45.

  • §DF-repo-conversation-opinion / §DISC-conversation-rendering-layers: repositories may commit a link-only conversation-rendering opinion via [reference] conversation (§FS-config.3.1). When set, the generated agent entrypoint teaches linked local-conversation citations — the declaration location beside the citation — at the time as plain path:line text, superseded within this same cycle by the absolute-URI link form of §DF-conversation-link-target (then recorded non-working in terminal TUIs by the §DF-neural-link-generation matrix). The grund integrations global block texts become self-scoping (inert outside grund repositories) and carry the precedence rule: explicit machine preference > repository opinion > plain — the committed opinion is the no-knowledge fallback for readers whose machines grund never touched (fresh clones, cloud and CI sessions, Cursor and Windsurf, whose only channel is the committed entrypoint), while a recorded plain proves an installed rendering layer and wins, so an opinionated repository costs installed users nothing. A preference-only design (no repository key) was considered and rejected: it permanently orphans the entrypoint-only readers; the serving matrix in the DISC records who is reached by which layer, and the setup guide (docs/user-facing/clickable-citations.md §5) walks users through each case. A repo-local uncommitted instruction file was researched across the supported-agent set and deferred (portable to Codex alone). PR #45.

  • §DF-neural-link-generation: record the clickable-citations experiment and decision for conversation text as an agent convention, not a per-citation tool. Local/TUI rendering follows a user preference installed into global agent instructions; repository web text follows one fixed, context-sensitive rule. Links keep the citation as visible text and plain is always the fallback. Markdown link-title hover is explicitly rejected: it repeats declaration headings in output for a limited desktop tooltip rather than a portable preview. grund grows no link command (a prototype was built and reverted on the PR branch); grund fmt --cross-refs (§FS-fmt.6) remains the only link emitter for repository Markdown. The Codex TUI rows of the matrix are now observed rather than pending: its renderer hyperlinks only web URLs and displays a local-path Markdown link as the destination in place of the label, so a local Markdown target is not usable there. (Later in this same cycle, click-testing reversed the Claude Code rows and the local-conversation form became an absolute-URI Markdown link — see the §DF-conversation-link-target entry above.) PR #45.

  • §FS-integrations / §DF-integrations-command: add the grund integrations [<client>] command — the one-stop shop that makes the clickable-citation rendering layer installable from cargo install grund. It prints embedded artifacts on demand, detects the caller's terminal/editor, and installs on --write as an idempotent marked block. A write also records the user-local conversation preference and synchronizes global Codex, Claude, Gemini, GitHub Copilot, Zed, and Pi instructions; clientless --write --conversation link overrides the plain default without installing an arbitrary client or changing repository configuration. --format json emits a machine detection plan. Every artifact is embedded in the binary; nothing is published to a marketplace (§FS-lsp.2.3). Resolves issue #46. PR #45.

  • §FS-integrations.3.2: add codium. VSCodium is a separate application with a separate extensions root, so grund integrations vscode --write installed the extension into ~/.vscode/extensions where VSCodium never looks — and the failure was silent, reporting success while no link ever appeared. codium installs the identical extension into ~/.vscode-oss/extensions. Detection cannot tell the two apart by presence, since both export an identical VSCODE_* environment; what differs is where those values point, so codium is marked alongside vscode when one of them names VSCodium's application directory, and the catalog offers both installs rather than guessing. PR #45.

  • §FS-integrations.3.5: record the terminals that cannot be supported and why, so the question is not re-litigated. Ghostty documents exactly the needed option — link, a regex bound to an arbitrary action — but its reference marks it TODO: This can't currently be set!; only built-in URL matching works, and with no path:line opener the --conversation link fallback does not help either. Apple Terminal.app and Windows Terminal have no regex-to-action hook at all. The shared requirement is stated once: a terminal must let configuration bind arbitrary matched text to an arbitrary command. PR #45.

  • §FS-integrations.3.1: the location beside a citation is a link too. The link conversation form prints §<ID> path:line, and iTerm2 and the VS Code terminal open such locations natively — WezTerm and kitty matched URLs only, leaving the location half inert text. The terminal matchers gain a location shape (a dot-extension segment with a :line[:col] suffix); grund-open tells it from an ID mechanically — a section suffix is dotted, never coloned — climbs to the nearest ancestor holding the file, and opens the editor at that line, dropping any column. No grund and no config is consulted, so a location click works in any repository; peek pages the file from the cited line. Registered before the citation rule in WezTerm, the location matcher also converts the recorded path false positive into one correct link for :line-suffixed paths. PR #45.

  • §FS-integrations.3.4: add iterm2, the most-used macOS terminal, as the first manual client. It keeps its rules in a binary property list, so the managed-block contract does not apply and grund will not rewrite a live profile blob for a convenience. grund integrations iterm2 prints the Smart Selection rule to add — the shared citation regex at Very High precision so it does not lose to iTerm2's built-in path rule, with a Run Command… action of grund-open \0 on cmd-click and grund-open --peek \0 as a second action on the right-click menu. --write installs the resolver and the user preference, then prints what only a human can apply, reporting manual and exiting 0. A manual client always reports installed: false because grund never reads that plist; the detection plan gains "install_kind" so a caller can tell not installed from not knowable. Noted where it matters: iTerm2's Semantic History already makes path:line cmd-clickable, so --conversation link alone gives Mac users clickable citations with no rule at all. PR #45.

  • §FS-integrations.3.3: reach a citation from the keyboard in WezTerm. ctrl+shift+g labels every citation on the screen and opens the one whose label you type, ctrl+shift+i peeks at it instead — kitty's hints model, built on WezTerm's quick-select. This is the more dependable of the two paths, not a convenience twin of the click: a full-screen program that has captured the mouse can swallow a click, and citations are read while typing. p would have mirrored kitty exactly, but WezTerm binds it to the command palette, so peek takes i for inspect. Every gesture — both clicks and both keys — now ends in one shared resolver call, so they cannot drift apart, and a custom picker action suppresses quick-select's copy so the clipboard is left alone. Asked and answered while investigating: true hover is not possible in any terminal, and for WezTerm the reason is now recorded rather than asserted — its mouse bindings trigger only on Down, Up, Drag, WheelUp, WheelDown, no callback learns the cursor's row and column, and wezterm#4 has requested a link tooltip since 2018 with no implementation. PR #45.

  • §FS-integrations.3.3: read a declaration without leaving what you are doing. Opening a citation answers where; peek answers what it says. grund-open --peek renders the resolved path:line and the declaration lead through a pager, and each terminal client binds it to a disposable surface: a kitty overlay (ctrl+shift+p), a tmux popup (prefix + G, tmux 3.2+), a wezterm split pane (ctrl+shift+-click). It is the same resolver in a second mode, so a peek and a click cannot disagree about where a citation points. VS Code gets true hover instead — its terminal-link tooltip now carries the declaration's --brief slice and resolved location, cached per citation because the provider runs per rendered line. No terminal can hover: none exposes a hover event or link tooltip to configuration, and WezTerm's request for one has been open since 2018. PR #45.

  • docs/user-facing/clickable-citations.md, linked from the README: a user-facing setup guide for the terminal and editor integrations. It opens on a quick start — three commands, the three checks that each fail silently (grund and ~/.local/bin on PATH, an editor the resolver can find), and the reload every client needs — so a working install is reachable without reading the rest. Then: the per-client install, a verification walkthrough that names headings rather than line numbers and points at grund <ID> --format json as the authority, peek, troubleshooting that separates a matcher problem from a resolver problem in one command and lists the resolver's actual error messages, the plain vs link conversation preference and how a repository opinion overrides it, and an uninstall that names all four things --write touches. Documents that WezTerm requires wiring grund_apply_hyperlink_rule(config) by hand — the block installs but does nothing until it is called, which looks identical to a broken install. PR #45.

  • scripts/try-integrations.sh: a manual testbed for the §FS-integrations clients. It installs the integrations built from the working tree into a throwaway HOME — so the client dotfiles, the resolver, the user preference, and six global agent instruction files all land in a sandbox rather than on the developer's machine — then launches the client in a repository full of real citations with every open logged. show skips all of that and prints one citation of every shape into the terminal you are already in — with --tui, under mouse capture, the state an agent TUI leaves the terminal in. doctor reports what is testable on this machine, including a wezterm on PATH that is really a Flatpak wrapper (there the sandbox environment never crosses the sandbox boundary, so the launch would silently test the real configuration); resolve runs the click path headlessly (marker stripping, section suffix, swept-in punctuation, the root climb from a subdirectory and past a workspace member, E2E directory targets, unknown ids, --peek), so the part that can be automated does not need a human clicking. PR #45.

Fixed

  • §FS-config.3.1 / §FS-integrations.4.3: the user-level preference is spelled [reference] conversation, the same key a repository commits — it was [render.links] conversation, a second name for one setting that appeared in no documentation at all. The file is hand-editable, so the repository spelling is the one a user reaches for, and the scan matched a single literal: [reference] conversation = "link" there was silently ignored, recorded as its opposite (plain), and written back beside what the user wrote, leaving a duplicate table no TOML parser will load. So were [ reference ] with spaces and the dotted reference.conversation, both plain TOML; conversation = 'link' was rejected outright as "not quoted". The key is now read the way TOML defines it — header whitespace, dotted paths, either quote style. Both scopes are documented, with which value to choose and why plain stays machine-only (docs/user-facing/clickable-citations.md §5.1). PR #45.
  • §FS-integrations.4.3: nothing in the user configuration is an error any more — every line grund does not act on is one warning: at its line, then ignored. That covers a key grund does not read (naming reference.conversation as the only one it consumes there — so a typo like converstaion, a spelling from an older grund, and a repository-only key such as marker set there in the belief that it applies to every project are all reported instead of reading as configured and doing nothing), a value it cannot interpret (which leaves it with no preference from this file, the same state as a machine that never wrote one), and a repeated key (the first wins, which is the occurrence a write rewrites, so a read and a write cannot disagree). This is the one place the two configuration files deliberately differ, and the difference is what each decides: the repository config is a closed allow-list that refuses an unknown key or a bad value outright (§FS-config.4.3) because it governs whether a tree checks clean, while this file is machine-local, read by one command, and only picks between two renderings of the same true citation — a stale line in a personal config is not a reason to refuse to install a terminal integration. --conversation given on the command line is still validated as an argument. Exit code is unchanged at 0. PR #45.
  • §FS-integrations.4.3: installing a terminal integration no longer provisions the configuration trees of five agents the machine does not have. grund integrations kitty --write created ~/.gemini/GEMINI.md, ~/.copilot/copilot-instructions.md, ~/.config/zed/AGENTS.md, and ~/.pi/agent/AGENTS.md from nothing — files the user did not ask for and would not think to remove. A target is written when the agent's own directory or its instruction file already exists, and reported skipped <path> (no <dir>) otherwise, the same discovery rule the repository entrypoints follow (§FS-init.2.3); re-running after installing an agent picks it up. PR #45.
  • §FS-integrations.4: ~/.config install targets resolve through $XDG_CONFIG_HOME. grund honored it for its own user config while writing kitty's, WezTerm's, and Zed's to a hardcoded ~/.config, so on a machine that sets the variable the guidance and the terminal snippets landed where those tools never look — the silent install-reports-success failure the separate codium client exists to prevent (§FS-integrations.3.2). Printed target hints stay ~-rooted and byte-stable; only resolution changed. PR #45.
  • §FS-integrations.4.3: a preference file grund cannot parse fails the command before anything is installed, instead of after the terminal config and the resolver are already on disk. And a --write whose recorded value already matches leaves the file byte-for-byte alone — it used to rewrite the line in grund's own spelling, dropping any comment beside it and reporting updated for a no-op, contradicting the idempotence contract (§FS-integrations.6). PR #45.
  • §FS-init.2.3: grund init reports an unloadable .agents/grund.toml instead of silently rendering the managed block from defaults. It exits 2 with the message and location grund check gives for the same file; previously the two disagreed about a file both of them read, and an invalid [reference] conversation, marker, or kind set produced agent instructions describing a repository the user does not have while init reported success. PR #45.
  • §FS-integrations: four Markdown cross-reference anchors in the new integrations documentation pointed at headings that do not exist (#2346-clickable-citations for #### 2.3.6, #81-grund- for ### 8.1 \grund /`), so the links landed at the top of the target file. grunddoes not validate Markdown link fragments ([§FS-non-goals.1](functional-spec/FS-non-goals.md#1-markdown-link-validation)), which is why a cleangrund check` did not catch them. PR #45.
  • §FS-integrations.3.1: the kitty integration took two of kitty's own keymaps away and then could not run the resolver. ctrl+shift+g is kitty's show_last_command_output, and ctrl+shift+p is the prefix its nine hint kittens already live under (p f a path, p y a hyperlink, p c choose-files) — where a plain binding is not a collision but a deletion, because kitty resolves a trigger by discarding every sequence mapped before the last non-sequence definition, which was ours. The two gestures now join that family instead of replacing it: ctrl+shift+p g opens a citation, ctrl+shift+p i peeks — the same go and inspect letters WezTerm takes plainly, verified against kitty's own get_shortcut to leave all nine defaults reachable. Second, the resolver was invoked as a bare grund-open, which a desktop-launched kitty cannot find: the session environment never sourced the user's shell profile and does not carry ~/.local/bin, so kitty raised FileNotFoundError: 'grund-open' into a log nobody opens while the citation did nothing. Both gestures now spawn through sh with ~/.local/bin and ~/.cargo/bin prepended, as WezTerm already did — tested end to end against a kitty started with a desktop-session PATH. No cd joins them: kitty hands the picked window's directory to whatever it spawns, which is the one piece of this that was already right. The guide gains the matching prerequisite it was missing — GRUND_OPEN_CMD/EDITOR must be set where the terminal process sees them, since a GUI terminal never ran your .zshrc. PR #45.
  • §FS-integrations.3.1: peek in a Flatpak WezTerm opened a split pane that vanished instantly — a flicker with nothing in it. The resolver argv was wrapped in flatpak-spawn --host at both spawn sites, but a peek is a pane command, which the Flatpak build already routes to the host exactly as it does the user's shell; the second wrap therefore ran flatpak-spawn on the host, where it has no portal and exits 127 silently, closing the pane before it drew. Only the spawn grund performs from inside the sandbox is wrapped now. Found by instrumenting the host resolver, because that segment of the click path produces output nowhere. PR #45.
  • §FS-integrations.3.1: WezTerm clicks did nothing at all on any build that does not export pane:get_current_working_directory() — it is spelled get_current_working_dir there, and calling the absent name is a Lua error that aborts the open-uri handler before it spawns anything, leaving the citation inert and the reason in a log nobody opens. Every lookup is now guarded and tried in turn, with get_foreground_process_info().cwd behind them — except under Flatpak, where WezTerm spawns the pane's program on the host through flatpak-spawn and can only see the sandbox-side helper, whose directory is a real one that is not the shell's. That leaves OSC 7 as the only channel crossing the boundary, and no shell emits it by default (vte.sh returns early for every non-VTE terminal), so it is stated as a prerequisite in the artifact and the setup guide, and a click arriving with no directory now says so in a toast and the log instead of doing nothing. PR #45.
  • §FS-integrations.3.1: clicking a citation now opens the line it actually cites, from anywhere in the tree, under any configured marker. A product-management pass over the rendering layer found the shipped resolver truncated the citation at the first . — so every §<ID>.<section> click landed on the declaration heading rather than the section; handed the editor a config-root-relative path, which opens nothing when the shell sits in a subdirectory; and matched a hardcoded §, leaving repositories with a custom [reference] marker silently unclickable. grund-open and the VS Code extension now resolve through grund <ID>[.<section>] --format json, walk up to the config root and join against it, and strip whatever marker they are given; the click matchers accept any punctuation marker and the namespace-qualified §<alias>/<ID> form. Field extraction is anchored to the end of the JSON object so declaration prose containing "path": or "line": cannot shadow the real fields. PR #45.
  • §FS-integrations.4.1: grund integrations wezterm --write produced a wezterm.lua that does not parse. The managed-block markers were hardcoded to #, which comments kitty.conf and .tmux.conf but is the length operator in Lua — verified against the Lua 5.4 compiler as unexpected symbol near '#', which costs the user their entire WezTerm configuration rather than just the grund block. Markers now use the host file's own comment token, and block lookup is scoped to that dialect so an existing block is never respliced with the wrong one. Separately, a from-scratch wezterm.lua defined grund_apply_hyperlink_rule but never called it and returned no config, so even a parsing file registered nothing; a fresh write now appends an unmanaged starter config that wires the helper up. Found by attempting the documented setup end to end. PR #45.
  • §FS-workspace.8.1: grund <alias>/<ID> --format json reported a member-relative path while grund list reported a workspace-root-relative one, contradicting the §FS-config.3.6 promise that report paths are relative to the config root. Both now agree — including for E2E cases, whose pre-baked manifest JSON bypassed the fix — which is what lets the resolver join the reported path against the root it discovered. PR #45.
  • §FS-integrations.3.1: the click handlers now run the resolver in the clicked pane's working directory — tmux's run-shell starts in the tmux server's start directory and WezTerm's spawn in the GUI process's, so a click failed unless the terminal happened to be launched inside the repository. The click matchers accept digits inside the kind — the letters-only pattern could never match a §E2E-<case> citation — and the resolver accepts the §FS-show.2.4 E2E manifest shape (no "line"; the case directory opens, with no :line suffix) instead of failing on every E2E click. A failed resolution continues the root climb upward instead of ending it, so a workspace-qualified §<alias>/<ID> clicked from inside a member resolves at the workspace root. WezTerm's gestures are additionally registered with mouse_reporting = true — without it WezTerm drops user mouse bindings inside mouse-capturing TUIs, which is where agents print citations — and its resolver spawn prepends ~/.local/bin and ~/.cargo/bin to PATH and routes through flatpak-spawn --host under a Flatpak sandbox, whose own PATH carries neither grund-open nor grund. With no editor named at all, grund-open now falls back through the VS Code family (code, codium, code-insiders). PR #45.
  • §FS-integrations.3.2: the VS Code extension walked no further than the first workspace folder, so opening a subdirectory of the repository ran grund there and joined the config-root-relative path against the wrong base; it now walks up to .agents/grund.toml exactly as the shell resolver does. It also cached failed resolutions forever — a citation that resolved after its declaration was added stayed "unknown" until the extension host restarted; only successes are cached now. And a click on a §E2E-<case> citation failed with an editor error: a directory-backed E2E declaration answers with the manifest shape — no "line", and a path naming the case directory (§FS-show.2.4) — which showTextDocument rejects; the case directory is now revealed in the Explorer, the editor's form of the bare directory open the terminal resolver already performed — falling back to the OS file manager when the opened folder is a subdirectory of the repository and the Explorer cannot show the case. Hover and click now share one --brief resolution, since the brief report already carries the path and line a click needs; a click on a hovered citation spawns nothing. PR #45.
  • §FS-init.2.3.6: the generated ### Clickable citations section hardcoded § while every other part of the managed block renders the repository's configured [reference] marker. In a repo using another marker the block therefore instructed agents to write a token that repo does not treat as a citation at all — grund check ignores it under strict, so the claim it grounded was silently never verified. Both sentences now carry the real marker; with the default § the output is byte-identical, so no existing block changes. Found by generating a marker = "@" repo and reading what agents then wrote into it. PR #45.
  • §FS-integrations.4.3: the global agent-guidance blocks name no marker. They are user-global and written once, before grund knows which repositories will be opened, while [reference] marker is per-repo — the same constraint that already forbids the click matchers and the resolver from hardcoding § (§FS-integrations.3.1), which these texts alone were violating. Unlike the repository entrypoint there is nothing to interpolate at install time, so the user layer now carries the policy (write citations bare / follow each citation with its declaration location) and the repository layer carries the syntax. Verified in a marker = "@" repository: agents wrote bare @-marked citations and suppressed the repository's link opinion, so dropping the marker cost no actionability. PR #45.
  • §FS-completions.1: the generated bash, zsh, and fish completion scripts complete the integrations subcommand the spec already promised, and grund help integrations and the README name all six supported clients instead of four. PR #45.
  • §FS-integrations.4.1: grund integrations wezterm --write into an existing config now reports the one wiring step it cannot take. WezTerm applies hyperlink rules only from the config object the user's Lua returns, so a block installed into a config that never calls grund_apply_hyperlink_rule(config) registers nothing — and the run said updated and stopped, which reads exactly like a working install while every click is inert. The write now emits one note: line naming the file and the call. The test is the file outside the managed block, because the block defines that helper and names it in its own comments; a config grund scaffolded from scratch already calls it below the block and stays silent, as does one the user has wired. A report, not a finding: nothing is rewritten and the exit code is untouched, and it repeats until the call appears. PR #45.
  • §FS-integrations.2: grund integrations now closes with the setup guide's URL. Detection is the first command a user runs, often reached from grund --help rather than the README, and everything --write cannot do for them — ~/.local/bin on PATH, an editor the resolver can find, the WezTerm and iTerm2 manual steps — is written down only in the guide. Both the detected and the nothing-detected form now end on the same two lines. PR #45.
  • §FS-integrations.3.3: the WezTerm hover-tooltip issue is cited at its current address. The project moved from wez/wezterm to wezterm/wezterm and GitHub does not redirect the old owner's issue URLs, so the link 404'd — in the spec, the setup guide, the changelog, and the wezterm.lua artifact the binary ships. The issue itself is unchanged and still says what it is cited for: "Tool-tip when hovering over explicit hyperlinks", open since 2018-02-25. PR #45.
  • §FS-fmt.6.2 / §DF-github-anchor-fidelity: grund fmt --cross-refs generated an anchor that resolves nowhere for any heading whose text carries angle brackets inside an inline code span. A renderer resolves code spans before it looks for markup, so the <alias>/<ID> in ### 8.1 `grund <alias>/<ID>` is literal text and GitHub slugs the heading #81-grund-aliasid; grund stripped it as an HTML tag and emitted #81-grund-, dropping the reader at the top of the file. Verified against the rendered heading on github.com rather than re-reasoned — as was the case it must not break, ## RM-refs: grund refs <ID>, where the same shape really is a tag and the anchor really does end in -. The fix is in the shared heading reduction, so both the section-anchor and declaration-anchor paths get it, and inline links inside code spans stay literal too. This anchor was reported fixed by hand earlier in this cycle and the formatter simply regenerated it on the next commit; that is why the fix is in the slugger. PR #45.
  • §FS-init.5: grund agent-setup-instructions printed a stale copy of the guided-setup skill, which §FS-init.5 calls an invalid release. skills/grund-init/SKILL.md and the embedded crates/grund-core/assets/skills/grund-init/SKILL.md are byte-identical on every release, and this cycle updated only the first: the shipped text still said --write synchronizes "global Codex, Claude, and Gemini instruction files" when it reaches six agents, and was missing the committable-opinion guidance entirely. The two copies are back in sync, and the opinion bullet now states the per-agent gate rather than one form for both entrypoints — CLAUDE.md teaches the file://<abs>#L<line> Markdown link while AGENTS.md keeps plain path:line (§DF-conversation-link-target.2.4). PR #45.
  • docs/user-facing/clickable-citations.md: four errors a reader would hit while following the guide. The verification walkthrough named line numbers that had drifted (§FS-integrations.3.1 at 36, 4.3 at 137; really 37 and 142) — the one section whose whole job is to tell a working install from a broken one, so it now names headings and defers to grund <ID> --format json. "Remove it" claimed nothing but the client block and the resolver was touched, omitting the user config, the global agent blocks, and the VS Code/VSCodium extension directory. The no-editor branch said grund-open "prints nothing and exits" when it prints grund-open: set GRUND_OPEN_CMD or EDITOR to open …. And WezTerm was documented as ctrl/cmd-click, but the installed block binds CTRL and CTRL|SHIFT only. PR #45.

Changed

  • Schema: the AGENTS.md init block version bumps v4 → v5 (§FS-init.2.3.6): the ### Clickable citations section gains the config-derived local-conversation sentence and joins the §FS-check.3.5 drift check. Migration: re-run grund init. The grund integrations user-instruction block bumps v1 → v2 (§FS-integrations.4.3); re-run grund integrations --write --conversation <value> to refresh global agent instructions. PR #45.