Skip to content

feat(apr-code): wire org_policy into build_default_manifest (PMAT-CODE-ORG-POLICY-RUNTIME-001)#1573

Merged
noahgift merged 18 commits into
mainfrom
feat/apr-code-org-policy-runtime
May 13, 2026
Merged

feat(apr-code): wire org_policy into build_default_manifest (PMAT-CODE-ORG-POLICY-RUNTIME-001)#1573
noahgift merged 18 commits into
mainfrom
feat/apr-code-org-policy-runtime

Conversation

@noahgift
Copy link
Copy Markdown
Contributor

@noahgift noahgift commented May 7, 2026

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_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.

Source path is surfaced in the heading so operators can spot policy origin.

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. Each block is Option-wrapped.

Test plan

  • cargo test -p aprender-orchestrate --lib assemble_prompt_tests — 5/5 pass
  • cargo fmt -p aprender-orchestrate -- --check clean
  • No behavior change on hosts without /etc/apr-code/CLAUDE.md (loader silently skips missing files)

🤖 Generated with Claude Code

…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>
@noahgift noahgift enabled auto-merge (squash) May 7, 2026 17:14
@noahgift noahgift merged commit 036fa7b into main May 13, 2026
10 checks passed
@noahgift noahgift deleted the feat/apr-code-org-policy-runtime branch May 13, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant