297 lines
7.7 KiB
Markdown
297 lines
7.7 KiB
Markdown
# Context Handoff in Orquestra
|
|
|
|
Orquestra keeps agents focused by making context explicit. Agents do not pass a whole chat history to the next agent. They pass durable artifacts on disk, and each new stage reads only the files declared for that stage.
|
|
|
|
## Quick path
|
|
|
|
1. The current agent writes its result to `work/artifacts/<feature_id>/`.
|
|
2. From the active Pi session, `/orquestra-stage <stage> [feature_id]` calls `scripts/run_stage.py`.
|
|
3. `run_stage.py` starts a fresh Pi process.
|
|
4. The new agent receives only the `input` paths declared in `harness/workflow.stages.yml`.
|
|
5. The new agent writes its own output artifact.
|
|
6. `scripts/agent_status.py` and `scripts/verify.sh` enforce stage order and gates.
|
|
7. When the `close` stage completes, `scripts/close_feature.py <feature_id>` runs automatically to validate gates, update the backlog, commit and push if a remote repo is configured.
|
|
|
|
## Mental model
|
|
|
|
```text
|
|
Agent A
|
|
reads its stage inputs
|
|
writes one durable artifact
|
|
│
|
|
▼
|
|
work/artifacts/F-001/agent-a-output
|
|
│
|
|
▼
|
|
run_stage.py starts a fresh Pi process
|
|
│
|
|
▼
|
|
Agent B
|
|
reads only declared inputs, including Agent A's artifact if relevant
|
|
writes its own artifact
|
|
```
|
|
|
|
The agents “talk” through files, not through memory-heavy chat context.
|
|
|
|
## Why fresh processes matter
|
|
|
|
A single long Pi session naturally accumulates chat, tool output, false starts, and old assumptions. That causes two problems:
|
|
|
|
| Problem | Orquestra answer |
|
|
|---|---|
|
|
| The next agent gets distracted by old context | Start the next stage with `--no-session --no-context-files` |
|
|
| Token usage grows until compaction | Each stage starts with a small prompt and declared files |
|
|
| Claims become hard to verify | Only artifacts on disk count as handoff evidence |
|
|
| Agents can skip gates in chat | `agent_status.py` validates stage owner and prerequisites |
|
|
|
|
## What a stage receives
|
|
|
|
Each stage receives three kinds of context:
|
|
|
|
1. **Harness rules** — always read first.
|
|
- `AGENTS.md`
|
|
- `harness/agents.matrix.yml`
|
|
- `harness/workflow.stages.yml`
|
|
- `harness/contracts/handoff.md`
|
|
|
|
2. **Declared stage inputs** — from `harness/workflow.stages.yml`.
|
|
|
|
3. **Selected Engram memory** — only when the agent performs a narrow search for a concrete need.
|
|
|
|
The full previous chat is not valid input.
|
|
|
|
## Example: design to build
|
|
|
|
`architect` receives product/spec context:
|
|
|
|
```yaml
|
|
- name: design
|
|
owner: architect
|
|
input:
|
|
- work/current.md
|
|
- spec/product.md
|
|
- spec/tech.md
|
|
- spec/acceptance.md
|
|
output:
|
|
- work/artifacts/<feature_id>/architect.md
|
|
```
|
|
|
|
It writes:
|
|
|
|
```text
|
|
work/artifacts/F-001/architect.md
|
|
```
|
|
|
|
Then `implementer` starts fresh from the active Pi session:
|
|
|
|
```text
|
|
/orquestra-stage build F-001
|
|
```
|
|
|
|
Equivalent shell form:
|
|
|
|
```bash
|
|
python3 scripts/run_stage.py build --feature-id F-001
|
|
```
|
|
|
|
The generated prompt gives it only:
|
|
|
|
```yaml
|
|
- name: build
|
|
owner: implementer
|
|
input:
|
|
- work/current.md
|
|
- spec/product.md
|
|
- spec/tech.md
|
|
- spec/acceptance.md
|
|
- work/artifacts/<feature_id>/architect.md
|
|
output:
|
|
- work/artifacts/<feature_id>/implementer.md
|
|
```
|
|
|
|
So the implementer knows the design result, but not the architect's full chat.
|
|
|
|
## Example: build to review
|
|
|
|
The implementer writes evidence:
|
|
|
|
```text
|
|
work/artifacts/F-001/implementer.md
|
|
```
|
|
|
|
A minimal implementer artifact should answer:
|
|
|
|
```markdown
|
|
# Implementer Evidence
|
|
|
|
## Changed files
|
|
- project/app.py
|
|
- tests/test_app.py
|
|
|
|
## What changed
|
|
- Added ticket creation validation.
|
|
|
|
## Checks
|
|
- `python3 -m unittest discover -s tests -v` passed.
|
|
|
|
## Notes for reviewer
|
|
- Main behavior lives in `project/app.py:create_ticket`.
|
|
```
|
|
|
|
Then reviewer starts fresh:
|
|
|
|
```text
|
|
/orquestra-stage review_gate F-001
|
|
```
|
|
|
|
Reviewer input is only:
|
|
|
|
```yaml
|
|
input:
|
|
- work/current.md
|
|
- spec/acceptance.md
|
|
- work/artifacts/<feature_id>/implementer.md
|
|
```
|
|
|
|
Reviewer does not need the architect's whole reasoning unless the workflow explicitly declares it. If reviewer needs more, it blocks and asks for a specific artifact/path.
|
|
|
|
## Example: security and QA reuse only relevant context
|
|
|
|
Security does not need all acceptance prose plus every design note. It needs the implementation evidence and review result:
|
|
|
|
```yaml
|
|
- name: security_gate
|
|
owner: security
|
|
input:
|
|
- work/current.md
|
|
- work/artifacts/<feature_id>/implementer.md
|
|
- work/artifacts/<feature_id>/reviewer.json
|
|
```
|
|
|
|
QA needs acceptance criteria and approved gate context:
|
|
|
|
```yaml
|
|
- name: qa_gate
|
|
owner: qa
|
|
input:
|
|
- work/current.md
|
|
- spec/acceptance.md
|
|
- work/artifacts/<feature_id>/implementer.md
|
|
- work/artifacts/<feature_id>/reviewer.json
|
|
- work/artifacts/<feature_id>/security.json
|
|
```
|
|
|
|
That is the core rule: give each agent the smallest context that lets it do its job.
|
|
|
|
## Anti-cheating controls
|
|
|
|
```text
|
|
run_stage.py
|
|
├─ starts fresh Pi process
|
|
├─ disables previous session/context files
|
|
└─ injects only declared input/output paths
|
|
|
|
agent_status.py
|
|
├─ validates stage owner
|
|
├─ requires feature_id for real stages
|
|
├─ rejects gated stages when prerequisite artifacts are missing
|
|
└─ keeps visible runtime status
|
|
|
|
orquestra-status extension
|
|
├─ blocks writes outside allowed directories: project/, tests/, work/, backlog/, spec/, harness/, scripts/, platforms/, docs/
|
|
├─ blocks product/test writes outside implementer build stage
|
|
└─ blocks product code in repository root
|
|
|
|
verify.sh
|
|
├─ validates harness structure
|
|
├─ validates backlog/runtime JSON
|
|
├─ validates Engram availability
|
|
└─ rejects done features without approved gate artifacts
|
|
```
|
|
|
|
Chat-only claims do not pass any gate. The agent must write evidence to disk.
|
|
|
|
## Ticket lifecycle commands
|
|
|
|
Do not edit `backlog/features.json` directly. Use the repository scripts:
|
|
|
|
```bash
|
|
# Create a pending ticket interactively.
|
|
python3 scripts/new_ticket.py
|
|
|
|
# Select exactly one pending ticket and promote it to in_progress.
|
|
python3 scripts/new_ticket.py --start F-048
|
|
|
|
# Repair the deprecated `review` gate key in imported/legacy tickets.
|
|
python3 scripts/new_ticket.py --normalize-gates
|
|
|
|
# After reviewer, security and QA approve, close and commit the ticket.
|
|
python3 scripts/close_feature.py F-048
|
|
```
|
|
|
|
`--start` refuses to run when another feature is already `in_progress`. `verify.sh` also rejects a runtime marked `running` when the matching backlog feature is still `pending`.
|
|
|
|
## What Engram is for
|
|
|
|
Engram is durable memory for reusable facts, not a replacement for stage artifacts.
|
|
|
|
Each stage must save to Engram only when it produced durable knowledge.
|
|
|
|
Use Engram for:
|
|
|
|
- stable project decisions,
|
|
- bug fixes,
|
|
- non-obvious discoveries,
|
|
- reusable conventions or patterns,
|
|
- configuration changes,
|
|
- repeated gotchas,
|
|
- environment facts,
|
|
- lessons learned across features.
|
|
|
|
Do not use Engram for:
|
|
|
|
- replacing `implementer.md`,
|
|
- hiding gate evidence,
|
|
- routine progress,
|
|
- command output dumps,
|
|
- artifact summaries,
|
|
- passing huge summaries to every stage,
|
|
- bypassing declared workflow inputs.
|
|
|
|
A good Engram lookup is narrow:
|
|
|
|
```text
|
|
Search: "orquestra project root product files rule"
|
|
Use result only if it affects this stage.
|
|
```
|
|
|
|
A bad lookup is broad:
|
|
|
|
```text
|
|
Search: "everything about this project"
|
|
```
|
|
|
|
## Updating an installed project safely
|
|
|
|
From the Orquestra source checkout:
|
|
|
|
```bash
|
|
/path/to/orquestra/scripts/install.sh /path/to/project
|
|
cd /path/to/project
|
|
./scripts/verify.sh
|
|
```
|
|
|
|
The installer updates harness-owned files and preserves project-owned progress files when they already exist:
|
|
|
|
```text
|
|
backlog/features.json
|
|
spec/*
|
|
work/current.md
|
|
work/history.md
|
|
work/runtime-status.json
|
|
project/*
|
|
work/artifacts/*
|
|
```
|
|
|
|
That means an existing project can adopt fresh-stage handoff without losing its current feature state.
|