diff --git a/hive-ag3nt/prompts/docs-pointer.md b/hive-ag3nt/prompts/docs-pointer.md new file mode 100644 index 00000000..21cd380e --- /dev/null +++ b/hive-ag3nt/prompts/docs-pointer.md @@ -0,0 +1,19 @@ +# hyperhive reference docs + +The hyperhive reference docs are mounted read-only in this directory +(the harness exposes the path as `$HIVE_DOCS_DIR`). They are the +canonical reference for how this swarm actually works - the turn loop, +the tool surface, persistence, conventions, runbooks, and the +approval/CI/forge/matrix workflows. + +- On a fresh deploy, or any time you are unsure how a hyperhive + mechanism behaves, read `setup.md` first, then the topic file for the + area you are touching (e.g. `turn-loop.md`, `persistence.md`, + `tools/`, `conventions.md`, `gotchas.md`). +- Prefer these docs over guessing: they describe the live system, not a + generic one. + +This pointer is additive. It does not replace your own memory or project +instructions - your `~/.claude/CLAUDE.md` and any harness/project memory +still apply in full. Nothing here overrides what you already know about +yourself; it only tells you where the shared reference material lives. diff --git a/hive-ag3nt/src/turn.rs b/hive-ag3nt/src/turn.rs index 509bd435..523ed568 100644 --- a/hive-ag3nt/src/turn.rs +++ b/hive-ag3nt/src/turn.rs @@ -708,10 +708,12 @@ async fn run_claude(prompt: &str, files: &TurnFiles, bus: &Bus) -> Result<(bool, .arg("--allowedTools") .arg(mcp::allowed_tools_arg()); // hyperhive.docs.enable wires HIVE_DOCS_DIR to the in-container - // reference-docs tree. Expose it to claude as an additional - // directory so the docs are readable; the agent is NOT pointed at - // them (no CLAUDE.md autoload) — surfacing a pointer is the open - // follow-up. Unset (docs disabled) → the flag is not passed. + // reference-docs tree (with a generic CLAUDE.md pointer at its root). + // Expose it to claude as an additional directory so the docs are + // readable; harness-base.nix also sets + // CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 so claude loads that + // pointer additively (never replacing the agent's own CLAUDE.md). + // Unset (docs disabled) → the flag is not passed. if let Some(docs_dir) = std::env::var_os("HIVE_DOCS_DIR") && !docs_dir.is_empty() { diff --git a/nix/templates/harness-base.nix b/nix/templates/harness-base.nix index f75c3343..7b98750e 100644 --- a/nix/templates/harness-base.nix +++ b/nix/templates/harness-base.nix @@ -100,6 +100,22 @@ let iconPng = pkgs.runCommand "hive-agent-icon.png" { nativeBuildInputs = [ pkgs.librsvg ]; } '' rsvg-convert -f png -w 512 -h 512 ${config.hyperhive.icon} -o $out ''; + # hyperhive.docs.enable: the reference-docs tree (`pkgs.hyperhive-docs`, + # the repo `docs/` verbatim) with a generic `CLAUDE.md` pointer dropped + # at the root. The harness passes this dir to claude via `--add-dir`; + # paired with `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1` claude + # loads `/CLAUDE.md` ADDITIVELY (alongside, never replacing, the + # agent's own `~/.claude/CLAUDE.md`). The pointer prose lives in + # `hive-ag3nt/prompts/docs-pointer.md` (prompts belong in prompts/, not + # nix/) and is shipped via `hyperhive-assets`. `hyperhive-docs` itself + # stays pure (no CLAUDE.md) so the website can reuse the same tree. + # Lazy: only forced when `hyperhive.docs.enable` references it below. + agentDocs = pkgs.runCommand "hyperhive-agent-docs" { } '' + mkdir -p $out + cp -r ${pkgs.hyperhive-docs}/. $out/ + chmod -R u+w $out + cp ${pkgs.hyperhive-assets}/share/hyperhive/prompts/docs-pointer.md $out/CLAUDE.md + ''; in { # Shared scaffolding for every hyperhive harness container. @@ -245,10 +261,12 @@ in read-only as the standalone `hyperhive-docs` derivation) available in-container. When enabled the harness exposes the docs dir to claude via `claude --add-dir`, so the markdown is readable at - `$HIVE_DOCS_DIR/`. The agent is NOT yet pointed at the docs (no - auto-loaded `CLAUDE.md` pointer) — surfacing a pointer is a tracked - follow-up. Default-on for the root/manager agent (see `manager.nix`), - off elsewhere; any agent can flip it from its `agent.nix`. + `$HIVE_DOCS_DIR/`. A generic `CLAUDE.md` pointer is dropped at the dir + root and loaded additively (via + `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1`), so the agent knows + the docs exist without its own `~/.claude/CLAUDE.md` being replaced. + Default-on for the root/manager agent (see `manager.nix`), off + elsewhere; any agent can flip it from its `agent.nix`. ''; options.hyperhive.allowedBashPatterns = lib.mkOption { @@ -1384,12 +1402,15 @@ in HIVE_COMPACT_WATERMARK_TOKENS = "0"; } // lib.optionalAttrs config.hyperhive.docs.enable { - # hyperhive.docs.enable: the in-container reference-docs tree - # (`pkgs.hyperhive-docs`, the repo docs/ verbatim). The harness - # reads this and passes it to claude as `--add-dir` so the docs are - # readable; the agent is not auto-pointed at them. See - # hive-ag3nt::turn. - HIVE_DOCS_DIR = "${pkgs.hyperhive-docs}"; + # hyperhive.docs.enable: the in-container reference-docs tree plus a + # generic `CLAUDE.md` pointer at its root (see `agentDocs` above). + # The harness reads HIVE_DOCS_DIR and passes it to claude as + # `--add-dir` so the docs are readable; with + # `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1` claude also loads + # the pointer additively, telling the agent the docs exist without + # clobbering its own memory. See hive-ag3nt::turn. + HIVE_DOCS_DIR = "${agentDocs}"; + CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD = "1"; } // lib.optionalAttrs (config.hyperhive._bashEnvFragments != "") { # Non-interactive bash invocations (claude's `Bash` tool runs