Skip to content

Replace inline @ directives with included content at install time #535

Description

@williamthorsen

Problem

The @~/path directive used in source guidance files (content/guidance/_platforms/{platform}/{file}.md) is unreliable as a means of getting shared content in front of agents:

  • On Claude Code, the directive loads the referenced file as a separately-framed section ("Contents of {path}:") in the system prompt. Empirically, content presented this way is sometimes not attended to alongside the primary host file.
  • On Rovo Dev, the @ directive isn't recognized at all — referenced content is never loaded.

The result: shared instructions intended to apply across platforms (e.g., ~/.agents/AGENTS.md) are inconsistently consumed by agents.

Context

Source guidance files containing inline @ directives:

  • content/guidance/_platforms/claude/CLAUDE.md — references @~/.agents/AGENTS.md
  • content/guidance/_platforms/rovodev/AGENTS.md — references @~/.agents/AGENTS.md and @~/.rovodev/codeassembly-guidance.md

The installer already does install-time markdown transformation (rewritePathsInFile for link rewriting and template-variable expansion in installPlatformGuidance). The new include-resolution step fits the same pattern.

~/.agents/AGENTS.md and ~/.rovodev/codeassembly-guidance.md continue to be installed as standalone files (separate from being inlined). They serve ad-hoc references from other instructions (e.g., user-authored project guidance pointing at ~/.agents/AGENTS.md). After this change, two installed copies of shared content will exist (the standalone file and the inlined content in platform files). This duplication is consistent-by-construction at install time and accepted as the cost of reliable consumption.

The directive form is build-time-only and source-tree-scoped: the path inside an include is interpreted relative to the source file's directory in the content tree, never against installed paths. Runtime references to installed-tree files should use natural-language prose ("Read X"), not the include directive.

Related: #522 proposes a partials/include mechanism for subagent files. That mechanism has different semantics (parameterized partials, subagent-specific) and is intentionally kept separate from this directive.

Solution

  1. Introduce a build-time include directive with the syntax <!-- include: {source-relative-path} -->, distinct from the runtime @ directive.
  2. At install time, in the platform-guidance install step, resolve each directive against the source file's directory, read the referenced source file, and substitute the directive line with that file's content. Process the substitution recursively so nested includes resolve.
  3. Update source files to use the new directive in place of @~/path references that point at installable shared/platform content:
    • content/guidance/_platforms/claude/CLAUDE.md: replace @~/.agents/AGENTS.md with <!-- include: ../../shared/AGENTS.md -->.
    • content/guidance/_platforms/rovodev/AGENTS.md: replace @~/.agents/AGENTS.md with <!-- include: ../../shared/AGENTS.md -->, and @~/.rovodev/codeassembly-guidance.md with <!-- include: ./codeassembly-guidance.md -->.
  4. Continue installing ~/.agents/AGENTS.md and ~/.rovodev/codeassembly-guidance.md standalone (no change to that behavior).
  5. Fail loudly at install time if a directive's resolved path doesn't exist or escapes the content directory.

Acceptance criteria

  • An <!-- include: {path} --> directive in a platform guidance source file is replaced at install time by the content of the referenced source file, resolved relative to the source file's directory.
  • Nested includes (an included file containing its own include directive) resolve recursively.
  • A directive whose path doesn't resolve to an existing file under the content directory causes the install to fail with a clear error identifying the offending source file, line, and target path.
  • A directive whose resolved path escapes the content directory (../../../etc/passwd-style) causes the install to fail with a clear error.
  • After install, no <!-- include: ... --> directive remains in any installed .md file.
  • After install, no @~/path directive intended as a build-time include remains in installed platform guidance files (the source files are migrated; only directives intentionally kept for runtime use remain, of which there are currently none).
  • ~/.agents/AGENTS.md and ~/.rovodev/codeassembly-guidance.md continue to be installed as standalone files with content matching their sources.
  • New/modified behavior in this change is covered by tests, including: simple include resolution, nested include resolution, missing-target error, path-escape error, and end-to-end verification that installed platform guidance contains the expected inlined text.
  • No existing behaviors regress: Markdown link rewriting, {platform_home_dir} expansion, provenance marker injection, drift detection, and dry-run mode continue to work for files that contain include directives.

Metadata

Metadata

Labels

featureAdded or improved external functionalityscope:agents

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions