Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .agent/AGENT_CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,31 @@ A chat activates exactly one role at a time. The role contract determines what t
1. Current explicit human instruction
2. Repository Agent Contract under `.agent/`
3. Repository Map / Decision / Spec and other approved design records
4. Assigned GitHub Issue and its accepted updates
5. Current chat context
4. Assigned GitHub Issue / PR and their accepted durable updates
5. Current chat context / handoff text
6. Historical chat context

A higher-priority source may clarify or supersede a lower-priority source, but it does not automatically grant a role permission that the role contract forbids. If a human asks a role to perform work outside its contract, the agent should identify the required handoff unless the human explicitly changes the active role or role contract.

## Shared invariants

- GitHub is the authoritative project state for durable decisions, Issues, PRs, code, and review evidence.
- GitHub is the authoritative project state for durable decisions, Issues, PRs, code, findings, and review evidence.
- Each chat must declare one `ACTIVE_ROLE` before doing repository-changing work.
- Agents must read the current role contract before acting.
- Agents must not silently cross role boundaries.
- Repository state must be checked before repository-changing work.
- Before writing durable repository content, determine the target repository's visibility and applicable information boundary.
- Never expose private-repository names, URLs, paths, Issue/PR identifiers, branch names, internal artifact names, or other private-source metadata in a public repository unless the human owner explicitly approves that disclosure.
- Public repository records must be self-contained and should reference only public artifacts or information intentionally approved for disclosure. Private-source provenance or traceability must remain in an approved private durable location.
- Durable-first requirements never override repository visibility or confidentiality boundaries; when material context is private, persist it privately and expose only the public-safe resulting decision, specification, evidence, or status in the public repository.
- Existing ownership, active PRs, branches, and conflicting work must be checked before implementation.
- Implementation Agents must not approve or merge their own implementation.
- Review and Security findings must remain independent from the implementation that produced the change.
- Acceptance criteria must not be silently weakened to make work pass.
- Material uncertainty, unresolved conflicts, secret exposure, destructive changes, or required product decisions must be escalated.
- Material project information must be persisted to durable repository state and must not exist only in a chat handoff.
- Agent-to-Agent handoffs are structural workflow transitions defined by `.agent/HANDOFF_PROTOCOL.md`; they are not substitutes for Issue / PR / Spec evidence.
- A receiving Agent must reconstruct current context from GitHub during Bootstrap rather than relying on copied handoff narrative.
- A role declaration is a policy boundary, not merely a descriptive label.

## Domain model
Expand Down
76 changes: 54 additions & 22 deletions .agent/BOOTSTRAP.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# Agent Bootstrap Protocol

Every agent chat must perform this bootstrap before substantive repository work.
version: 3

Every Agent chat must perform this bootstrap before substantive repository work.

## 1. Identify execution context

Confirm:

- `ACTIVE_ROLE`
- role contract path
- Role Contract path
- project/repository
- target repository visibility (`public` / `private`) before any write
- assigned Issue(s), if any
- referenced PR / handoff, if any
- `DOMAIN`, according to the active Role's Domain mode

Domain modes are defined in `.agent/AGENT_CATALOG.md` and `.agent/roles.yaml`:
Expand All @@ -18,7 +22,7 @@ Domain modes are defined in `.agent/AGENT_CATALOG.md` and `.agent/roles.yaml`:
- `optional`: `DOMAIN` may be present; omission means cross-domain operation within the same Role.
- `forbidden`: `DOMAIN` must not be present.

If the role is missing or ambiguous, do not infer a privileged role from the requested action. If Domain usage conflicts with the active Role's Domain mode, classify the start state as `BLOCKED_ROLE_BOUNDARY` until the activation is corrected.
If the Role is missing or ambiguous, do not infer a privileged Role from the requested action. If Domain usage conflicts with the active Role's Domain mode, classify the start state as `BLOCKED_ROLE_BOUNDARY` until activation is corrected.

## 2. Load policy

Expand All @@ -29,47 +33,73 @@ Read:
3. `.agent/HANDOFF_PROTOCOL.md`
4. relevant Map / Decision / Spec / Task records

For long-running chats, re-read the role contract when the repository indicates that it changed.
For long-running chats, re-read the Role Contract only after recovery, an explicit Role change, or when repository state indicates the contract changed.

