Research brief

Personal Orchestrator Compound Action Spine Implementation Plan

Business model, technical architecture, product lessons, and strategic implications.

Personal Orchestrator Compound Action Spine Implementation Plan

For Hermes: Use compound-work or subagent-driven-development to implement this plan task-by-task. Treat this as the source-of-truth implementation contract for upgrading the Personal Orchestrator Action Manager card template and routing behavior.

Date: 2026-05-27

Source prompt: Connor asked for an implementation-ready plan for making the Personal Orchestrator use Hermes Compound Engineering as its “action spine”: detect candidate work, classify altitude, make vague nudges approvable, autonomously do safe local work, ask only at true decision gates, review before surfacing done, and capture learning.

Related proof: Prior quick consult: /root/personal-orchestrator/consults/2026-05-27T20-28-31.779665-00-00/CONSULT.md

Goal: Upgrade the Personal Orchestrator so every action proposal is routed through a Compound Engineering phase and rendered as an approval-ready card with problem, why now, implementation outline, autonomy lane, risk, done condition, and proof path.

Architecture: Keep the existing Personal Orchestrator faculty/synthesis pipeline. Add a thin Compound Action Spine inside/near runners/action_manager.py: normalize candidate cards, classify them into strategy | brainstorm | plan | work | review | learn, enrich the rendered card fields, route safe local work autonomously, and require proof/review before any “done” surface. Do not make PO busy; suppression remains a first-class action.

