Skip to main content

splice_project_instructions_component

Function splice_project_instructions_component 

Source
pub(super) fn splice_project_instructions_component(
    export: &mut BundleExport,
    files: &[ProjectInstructionFile],
) -> Result<(), String>
Expand description

Splice native-memory files into an already-built bundle export’s bundle.json manifest and files list, adding components.memory (ABF v0.2 §2.3). Kept OUTSIDE bundle_export.rs deliberately — that module’s export_bundle() is scoped to a bundle’s own components (instructions/skills/MCP/accounts) with no concept of “agent” or native memory at all; memory is agent-scoped, not bundle-scoped, so splicing it in here (the RPC-handler layer, which already resolves other agent-scoped data like skill rows) keeps that module’s documented scope intact rather than growing it a fifth, unrelated component category. A no-op when memory_files is empty — matches the existing omit-empty-components convention used elsewhere in the manifest. Carry the agent’s project instructions into the export as components.projectInstructions.

Phase 3 of SPEC_INSTRUCTION_AND_MEMORY_PORTABILITY_2026_09_09.md. Files land under instructions/project/<sanitized-path>, and each manifest entry carries its original path, a contentHash, and an owner.

owner is the load-bearing field. It is what stops this from becoming a way to install one repository’s instructions into another: an importer that treated a foreign entry as content to write would be doing precisely what SPEC_CLAUDE_MD_OWNERSHIP_PROTECTION_2026_08_22.md exists to prevent. Import surfaces these and never applies them (spec §5.2), so an operator who wants them acts deliberately.

Only files that exist and were readable are carried — there is nothing to put in an archive otherwise. Their absence from the manifest is therefore not a claim that the source agent had none; agent.project_instructions is where the fuller picture, including absent and unreadable files, lives.

“Readable” is decided by error/truncated, NOT by whether the content is empty (Codex P2, PR #3163). A real, readable, zero-byte CLAUDE.md is a fact about the source agent — dropping it would make the export indistinguishable from one where the file was absent, which is the exact kind of quiet lie this component exists to remove.

Paths go through the same sanitizer the exporter uses for context files, so a scanned path can never write outside the archive’s own tree.