## 3. Reconstruct context from a handoff

When the chat is started or resumed from a handoff:

1. Parse the structural handoff fields only: `FROM`, `TO`, optional `DOMAIN`, `ISSUE`, optional `PR`, optional `HEAD`, and `STATE`.
2. Treat the handoff as a transition pointer, not as project evidence.
3. Fetch the referenced Issue and its latest durable comments/state.
4. Fetch the referenced PR when present, including the current head, diff/review state, and relevant checks/evidence.
5. If `HEAD` is present, compare it with the current PR head.
6. Read relevant approved Spec / Decision / Acceptance Criteria and any referenced durable findings.
7. Derive the current actionable state from GitHub rather than from stale chat history.

## 3. Inspect current repository state
If the current PR head differs from `HANDOFF.HEAD`, classify the handoff as stale. Do not assume the original transition still applies. Inspect the latest durable state and determine the current disposition before acting.

Material context that exists only in a chat handoff must not be treated as a substitute for repository evidence. If required material information is missing from durable state, record or request that deficiency rather than relying on transient chat text.

## 4. Inspect current repository state and information boundary

Before repository-changing work, inspect the relevant current state:

- assigned Issue and recent comments
- related PRs
- active branches or ownership markers when available
- prerequisite Issues / PRs
- CI/check status when relevant
- recent changes that may invalidate the task context
- repository visibility (`public` or `private`);
- assigned Issue and recent comments;
- related PRs and exact current head;
- active branches or ownership markers when available;
- prerequisite Issues / PRs;
- CI/check status when relevant;
- durable Review / Security / Human Gate findings;
- recent changes that may invalidate the task context.

Before any GitHub write, apply the repository visibility boundary defined by `.agent/AGENT_CATALOG.md`:

- do not copy private-repository names, URLs, paths, Issue/PR identifiers, branch names, internal artifact names, or other private-source metadata into a public repository without explicit human approval;
- when public work is derived from a private source, write only the public-safe resulting decision, specification, evidence, or status to the public repository;
- keep private provenance/traceability in an approved private durable location;
- durable-first does not mean that private material should be moved into a public repository.

Do not rely on stale chat summaries when GitHub contains newer state.
Prefer current GitHub state over handoff text, chat summaries, or historical context.

## 4. Check ownership and collision risk
## 5. Check ownership and collision risk

For implementation work, verify that:

- the Issue is not already owned by another active agent unless collaboration is explicit;
- the Issue is not already owned by another active Agent unless collaboration is explicit;
- there is no conflicting PR implementing the same task;
- the intended files/domain do not materially overlap another active task without coordination;
- prerequisites are satisfied.

For optional-Domain Roles, treat `DOMAIN` as the primary specialist focus. Inspect adjacent domains when needed to perform the Role correctly, but do not silently take ownership of another Agent/domain's work.

If collision risk is material, stop mutation and hand off to Integration when it concerns repository integration/dependencies, or request a human decision. If an external Control Plane owns runtime coordination, follow its durable coordination state instead of creating a separate ChatGPT Supervisor role.
If collision risk is material, stop mutation and hand off to Integration when it concerns repository integration/dependencies, or request a human decision. If an external Control Plane owns runtime coordination, follow its durable coordination state instead of creating a separate ChatGPT Supervisor Role.

## 5. Determine readiness
## 6. Determine readiness

Classify the start state as one of:

- `READY`
- `BLOCKED_DEPENDENCY`
- `BLOCKED_ROLE_BOUNDARY`
- `BLOCKED_CONFLICT`
- `STALE_HANDOFF`
- `NEEDS_HUMAN_DECISION`

Only `READY` permits normal execution.
Only `READY` permits normal execution. `STALE_HANDOFF` requires reevaluation from current GitHub state; it does not automatically mean the underlying work is blocked.

## 6. Startup report
## 7. Startup report

Keep the startup report concise. Include Domain when declared or required.

Expand All @@ -91,12 +121,14 @@ For an optional-Domain Role operating cross-domain, Domain may be omitted:
```text
ROLE: review
ISSUE: #130
PR: #135
STATE: READY
NEXT_ACTION: review cross-domain integration behavior
HANDOFF_HEAD_MATCH: yes
NEXT_ACTION: independently review current PR against durable requirements/evidence
```

