Skip to content
Closed
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
2 changes: 2 additions & 0 deletions docs/10-prd/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
| Profile Tag | Agent Profile 声明适用面的 tag-like 类型,例如 `issue`、`pr`;同一 Profile 可同时拥有多个 tag,也可以只适用于 Issue。 |
| Braid System Prompt | Braid 在创建 Provider Session 时注入的高优先级、版本化指令,包括 Braid/CLI 的存在、GitHub Working Memory 协议,以及按 Issue/PR surface 选择的角色与任务说明。它帮助 Agent 使用产品能力,而不是把 Braid 变成限制 Agent 的权限沙箱。 |
| Effective Agent Instructions | Provider 实际收到的指令组合:Braid System Prompt 加 Profile User Instructions。GitHub Context 是带来源边界的不可信工作数据,Event Reference 是 user message,两者都不是系统指令。 |
| Publication Discretion | 收到评论、review 或提及从不构成公开发表的义务。Agent 自行决定什么内容 Human-relevant;沉默是合法结果。私有推理只存活在物理 Provider Session 内,Context Reset 后即被丢弃。 |
| Issue Agent | 一个带 `issue` Profile Tag、运行在某个 Issue 上的 Agent 实例。 |
| Issue Agent Group | 同一 Issue 上所有平行 Issue Agents;没有 primary/sub-agent,收到相同 Context 与 Event Reference batch。 |
| Issue Group Turn | 同一 Context Revision 和 Event Reference batch 并行扇出给一个 Issue Agent Group 的一次 turn。 |
| PR Agent | 一个带 `pr` Profile Tag、运行在某个 PR 上的 Agent 实例。v1 只有 Implementation Agent;未来可增加 reviewer、advisor 等角色。 |
| PR Agent Group | 同一 PR 上的 Agent 集合。v1 恰好包含一个 Implementation Agent;架构保留未来增加非实现角色的路径。 |
| Implementation Agent | PR Agent Group 中负责修改代码的 Agent。v1 每个 PR 恰好一个,并独占一个专用 worktree。 |
| Agent Worktree | Braid 为每个 Agent Group session 供给的按 assignment 代际隔离的专用 worktree,即 Agent 的实际 cwd。PR Agent 绑定 PR head;Issue Agent 绑定该 Issue 唯一的同仓 Development 链接分支(无则绑定默认 origin 分支,多个则视为歧义并阻塞物化)。 |
| Implementation Request | Issue Agent 根据某条 Issue comment 发起的一次实现请求。该 GitHub comment ID 是 `braid pr ensure` 的幂等键;同一 comment 只得到一个 PR,不同 comment 可得到不同 PR。 |
| PR Activation | 启动一个 PR Agent Group 的机械事实。产品上等价于把 PR 交给 Braid;具体 GitHub signal 由 adapter 提供,不能在未验证前假定为原生 PR assignee。 |
| PR Agent Lease | 将一个 PR、一个专用 worktree 和一个 `pr`-capable Profile 原子绑定给唯一 Implementation Agent 的独占租约。 |
Expand Down
7 changes: 5 additions & 2 deletions docs/10-prd/objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ An Agent Profile is a versioned Braid configuration containing a provider,
model, reasoning setting, Profile User Instructions, cwd/workspace policy,
sandbox/approval settings, and optional tools, skills, MCP, or other
provider-specific resources. Tags declare whether it can serve `issue`, `pr`,
or both.
or both. The Profile `workspace` names a clean source checkout, never the
Agent's cwd: every Agent Group session runs in a dedicated generation-scoped
Braid worktree (the Issue's sole Development branch when unambiguous,
otherwise the default branch; the PR head for a PR Agent).

Braid adds its own versioned System Prompt when materializing a Provider
Session. It explains GitHub Working Memory, Braid and `braid gh`, concise public
Expand All @@ -41,7 +44,7 @@ sub-agent roles. MVP acceptance deliberately uses:

- one active Issue Agent per Issue Agent Group;
- one Implementation Agent per PR Agent Group;
- one dedicated worktree provisioned for that PR Implementation Agent.
- one dedicated generation-scoped worktree per Agent Group session.

Multi-Agent fan-out is not rejected, but cross-peer ordering, semantic merge,
arbitration, and convergence are outside the MVP correctness claim.
20 changes: 19 additions & 1 deletion docs/10-prd/publication.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
## Agent Publication and Identity

Braid does not mirror turn activity or final responses. Coding Agents publish
short messages themselves. `braid gh` implements the write side needed to use
short messages themselves.

## Publication Discretion

