feat(apr-code): wire org_policy into build_default_manifest (PMAT-CODE-ORG-POLICY-RUNTIME-001)#1573
Merged
Merged
Conversation
…E-ORG-POLICY-RUNTIME-001)
Closes PMAT-CODE-ORG-POLICY-RUNTIME-001 — the P2 follow-up from
PMAT-CODE-ORG-POLICY-001 that called out:
Prompt-builder integration deferred to PMAT-CODE-ORG-POLICY-RUNTIME-001 (P2)
The primitive (`load_org_policy` + `canonical_system_roots` in
`agent/org_policy.rs`) shipped 2026-04-18 with 13 unit tests but
was never called from `cmd_code`. This PR closes that gap.
## Wiring
`build_default_manifest` now calls
`load_org_policy(canonical_system_roots(), "CLAUDE.md", budget)` and
prepends the result FIRST in the system prompt under
`## Enforced organization policy (<source-path>)`. Order matters:
`PolicyTier::Enforced` is the highest tier in the precedence
lattice, so it must appear BEFORE Project Context / Instructions /
Auto-memory so a downstream section can't override it.
The org_policy loader silently skips missing files + I/O errors
(boot-safe — a sandboxed runtime can't ransom REPL boot), so on a
host without `/etc/apr-code/CLAUDE.md` or `/etc/claude-code/CLAUDE.md`
the section simply isn't emitted.
Source path is surfaced in the heading so operators (and CCPA
tracing) can spot where the policy came from.
## Refactor: `assemble_system_prompt` helper
Extracted prompt assembly into a pure-function helper so the
ordering invariant ("policy < context < instructions < memory") is
testable without `cwd` / `/etc` / I/O. The helper takes each block
as `Option<&str>` (or `Option<&OrgPolicy>` for the policy) so the
caller decides whether to emit each section.
## Tests
5 new unit tests in `agent::code::tests::assemble_prompt_tests`:
* `no_policy_no_extras_yields_base_plus_context` — only base + ctx
emitted when all optionals are None
* `policy_appears_before_context_and_instructions` — strict ordering
test (policy < context < instructions < memory)
* `policy_only_omits_other_optional_sections` — instructions / memory
not emitted when their args are None
* `policy_source_path_is_surfaced` — operator can spot origin path
in the heading
* `instructions_only_no_memory_no_policy` — partial-optional case
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.
Summary
Closes PMAT-CODE-ORG-POLICY-RUNTIME-001 — the P2 follow-up from PMAT-CODE-ORG-POLICY-001 that called out: "Prompt-builder integration deferred to PMAT-CODE-ORG-POLICY-RUNTIME-001 (P2)". The primitive shipped 2026-04-18 with 13 unit tests but was never called from
cmd_code.Wiring
build_default_manifestnow callsload_org_policy(canonical_system_roots(), "CLAUDE.md", budget)and prepends the result first in the system prompt under## Enforced organization policy (<source-path>). Order matters:PolicyTier::Enforcedis the highest tier in the precedence lattice, so it must appear BEFORE Project Context / Instructions / Auto-memory.Source path is surfaced in the heading so operators can spot policy origin.
Refactor:
assemble_system_prompthelperExtracted prompt assembly into a pure-function helper so the ordering invariant (policy < context < instructions < memory) is testable without
cwd//etc/ I/O. Each block isOption-wrapped.Test plan
cargo test -p aprender-orchestrate --lib assemble_prompt_tests— 5/5 passcargo fmt -p aprender-orchestrate -- --checkclean/etc/apr-code/CLAUDE.md(loader silently skips missing files)🤖 Generated with Claude Code