## 7. Execute within role
## 8. Execute within Role

After bootstrap, perform only actions allowed by the active role contract. If the task evolves beyond that boundary, use the Handoff Protocol rather than silently expanding the role.
After Bootstrap, perform only actions allowed by the active Role Contract. If the task evolves beyond that boundary, persist the material state and use the Handoff Protocol rather than silently expanding the Role.

A Domain change must be explicit. It does not change the active Role or grant additional permissions.
A Domain change must be explicit. It does not change the active Role or grant additional permissions.
137 changes: 89 additions & 48 deletions .agent/HANDOFF_PROTOCOL.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,114 @@
# Handoff Protocol

version: 3

## Purpose

A handoff transfers responsibility without requiring another agent to reconstruct the task from chat history.
A handoff is a **workflow ownership/state transition notification**, not a context-transfer document.

The repository is the durable source of truth. The receiving Agent reconstructs the current working context from the referenced GitHub Issue / PR / Spec / checks during Bootstrap rather than relying on copied chat context.

## Core invariant: durable first

Material information MUST NOT exist only in a handoff message.

Before emitting a handoff, the source Agent must persist all material information needed by the next Role to the appropriate durable repository location, including as applicable:

- requirements, Acceptance Criteria, scope, dependencies, and specification decisions;
- implementation summary and changed behavior;
- test / CI evidence and verification results;
- review or security findings and their supporting evidence;
- known limitations and unresolved risks;
- Human Gate requirements/results;
- integration findings or decisions.

Use the relevant Issue, PR, Spec / Decision artifact, checks, or another repository-approved durable record.

The handoff MUST NOT duplicate information that the receiving Agent can retrieve from those durable sources.

## Repository visibility boundary

Durable-first does not override repository visibility or confidentiality boundaries.

Before persisting material state or a durable handoff record, determine whether the target repository/location is public or private.

For a public repository:

- do not expose private-repository names, URLs, paths, Issue/PR identifiers, branch names, internal artifact names, or other private-source metadata unless the human owner explicitly approves disclosure;
- when work is derived from a private source, persist only the public-safe resulting decision, specification, evidence, or status;
- keep private provenance/traceability in an approved private durable location;
- make public Issue / PR / comment / commit / documentation content self-contained using public artifacts or intentionally disclosed information.

If material context cannot be safely persisted in the public repository, persist it in an approved private durable location and put only the minimum public-safe state needed for workflow execution in the public repository. Do not compensate by placing private details in the chat handoff.

## Handoff triggers

Use a handoff when:

- the next action is forbidden by the active role;
- another role owns the required decision;
- the next action is forbidden by the active Role;
- another Role owns the required decision or work;
- implementation requires a specification change;
- review finds rework;
- integration finds unresolved implementation or test work;
- a security finding requires remediation by an Implementation Agent;
- Review finds rework or clears work for Integration;
- Integration finds unresolved implementation, specification, security, dependency, or Human Gate work;
- Security requires remediation or another Role's decision;
- a dependency or ownership conflict blocks progress;
- a human decision or Human Gate is required.

Do not silently perform cross-role work merely because it is small.

## Domain-aware routing
## Canonical handoff schema

When the target Role has `domain_mode: required`, the handoff must identify the target `DOMAIN`.
Agent-to-Agent handoffs should contain only the structural transition fields below.

When the target Role has `domain_mode: optional`, include `DOMAIN` when a specialist owner/focus is known and useful. Omit it when the target work is intentionally cross-domain.
```text
HANDOFF
FROM: implementation
TO: review
DOMAIN: web
ISSUE: #146
PR: #147
HEAD: 33c555696445637043a5e2858c42a23a1858d01a
STATE: READY_FOR_REVIEW
```

When the target Role has `domain_mode: forbidden`, do not assign a `DOMAIN`.
Do not append `Finding`, `Evidence`, `Required action`, `Completion condition`, implementation summaries, test summaries, or other narrative sections when that information is durably available in GitHub.

A Domain declaration does not grant permissions beyond the target Role Contract.
The same canonical structure should be used for both:

