Ship doctrine and subagents in CE

Task 10760 · Done · Coder · created · updated

Epic 10745 "Close the identified gaps in Jaah CE". Original request (verbatim): "Close the identified gaps in Jaah CE". Settled inputs: PRD (Task 10746) and Architecture (Task 10747). Requirement and AC ids below are the PRD's; section refs (§) are the Architecture's. Read them with task_read on 10746/10747 if you need more than is quoted here. ## Requirement (verbatim) Operator (Q1, Q5, verbatim): "We also need to move some of the md files that are distributed with the package that are essential for proper jaah functionality" → "Runner doctrine, Runner subagents" + "Memory should be excluded as another paid feature". Architect interview: D4 "We are not moving it, it is just a static subset of the same repo"; D5 "We are not removing anything, we are just selecting what will be mirrored to jaah-ce and what not". R5 — Runner doctrine lives in the product (PRD, verbatim). The md files the dispatch composer needs at runtime ship from a product-owned home inside the shipped tree, not from this management repo's `portfolio/fleet/` and `docs/policies/` paths: `runner-charter.md`, `memory-off.md`, `context-architecture.md`. Single home: one copy only (the management repo points to it; no duplicate). [Realized per D4 as a mirror selection: the monorepo source stays the single home; the tree path is a layout.] R6 — Memory is paid: `memory-on.md` does not ship (PRD, verbatim). Project memory is a cloud feature in the R2 map; its doctrine file is excluded with it. R7 — Runner subagents ship with the product (PRD, verbatim). The subagent definitions the product's prompts name are delivered by CE to every runner session: `recon-explore`, `spec-validator`, `back-translator`, `copy-reviewer`, `translation-reviewer`. cto-only agents (`cto-architect`, `cto-code-reviewer`) do not ship. ## Scope and approach Child C5 of Architecture §7 (Architecture §5). This is a mirror selection: nothing moves (D4/D5). **Manifest (`tools/community_edition/manifest.toml`).** - Add `[[layout]]` entries that map into the public tree's product home `doctrine/`: - `portfolio/fleet/runner-charter.md` → `doctrine/fleet/` - `portfolio/fleet/memory-off.md` → `doctrine/fleet/` - `docs/policies/context-architecture.md` → `doctrine/` - five named includes (no glob), `.claude/agents/{recon-explore,spec-validator,back-translator,copy-reviewer,translation-reviewer}.md` → `doctrine/agents/` - Drop `portfolio/fleet/memory-on.md` from `include` (R6). If C1 has merged, add it to the `project_memory` row's `paths` instead. - Do not include `cto-architect.md` or `cto-code-reviewer.md`. - Confirm `tools/mirror/build.py` supports a single-file layout source mapped to a renamed dir. Extend it (with a test) if not. - The tree must contain no `portfolio/` and no `docs/policies/`. **`infra/community-edition/Dockerfile.api:28-29`.** Replace with `COPY doctrine/fleet/ ./doctrine/fleet/` and `COPY doctrine/context-architecture.md ./doctrine/`. DOCTRINE_ROOT is `/app/doctrine` (`system_prompt.py:40-45`), and the CE Dockerfile is only built from the public tree. **`infra/community-edition/node/stage_bundle.py`.** - Stage `doctrine/agents/` into the node bundle. Take it from the tree, or from `.claude/agents/` via the manifest when staged from the monorepo (the existing dual-source rule). - Install `doctrine/context-architecture.md` at the bundle's relative `docs/policies/` location, so the `roles_build.py:425` pointer resolves. **Claude subagent placement in `apps/jaahd/agents/agent_layer.py` (`place_subagents`).** - Add a Claude branch guarded by `edition.IS_CE`. This is edition-wide: the CE node is its own harness. C1 pre-lists the site key `apps/jaahd/agents/agent_layer.py::place_subagents` in `EDITION_WIDE`, so keep the guard inside `place_subagents`. - At dispatch, the branch copies the bundle's `doctrine/agents/*.md` into the Claude account config dir's `agents/`. - It touches only names it wrote (the existing manifest-of-written-names pattern) and yields to a pre-existing user file of the same name with another hash. - Use bare names (`recon-explore`), not plugin-namespaced ones. - Tests: placement, idempotence, user-file yield, cleanup of a removed name. Cloud delivery (`reconcile.py`, `portable_standard.AGENTS`, `infra/local/Dockerfile.api`) is untouched. Credentials & reach: (Architecture §10 rows, verbatim) - Build, check (incl. gitleaks), tooling + app test suites | worktree only; gitleaks at `~/.local/bin/gitleaks` on node h2 | verified (binary present on h2) - Local CE install from the built tree (AC1.4, AC3.2, AC5.2, AC6.1, AC7.2) | Docker on the coder's node; no registry login (compose `build:` blocks, D3) | verified (`docker` present on h2; C6 re-probes its own node first and, lacking Docker, asks for an h2-class node) - Jaah Deploy watch per child PR | `jaah-forge` read verbs (`pr checks`, `ci log`) | verified (same forge identity and read probe as above) Out of scope: (PRD §3, verbatim — do NOT touch) - MUST NOT make `jaah-ai/jaah-ce` public, change repo visibility, or run a `ce-mirror` publish. - MUST NOT edit LICENSE text or any legal page (legal review is a human item). - MUST NOT edit `docs/pricing.md` or the marketing site (deferred to the flip; not in this repo). - MUST NOT add a second secret scanner (trufflehog etc.). - MUST NOT add an env var, setting, build arg or runtime flag that selects an edition, enables a feature or moves a cap. - MUST NOT change cloud behaviour or cloud plan entitlements/pricing; the R2 guard rewrite is behaviour-preserving for `cloud`. - MUST NOT ship `.claude/skills/` (translate, marketing-copy) — named a deferred follow-up below. - MUST NOT build an on-prem or enterprise edition — only make the map able to describe one. Architecture boundaries: - D4, D5: no monorepo file moves. `portfolio/fleet/*.md`, `docs/policies/context-architecture.md`, `.claude/agents/*.md`, hub pointers, `tools/check_context.py`, `tools/portable_standard.py`, `infra/local/Dockerfile.api` and `infra/host/fleet-harness/reconcile.py` stay untouched. - D1: keep schema, strip logic. No edition-forked schema, no new migration. Done means: - AC5.1 → verify: built tree contains the three files under the product home; `portfolio/` and `docs/policies/` are absent from the tree. - AC5.2 (image side) → verify: `Dockerfile.api` copies from the product home. The CE api image builds from the built tree (`docker build -f infra/community-edition/Dockerfile.api $T`), and `/app/doctrine/fleet/runner-charter.md` exists in it. (The installed-CE transcript observation, the "Runner Charter" heading in a dispatched task's system prompt, is C6's.) - AC5.3 → verify: `python3 tools/check_context.py` green in the monorepo (no orphan, no duplicate, every router row resolves). - AC6.1 (tree side) → verify: built tree has no `memory-on.md`. (The dispatch-content check is C6's.) - AC7.1 → verify: built tree contains those five definitions under the product home; not the two cto ones. - jaahd placement tests green: - a CE-mode dispatch writes the five agent files into the account's `agents/` dir; - a cloud-mode dispatch writes none; - a user's own same-named file is left untouched. - Quick gate `./dc check quick` green. - `python3 tools/community_edition/build_tree.py $T && python3 tools/community_edition/check_tree.py $T` exits 0 (AC1.2: import closure intact). - The PR's Jaah Deploy on GitHub succeeds. If not, fix it and re-merge; leave a cancelled or superseded deploy alone.

Outcome

CE tree ships doctrine/ (charter, memory-off, context-arch) + 5 subagents; memory-on and cto agents excluded; Dockerfile.api/stage_bundle use doctrine/; CE Claude placement of subagents. Quick gate, CE suite, image check green; PR #7165 queued. Memory: none applied.

Pull request

Artifacts

Activity

  • Draft
  • Ready
  • Runner started
  • Runner ended (done)