A delivered comment, review, or mention never obligates a public reply. The
Agent alone decides what is Human-relevant; a silent turn that only reads,
thinks, or edits local files is a valid outcome. Event References report
changes; they are not commands.

The Agent may keep private working reasoning inside its Provider Session and
publish conclusions when they are ready. Braid never publishes private
reasoning. Private reasoning lives only in the physical Provider Session: a
Context Reset replaces that session and discards it, so durable conclusions
must be published to GitHub (a comment, a description update, or a commit)
before they are needed again.

## Attribution and Writes

`braid gh` implements the write side needed to use
the stable Braid App identity and prepends an immutable attribution block:

```markdown
Expand Down
16 changes: 9 additions & 7 deletions docs/10-prd/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

### Discuss

Issue Activation creates the Issue session. A native assignment does not
invent a turn. On installations without the special Agent App assignment
capability, the first trusted visible `@braid` both activates the dormant Issue
and supplies the first Wake Event. Later Human comments, newly populated
Issue Activation creates the Issue session. A native assignment and the first
trusted visible `@braid` on a dormant Issue are the same internal `assign`
event; neither invents a turn by itself. On installations without the special
Agent App assignment capability, that first mention both activates the dormant
Issue and supplies the first Wake Event. Later Human comments, newly populated
included metadata, and unfolded content are Wake Events. They accumulate until
the Quiet Window expires or the count threshold is reached. The Issue Agent
receives one current Context plus coalesced Event References and decides
Expand Down Expand Up @@ -49,6 +50,7 @@ Context on the next materialization.
Issue unassignment is debounced; once settled it retires the active Issue Agent
Group. Closing an Issue, closing a PR, or merging a PR does not interrupt a
current turn. It grants at most one Finalization Turn, then a closed Issue or
closed-unmerged PR sleeps and a merged PR retires. Reopen rematerializes Context
and starts one ordinary debounced turn. Duplicate deliveries never grant extra
finalization turns.
closed-unmerged PR sleeps and a merged PR retires. A mention on a closed Work
Item does not wake the sleeping group; Reopen is the designed re-entry. Reopen
rematerializes Context and starts one ordinary debounced turn. Duplicate
deliveries never grant extra finalization turns.
40 changes: 31 additions & 9 deletions docs/20-product-tdd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ crates. Modules are deep and align with authority boundaries:
| `provider::session` | `ProviderAgentSession` adapter that maps `AgentSession` to `AgentProvider` primitives and translates provider notifications into `SessionEvent`s, deduplicating the provider's response-side and notification-side observation of the same fact. |
| `session_manager` | In-process `SessionManager` keyed by provider thread id; start/resume/get. Ephemeral per connection epoch: it is rebuilt from the durable store on every (re)connect because sessions bind the epoch's provider handle. |
| `provider` | Provider-neutral capability contract and Codex NDJSON implementation. |
| `worktree` | Validate a Profile source checkout, fetch the bound PR head, provision one generation-scoped worktree per Implementation Agent, and expose recovery diagnostics; no Git-operation sandbox. |
| `worktree` | Validate a Profile source checkout, resolve the bound ref (PR head, sole Development branch, or default origin branch), provision one generation-scoped worktree per Agent Group, and expose recovery diagnostics; no Git-operation sandbox. |
| `writer` | `braid gh`, attribution, reaction/status desired state, and write-outbox convergence. |
| `telemetry` | Trace/metric/log creation, payload events, sampling configuration, and OTLP export. |
| `tunnel` | Wrangler Quick Tunnel supervision and webhook URL handoff. |
Expand All @@ -119,6 +119,18 @@ Module dependencies point one way only: `runtime` → `group` → `queue`, and
sit above the leaf modules (`store`, `context`, `github`, `config`,
`provider`, `worktree`, `telemetry`) and no lower layer imports an upper one.

### Internal Event Model

`protocol.rs` owns the typed, platform-neutral event contract `EventKind`
(`assign`, `unassign`, `mention`, `wake`, `invalidate`, `lifecycle`,
`origin_echo`, `noop`). A producer translates platform deliveries into
`EventKind` at ingress and records only the internal kind plus the per-platform
opaque Event Reference; `queue` and `group` consume `EventKind` exclusively
and never branch on platform event names or actions. This is the seam at
which a future non-GitHub platform plugs in: it adds a producer mapping, not
new consumer logic. The current GitHub mapping is owned by
[`github.md`](github.md).

### State authority

Every piece of state has exactly one authority; everything else is a
Expand Down Expand Up @@ -209,14 +221,24 @@ newer than the binary. Compatible application rollback is declared per release;
an incompatible schema rollback restores the pre-migration backup rather than
running a down migration.

For a PR-capable Profile, `workspace` names a clean source Git checkout of the
configured repository, not the directory in which the Agent edits. Braid
fetches the PR head from that checkout and provisions the actual Agent cwd under
`runtime.root/worktrees/pr-<number>/<profile>-g<generation>`. SQLite records the
resolved source, worktree, remote head, and local branch as operational facts.
The provider session is started and later resumed only against that worktree.
This provides isolation and recovery identity without turning Braid into a Git
policy engine.
For any Agent-serving Profile, `workspace` names a clean source Git checkout of
the configured repository, not the directory in which the Agent edits. Every
Agent Group session runs in a dedicated generation-scoped worktree that Braid
provisions from that checkout:

- PR Agent Group: `runtime.root/worktrees/pr-<number>/<profile>-g<generation>`,
bound to the fetched PR head;
- Issue Agent Group: `runtime.root/worktrees/issue-<number>/<profile>-g<generation>`,
bound to the Issue's sole same-repository Development linked branch when
exactly one exists, otherwise to the repository default branch
(`refs/remotes/origin/<default>`). Several Development branches are ambiguous
and block materialization with an operator diagnostic, mirroring `pr ensure`
disambiguation.

SQLite records the resolved source, worktree, bound ref, and local branch as
operational facts. The provider session is started and later resumed only
against that worktree. This provides isolation and recovery identity without
turning Braid into a Git policy engine.

## Error and Concurrency Model

Expand Down
6 changes: 6 additions & 0 deletions docs/20-product-tdd/app-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ string consisting of:
2. a clear delimiter;
3. Profile User Instructions.

The versioned Braid System Prompt must state Publication Discretion
explicitly: a delivered comment, review, or mention never obligates a public
reply; the Agent may keep private working reasoning inside the session and
publish conclusions when they are ready; private reasoning does not survive a
Context Reset, so durable conclusions belong on GitHub.

GitHub Context is not developer instructions. Immediately after start, Braid
calls stable `thread/inject_items` with one Responses-API user message:

Expand Down
24 changes: 24 additions & 0 deletions docs/20-product-tdd/github.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,26 @@ external activity.
- Unknown event/action/union variants are durably recorded and trigger
reconciliation. They are never serialized generically into Agent input.

### GitHub → EventKind Mapping

The GitHub producer maps deliveries onto the platform-neutral `EventKind`
contract; consumers never see GitHub event names or actions:

| GitHub delivery | Internal `EventKind` |
| --- | --- |
| `issues.assigned` / PR assignment to the App (canonical-reread confirmed) | `assign` |
| First Trusted Braid Mention on a dormant Work Item | `assign` (same internal event as native assignment) |
| `issues.unassigned` (canonical-reread confirmed) | `unassign` |
| Comment/review created, `pull_request.synchronize`, review requested; Trusted Braid Mention on an already-active Work Item | `mention` / `wake` |
| Body/description/comment edits or deletions, review dismissed, review thread resolved | `invalidate` |
| `closed` / `reopened` / `merged` | `lifecycle` |
| Correlated Braid App or Profile-actor writes | `origin_echo` (recorded, never wakes or invalidates the same Agent) |
| `ping`, unknown variants | `noop` (recorded as reconciliation evidence) |

A Trusted Braid Mention on a Work Item whose group sleeps because the Work
Item is closed is a `mention`, not an `assign`: closed groups do not wake;
reopen is the designed re-entry.

Subscribe to:

- `issues` and `issue_comment`;
Expand Down Expand Up @@ -82,6 +102,10 @@ activation modes:
`ActivationIntent` and preserves that same comment as an urgent Wake Event,
so materialization is followed by the first turn.

Both modes converge on the same internal `assign` event; the activation paths
differ only in how the platform expresses the signal, never in consumer
behavior.

Native unassignment is likewise available only in the first mode and must be
confirmed from canonical assignees before entering debounce. The fallback is
not presented as a fabricated assignment.
Expand Down
2 changes: 1 addition & 1 deletion docs/20-product-tdd/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Each Work Item/Profile pair has an Assignment Generation and one state:
| State | Meaning |
| --- | --- |
| `dormant` | No active Braid assignment/activation. |
| `materializing` | Profile, Context, worktree when applicable, and physical Provider Session are being created. |
| `materializing` | Profile, Context, the generation-scoped worktree, and physical Provider Session are being created. |
| `idle` | Session exists and no turn or pending Wake batch exists. |
| `debouncing` | Wake Events are accumulating against one quiet deadline/count. |
| `running` | One provider turn is active. |
Expand Down
Loading