## Required handoff content
1. the durable handoff record in GitHub when the workflow records one; and
2. the copy-paste-ready handoff message sent to another Agent chat.

A durable handoff should identify:
This avoids separate GitHub and chat representations of the same transition.

- source role
- target role
- target Domain when required or useful under the target Role's Domain mode
- Issue / PR
- current state
- concise finding or reason
- evidence
- exact requested next action
- blocking/non-blocking status
- relevant acceptance criteria or specification references
## Field rules

Recommended format for a domain-targeted handoff:
- `FROM`: required. Source Role.
- `TO`: required. Target Role or `human` for an explicit Human Gate / human decision transition.
- `DOMAIN`: conditional. Include when the target Role requires Domain, or when an optional-Domain target has an explicit specialist owner/focus. Omit when the target Role forbids Domain or the target work is intentionally cross-domain.
- `ISSUE`: required for normal repository work. It identifies the durable work item from which the receiver reconstructs context.
- `PR`: required when the transition concerns an implementation/review/integration PR; otherwise omit it.
- `HEAD`: required when `PR` is present and the transition is tied to a specific PR revision. Use the full commit SHA when available.
- `STATE`: required. Use the stable workflow vocabulary defined by the Role/Protocol.

```markdown
## HANDOFF
Do not add a separate `BLOCKING` field when blocking semantics are already represented by `STATE`; avoiding redundant fields prevents contradictory transitions.

FROM: review
TO: implementation
DOMAIN: device
ISSUE: #123
PR: #130
STATE: REWORK_REQUIRED
BLOCKING: yes
## Domain-aware routing

### Finding
<concise finding>
When the target Role has `domain_mode: required`, the handoff must identify the target `DOMAIN`.

### Evidence
<files/tests/logs/spec references>
When the target Role has `domain_mode: optional`, include `DOMAIN` when a specialist owner/focus is known and useful. Omit it when the target work is deliberately cross-domain.

### Required action
<what the target role must do>
When the target Role has `domain_mode: forbidden`, do not include `DOMAIN`.

### Completion condition
<observable condition for handing back>
```
A Domain declaration never grants permissions beyond the target Role Contract.

## Revision identity and stale handoffs

For PR-based transitions, `HEAD` identifies the exact revision that entered the stated workflow state.

The receiving Agent must compare `HEAD` with the current PR head during Bootstrap. If they differ, the handoff is stale. Do not assume that the old transition still applies; inspect the latest durable Issue / PR / review / checks and derive the current disposition from GitHub.

For optional-Domain Roles, omit `DOMAIN` when the work is deliberately cross-domain.
A handoff is never authority to ignore newer repository state.

## Standard handoff routes

Expand All @@ -85,25 +123,28 @@ For optional-Domain Roles, omit `DOMAIN` when the work is deliberately cross-dom
| Security | remediation required | Implementation |
| Integration | implementation defect | Implementation |
| Integration | specification ambiguity | Specification |
| Integration | human/physical verification required | Human Gate |
| Integration | human/physical verification required | Human |
| Any | unresolved ownership/runtime coordination problem | Human or external Control Plane |

## Status vocabulary

Prefer a small stable vocabulary:
Prefer a small stable vocabulary. Role Contracts may define role-specific states; common transition states include:

- `READY_FOR_IMPLEMENTATION`
- `READY_FOR_REVIEW`
- `REWORK_REQUIRED`
- `READY_FOR_INTEGRATION`
- `BLOCKED`
- `BLOCKED_DEPENDENCY`
- `BLOCKED_CONFLICT`
- `SPEC_CHANGE_REQUIRED`
- `NEEDS_SECURITY_REVIEW`
- `NEEDS_HUMAN_DECISION`
- `HUMAN_GATE_REQUIRED`
- `INTEGRATED`

## Handoff completion
## Completion rule

The receiving role should verify current repository state before acting. A handoff is context, not permission to ignore newer GitHub state.
A Role may emit a handoff only after the material state supporting that transition has been persisted durably in a location appropriate for its visibility/sensitivity.

When work is completed, the receiving role should leave durable evidence in the Issue/PR and hand responsibility to the next role rather than relying only on a chat message.
The handoff itself is intentionally insufficient to perform the target Role's work. The receiver must Bootstrap and reconstruct current context from GitHub.
Loading