|
|
|
|
@ -1,65 +1,99 @@
|
|
|
|
|
# agent-team — R720 Plane-2 FOUNDATION
|
|
|
|
|
# agent-team — R720 Plane-2 SDLC pipeline
|
|
|
|
|
|
|
|
|
|
Pre-deployment scaffolding for the R720 agent-team SDLC pipeline (design:
|
|
|
|
|
`../docs/r720-agent-team-design.md`). This commit ships the **Plane-2
|
|
|
|
|
FOUNDATION** layer only — the durable, transport-agnostic **contracts** the leaf
|
|
|
|
|
builders import verbatim. Nothing here is provisioned, scheduled, or wired to
|
|
|
|
|
live infrastructure.
|
|
|
|
|
The durable, human-gated agentic SDLC pipeline for the R720 (`sh-secrev` VM),
|
|
|
|
|
design: `../docs/r720-agent-team-design.md`. A task flows INTAKE → CLARIFY (the
|
|
|
|
|
human gate) → PLAN → REVIEW, and (opt-in, deploy-gated) → BUILD → VERIFY → draft
|
|
|
|
|
PR. Every stage is durable and resumable (LangGraph + a SQLite checkpointer);
|
|
|
|
|
the human gate suspends on `interrupt()` and resumes on a real answer.
|
|
|
|
|
|
|
|
|
|
> Status: FOUNDATION modules only. No coordinator, no transports' concrete
|
|
|
|
|
> adapters, no CI workflow, no provisioning. Those are later phases (§7).
|
|
|
|
|
```
|
|
|
|
|
INTAKE → CLARIFY (Claude, human gate) → PLAN (Claude) → REVIEW (GPT-4.1)
|
|
|
|
|
▲ │
|
|
|
|
|
└── loop-back ───┤
|
|
|
|
|
approve/escalate → END
|
|
|
|
|
(P3, opt-in + INERT until the CI gate clears):
|
|
|
|
|
approve → BUILD (DeepSeek) → VERIFY (ci_gate) → draft PR
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
> **Status (2026-06-18).** P1 (human gate) + P2 (planner + adversarial review
|
|
|
|
|
> loop) + the live runtime (coordinator, Slack/GitHub/Claude-Code transports,
|
|
|
|
|
> intake) + P3-inert (build/verify subgraph, opt-in) + P4 (more transports +
|
|
|
|
|
> GitHub-issue intake) are **built, reviewed, and merged to main** (~795 tests).
|
|
|
|
|
> **Nothing is provisioned**: not rsync'd to the box, no live tokens, no
|
|
|
|
|
> systemd, no live CI. Production default runs **P2** (no builders).
|
|
|
|
|
> **Deploy-gated / not yet built:** the P3 *live* CI apply/verify + OIDC role
|
|
|
|
|
> (held behind `/sh-security-review` + the mandatory GPT-4.1 cross-review), and
|
|
|
|
|
> all provisioning. See the project memory `project_r720_agent_team` and §7 of
|
|
|
|
|
> the design for the phased rollout.
|
|
|
|
|
|
|
|
|
|
## Layout
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
agent-team/
|
|
|
|
|
agent_team/ # importable package (snake_case)
|
|
|
|
|
state_store.py # §6.7 atomic write + integrity-checked read
|
|
|
|
|
billing.py # §3.1 claude_invoke billing-mode seam
|
|
|
|
|
task_model.py # §3.3 TaskRecord / Phase / PipelineState
|
|
|
|
|
db/
|
|
|
|
|
schema.py # §3.3.1/§6.7 SQLite DDL + connect/init/migrate
|
|
|
|
|
schema.sql # raw DDL, mirrors schema.py verbatim
|
|
|
|
|
transport/
|
|
|
|
|
base.py # §3.3.1 Transport ABC + QuestionSet/NormalizedAnswer
|
|
|
|
|
tests/ # pytest unit tests, one module per source module
|
|
|
|
|
run-team.py # operator CLI: init-db, list/show/answer/expire/
|
|
|
|
|
# force-resume (ledger), start (intake), serve (daemon),
|
|
|
|
|
# intake-github
|
|
|
|
|
agent_team/ # importable package (snake_case)
|
|
|
|
|
coordinator.py # the live runtime keystone: invoker→graph→ResumeWorker;
|
|
|
|
|
# start_task / submit_answer / drain / tick / recover / serve
|
|
|
|
|
graph.py # LangGraph wiring: P1 (intake→clarify→plan) + opt-in P2
|
|
|
|
|
# review loop + opt-in P3 build/verify subgraph
|
|
|
|
|
invoker.py # §3.1 real Claude path (subscription-OAuth / API / Bedrock)
|
|
|
|
|
billing.py # §3.1 claude_invoke billing-mode seam
|
|
|
|
|
ci_gate.py # §3.3.2 pure-code authenticated-Checks PASS/FAIL gate
|
|
|
|
|
task_model.py / state_store.py
|
|
|
|
|
db/{schema.py,schema.sql} # SQLite ledger DDL + BEGIN IMMEDIATE compare-and-set
|
|
|
|
|
ledger.py / responder.py / resume_worker.py / deadline_timer.py / recovery.py
|
|
|
|
|
operator_cli.py
|
|
|
|
|
nodes/ # pipeline stages + their model bindings
|
|
|
|
|
clarifier.py + clarifier_llm.py # human gate (Claude)
|
|
|
|
|
planner.py # plan (Claude)
|
|
|
|
|
review_loop.py + review_loop_llm.py # adversarial review (GPT-4.1 via orchestrator)
|
|
|
|
|
builders.py + builders_llm.py # candidate diff (DeepSeek) — INERT, proposes only
|
|
|
|
|
verifier.py + verifier_llm.py # ci_gate sole PASS authority; LLM = fix-proposer
|
|
|
|
|
build_verify_subgraph.py # P3 BUILD→VERIFY topology (opt-in)
|
|
|
|
|
transport/ # one adapter contract + a live impl per channel
|
|
|
|
|
base.py # Transport ABC + QuestionSet / NormalizedAnswer
|
|
|
|
|
slack_adapter.py + slack_live.py + slack_listener.py # Block Kit + Socket Mode
|
|
|
|
|
github_adapter.py + github_live.py + github_intake.py # issue-comment + issue intake
|
|
|
|
|
claude_code_adapter.py + claude_code_live.py # file-drop responder
|
|
|
|
|
ci/ # §3.3.2 split-job CI apply/verify workflow (DEPLOY-GATED)
|
|
|
|
|
systemd/ # agent-team-coordinator.service (not installed)
|
|
|
|
|
DEPLOY-R720.md # provisioning runbook (snapshot-first, rsync, tokens, demo)
|
|
|
|
|
tests/ # pytest, one module per source module + sim harness
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The top directory is kebab-case (`agent-team/`); the importable package is
|
|
|
|
|
snake_case (`agent_team/`), per the engineering handbook.
|
|
|
|
|
|
|
|
|
|
## Modules (contracts)
|
|
|
|
|
## Key design points
|
|
|
|
|
|
|
|
|
|
| Module | Design ref | What it provides |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| `state_store` | §6.7 | `atomic_write(path, data)` (write-temp → fsync → rename), `read_checked(path, *, schema_version)` (schema-version + content-hash integrity check, raises `IntegrityError`), `compute_content_hash(data)`. Pure stdlib; no other `agent_team` deps. |
|
|
|
|
|
| `db.schema` | §3.3.1, §6.7 | `SCHEMA_VERSION`, `PENDING_QUESTIONS_DDL`, `BUDGET_LEDGER_DDL`, `connect()` (WAL + foreign_keys + busy_timeout), `init_db()`, `migrate()`, and the `BEGIN IMMEDIATE` compare-and-set helpers (`answer_question`/`expire_question`/`supersede_question`). SQL DDL lives **only** here. |
|
|
|
|
|
| `billing` | §3.1 | `BillingMode{SUBSCRIPTION,API,BEDROCK}`, `claude_invoke(prompt, *, mode=None, **kw) -> ClaudeResult`, `resolve_mode(config)`. Single seam; subscription mode pops any stray `ANTHROPIC_API_KEY` so OAuth can't be overridden. |
|
|
|
|
|
| `transport.base` | §3.3.1 | `Transport` ABC (`post_question` → `channel_ref`; `parse_answer` → `(question_id, answer, via)`), `QuestionSet`, `NormalizedAnswer`. Transport-independent; Slack/GitHub/Claude-Code adapters subclass in the leaves. |
|
|
|
|
|
| `task_model` | §3.3 | `TaskRecord`, `TaskStatus`, `Phase{INTAKE…DONE}`, `new_thread_id()`, `PipelineState` TypedDict (LangGraph state schema), JSON serialization helpers. Pure model, no I/O. |
|
|
|
|
|
|
|
|
|
|
### Durable human-in-the-loop (§3.3.1)
|
|
|
|
|
|
|
|
|
|
The `pending_questions` ledger is the single durable source of truth for the
|
|
|
|
|
question lifecycle. Every race (duplicate answers, transport redelivery,
|
|
|
|
|
answer-vs-timeout) resolves via one atomic compare-and-set against the `status`
|
|
|
|
|
column, run inside a `BEGIN IMMEDIATE` transaction so concurrent responders are
|
|
|
|
|
serialized — first-answer-wins (`rowcount == 1`), late/duplicate ignored
|
|
|
|
|
(`rowcount == 0`). The LangGraph `SqliteSaver` checkpointer creates its own
|
|
|
|
|
tables against the **same** DB file.
|
|
|
|
|
- **Durable human gate (§3.3.1).** The `pending_questions` ledger is the single
|
|
|
|
|
source of truth for the question lifecycle. Every race (duplicate answers,
|
|
|
|
|
transport redelivery, answer-vs-timeout) resolves via one atomic
|
|
|
|
|
compare-and-set against `status`, inside a `BEGIN IMMEDIATE` transaction —
|
|
|
|
|
first-answer-wins (`rowcount == 1`), late/duplicate ignored. The LangGraph
|
|
|
|
|
`SqliteSaver` checkpointer shares the same DB file.
|
|
|
|
|
- **Fail-safe model seams.** Every node treats model output as untrusted and
|
|
|
|
|
fails SAFE: garbage never clears the 98% clarifier gate, never auto-approves a
|
|
|
|
|
plan, never fabricates a build success, and the verifier's `ci_gate` is the
|
|
|
|
|
**sole** PASS authority (the LLM is structurally a fix-proposer only).
|
|
|
|
|
- **Inbound auth (§3.3.1).** The Slack Socket Mode listener authorizes the
|
|
|
|
|
**sender** against an owner allowlist (`AGENT_TEAM_SLACK_OWNER_IDS`,
|
|
|
|
|
fail-closed) on top of the open-status CAS anti-replay.
|
|
|
|
|
- **Billing seam (§3.1).** Claude runs under subscription OAuth on the box;
|
|
|
|
|
GPT-4.1 (review) and DeepSeek (builders) route through the local orchestrator
|
|
|
|
|
`run.py`. Switching Claude billing is a config flip.
|
|
|
|
|
|
|
|
|
|
## Running the tests
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
cd agent-team
|
|
|
|
|
python3 -m pytest tests/ -q
|
|
|
|
|
python3 -m pytest -q # conftest puts the package on sys.path; no install needed
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`tests/conftest.py` puts the package on `sys.path`, so no install is required.
|
|
|
|
|
## Deploy
|
|
|
|
|
|
|
|
|
|
## Not in this commit (later phases)
|
|
|
|
|
|
|
|
|
|
Coordinator/brain, concrete Slack/GitHub/Claude-Code transport adapters, the
|
|
|
|
|
CI apply/verify workflow (§3.3.2), step-ca / Roles Anywhere, scheduling, and
|
|
|
|
|
the operator CLI (`run-team.py`). See `../docs/r720-agent-team-design.md` §7
|
|
|
|
|
for the phased rollout. Secrets are never committed.
|
|
|
|
|
Deploy-gated. See `DEPLOY-R720.md` for the provisioning runbook (VM snapshot
|
|
|
|
|
first, rsync, venv deps, `~/secrev.env` tokens, `init-db`, systemd, and the live
|
|
|
|
|
P1 exit-criteria demo). Secrets are never committed.
|
|
|
|
|
|