Tech stack / surfaces: Python, pytest, markdown/JSON artifacts under /root/personal-orchestrator/runs/*, Action Manager in runners/action_manager.py, tests in tests/test_action_manager.py, delegation/lifecycle state under state/ and delegations/.


Requirements

R-001: Detect candidate work from existing faculties and sources

PO must continue taking candidate work from existing faculty and synthesis outputs: Open Tabs, cron outputs, Gmail/calendar context assets, GBrain/context assets, feedback ledger, source health, and collaborator synthesis.

R-002: Classify Compound Engineering altitude

Every action candidate must include one compound_phase:

  • strategy — clarify direction, principles, tradeoffs, priorities.
  • brainstorm — explore options when solution space is under-shaped.
  • plan — create a traceable implementation/spec/delegation plan.
  • work — execute a bounded safe task or queue a goal packet.
  • review — audit correctness, evidence, risk, noise, or proof.
  • learn — convert repeated patterns into skills, templates, source adapters, or durable memory.

R-003: Make vague nudges approvable

Every surfaced proposal must render these fields:

  • Problem being solved.
  • Why now.
  • Proposed implementation outline.
  • Compound phase.
  • Autonomy lane.
  • Risk class.
  • Done condition.
  • Proof path / proof requirement.
  • Evidence/source refs.
  • Stop conditions / approval gates.

R-004: Autonomously do safe local work

For low-risk local candidates, PO may act without asking by creating local artifacts only:

  • diagnostic notes;
  • draft specs;
  • repair notes;
  • local proof/status logs;
  • queued delegation packets;
  • local candidate implementation plans;
  • source-near adapter proposals.

It must not silently send messages, mutate email/calendar/finance, publish externally, delete data, deploy, or make irreversible changes.

R-005: Ask only at true decision gates

The card must require approval for:

  • external side effects;
  • finance/email/calendar/messaging;
  • destructive changes;
  • deployments;
  • ambiguous priorities;
  • changes to user-facing behavior with meaningful risk;
  • anything with insufficient evidence.

R-006: Review before “done”

No candidate should be marked done unless the proof packet exists and a review gate has passed. For this implementation, the minimum review is an Action Manager self-check; for higher-risk cards, compound-review is required.

R-007: Capture learning

Repeated successful repairs or repeated noisy proposals should route to learn and produce one of:

  • Hermes skill patch proposal;
  • card template update proposal;
  • source adapter rule;
  • suppression heuristic;
  • GBrain fact candidate;
  • Faculty Experience Ledger entry.

R-008: Preserve suppression as intelligent action

The Action Manager must still suppress low-impact, duplicate, weak-evidence, or already-delegated cards. “No action” is allowed and should be explained when useful.


Non-goals

  • Do not rewrite the full Personal Orchestrator architecture.
  • Do not run a new full-faculty E2E pass just to implement the template upgrade.
  • Do not mutate external systems.
  • Do not publish private/raw context assets.
  • Do not force every card into action; suppression remains valid.
  • Do not create opaque card IDs as the only UX; natural-language feedback and numbered nudges should continue to work.

Current implementation findings

Relevant existing surfaces:

  • runners/action_manager.py
  • ActionCandidate currently has fields such as action_id, source_card_id, title, action_class, routing_lane, risk_class, status, evidence, expected_benefit, done_condition, proof_required, scores, capability_id, and routing_rationale.
  • It already models routing lanes (suppress, remember, ask, suggest, draft, local_safe_work, delegate, modify_local_system, approval_required_external) and risk classes.
  • It already renders # Action Manager markdown.
  • tests/test_action_manager.py
  • Existing tests cover lane mapping, external approval gating, suppression, capability registry rendering, lifecycle events, and proof rendering.
  • IMPLEMENTATION_STATUS.md
  • Confirms Action Manager artifacts are emitted and tested in prior smoke checks.

The implementation can therefore be incremental: enrich schema/rendering/classification rather than replacing the pipeline.


Implementation units

U-001: Add Compound phase vocabulary and validation

Goal: Make Compound Engineering phase a first-class field on every ActionCandidate.

Traces to: R-002, R-003

Files:

  • Modify: /root/personal-orchestrator/runners/action_manager.py
  • Modify: /root/personal-orchestrator/tests/test_action_manager.py

Steps:

  1. Add constant:
COMPOUND_PHASES = {"strategy", "brainstorm", "plan", "work", "review", "learn"}
  1. Add compound_phase: str = "work" to ActionCandidate.

  2. Validate in ActionCandidate.__post_init__:

_validate_choice("compound_phase", self.compound_phase, COMPOUND_PHASES)
  1. Ensure to_dict() includes compound_phase automatically via asdict.

  2. Add test: a candidate created from a local diagnostic card defaults to work or the inferred phase.

Acceptance: pytest tests/test_action_manager.py -q passes and JSON candidates include compound_phase.


U-002: Implement phase inference from card content and lane

Goal: Route candidate altitude automatically when upstream cards do not provide it.

Traces to: R-002, R-003, R-008

Files:

  • Modify: /root/personal-orchestrator/runners/action_manager.py
  • Modify: /root/personal-orchestrator/tests/test_action_manager.py

Recommended helper:

def infer_compound_phase(card: dict, *, action_class: str, routing_lane: str, title: str) -> str:
    explicit = str(card.get("compound_phase") or card.get("workflow_phase") or "").strip().lower()
    if explicit in COMPOUND_PHASES:
        return explicit
    text = " ".join(str(x or "") for x in [title, card.get("claim"), card.get("done_condition"), card.get("evidence")]).lower()
    if routing_lane == "suppress":
        return "review"
    if "skill" in text or "template" in text or "learn" in text or "repeated" in text:
        return "learn"
    if "review" in text or "audit" in text or "verify" in text or "proof" in text:
        return "review"
    if "plan" in text or "spec" in text or "requirements" in text or "implementation" in text:
        return "plan"
    if "option" in text or "brainstorm" in text or "explore" in text:
        return "brainstorm"
    if "strategy" in text or "principle" in text or "priority" in text or "direction" in text:
        return "strategy"
    return "work" if routing_lane in {"local_safe_work", "delegate", "modify_local_system"} else "plan"

Tests:

  • “write implementation plan” → plan.
  • “audit proof packet” → review.
  • “patch repeated pattern into skill/template” → learn.
  • Suppressed low-value card → review.
  • Explicit compound_phase wins.

Acceptance: Phase inference is deterministic and covered by tests.


U-003: Enrich ActionCandidate with approvable card fields

Goal: Every card has enough detail for Connor to approve without asking “what exactly would happen?”

Traces to: R-003, R-005

Files:

  • Modify: /root/personal-orchestrator/runners/action_manager.py
  • Modify: /root/personal-orchestrator/tests/test_action_manager.py

Fields to add:

problem: str = ""
why_now: str = ""
implementation_outline: str = ""
approval_gate: str = ""
proof_path: str = ""

Normalization rules:

  • problem: use upstream problem, else derive from claim/title.
  • why_now: use upstream why_now, else concise evidence-based sentence.
  • implementation_outline: use upstream implementation_outline, else phase-specific default.
  • approval_gate: derive from risk/lane; “No approval needed for local artifact only” for safe local work; explicit approval for external/destructive/ambiguous work.
  • proof_path: use upstream proof_path, else local artifact path expectation such as runs/<run_id>/ACTION_MANAGER.md or delegation proof path.

Acceptance: Rendered markdown includes all fields for every non-suppressed surfaced candidate.


U-004: Upgrade markdown rendering to approval-ready card format

Goal: Make PO output cards immediately actionable and readable.

Traces to: R-003, R-005, R-006

Files:

  • Modify: /root/personal-orchestrator/runners/action_manager.py
  • Modify: /root/personal-orchestrator/tests/test_action_manager.py

Rendering shape:

The rendered card should look like this:

  • Heading: candidate title.
  • Metadata: action id, compound phase, autonomy lane, risk, status.
  • Body fields: problem, why now, implementation outline, done condition, proof required, proof path, approval gate, evidence, and score summary.

Do not rely on an opaque card id alone; the rendered card must explain what would happen and how it will be proven.

Tests: Extend test_action_manager_render_includes_scores_and_proof to assert the markdown contains Problem, Why now, Implementation outline, Compound phase, Autonomy lane, Approval gate, and Proof path.

Acceptance: Existing and new tests pass; rendered ACTION_MANAGER.md can be read as an approval queue.


U-005: Add safe-local-work artifact/delegation packet stub

Goal: Allow low-risk local candidates to move beyond suggestion into prepared local action without side effects.

Traces to: R-004, R-005, R-006

Files:

  • Modify: /root/personal-orchestrator/runners/action_manager.py or add /root/personal-orchestrator/runners/action_spine.py
  • Modify/Add tests in /root/personal-orchestrator/tests/

Behavior:

For candidates with:

  • risk_class == "low-risk"; and
  • routing_lane in {"local_safe_work", "delegate"}; and
  • compound_phase in {"plan", "work", "review", "learn"}

create a local proof/prep artifact, not external execution:

runs/<run_id>/action_spine/<action_id>/goal.md
runs/<run_id>/action_spine/<action_id>/status.json
runs/<run_id>/action_spine/<action_id>/proof.md

goal.md must include objective, source evidence, boundaries, acceptance criteria, validation command, and reporting expectations.

Safety rule: If candidate is external/destructive/ambiguous, write only an approval-needed card; do not create execution artifacts beyond a proposal.

Acceptance: Test creates a temp run directory and verifies safe local candidate writes goal/status/proof stubs; external candidate does not.


U-006: Add review gate before marking done

Goal: Prevent PO from claiming completed work without proof.

Traces to: R-006

Files:

  • Modify: /root/personal-orchestrator/runners/action_manager.py or lifecycle helper.
  • Modify: /root/personal-orchestrator/tests/test_action_manager.py or tests/test_action_lifecycle_linkage.py.

Behavior:

Add helper:

def can_mark_done(candidate: ActionCandidate, *, proof_exists: bool, review_status: str = "") -> tuple[bool, str]:
    if not proof_exists:
        return False, "missing proof packet"
    if candidate.risk_class != "low-risk" and review_status != "passed":
        return False, "review gate required"
    return True, "done gate passed"

Acceptance: Tests show missing proof blocks done; high-risk card requires passed review; low-risk with proof can pass.


U-007: Route repeated patterns to learning artifacts

Goal: Convert repeated repairs/noisy suggestions into durable learning instead of recurring nudges.

Traces to: R-007, R-008

Files:

  • Modify: /root/personal-orchestrator/runners/action_manager.py
  • Potentially add: /root/personal-orchestrator/docs/templates/compound-learn-card.md
  • Tests in /root/personal-orchestrator/tests/test_action_manager.py

Behavior:

If card evidence/title mentions repeated pattern, template, skill, source adapter, suppression heuristic, or Connor feedback cluster:

  • infer compound_phase = "learn";
  • set implementation_outline to a learning artifact proposal;
  • set proof requirement to “skill/template/source-adapter patch proposal exists and cites source feedback.”

Acceptance: Test repeated-card fixture maps to learn and renders learning-specific proof.


U-008: Wire Action Manager output into latest run artifacts

Goal: Ensure PO runs emit the upgraded card format and optional local action spine artifacts.

Traces to: R-001 through R-008

Files:

  • Inspect/modify: /root/personal-orchestrator/runners/observability_run.py
  • Inspect/modify: /root/personal-orchestrator/runners/consult.py if consult surfaces Action Manager cards.
  • Tests: /root/personal-orchestrator/tests/test_observability_run.py and/or existing Action Manager tests.

Steps:

  1. Locate where ACTION_CANDIDATES.json and ACTION_MANAGER.md are written.
  2. Ensure new candidate fields are serialized.
  3. Ensure markdown render includes new card fields.
  4. If local action spine stubs are enabled, write them under the current run directory.
  5. Do not break existing synthesis.json consumers; add fields backward-compatibly.

Acceptance: Smoke command emits upgraded markdown and JSON:

cd /root/personal-orchestrator
python3 runners/action_manager.py \
  --synthesis runs/latest/synthesis.json \
  --out-json /tmp/action-candidates-compound-spine.json \
  --out-md /tmp/action-manager-compound-spine.md

Expected:

  • command exits 0;
  • markdown contains Compound phase, Problem, Why now, Implementation outline, Approval gate, Proof path;
  • JSON contains compound_phase for every candidate.

U-009: Add docs and operator notes

Goal: Make future agents understand the Action Spine behavior.

Traces to: all requirements

Files:

  • Update: /root/personal-orchestrator/IMPLEMENTATION_STATUS.md
  • Add/update: /root/personal-orchestrator/docs/action-spine.md
  • Optional update: relevant Hermes skill or PO faculty reference if implementation reveals reusable workflow.

Docs must cover:

  • Compound phase definitions.
  • Autonomy lane rules.
  • Approval gates.
  • Proof packet expectations.
  • Safe local work boundaries.
  • How Connor can approve: natural language, do 1, do_this, etc.
  • Suppression/no-action as intelligent behavior.

Acceptance: Docs cite tests and smoke command outputs.


Verification commands

Run from /root/personal-orchestrator:

python3 -m pytest tests/test_action_manager.py -q
python3 -m pytest tests/test_action_lifecycle_linkage.py tests/test_delegation_backlog.py -q
python3 runners/action_manager.py --synthesis runs/latest/synthesis.json --out-json /tmp/action-candidates-compound-spine.json --out-md /tmp/action-manager-compound-spine.md
python3 - <<'PY'
import json, pathlib
rows = json.loads(pathlib.Path('/tmp/action-candidates-compound-spine.json').read_text())
items = rows.get('candidates', rows if isinstance(rows, list) else [])
assert items, 'no candidates emitted'
for row in items:
    assert row.get('compound_phase'), row
md = pathlib.Path('/tmp/action-manager-compound-spine.md').read_text()
for term in ['Compound phase', 'Problem', 'Why now', 'Implementation outline', 'Approval gate', 'Proof path']:
    assert term in md, term
print('compound action spine smoke ok')
PY

If runs/latest/synthesis.json has no candidates, use a fixture synthesis file or add a unit test fixture rather than weakening the assertions.


Review gate

Review level: Tier 2 (compound-review) because this changes the PO action-routing surface and could increase noisy/autonomous work if implemented poorly.

Review lenses:

  1. Correctness: Every card gets valid phase/lane/risk/proof fields.
  2. Actionability: A human can approve/reject without asking for missing implementation details.
  3. Safety: External/destructive/ambiguous work cannot run without approval.
  4. Noise suppression: Low-value cards are suppressed or batched; action spine does not create busywork.
  5. Proof: Done requires proof packet and review gate.
  6. Backward compatibility: Existing synthesis/action consumers still read JSON.

Parallelization

Safe to parallelize:

  • U-001/U-002 schema + inference with tests.
  • U-004 rendering once U-001 field names are agreed.
  • U-009 docs after schema names stabilize.

Do not parallelize:

  • U-003 and U-004 if both touch the same render function.
  • U-005 and U-008 until artifact paths are agreed.
  • U-006 until lifecycle status semantics are confirmed.

Stop conditions

Stop and ask Connor before continuing if:

  • implementation requires sending messages, changing calendar/email/finance, publishing private PO outputs, or deploying services;
  • existing Action Manager semantics conflict with this plan in a way that would break current nudges;
  • test fixtures show all candidates become action/work and suppression disappears;
  • the system starts creating opaque busywork artifacts without a clear proof path;
  • the plan would require rewriting the full faculty/synthesis pipeline.

Expected final proof packet

Implementation is done when the executor can point to:

  • code diff for runners/action_manager.py and related wiring;
  • tests added/updated;
  • passing pytest output;
  • smoke output files under /tmp/ or a real run directory;
  • one rendered ACTION_MANAGER.md example showing approval-ready fields;
  • one safe-local-work goal/proof stub example;
  • review notes from compound-review;
  • updated docs/status file.

Implementation-ready delegation prompt

Use this prompt if delegating to a fresh agent:

Objective: Implement the Personal Orchestrator Compound Action Spine plan at /root/personal-orchestrator/docs/plans/2026-05-27-compound-action-spine-plan.md.

Done state: Action Manager candidates include compound_phase, problem, why_now, implementation_outline, approval_gate, proof_path; rendered cards are approval-ready; safe local work can create local proof/delegation stubs only; done transitions require proof/review; tests and smoke checks pass.

Boundaries: Work only under /root/personal-orchestrator unless explicitly approved. Do not send external messages, mutate calendar/email/finance, deploy, delete data, or publish private run artifacts. Preserve existing unrelated changes. Keep JSON backward-compatible.

Verification: Run the exact pytest and smoke commands in the plan. Save proof paths and command output in a status/proof artifact. Finish with a concise report listing files changed, tests run, proof paths, and any blocked items.

Detected source links

  1. No external source links detected.