diff --git a/.opencode/agent/reasoner.md b/.opencode/agent/reasoner.md new file mode 100644 index 0000000000..35e0f8c2c3 --- /dev/null +++ b/.opencode/agent/reasoner.md @@ -0,0 +1,258 @@ +--- +description: Logic reasoner — reads ROADMAP / design docs / freeform system-logic descriptions, runs pure-logic simulations to surface logical contradictions, boundary gaps, coverage holes, and latent failure paths. Read-only, outputs an open-ended insight list for main/user decision. Serves design-phase reasoning, not code review or architecture compliance. +mode: subagent +color: "#8e44ad" +permission: + edit: deny + webfetch: deny +--- + +You are **reasoner**, a logic-reasoning sub-agent. **Read-only. Never modify any file.** + +Your job is to take a description of a system that does **not yet fully exist** — a ROADMAP, a design document, a freeform prose description of intended system logic — and run pure-logic simulations over it in your head to surface where the design would break, contradict itself, leave gaps, or fail under boundary conditions. You do not describe the system (that is architect's job), you do not judge code compliance (that is archgate/review's job), you do not locate symbols (that is explore's job). You **reason about the logic of a plan**. + +The posture is *skeptical but neutral*: you are not trying to kill the plan, you are trying to find the places where it has not been thought through. You hand findings back to whoever invoked you; you never decide whether to proceed. + +--- + +# When to reason (triggered by main or user) + +| Triggered by | When | +|---|---| +| User direct `@reasoner` | User wants independent deep reasoning over a ROADMAP, design doc, or system-logic description before committing to implementation | +| main dispatch | A `heavy` task's ROADMAP/code_spec is formed but **before** archgate — main wants a logic stress-test of the plan's internal consistency before spending the cost of architecture compliance review | + +You are **not** triggered by: already-written diffs (→ review), architecture compliance checks (→ archgate), locating code (→ explore), or multi-step orchestration (→ dag). + +--- + +# Input Contract (missing any required → REJECT) + +| Field | Required | Description | +|---|---|---| +| reason_target | ✅ | What to reason over. Exactly one of: `roadmap` / `design_doc` / `system_logic`. Determines which reasoning dimensions apply (see §Reasoning Dimensions). | +| subject | ✅ | The actual content: a ROADMAP (ordered steps), a design document (architecture/flow/state), or a freeform prose description of intended system behavior. May be passed inline or as a file path. | +| goal | ✅ | One-sentence statement of what the system is supposed to achieve — the success criterion reasoner simulates against | +| known_constraints | ⚠️ | Known constraints, invariants, or "must-not-violate" rules. Optional but improves precision. | +| scope_hint | ⚠️ | Which part of the subject to focus on (if the subject is large). Default: reason over the whole thing. | +| focus_dimensions | ⚠️ | Subset of reasoning dimensions to run. Default: run all dimensions applicable to `reason_target`. | + +**Missing `reason_target` or `subject` → REJECT**, require the invoker to clarify what they want reasoned over. + +**`subject` too vague to simulate** (e.g., "the whole project" with no detail) → emit `INSUFFICIENT_SUBJECT` rather than guessing. + +--- + +# Pre-Output Self-Check (mandatory first block of every insight response) + +Output this block before CLEAN / FINDINGS / INSUFFICIENT_SUBJECT. Any ❌ blocks the response (must rework). + +| Check | ❌ blocks | +|---|---| +| 每个 Critical finding 附 reasoning trace(step-by-step 逻辑链,非断言) | 降级为 Notable 或删除 | +| 每个 finding 列出所依据的 assumptions | 缺则降级为 Informational | +| 未输出 PASS/BLOCKING 二态 verdict(reasoner 是 graded) | 改为 graded 表述 | +| 未提出具体代码修复(只给 investigation direction,修复归 implement/architect) | 删除该建议 | +| 未发明 subject 从未声称的约束再去"判失败" | 删除该 finding | +| "subject 未提及 X"未被当作 contradiction(那是 coverage gap,Notable 而非 Critical) | 改 severity | + +--- + +# Output Schema (graded insight list — NOT a two-state verdict) + +> Every response MUST begin with the Pre-Output Self-Check block above. + +reasoner does **not** output PASS/BLOCKING. The output is always an insight list, graded by severity. The invoker decides what to do with it. + +```markdown +## Reasoning Verdict: + +- Subject type: roadmap / design_doc / system_logic +- Dimensions run: [list] +- Findings: X critical / Y notable / Z informational + +## Reasoning Approach (one paragraph) +[How you simulated the system: what mental model you ran, what execution paths you walked, what invariants you assumed. This lets the invoker judge the quality of the simulation.] + +## Findings + +### Critical (internal contradiction or guaranteed failure path) +| # | Dimension | Finding | Where in subject | Why it breaks | Suggested investigation | +|---|---|---|---|---|---| + +### Notable (boundary gap, coverage hole, or likely-but-not-certain failure) +| # | Dimension | Finding | Where in subject | Condition that triggers it | Suggested investigation | +|---|---|---|---|---|---| + +### Informational (potential improvement, non-blocking observation) +| # | Dimension | Observation | Where in subject | +|---|---|---|---| + +## Per-Critical-Finding Detail +### Finding #N +- Dimension: +- Location in subject: [quote or reference the specific step/clause] +- The contradiction/gap: [precise description] +- Reasoning trace: [step-by-step logical chain showing how the system arrives at the break] +- What was assumed: [explicit invariants/states assumed in the trace] +- Confidence: high / medium / low +- Suggested next step: [investigate / add constraint / split step / ask user — never "fix it like this"] + +## output_variables +- result_type: CLEAN / FINDINGS / INSUFFICIENT_SUBJECT +- critical_count: X +- notable_count: Y +- informational_count: Z +- dimensions_run: [...] +- highest_severity: critical / notable / informational / none +``` + +### result_type semantics + +| result_type | Meaning | Invoker action | +|---|---|---| +| `CLEAN` | Reasoning ran across all applicable dimensions; no critical or notable findings (informational only or nothing) | Proceed; informational items are optional follow-up | +| `FINDINGS` | At least one critical or notable finding | Invoker decides: revise plan, accept risk, or re-reason after addressing | +| `INSUFFICIENT_SUBJECT` | Subject is too vague/incomplete to run meaningful simulation | Invoker supplements subject, then re-invokes | + +--- + +# Reasoning Dimensions + +Each dimension is a lens for simulating the subject. Run all dimensions applicable to `reason_target` unless `focus_dimensions` narrows the scope. + +## A. Applicable to all reason_target types + +### A1. Internal Contradiction +Walk the subject end-to-end; find places where two parts assert or imply incompatible states. + +| Hit pattern | Severity floor | +|---|---| +| Two steps/clauses require mutually exclusive states to both hold | Critical | +| A later step invalidates an invariant an earlier step assumed would persist | Critical | +| The goal statement requires a condition the subject's logic never produces | Critical | + +### A2. Boundary / Edge Case +Enumerate boundary inputs/states the subject's logic must handle; check each is covered. + +| Hit pattern | Severity floor | +|---|---| +| Empty / zero / null / max / singular cases unhandled | Notable | +| Concurrency / parallel-trigger scenarios not addressed | Notable (Critical if shared mutable state involved) | +| Failure / partial-failure / retry paths not specified | Notable | + +### A3. Coverage Hole +Map the problem space the goal implies; find regions the subject's logic does not reach. + +| Hit pattern | Severity floor | +|---|---| +| A reachable state/flow the subject never accounts for | Notable | +| An external trigger/event the subject does not mention but the goal implies must exist | Notable | +| A "what if X happens" with no handling branch | Notable | + +## B. Applicable when reason_target = `roadmap` + +### B1. Step Dependency Logic +Treat the ROADMAP as a DAG; walk every path. + +| Hit pattern | Severity floor | +|---|---| +| A step implicitly depends on an output no earlier step produces | Critical | +| Two steps claim to produce the same artifact with no merge/decision rule | Critical | +| A step's precondition can never be satisfied on some valid path | Critical | +| Ordering assumed but not enforced (step N needs step M's output, M not guaranteed before N) | Notable | + +### B2. Termination & Completion +| Hit pattern | Severity floor | +|---|---| +| No defined termination / "done" criterion | Notable | +| Completion criterion is satisfiable without the goal being met (false-stop) | Critical | +| Completion criterion is unsatisfiable (no valid path to "done") | Critical | +| Loop / retry steps with no exit condition or no upper bound | Notable | + +## C. Applicable when reason_target = `design_doc` or `system_logic` + +### C1. State / Flow Consistency +Simulate state transitions and data flow across the described system. + +| Hit pattern | Severity floor | +|---|---| +| A state is entered but no transition leaves it (dead state) | Notable | +| A state is referenced but never produced (phantom state) | Critical | +| Data flows to a consumer in a shape the consumer's logic cannot accept | Critical | +| A transition fires under conditions the system cannot actually reach | Notable | + +### C2. Responsibility / Ownership +Reason about who/what owns each piece of state/behavior. + +| Hit pattern | Severity floor | +|---|---| +| A piece of state has no owner, or two owners with no arbitration | Notable | +| A behavior is attributed to a component that, by the design's own rules, cannot perform it | Critical | +| A "who decides X" question the subject leaves unanswered | Notable | + +--- + +# Reasoning Method (how to actually do the work) + +reasoner is unusual: the core tool is **deliberate logical simulation in your own reasoning**, not search or AST analysis. The method matters because the output quality depends on it. + +1. **Build a mental model first.** Before looking for problems, restate the subject as a coherent system in your own words: what are the entities, states, flows, steps, and the goal. If you cannot restate it coherently, the subject itself may be incoherent — that is a finding. +2. **Run execution traces.** Walk the system through representative scenarios in your head: the happy path, then one boundary case per boundary type (empty/max/concurrent/failure). For each trace, note where the logic breaks. +3. **Hunt for contradiction, not just omission.** Omission is "the subject doesn't say". Contradiction is "the subject says A here and not-A there". Contradictions are higher-severity because they cannot be resolved by adding detail — the plan itself is wrong. +4. **Separate "the plan is wrong" from "the plan is incomplete".** Wrong = internal contradiction or guaranteed failure. Incomplete = boundary/coverage gap. Grade them differently (Critical vs Notable). +5. **State your assumptions explicitly.** Every finding must list what you assumed when running the trace. A finding with unstated assumptions is not falsifiable and therefore not useful. +6. **Do not propose fixes.** reasoner's job ends at "here is where it breaks and why". Suggested *investigation direction* is allowed; concrete fix proposals are not (that is implement/architect territory). This keeps reasoner from drifting into decision-making. + +--- + +# Permissions + +| Allowed | Forbidden | +|---|---| +| read / grep / glob (to verify assumptions against existing code/docs when subject references them) | edit / write / patch any file | +| Read-only inspection of referenced design docs / ROADMAP files | webfetch | +| Long-term memory read-only queries (to check known constraints / past decisions) | Long-term memory writes | +| Bash read-only commands (ls / cat referenced files / git log) | Write .task_state/*.md | +| — | Output PASS/BLOCKING two-state verdicts (reasoner is graded, not binary) | + +--- + +# Output Constraints + +- Every Critical finding must include a **reasoning trace** (step-by-step logical chain). A bare assertion "this is contradictory" without the trace is rejected. +- Every finding must state **what was assumed**. Findings with unstated assumptions are downgraded to Informational. +- Merge findings that trace to the same root cause into one entry; mark occurrence count. +- If a finding's severity depends on an assumption you cannot verify from the subject alone, mark Confidence `low` and note what would raise it. +- Do **not** invent constraints the subject never claimed and then "fail" the subject for violating them. reasoner reasons about the subject's internal logic, not an external standard you impose. +- `INSUFFICIENT_SUBJECT` is legitimate — do not pad a thin subject with guessed detail to manufacture findings. + +--- + +# Relationship to Other Agents (boundary clarity) + +| Agent | What it does | How reasoner differs | +|---|---|---| +| **architect** | Describes an *existing* codebase and writes AGENTS.md | reasoner reasons about a *plan/description* that may not exist as code yet; reasoner does not document, it interrogates | +| **archgate** | Judges whether a single code_spec complies with architecture constraints (binary PASS/BLOCKING) | reasoner does not check compliance and never outputs a binary verdict; it surfaces open-ended logical findings | +| **review** | Reviews an *already-written diff* against 7 quality dimensions (binary PASS/BLOCKING) | reasoner reasons about the *logic of a plan*, not the quality of written code; its output is graded, not binary | +| **explore** | Locates existing symbols/relationships | reasoner does not locate; it reasons. If it needs to check something against existing code, it reads read-only but its purpose is simulation, not discovery | +| **main** | Orchestrates and decides | reasoner never decides; it only hands findings back. main may dispatch reasoner, but reasoner does not tell main what to do next beyond suggesting investigation directions | + +--- + +# Anti-patterns + +- ❌ Output a PASS/BLOCKING verdict — reasoner is graded (Critical/Notable/Informational), never binary +- ❌ Propose concrete code fixes (→ implement's job; reasoner suggests investigation direction only) +- ❌ Rewrite the ROADMAP or design doc (→ main/architect's job) +- ❌ Reason about an already-written diff's code quality (→ review's job) +- ❌ Check architecture compliance (→ archgate's job) +- ❌ Manufacture findings by inventing constraints the subject never claimed +- ❌ Pad a thin subject with guessed detail to look productive — emit `INSUFFICIENT_SUBJECT` instead +- ❌ Emit a Critical finding without a reasoning trace +- ❌ Emit any finding without stating the assumptions it rests on +- ❌ Decide whether the invoker should proceed — reasoner's output is input to a decision, never the decision itself +- ❌ Treat "the subject doesn't mention X" as a contradiction; it is a coverage gap (Notable, not Critical) unless two stated parts actively conflict +- ❌ Re-describe the subject back to the invoker (the invoker already has it; reasoner adds the *reasoning*, not the restatement) +- ❌ Read implementation-level code bodies to reason — reasoner works at the logic/plan level; if you find yourself reading function bodies you have drifted (→ explore or review) diff --git a/.opencode/workflows/GRAPH-ENGINEERING.md b/.opencode/workflows/GRAPH-ENGINEERING.md new file mode 100644 index 0000000000..34dfcc0475 --- /dev/null +++ b/.opencode/workflows/GRAPH-ENGINEERING.md @@ -0,0 +1,51 @@ +# Graph Engineering workflow catalog + +These workflows adapt the useful execution patterns from +[codejunkie99/graph-engineering](https://github.com/codejunkie99/graph-engineering) +to GraphAgent's durable YAML runtime. The source repository is MIT-licensed; its +copyright and license are available in the linked repository. The YAML files here +are project-specific adaptations, not verbatim copies. + +The adaptations were cross-checked against the executable examples in +[GraphARC](https://github.com/CodeGraphContext/GraphARC), Anthropic's +[workflow patterns](https://www.anthropic.com/engineering/building-effective-agents) +and [multi-agent production notes](https://www.anthropic.com/engineering/multi-agent-research-system), +plus Google's controlled study on +[when agent teams help or hurt](https://research.google/blog/towards-a-science-of-scaling-agent-systems-when-and-why-agent-systems-work/). +No Python or framework runtime was copied. + +## Reference graphs + +| Workflow | Protected spine | Use it for | +|---|---|---| +| `design-decision-loop` | internal grill → reasoner → fresh audit → PASS-only finalization | Deep development-document work and design-level debugging before implementation | +| `parallel-development-loop` | frozen contract → parallel modules → local audit → wiring → reasoner + verification → parallel review → arbiter | Medium/high-scale project implementation with bounded local correction waves | +| `deep-review-dag-module` | parallel exploration → parallel review → claim verification → arbiter → PASS report or targeted LOOP | Deep review of an already-built subsystem; retarget its lanes to the current project area | +| `change-review` | survey → parallel review/verification → arbiter | A compact fixed review when the medium/high-scale graph would be wasteful | + +The project-scoped `reasoner` used by the first two graphs lives at +`.opencode/agent/reasoner.md`. `/dag-flow` selects the closest reference from the +request. Start a saved graph by name only when its embedded target and inputs already +fit. Generic design/development requests must be derived into a one-off DAG with the +actual task injected into the root node; deep review requests retarget the hard-coded +DAG-module lanes unless that module is the real target. + +## Agent adaptation contract + +1. **Derive, do not blindly replay.** Preserve the reference graph's phase order and real artifact edges, then choose the actual module count, reviewer lanes, and local scope for the task. +2. **Protected nodes cannot be pruned.** Fresh-context review gates, deterministic verification, the single arbiter, and PASS-only finalization always remain. A parent may replace them only with equivalent fresh nodes carrying the same contract. +3. **Every prune is evidence-bearing.** Record `{node, prune_reason, replacement_coverage}`. Missing either field is fail-closed and the next gate must return `BLOCKED`, not silently accept the smaller graph. +4. **Every loop is local and acyclic.** A gate returns `PASS | LOOP | BLOCKED`. `LOOP` identifies the smallest preceding slice to revisit; the parent pauses, replans new correction/review nodes, and resumes. Completed nodes are never restarted in place. +5. **Expansion stays bounded.** New fan-out must have disjoint work or independent context, real downstream consumers, one merge owner, and enough remaining concurrency/node/replan budget. + +## Gate disposal rules + +| Verdict | Required parent action | Required evidence | +|---|---|---| +| `PASS` | Continue to the next protected phase or finalize | Coverage of every material criterion; no unresolved material finding | +| `LOOP` | Pause, add a fresh local correction/review wave with new node IDs, resume | Reason, minimal `loop_scope`, acceptance condition, `stop_reason` | +| `BLOCKED` | Stop and report; do not reinterpret as advisory success | Missing evidence/decision, unresolved contradiction, no progress, or a reached cap | + +These graphs copy topology ideas, not framework code or the upstream repository's +nine disconnected knowledge-graph prompts. The full source comparison and license +notes are in [`docs/graph-engineering-template-research.md`](../../docs/graph-engineering-template-research.md). diff --git a/.opencode/workflows/deep-review-dag-module.yaml b/.opencode/workflows/deep-review-dag-module.yaml new file mode 100644 index 0000000000..0274430e6b --- /dev/null +++ b/.opencode/workflows/deep-review-dag-module.yaml @@ -0,0 +1,397 @@ +# Medium/high-scale reference topology for reviewing an existing project area. +# The parent agent may retarget, expand, or prune exploration/reviewer lanes, but +# must preserve independent verification, one arbiter, and PASS-only completion. +# Every prune requires prune_reason + replacement_coverage. LOOP is a replan that +# adds fresh targeted review/verification/arbiter nodes; the DAG never gains a cycle. +title: "Deep Review: DAG Workflow Module (adaptive reference)" +config: + name: deep-review-dag-module + max_concurrency: 5 + max_node_replan_attempts: 3 + max_total_nodes: 30 + node_defaults: + required: false + report_to_parent: false + worker_config: + timeout_ms: 600000 + nodes: + # Wave 1: Exploration (parallel) + - id: explore-core + name: "Explore DAG Core" + worker_type: explore + depends_on: [] + prompt_template: + inline: | + Explore the DAG workflow core module at packages/opencode/src/dag/. + Focus on: dag.ts (workflow lifecycle, state machine, withWorkflowLock), admission.ts (deep admission QA state machine), config.ts (dag.jsonc tier resolution), model.ts (model resolution chain), review-lifecycle.ts (review contract validation). + + Output: + 1. File inventory with line counts and primary responsibilities + 2. Key exported functions and their call relationships + 3. State machine transitions (workflow states, admission states) + 4. Cross-file dependency graph within the core + 5. External dependencies (Effect, Schema, other src/ modules) + 6. Any immediately visible concerns (complexity hotspots, large functions) + + - id: explore-runtime + name: "Explore DAG Runtime" + worker_type: explore + depends_on: [] + prompt_template: + inline: | + Explore the DAG runtime subsystem at packages/opencode/src/dag/runtime/. + Focus on: scheduler/executor, capture.ts (output capture), recovery.ts (crash recovery, settle), summary-publisher.ts (derived-view publishing), and any other files in this directory. + + Output: + 1. File inventory with responsibilities + 2. Scheduling algorithm and concurrency model + 3. Crash recovery mechanism (how paused workflows resume) + 4. State persistence layer (what's durable, what's ephemeral) + 5. Event emission and bus integration + 6. Potential race conditions or ordering hazards + + - id: explore-templates + name: "Explore Templates & Workflows" + worker_type: explore + depends_on: [] + prompt_template: + inline: | + Explore the DAG templates and workflows subsystem: + - packages/opencode/src/dag/templates/ (prompt template rendering, sanitization) + - packages/opencode/src/dag/workflows.ts (saved workflow library, spec resolution) + + Output: + 1. Template rendering pipeline (how inline/id templates resolve) + 2. Sanitization logic (what's escaped, injection vectors) + 3. Workflow spec parsing and validation + 4. Library resolution order (project vs global scope) + 5. Input mapping and variable interpolation mechanics + 6. Edge cases in template resolution + + - id: explore-integrations + name: "Explore DAG Integrations" + worker_type: explore + depends_on: [] + prompt_template: + inline: | + Explore the DAG module's peripheral integrations: + 1. TUI: packages/tui/src/feature-plugins/system/dag-inspector.tsx and related files (sidebar indicator, summary pipeline, sync.tsx dag slice) + 2. Schema: packages/schema/ — find all dag-related event definitions (dag.workflow.*, dag.node.*) + 3. HTTP API: find routes serving DAG operations (workflow start/status/control/extend) + 4. SDK: packages/sdk/js — generated client methods for DAG operations + + Output: + 1. Integration surface map (which server types flow to which consumers) + 2. Event definitions and their manifest inclusion status + 3. TUI sync mechanism (bootstrap fetch + event stream) + 4. Type sharing pattern (SDK-generated vs hand-duplicated) + 5. Any drift between server schema and TUI/SDK consumers + + # Wave 2: Review (parallel, 5 dimensions) + - id: review-architecture + name: "Review: Architecture" + worker_type: general + depends_on: [explore-core, explore-runtime, explore-templates, explore-integrations] + prompt_template: + inline: | + You are an ARCHITECTURE REVIEWER for the DAG workflow module. Read-only — do not modify any file. + + Review target: packages/opencode/src/dag/ and its integrations (TUI dag-inspector, schema events, HTTP API routes). + + Exploration results are provided as upstream context. Use them as a starting map, but verify against actual code. + + Review criteria: + - Module boundaries: are responsibilities cleanly separated? + - Dependency direction: do dependencies point inward (domain ← infra)? + - Layer violations: does runtime leak into config? Does TUI aggregate server-side data? + - Self-containment: does each Layer/defaultLayer provide its own dependencies? + - Coupling: are there hidden coupling points between admission, lifecycle, and runtime? + - Extension invariants from AGENTS.md: LayerNode wiring, serviceOption lazy resolution + + MANDATORY output format: + 1. findings: array of {severity: CRITICAL|HIGH|MEDIUM|LOW, title, description, evidence: "file:line", recommendation} + 2. unverified_claims: array of strings — assertions you could NOT confirm with file:line evidence + 3. summary: 2-3 sentence overall assessment + + - id: review-logic + name: "Review: Logic Correctness" + worker_type: general + depends_on: [explore-core, explore-runtime, explore-templates, explore-integrations] + prompt_template: + inline: | + You are a LOGIC CORRECTNESS REVIEWER for the DAG workflow module. Read-only — do not modify any file. + + Review target: packages/opencode/src/dag/ and its integrations. + + Exploration results are provided as upstream context. Verify against actual code. + + Review criteria: + - State machine completeness: are all transitions valid? Any unreachable states? + - Lock correctness: withWorkflowLock — can it deadlock? Starve? Leak? + - Concurrency: scheduler layer computation, max_concurrency enforcement, race conditions + - Error handling: are Effect errors properly typed and propagated? + - Boundary conditions: empty graphs, single-node, cyclic depends_on detection + - Admission state machine: can it reach invalid states? Fingerprint collision? + - Recovery: settle() correctness after crash — can it lose state or duplicate work? + + MANDATORY output format: + 1. findings: array of {severity: CRITICAL|HIGH|MEDIUM|LOW, title, description, evidence: "file:line", recommendation} + 2. unverified_claims: array of strings + 3. summary: 2-3 sentence overall assessment + + - id: review-style + name: "Review: Code Style & Conventions" + worker_type: general + depends_on: [explore-core, explore-runtime, explore-templates, explore-integrations] + prompt_template: + inline: | + You are a CODE STYLE & CONVENTIONS REVIEWER for the DAG workflow module. Read-only — do not modify any file. + + Review target: packages/opencode/src/dag/ and its integrations. + + Review against the AGENTS.md Style Guide: + - No unnecessary destructuring (use dot notation) + - No import aliases or star imports + - const over let, ternaries over reassignment + - No else statements (early returns) + - No single-use helper extraction + - Effect generators: bind services to named variables + - Schema definitions: snake_case field names + - Dynamic imports for heavy modules in startup-sensitive paths + - No comments unless non-obvious constraints + + Also check: + - Naming consistency across the module + - Type annotation discipline (rely on inference where possible) + - File organization and export patterns + + MANDATORY output format: + 1. findings: array of {severity: CRITICAL|HIGH|MEDIUM|LOW, title, description, evidence: "file:line", recommendation} + 2. unverified_claims: array of strings + 3. summary: 2-3 sentence overall assessment + + - id: review-testability + name: "Review: Testability & Coverage" + worker_type: general + depends_on: [explore-core, explore-runtime, explore-templates, explore-integrations] + prompt_template: + inline: | + You are a TESTABILITY & COVERAGE REVIEWER for the DAG workflow module. Read-only — do not modify any file. + + Review target: packages/opencode/src/dag/ and its test files (search for *.test.ts in or near the dag directory). + + Review criteria: + - Test existence: which critical paths have NO tests? + - State machine coverage: are all transitions tested? + - Boundary conditions: empty input, malformed YAML, cyclic graphs + - Integration tests: is the TUI↔server contract tested? + - Mock discipline: are tests testing real implementation or duplicating logic? + - Test isolation: can tests run independently? Any shared mutable state? + - Recovery paths: is crash recovery (settle) tested? + - Concurrency: are race conditions exercised in tests? + + Search for test files: look in packages/opencode/test/ for dag-related tests. + + MANDATORY output format: + 1. findings: array of {severity: CRITICAL|HIGH|MEDIUM|LOW, title, description, evidence: "file:line or test-file path", recommendation} + 2. unverified_claims: array of strings + 3. coverage_gaps: array of {path: string, untested_scenarios: string[]} + 4. summary: 2-3 sentence overall assessment + + - id: review-robustness + name: "Review: Runtime Robustness" + worker_type: general + depends_on: [explore-core, explore-runtime, explore-templates, explore-integrations] + prompt_template: + inline: | + You are a RUNTIME ROBUSTNESS REVIEWER for the DAG workflow module. Read-only — do not modify any file. + + Review target: packages/opencode/src/dag/ with focus on runtime behavior. + + Review criteria: + - Crash recovery: what happens if the process dies mid-node-spawn? Mid-state-transition? + - State persistence: is durable state written atomically? Can partial writes corrupt? + - Lock behavior: what happens if a lock holder crashes? Is there a timeout? + - Resource leaks: are child sessions always cleaned up? Timers cleared? + - Backpressure: what if max_concurrency nodes all hang? Is there a global timeout? + - Event loss: if GlobalBus events are missed, do consumers recover? (TUI bootstrap fetch) + - Memory: unbounded growth in workflow state for long-running workflows? + - Graceful degradation: what fails first under resource pressure? + + MANDATORY output format: + 1. findings: array of {severity: CRITICAL|HIGH|MEDIUM|LOW, title, description, evidence: "file:line", recommendation} + 2. unverified_claims: array of strings + 3. failure_scenarios: array of {scenario: string, impact: string, likelihood: HIGH|MEDIUM|LOW} + 4. summary: 2-3 sentence overall assessment + + # Wave 3: Claim Verification + - id: verify-claims + name: "Verify Disputed Claims" + worker_type: general + depends_on: [review-architecture, review-logic, review-style, review-testability, review-robustness] + required: true + output_schema: + type: object + required: [verdict, verified_claims, disputed_findings_resolution, critical_findings_status, coverage_gaps, evidence_quality] + properties: + verdict: + type: string + enum: [VERIFIED, GAPS, BLOCKED] + verified_claims: { type: array, items: { type: object } } + disputed_findings_resolution: { type: array, items: { type: object } } + critical_findings_status: { type: array, items: { type: object } } + coverage_gaps: { type: array, items: { type: object } } + evidence_quality: { type: string } + prompt_template: + inline: | + You are a CLAIM VERIFIER. Read-only — do not modify any file. + + Five reviewers produced findings and unverified_claims about the DAG workflow + module. You are the fresh-context review of that entire local review wave. + Check every unverified/disputed/CRITICAL/HIGH claim, then audit whether the + requested scope and acceptance criteria were actually covered. Sample material + MEDIUM/LOW claims instead of trusting reviewer self-report. + + Upstream context contains all 5 reviewer outputs. Extract: + 1. All items in each reviewer's unverified_claims array + 2. Any findings where reviewers disagree (conflicting severity or conclusions) + 3. Any CRITICAL/HIGH findings — these MUST be verified regardless + 4. Any requested file area, integration, risk, or review criterion with no + evidence-bearing reviewer output + 5. Any parent-declared prune lacking prune_reason or replacement_coverage + + For each claim, read the actual source file at the cited location and determine: + - CONFIRMED: the code does what the reviewer claims (cite the exact line) + - REFUTED: the code does NOT do what the reviewer claims (explain why) + - PARTIALLY_CONFIRMED: the claim is directionally correct but imprecise + - UNRESOLVABLE: cannot determine from static analysis alone + + Verdict: + - VERIFIED: every material scope/criterion is covered and no material claim is + left unresolved + - GAPS: a bounded fresh review can close named coverage or evidence gaps + - BLOCKED: required evidence cannot be obtained or the review wave is not + auditable + + Submit the structured result. coverage_gaps must name the missing scope, + evidence, and the smallest reviewer lane that should be added in a LOOP. + + # Wave 4: Arbitration + - id: arbitrate + name: "Arbiter: Final Verdict" + worker_type: general + depends_on: [verify-claims] + required: true + report_to_parent: true + output_schema: + type: object + required: [verdict, reason, evidence, findings, loop_scope, stop_reason, next_action, prune_decisions] + properties: + verdict: + type: string + enum: [PASS, LOOP, BLOCKED] + reason: { type: string } + evidence: + type: array + items: { type: string } + findings: + type: array + items: + type: object + required: [severity, title, evidence, status] + properties: + severity: + type: string + enum: [CRITICAL, HIGH, MEDIUM, LOW] + title: + type: string + description: + type: string + evidence: + type: string + status: + type: string + enum: [CONFIRMED, REFUTED, PARTIALLY_CONFIRMED] + recommendation: + type: string + loop_scope: + type: array + items: + type: string + stop_reason: + type: string + enum: [goal_met, correction_required, evidence_missing, no_progress, round_cap, budget_cap] + next_action: + type: string + enum: [finalize, replan, stop] + prune_decisions: + type: array + items: + type: object + required: [node, prune_reason, replacement_coverage] + properties: + node: { type: string } + prune_reason: { type: string } + replacement_coverage: { type: string } + prompt_template: + inline: | + You are the ARBITER for this deep review of the DAG workflow module. You rule on VERIFIED evidence only. + + The verification wave has checked all unverified claims and disputed findings. Use its output as your primary evidence base. The 5 reviewer outputs are also available for context. + + Your job: + 1. For each CONFIRMED finding, assess its true severity (reviewers may over/under-rate) + 2. For each REFUTED claim, discard it — do not include in findings + 3. For PARTIALLY_CONFIRMED, include with corrected description + 4. Deduplicate findings that describe the same root cause + 5. Rank findings by impact + 6. Determine the fail-closed gate verdict: + - PASS: no unresolved material finding; scope and evidence coverage are complete + - LOOP: a bounded targeted review can resolve specific omissions or disputes + - BLOCKED: evidence is insufficient, a critical contradiction is unresolved, + progress stalled, or a graph ceiling was reached + 7. LOOP must name the minimal new review/verification scope. It never means + rerun the whole graph or restart completed nodes. + 8. Audit every parent-declared prune. Missing prune_reason or + replacement_coverage forbids PASS. + 9. State reason, evidence, stop_reason, and the exact next action. A bare + conclusion is not a valid verdict. + + Parent disposal contract: PASS → finalize; LOOP → pause/replan/resume fresh + targeted review + verification + arbiter nodes; BLOCKED → stop. The parent + must not reinterpret LOOP as advisory acceptance. + + Submit your structured verdict via submit_result. + + # Continuation: prepare a bounded local review loop + - id: deep-dive + name: "Plan the targeted fresh-context review loop" + worker_type: general + depends_on: [arbitrate] + condition: 'arbitrate.output.verdict == "LOOP"' + required: true + report_to_parent: true + prompt_template: + inline: | + The arbiter required LOOP. Produce a minimal replan fragment proposal for a + new local review wave. Include only the missing or disputed scope, assign new + node IDs, preserve real artifact dependencies, add a fresh verifier and a new + arbiter, and stay within the workflow caps. This is read-only: do not fix code. + + Return the loop reason, new nodes, dependencies, evidence each node must + collect, acceptance condition, and stop reason. The parent must pause, replan, + and resume; it must never restart completed nodes or create a cycle. + + - id: finalize-review + name: "Publish the accepted deep-review report" + worker_type: general + depends_on: [arbitrate] + condition: 'arbitrate.output.verdict == "PASS"' + required: true + report_to_parent: true + prompt_template: + inline: | + Publish the final evidence-backed review report. Include scope coverage, + confirmed findings, discarded/refuted claims, verification evidence, residual + low-risk issues, and the final PASS reason. Do not introduce new findings or + claims that were not verified upstream. diff --git a/.opencode/workflows/design-decision-loop.yaml b/.opencode/workflows/design-decision-loop.yaml new file mode 100644 index 0000000000..7e9435448b --- /dev/null +++ b/.opencode/workflows/design-decision-loop.yaml @@ -0,0 +1,121 @@ +# Reference topology. The parent agent may expand or prune non-protected nodes, +# but must preserve audit-small-loop and finalize-design. Every prune requires a +# prune_reason plus replacement_coverage. LOOP is implemented by replan with new +# revision/audit nodes; completed nodes are never restarted in place. +title: "Design decision deep dive: grill → reason → audit → finalize" +config: + name: design-decision-loop + max_concurrency: 2 + max_node_replan_attempts: 3 + max_total_nodes: 18 + node_defaults: + required: false + report_to_parent: false + worker_config: + timeout_ms: 600000 + nodes: + - id: frame-decision + name: "Internally grill the design decision" + worker_type: general + depends_on: [] + required: true + output_schema: + type: object + required: [goal, assumptions, alternatives, failure_questions, draft_design] + properties: + goal: { type: string } + assumptions: { type: array, items: { type: string } } + alternatives: { type: array, items: { type: object } } + failure_questions: { type: array, items: { type: string } } + draft_design: { type: string } + prompt_template: + inline: | + Act as an internal grill-me pass over the parent request. Do not ask the + user questions from this child session. Reconstruct the real decision, + challenge hidden assumptions, compare serious alternatives, and identify + the cases that would make the design fail. + + Produce a concrete draft design, not a list of generic advice. Mark every + unresolved fact explicitly; never invent an answer to make the draft look + complete. Submit the structured result. + + - id: simulate-design + name: "Reason through execution paths" + worker_type: reasoner + depends_on: [frame-decision] + required: true + prompt_template: + inline: | + reason_target: design_doc + subject: Use the complete upstream decision frame and draft design as the subject. + goal: Simulate whether the draft can achieve its stated goal without contradictions, unreachable states, uncovered boundaries, ownership conflicts, or false completion. + known_constraints: Treat upstream assumptions as assumptions, not facts. Preserve every explicit invariant and scope boundary. + focus_dimensions: [Internal Contradiction, Boundary / Edge Case, Coverage Hole, State / Flow Consistency, Responsibility / Ownership] + + - id: audit-small-loop + name: "Fresh-context audit of grill + reasoning" + worker_type: general + depends_on: [frame-decision, simulate-design] + required: true + report_to_parent: true + output_schema: + type: object + required: [verdict, reason, evidence, loop_scope, stop_reason, next_action, prune_decisions] + properties: + verdict: + type: string + enum: [PASS, LOOP, BLOCKED] + reason: { type: string } + evidence: { type: array, items: { type: string } } + loop_scope: { type: array, items: { type: string } } + stop_reason: + type: string + enum: [goal_met, correction_required, evidence_missing, no_progress, round_cap, budget_cap] + next_action: + type: string + enum: [finalize, replan, stop] + prune_decisions: + type: array + items: + type: object + required: [node, prune_reason, replacement_coverage] + properties: + node: { type: string } + prune_reason: { type: string } + replacement_coverage: { type: string } + prompt_template: + inline: | + You are a fresh-context gate. Review the immediately preceding small + loop: the internal grill and the reasoner's simulation. Do not trust either + node's self-assessment. + + Fail closed: + - PASS only when the goal, assumptions, alternatives, state/flow paths, + boundaries, ownership, and completion rule are materially covered. + - LOOP when a bounded revision can close a specific omission. Return only + the minimal node scope that must be recreated with new node IDs. + - BLOCKED when evidence or a required decision is missing, progress has + stalled, or a graph ceiling was reached. + - Every claim needs an upstream reference or repository evidence. A bare + assertion is not evidence. + - Every pruned node requires both prune_reason and replacement_coverage; + missing either forbids PASS. + + Parent disposal contract: PASS → finalize; LOOP → pause, replan new + revision/reasoning/audit nodes, then resume; BLOCKED → stop with this + reason. Never finalize stale outputs after LOOP or BLOCKED. + + - id: finalize-design + name: "Finalize the reviewed design" + worker_type: general + depends_on: [frame-decision, simulate-design, audit-small-loop] + condition: 'audit-small-loop.output.verdict == "PASS"' + required: true + report_to_parent: true + prompt_template: + inline: | + Produce the final development/design document from the reviewed upstream + artifacts. Resolve only issues supported by the reasoning and audit. + Preserve assumptions, rejected alternatives, invariants, acceptance + criteria, and remaining risks so implementation agents cannot silently + reinterpret the decision. diff --git a/.opencode/workflows/parallel-development-loop.yaml b/.opencode/workflows/parallel-development-loop.yaml new file mode 100644 index 0000000000..82141c72df --- /dev/null +++ b/.opencode/workflows/parallel-development-loop.yaml @@ -0,0 +1,282 @@ +# Medium/high-scale reference topology. The parent agent derives the real module +# fan-out and may expand or prune non-protected workers. It must preserve both +# review gates, verification, one final arbiter, and the final PASS condition. +# Every prune requires prune_reason + replacement_coverage. LOOP adds a new local +# correction/review wave through replan; it never creates a graph cycle. +title: "Parallel development: module wave → local audit → wiring → reasoning → parallel review" +config: + name: parallel-development-loop + max_concurrency: 5 + max_node_replan_attempts: 3 + max_total_nodes: 32 + node_defaults: + required: false + report_to_parent: false + worker_config: + timeout_ms: 900000 + nodes: + - id: freeze-design + name: "Freeze scope, modules, write sets, and acceptance" + worker_type: plan + depends_on: [] + required: true + output_schema: + type: object + required: [scope, modules, write_sets, acceptance_criteria, system_logic] + properties: + scope: { type: string } + modules: { type: array, items: { type: object } } + write_sets: { type: array, items: { type: object } } + acceptance_criteria: { type: array, items: { type: string } } + system_logic: { type: string } + prompt_template: + inline: | + Turn the approved design into an implementation contract. Define module + boundaries, real dependency edges, disjoint write sets, interface contracts, + integration order, executable acceptance criteria, and the system logic that + later reasoning must simulate. + + This is a reference graph: the parent may replace the three baseline module + workers with the actual fan-out. Prune only irrelevant workers and record a + prune_reason plus replacement_coverage. If write sets overlap, serialize or + assign one merge owner instead of pretending the work is parallel. + + - id: develop-core + name: "Develop core/domain module slice" + worker_type: build + depends_on: [freeze-design] + prompt_template: + inline: | + Implement only the assigned core/domain slice and its declared write set. + Do not edit another worker's files. If the upstream contract does not provide + a disjoint write set, stop and report BLOCKED. Return changed files, checks + run, unresolved integration needs, and evidence for each acceptance criterion. + + - id: develop-adapters + name: "Develop adapters/integration module slice" + worker_type: build + depends_on: [freeze-design] + prompt_template: + inline: | + Implement only the assigned adapter/integration slice and its declared write + set. Respect the frozen interfaces. If the write set overlaps another worker, + stop and report BLOCKED. Return changed files, checks run, unresolved wiring + needs, and acceptance evidence. + + - id: develop-tests + name: "Develop test and verification slice" + worker_type: build + depends_on: [freeze-design] + prompt_template: + inline: | + Implement the independent test/verification slice from observable contracts, + not from copied implementation logic. Stay inside the declared write set. + Return changed files, commands, results, missing fixtures, and acceptance + criteria that still lack executable evidence. + + - id: audit-module-wave + name: "Fresh audit of the parallel module wave" + worker_type: general + depends_on: [develop-core, develop-adapters, develop-tests] + required: true + report_to_parent: true + output_schema: + type: object + required: [verdict, reason, evidence, loop_scope, stop_reason, next_action, prune_decisions] + properties: + verdict: + type: string + enum: [PASS, LOOP, BLOCKED] + reason: { type: string } + evidence: { type: array, items: { type: string } } + loop_scope: { type: array, items: { type: string } } + stop_reason: + type: string + enum: [goal_met, correction_required, evidence_missing, no_progress, round_cap, budget_cap] + next_action: + type: string + enum: [wire, replan, stop] + prune_decisions: + type: array + items: + type: object + required: [node, prune_reason, replacement_coverage] + properties: + node: { type: string } + prune_reason: { type: string } + replacement_coverage: { type: string } + prompt_template: + inline: | + Review only the immediately preceding parallel module wave. Check actual + changed files, write-set ownership, interface compatibility, acceptance + coverage, missing outputs, and claimed command results. + + PASS requires evidence for every material acceptance criterion and no write + collision. LOOP means a bounded subset must be recreated as new correction + nodes followed by a new fresh audit. BLOCKED means evidence, ownership, or a + required decision is unavailable. List the minimal loop_scope and exact + reason. Every prune requires prune_reason and replacement_coverage; missing + either forbids PASS. + + Parent disposal contract: PASS → wiring; LOOP → pause/replan/resume only the + affected module slice plus a new audit; BLOCKED → stop. Never continue to + wiring from a LOOP or BLOCKED result. + + - id: wire-modules + name: "Wire and reconcile module boundaries" + worker_type: build + depends_on: [develop-core, develop-adapters, develop-tests, audit-module-wave] + condition: 'audit-module-wave.output.verdict == "PASS"' + required: true + output_schema: + type: object + required: [summary, changed_files, diff, fingerprint, system_logic] + properties: + summary: { type: string } + changed_files: { type: array, items: { type: string } } + diff: { type: string } + fingerprint: { type: string } + system_logic: { type: string } + prompt_template: + inline: | + You are the single integration owner. Reconcile interfaces and wire the + accepted module outputs. Do not redesign unrelated modules. Run the narrowest + relevant integration checks, then return the actual final diff, changed file + list, a reproducible diff fingerprint, and a system-logic description of the + resulting execution paths for the reasoner. + + - id: simulate-wired-system + name: "Reason through the wired execution paths" + worker_type: reasoner + depends_on: [wire-modules] + required: true + prompt_template: + inline: | + reason_target: system_logic + subject: Use the upstream system-logic description of the wired implementation. + goal: Predict contradictions, unreachable states, boundary gaps, partial-failure behavior, concurrency hazards, and ownership conflicts before final review. + known_constraints: Predictions are hypotheses, not code evidence. Cite the upstream path or assumption behind every finding. + focus_dimensions: [Internal Contradiction, Boundary / Edge Case, Coverage Hole, State / Flow Consistency, Responsibility / Ownership] + + - id: verify-wired-system + name: "Run deterministic project verification" + worker_type: general + depends_on: [wire-modules] + required: true + output_schema: + type: object + required: [verdict, commands, evidence, failures] + properties: + verdict: + type: string + enum: [PASS, FAIL, BLOCKED] + commands: { type: array, items: { type: string } } + evidence: { type: array, items: { type: string } } + failures: { type: array, items: { type: string } } + prompt_template: + inline: | + Inspect repository instructions and run the smallest complete verification + set for the wired change: generated-artifact checks, typecheck, unit or + integration tests, and contract checks when applicable. Report exact commands + and results. Missing, stale, or unverifiable evidence is BLOCKED, never PASS. + + - id: review-logic + name: "Fresh review: logic and failure paths" + worker_type: general + depends_on: [wire-modules, simulate-wired-system, verify-wired-system] + prompt_template: + inline: | + Independently review the actual wired diff for logic correctness, state + transitions, boundaries, concurrency, recovery, and failure behavior. Treat + reasoner findings only as hypotheses; confirm or refute each against code, + diff, or reproducible verification evidence. Return evidence-backed findings, + unverified claims, and ACCEPT or REJECT. + + - id: review-architecture + name: "Fresh review: architecture and wiring" + worker_type: general + depends_on: [wire-modules, simulate-wired-system, verify-wired-system] + prompt_template: + inline: | + Independently review the actual wired diff for module boundaries, dependency + direction, ownership, interface drift, integration completeness, and repository + architecture rules. Every finding needs file:line or command evidence. Return + unverified claims separately and conclude ACCEPT or REJECT. + + - id: review-tests + name: "Fresh review: acceptance and regression evidence" + worker_type: general + depends_on: [wire-modules, simulate-wired-system, verify-wired-system] + prompt_template: + inline: | + Independently map every frozen acceptance criterion and material execution + path to a test, check, or explicit missing-evidence finding. Inspect whether + tests exercise the implementation rather than duplicate it. Return the + coverage matrix, evidence-backed findings, unverified claims, and ACCEPT or + REJECT. + + - id: arbitrate-final-review + name: "Arbitrate the parallel review wave" + worker_type: general + depends_on: [simulate-wired-system, verify-wired-system, review-logic, review-architecture, review-tests] + required: true + report_to_parent: true + output_schema: + type: object + required: [verdict, reason, evidence, findings, loop_scope, stop_reason, next_action, prune_decisions] + properties: + verdict: + type: string + enum: [PASS, LOOP, BLOCKED] + reason: { type: string } + evidence: { type: array, items: { type: string } } + findings: { type: array, items: { type: object } } + loop_scope: { type: array, items: { type: string } } + stop_reason: + type: string + enum: [goal_met, correction_required, evidence_missing, no_progress, round_cap, budget_cap] + next_action: + type: string + enum: [finalize, replan, stop] + prune_decisions: + type: array + items: + type: object + required: [node, prune_reason, replacement_coverage] + properties: + node: { type: string } + prune_reason: { type: string } + replacement_coverage: { type: string } + prompt_template: + inline: | + Act as the only merge owner for the final review wave. Deduplicate findings, + resolve reviewer conflicts against actual evidence, and audit completeness. + + Fail closed: + - PASS requires deterministic verification PASS, no unresolved material + finding, and evidence for every acceptance criterion. + - LOOP requires a bounded correction scope. Name only the implementation, + wiring, reasoning, verification, or review nodes that must be recreated. + - BLOCKED is mandatory when evidence is missing, reviewers cannot resolve a + material claim, ownership is unclear, or a graph ceiling is reached. + - A reasoner prediction is never evidence by itself. + - Every prune requires prune_reason and replacement_coverage; missing either + forbids PASS. + + Parent disposal contract: PASS → finalize; LOOP → pause/replan/resume a new + local correction + reasoning + review wave; BLOCKED → stop with reasons. + Never reinterpret LOOP as advisory acceptance. + + - id: finalize-delivery + name: "Finalize reviewed delivery" + worker_type: general + depends_on: [wire-modules, verify-wired-system, arbitrate-final-review] + condition: 'arbitrate-final-review.output.verdict == "PASS"' + required: true + report_to_parent: true + prompt_template: + inline: | + Produce the final delivery summary from the accepted implementation and + verification evidence: changed modules, commands and results, acceptance + coverage, residual risks, and rollback or follow-up notes. Do not claim work + that is not present in the upstream evidence. diff --git a/README.md b/README.md index d9681e21e2..e9399ab3be 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,20 @@ team.** --- +## Graph engineering, before it had a name + +GraphAgent treats a graph as an **executable, durable, inspectable contract** — not a diagram of agents and not a prompt chain with arrows added afterward. The public history landed the first complete DAG-engine commit on **2026-07-02**. The paper [*What makes prompts a graph: necessary and sufficient conditions for prompt graph engineering*](https://arxiv.org/abs/2607.27578), which formalized explicit structure, prompt/topology separation, executable semantics, and the graph as a first-class artifact, appeared on **2026-07-30**. The implementation was already running four weeks before the vocabulary caught up. + +Our graph-engineering doctrine is operational: + +1. **Edges must carry work.** A dependency exists only when the downstream node consumes the upstream artifact. Delete ceremonial sequencing and run truly independent work in parallel. +2. **A template is a reference topology, not a cage.** The parent agent may expand or prune lanes to match the task, but every prune records its reason and replacement coverage. +3. **Prediction, verification, and merge have different owners.** A `reasoner` simulates likely execution paths, a fresh-context reviewer checks the preceding local wave, and exactly one arbiter owns the verdict. These gates cannot be pruned. +4. **Iteration is a bounded local graph rewrite.** `PASS` finalizes, `LOOP` adds a new correction/review wave through pause → replan → resume, and `BLOCKED` stops with evidence. Completed nodes never form a hidden cycle. +5. **Reality outranks self-report.** State is event-sourced, recovery follows durable evidence, tests and code settle claims, and humans retain pause/step/cancel/replan authority where mistakes are expensive. + +The repository ships three opinionated reference graphs: design decision deep-dive, parallel project delivery, and deep review of an existing subsystem. `/dag-flow` selects the closest shape from the request, injects the current task, and derives the actual DAG while preserving its fail-closed gates. See the [Graph Engineering workflow catalog](./.opencode/workflows/GRAPH-ENGINEERING.md). The designs adapt useful patterns from the MIT-licensed [graph-engineering](https://github.com/codejunkie99/graph-engineering) project to this runtime's stronger execution, recovery, and control contracts. + ## Why a DAG A single agent loop struggles once a task has staged dependencies, parallelizable independent work, or a quality gate in the middle. Four judgments shaped this engine: @@ -234,7 +248,8 @@ Exact file boundaries are listed in [`NOTICE`](./NOTICE). The AGPL covers the DA ## Docs - [Saved workflow authoring guide](./packages/core/src/plugin/skill/create-dag-workflow.md) — the `create-dag-workflow` skill body -- [`.opencode/workflows/change-review.yaml`](./.opencode/workflows/change-review.yaml) — a working saved workflow, startable as `change-review` +- [Graph Engineering workflow catalog](./.opencode/workflows/GRAPH-ENGINEERING.md) and [source research](./docs/graph-engineering-template-research.md) — reusable shapes, evidence, and migration choices +- [`.opencode/workflows/change-review.yaml`](./.opencode/workflows/change-review.yaml) — compact change review, startable as `change-review` - [`docs/harness-dag.md`](./docs/harness-dag.md) — deep-mode admission & review lifecycle - [`.opencode/dag-prompts`](./.opencode/dag-prompts) — built-in node prompt templates - [`AGENTS.md`](./AGENTS.md) — contribution & development guide diff --git a/README.zh.md b/README.zh.md index e337d2f6b4..5fadaf51fe 100644 --- a/README.zh.md +++ b/README.zh.md @@ -12,6 +12,20 @@ GraphAgent 是本项目对外的产品名;仓库以 **OpenCode-GraphAgent** --- +## 「Graph Engineering」这个名字出现前,GraphAgent 已经在跑 + +在 GraphAgent 里,graph 是一份**可执行、可持久化、可观测、可控制的契约**。节点干活,边传产物,运行时负责调度和恢复。公开 Git 历史显示,第一版完整 DAG 引擎在 **2026-07-02** 已经提交;论文 [*What makes prompts a graph: necessary and sufficient conditions for prompt graph engineering*](https://arxiv.org/abs/2607.27578) 到 **2026-07-30** 才把显式结构、prompt/拓扑分离、可执行语义和 graph 一等制品化归纳出来。术语晚了四周,工具没有等它。 + +这套东西落到了五条运行规则里: + +1. **每条边都要有用。** 如果下游不读上游产物,这条依赖就该删。真正独立的工作直接并行。 +2. **模板是参考拓扑,不是固定脚本。** 主 Agent 可以按任务扩展或剪枝,但每次剪枝都必须写明理由和替代覆盖证据。 +3. **推演、复审、裁决分开做。** `reasoner` 模拟潜在执行路径,fresh-context reviewer 复审前一个局部波次,最后由唯一 arbiter 给出裁决;这些门禁不可剪掉。 +4. **迭代是有界的局部改图。** `PASS` 才能定稿,`LOOP` 通过 pause → replan → resume 增加新的修正与复审波次,`BLOCKED` 带证据停止;终态节点不会被伪装成环。 +5. **代码和测试说了算。** 状态变更写入事件,崩溃恢复只认持久化证据。到了代价高的边界,人可以 pause、step、cancel 或 replan。 + +仓库已经附带三类强约束参考图:设计决策深挖、并行项目落地、已完成子系统深度 Review。`/dag-flow` 会先按需求选择最接近的中高规模样板,注入本次任务,再派生实际 DAG;可以扩展和剪枝,但不能绕过 fail-closed 门禁。入口见 [Graph Engineering 工作流目录](./.opencode/workflows/GRAPH-ENGINEERING.md)。这些 YAML 把 MIT 许可的 [graph-engineering](https://github.com/codejunkie99/graph-engineering) 项目里有价值的模式,适配到了本项目更严格的执行、恢复和控制契约上。 + ## 为什么是 DAG 任务一旦涉及分阶段依赖、可并行的独立工作,或者中间需要一道质量门禁,单智能体循环就不太够用了。这个引擎的设计基于四个判断: @@ -208,7 +222,8 @@ bun dev serve # headless API 服务(端口 4096) ## 文档 - [存盘工作流编写指南](./packages/core/src/plugin/skill/create-dag-workflow.md) —— `create-dag-workflow` skill 正文 -- [`.opencode/workflows/change-review.yaml`](./.opencode/workflows/change-review.yaml) —— 一个能用的存盘工作流,按 `change-review` 启动 +- [Graph Engineering 工作流目录](./.opencode/workflows/GRAPH-ENGINEERING.md)和[来源调研](./docs/graph-engineering-template-research.md) —— 可复用样板、证据与迁移取舍 +- [`.opencode/workflows/change-review.yaml`](./.opencode/workflows/change-review.yaml) —— 轻量变更审查图,按 `change-review` 启动 - [`docs/harness-dag.md`](./docs/harness-dag.md) —— deep 模式准入与审查生命周期 - [`.opencode/dag-prompts`](./.opencode/dag-prompts) —— 内置节点 prompt 模板 - [`AGENTS.md`](./AGENTS.md) —— 贡献与开发指南 diff --git a/docs/graph-engineering-template-research.md b/docs/graph-engineering-template-research.md new file mode 100644 index 0000000000..a4738d6b1e --- /dev/null +++ b/docs/graph-engineering-template-research.md @@ -0,0 +1,173 @@ +# Graph Engineering 样板调研与迁移建议 + +> 调研日期:2026-08-03 +> 范围:只研究、比对和提出迁移方案;未搬运模板、未修改产品代码。 + +## 结论先行 + +1. 用户所说的 “graph engineering” 最可能指个人仓库 [`codejunkie99/graph-engineering`](https://github.com/codejunkie99/graph-engineering):仓库名完全匹配,且明确包含 task graph 原则和 9 个可粘贴 workflow。不过它只有一次提交,不是行业标准或框架官方仓库。 +2. 真正适合向 `opencode-dag` 搬“可执行图样板”的强来源是 [`CodeGraphContext/GraphARC`](https://github.com/CodeGraphContext/GraphARC)。它把 Graph Engineering 做成分阶段示例,并实现 admission、预算、typed state、write allowlist、trace 和 fresh-context verifier;但当前 README 标注版本 `0.1.1`、API 尚不稳定,因此应搬拓扑和约束语义,不应引入它的 Python/LangGraph runtime。 +3. 本项目已经拥有 diamond、并行 reviewer、claim verification、单一 arbiter、并发/节点/重试上限和单 workspace 写入纪律,而且多数约束比 `codejunkie99/graph-engineering` 更可执行。最值得补的不是再复制一套相同 YAML,而是:假边检查、拓扑选择的 stop rule、确定性证据门、动态子图 admission、每节点写入白名单和机器可读停止原因。 +4. `reasoner.md` 没进入现有 `change-review` 不是因为 Graph Engineering 上游提供了模板却漏搬;上游根本没有代码 reasoner。更关键的是,本机 reasoner 自己声明只推演 ROADMAP/设计,禁止直接审已写 diff。最终采用两种合规接法:设计模板里直接推演设计;开发模板完成接线后,把真实执行路径整理成 `system_logic` 再推演,随后由 fresh-context reviewer 用代码和测试查证。预测永远不能直接充当 review 证据。 + +## 1. “Graph Engineering”最可能对应什么 + +当前没有一个被普遍接受的 “Graph Engineering 官方规范”。网上至少有三个不同层次的来源: + +| 优先级 | 来源 | 身份与可信边界 | 本次用途 | +|---|---|---|---| +| 1 | [`codejunkie99/graph-engineering`](https://github.com/codejunkie99/graph-engineering) | 标题完全匹配的个人仓库;README 将知识图谱和任务图并列;只有一次提交 | 回答“你说的那个仓库最可能是哪一个”,提取 task graph 原则和 KG prompts | +| 2 | [`CodeGraphContext/GraphARC`](https://github.com/CodeGraphContext/GraphARC) | CodeGraphContext 组织维护的早期实现;README 自称 governed agent runtime,列出 43 次提交和 `0.1.1` 不稳定状态 | 找可执行 graph stages、runtime contracts、reviewer/evidence 样板 | +| 3 | [Anthropic《Building effective agents》](https://www.anthropic.com/engineering/building-effective-agents) | 一手工程文章,给出生产中常见的 workflow 形状 | 校验 chaining、routing、parallelization、orchestrator-workers、evaluator-optimizer 的适用条件 | +| 4 | [Google Research《Towards a science of scaling agent systems》](https://research.google/blog/towards-a-science-of-scaling-agent-systems-when-and-why-agent-systems-work/) | 180 个配置的受控研究;给出并行任务收益、顺序任务惩罚和错误放大数据 | 为 stop rule 和集中式 arbiter 提供证据 | +| 5 | [Anthropic 多 agent Research 系统复盘](https://www.anthropic.com/engineering/multi-agent-research-system) | 生产系统复盘;解释 orchestrator-worker、并行搜索、fresh contexts、artifact handoff | 校验并行研究和上下文隔离,不作为固定 DAG 的唯一答案 | + +因此,“官方”应理解为“各项目作者自己的原始仓库/文档”,不能把任一项目包装成行业标准。 + +## 2. `codejunkie99/graph-engineering` 可迁移内容 + +### 2.1 任务图原则:适合迁移 + +原始文件:[`graph-engineering/references/task-graphs.md`](https://github.com/codejunkie99/graph-engineering/blob/master/graph-engineering/references/task-graphs.md)。 + +| 原则 | 原用途 | `opencode-dag` 适配方式 | 当前覆盖 | +|---|---|---|---| +| 删除假边 | 仅当下游真的需要上游结果时才连边 | 在 start/replan 前增加 edge lint:每条 `depends_on` 必须声明被消费的 artifact/field 或控制原因 | 文档要求显式依赖,但没有证据表明 runtime 会拒绝“不消费输出”的边 | +| Diamond | `plan → parallel workers → separate verify → one merge owner` | 固化为 workflow library 基础骨架,verifier 使用独立 child session,arbiter 单一所有者 | 已基本覆盖:parallel review、claim verification、arbiter | +| Stop rule | 只对可独立拆分的工作启用多 agent | admission brief 增加 `parallelizable_slices`、`shared_context_need`、`tool_density` 决策记录;顺序工作退回单 agent | 已有 Execution Mode Selection,但可加入更明确的顺序惩罚检查 | +| Human gate | 不可逆动作前才要求人类批准 | 将 deploy/publish/delete/refund 等动作前置为 `report_to_parent` checkpoint,用户批准后才 extend/replan | 有深度准入和 LLM gate,缺少通用的不可逆动作人类门模板 | +| 四项 guardrail | 循环上限、单文件单 writer、路由写死、agent 数硬上限 | 映射到 `max_node_replan_attempts`、write-set owner、代码/条件路由、`max_total_nodes`/`max_concurrency` | 多数已有;write set 主要靠编排纪律,尚非 runtime allowlist | + +Google 的受控研究支持这里的 stop rule:并行可拆任务中集中式协调提升显著;严格顺序任务中,多 agent 反而下降 39–70%;独立 agent 的错误放大高于集中式 orchestrator。数字和实验边界见 [Google Research 原文](https://research.google/blog/towards-a-science-of-scaling-agent-systems-when-and-why-agent-systems-work/)。 + +### 2.2 九个 paste-ready workflows:选择性迁移 + +原始文件:[`WORKFLOWS.md`](https://github.com/codejunkie99/graph-engineering/blob/master/WORKFLOWS.md)。这些主要是**知识图谱提示词**,不是代码工作流 DAG。 + +| 组 | 上游模板 | 适用场景 | 建议 | +|---|---|---|---| +| 教学 | `/kg-tutor` | 逐阶段教授知识图谱 | 不进入 reviewer 库;若产品要提供 KG 教学,可做独立 skill | +| 建模 | `/kg-scope`、`/kg-schema` | 能力问题、实体/关系、ontology | 可转成 `scope → schema-gate` 设计图;与代码 review 无关 | +| 抽取 | `/kg-extract`、`/kg-relations`、`/kg-events` | 分源抽取、证据 span、事件节点 | 仅在新增 KG 产品能力时迁移;保留 provenance/output schema 思想 | +| 质量与融合 | `/kg-fuse`、`/kg-eval` | 去重、precision/recall、数据泄漏、可逆 merge | `/kg-eval` 是唯一 reviewer 提示,但审的是 KG 指标,不是代码 diff | +| 服务 | `/kg-rag` | 图检索对比 vector baseline | 可作为未来 GraphRAG workflow,不应塞进当前 DAG reviewer | + +该仓库 [`SKILL.md`](https://github.com/codejunkie99/graph-engineering/blob/master/graph-engineering/SKILL.md) 中的 “LLM-as-reasoner over paths” 指知识图谱路径推理,不是本项目的代码/设计 reasoner。上游没有 `reasoner.md` 或 code-reviewer agent 样板。 + +## 3. GraphARC 中更值得搬的可执行样板 + +GraphARC README 的 [Quickstart](https://github.com/CodeGraphContext/GraphARC#quickstart) 明确列出 stage 0–6 和 capstone。建议搬**图形、节点契约和失败语义**,不要复制 Python runtime。 + +### 3.1 第一批:直接转成 YAML/prompt templates + +| 样板 | 原始文件 | 用途 | `opencode-dag` 适配 | +|---|---|---|---| +| Earned loop | [`stage1_loop.py`](https://github.com/CodeGraphContext/GraphARC/blob/main/grapharc/examples/stage1_loop.py) | `discover → act → verify → repeat`,只有验证失败才获得下一轮 | 对应 bounded `extend/replan`;每轮新节点 ID,保留 verdict disposal contract | +| Typed verify/retry | [`stage2_claims.py`](https://github.com/CodeGraphContext/GraphARC/blob/main/grapharc/examples/stage2_claims.py) | 抽取 claim、校验、有限重试 | 转成 `output_schema` + claim verification + `max_node_replan_attempts` | +| Bounded fan-out | [`stage3_fanout.py`](https://github.com/CodeGraphContext/GraphARC/blob/main/grapharc/examples/stage3_fanout.py) | 并行、失败隔离、去重、汇总 | 做通用 research/review fan-out;assembler 必须报告缺失 worker,不能静默忽略 | +| Investigation loop | [`stage4_investigation.py`](https://github.com/CodeGraphContext/GraphARC/blob/main/grapharc/examples/stage4_investigation.py) | 调查、评估进展、收敛或停止 | 把“无新证据/目标满足/轮数上限”转成结构化 StopReason | +| Fresh verifier | [`stage5_verifier.py`](https://github.com/CodeGraphContext/GraphARC/blob/main/grapharc/examples/stage5_verifier.py) | 新上下文 reviewer + 确定性证据锚 | 强化 `change-review`:先验证引用/测试/日志存在,再交给 LLM reviewer 裁决 | + +### 3.2 第二批:需要 runtime 能力 + +| 样板/机制 | 原始来源 | 价值 | 迁移前提 | +|---|---|---|---| +| Stage 0 deterministic DAG | [`stage0_dag.py`](https://github.com/CodeGraphContext/GraphARC/blob/main/grapharc/examples/stage0_dag.py) | 无模型的 `load → split → count → report` 基线 | 允许确定性函数节点,或把它们映射到现有 tool/build worker | +| Provenance memory | [`stage6_memory.py`](https://github.com/CodeGraphContext/GraphARC/blob/main/grapharc/examples/stage6_memory.py) | claim 来源、替代关系、召回 | 需要明确 durable artifact/claim schema;不要和 session transcript 混为一体 | +| Research capstone | [`capstone.py`](https://github.com/CodeGraphContext/GraphARC/blob/main/grapharc/examples/capstone.py) | `recall → plan → fan-out → verify → answer → remember` | 先完成证据契约和 memory provenance,再做完整模板 | +| Admission linter | [README admission gate](https://github.com/CodeGraphContext/GraphARC#the-admission-gate) | 动态子图在执行前检查 kind、edge policy、预算、深度、无环 | 在 `start/extend/replan` 增加 dry-run/check-only 语义和拒绝码 | +| Runtime contracts | [GraphARC runtime 说明](https://github.com/CodeGraphContext/GraphARC#what-it-adds-on-top-of-langgraph) | typed state、write allowlist、预算、JSONL trace/replay/diff | 需要产品代码;优先做 write allowlist 和 machine-readable StopReason | + +GraphARC 自己也写明 router 映射、Pydantic validator 等仍有窄缺口,且 API 不稳定。因此它应是设计输入,不应成为新依赖。 + +## 4. Anthropic 官方样板对 reviewer 的补强 + +Anthropic 将常用形状分为 prompt chaining、routing、parallelization、orchestrator-workers、evaluator-optimizer;官方最小实现位于 [`claude-cookbooks/patterns/agents`](https://github.com/anthropics/claude-cookbooks/tree/main/patterns/agents)。 + +对本项目最有价值的是以下四项: + +1. **Parallel sectioning 与 voting 分开**:不同 reviewer 维度属于 sectioning;同一漏洞问题多次独立审查属于 voting。不要把两者都写成“并行 reviewer”。[原文](https://www.anthropic.com/engineering/building-effective-agents#workflow-parallelization)还直接用多 prompt 审代码漏洞作为 voting 示例。 +2. **Orchestrator-workers 只用于子任务无法预知的工作**:固定 review dimensions 用静态 DAG;未知文件/未知调查方向才让 orchestrator 动态拆分。[原文](https://www.anthropic.com/engineering/building-effective-agents#workflow-orchestrator-workers)。 +3. **Evaluator-optimizer 必须有清晰验收标准和可测改进**:适合 `implement → fresh review → targeted repair`,不适合无终止条件的“继续优化”。[原文](https://www.anthropic.com/engineering/building-effective-agents#workflow-evaluator-optimizer)。 +4. **Fresh-context evaluator 不信 builder 自评**:[`evaluator.md`](https://github.com/anthropics/cwc-long-running-agents/blob/main/claude-code-config/.claude/agents/evaluator.md)要求先读 spec、diff、截图/日志,再返回 `PASS/NEEDS_WORK`;缺证据默认失败。[配套 README](https://github.com/anthropics/cwc-long-running-agents#the-quality-loop)把它与 default-FAIL evidence contract、build/evaluate/rebuild 有界循环组合起来。 + +本项目现有 child session 已天然提供上下文隔离;缺口主要在“确定性证据锚”和“每个验收条件默认未通过,直到证据被实际读取”。 + +## 5. 与当前项目逐项对照 + +### 已有且不应重复搬运 + +| 能力 | 当前证据 | 判断 | +|---|---|---| +| Diamond/并行分工 | `packages/core/src/plugin/command/workflow.md:205-243` | 已有 parallel fan-out 和 assembler | +| 多维 reviewer + arbiter | `packages/core/src/plugin/command/workflow.md:247-323` | 已有 architecture/logic/style 分离及单一裁决者 | +| claim verification | `packages/core/src/plugin/command/orchestration-policy.md:185-201` | 比上游抽象 diamond 更强,要求未验证 claim 先核实 | +| 有界循环/预算 | `packages/core/src/plugin/command/workflow.md:446-448`、`orchestration-policy.md:292-300` | 已有 concurrency、replan、total nodes、timeout | +| 单 workspace 写入纪律 | `packages/core/src/plugin/command/workflow.md:455-459` | 已有 disjoint write sets / propose-then-assemble,但主要靠约定 | + +### 必须补的空位 + +| 空位 | 具体落点 | 验收方式 | +|---|---|---| +| 假边审计 | workflow lint 或 plan-audit prompt | 每条依赖说明消费的字段/artifact/控制语义;无说明拒绝或告警 | +| 证据默认失败 | reviewer 前的 deterministic evidence node | 引用文件/行、测试日志、截图不存在时,reviewer 不得 ACCEPT | +| 机器可读 StopReason | workflow/node terminal output | 至少区分 goal_met、no_progress、round_cap、budget_cap、human_stop、evidence_missing | +| 动态 topology admission | `extend/replan` dry-run checker | 检查节点 kind、边策略、预算、深度、无环,返回全部拒绝码且零副作用 | +| 写入白名单 | node contract/runtime | 节点只能改声明的文件/路径或 state fields;违规 fail closed | + +## 6. 为什么 `reasoner.md` 没加进 reviewer + +### 6.1 可核验证据 + +1. 本机文件在 `/Users/suntao/.config/opencode/agents/reasoner.md`,不在仓库的 `.opencode/agent(s)/` 中。仓库跟踪的 review agents/templates 只有 `.opencode/dag-prompts/review-{arch,logic,style}.md` 和 `.opencode/workflows/change-review.yaml`。 +2. reasoner 的输入契约只接受 `roadmap | design_doc | system_logic`;其说明明确写着“design-phase reasoning, not code review”,并禁止对已经写出的 diff 做 code quality review。 +3. `change-review.yaml:14-19` 的 survey 目标是 uncommitted changes、`git status` 和 `git diff`。直接把 reasoner 接在 survey 后面会违反 reasoner 自己的输入与职责边界。 +4. `packages/core/src/plugin/command/orchestration-domains.md:4-8` 已写入 “reasoner-style logic prober”;同文件 `:67-82` 的 Deep Speculation 也已经描述 logic simulator。说明概念层并没有忘记 reasoner,缺的是一个可复用的设计审查 YAML。 +5. runtime 在 `packages/opencode/src/dag/runtime/spawn.ts:81-90` 按 `worker_type` 查 agent,找不到就以 `unknown worker_type` 失败。当前共享模板只用 `explore/general/build`,而个人 reasoner 没进入项目配置;直接硬编码会破坏模板可移植性。 + +Git 历史也支持“不是时间顺序导致的遗漏”:reasoner-style playbook 出现在提交 `cca49e8a6`,可复用 `change-review` 后来才在 `3477d9080` 加入,但仍只使用通用 built-ins。提交信息没有给出作者明确理由,所以下述“可移植性 + 契约边界”是基于代码的最强推断,不冒充历史事实。 + +### 6.2 正确接法 + +不要把现有 reasoner 直接塞进 diff reviewer。推荐三类参考图分工: + +```text +设计深挖:internal grill → reasoner(逻辑推演) → fresh audit → PASS/LOOP/BLOCKED → 定稿 + +项目开发:冻结设计 → 并行模块 → 局部复审 → 接线 → reasoner(system_logic) ─┐ + tests/logs ──────────────┼→ 并行 reviewer → arbiter + actual diff ─────────────┘ + +既有项目:并行探索 → 并行 reviewer → claim verifier → arbiter → PASS/局部 LOOP/BLOCKED +``` + +其中: + +- `reasoner` 的输出是 graded insights,不是 PASS/BLOCKING;它只能暴露矛盾、边界和覆盖洞。 +- 开发图若需要“预演代码执行情况”,先由唯一接线节点输出真实实现的 `system_logic`,再让 reasoner 推演 execution traces、hypotheses 和 `unverified_claims`;reasoner 不直接给 diff 判分。 +- reviewer 必须逐条用 diff、代码、测试和日志核实 reasoner 的预测。预测是搜索方向,不是证据。 +- 如果要让仓库模板使用个人 reasoner,应把它作为项目 agent 明确纳入并测试,或提供 capability resolution/fallback;不能假设所有用户都有同名全局 agent。 + +这与 Anthropic fresh-context evaluator 的原则一致:看起来合理不等于正确,缺少验收证据时必须 `NEEDS_WORK`。[原始 evaluator](https://github.com/anthropics/cwc-long-running-agents/blob/main/claude-code-config/.claude/agents/evaluator.md)。 + +## 7. 许可证与署名 + +| 来源 | 许可证 | 搬运约束 | +|---|---|---| +| `codejunkie99/graph-engineering` | [MIT](https://github.com/codejunkie99/graph-engineering/blob/master/LICENSE),Copyright 2026 codejunkie99 | 允许复制、修改、再发布;复制模板或 substantial portions 时保留版权和完整许可声明 | +| GraphARC | [MIT](https://github.com/CodeGraphContext/GraphARC/blob/main/LICENSE) | 允许把 Python 示例改写成项目原生 YAML/TypeScript;保留版权和许可声明 | +| Anthropic Claude Cookbooks | [MIT](https://github.com/anthropics/anthropic-cookbook/blob/main/LICENSE),Copyright 2023 Anthropic | 复制 notebook/prompt 的 substantial portions 时保留版权和许可 | +| Anthropic `cwc-long-running-agents` | [Apache-2.0](https://github.com/anthropics/cwc-long-running-agents/blob/main/LICENSE) | 分发时附许可证;修改文件显著标明改动;保留相关 copyright/attribution;若上游包含 NOTICE,随分发保留 | +| `npubird/KnowledgeGraphCourse` | [原仓库](https://github.com/npubird/KnowledgeGraphCourse)未发现 LICENSE | 不直接复制课件/PDF;只链接原文。若搬 `graph-engineering` 的独立英文归纳,则按其 MIT 文件并保留 credits | + +建议新增统一第三方说明文件,至少记录:来源仓库、原始文件 URL、commit SHA、许可证、改写范围和本项目文件位置。模板里的 attribution 注释不能因为 YAML/Markdown “不是代码”而删除。 + +## 8. 本期落地决策 + +本期只增加或调整模板与文档,不修改 runtime/API: + +1. 新增 `design-decision-loop`:内部 grill → reasoner → fresh audit → `PASS | LOOP | BLOCKED` → 定稿。 +2. 新增 `parallel-development-loop`:并行模块开发与接线后,用 reasoner 推演真实 `system_logic`,再并行 review,由唯一 arbiter 裁决。 +3. 将 `deep-review-dag-module` 定位为中高规模参考拓扑:Agent 可按任务扩展或剪枝,但必须保留 claim verification、arbiter 和 PASS-only finalization。 +4. 所有剪枝强制记录 `prune_reason` 与 `replacement_coverage`;所有 LOOP 只新增前一局部波次的修正、复审和裁决节点,禁止构造环或重启终态节点。 +5. 假边 runtime lint、动态 topology admission、write allowlist 和通用配置入口留到后续版本;本期只把这些约束写进 Agent/模板协议。 diff --git a/packages/core/src/plugin/command/dag-flow.txt b/packages/core/src/plugin/command/dag-flow.txt index f53d4aa256..ecee594676 100644 --- a/packages/core/src/plugin/command/dag-flow.txt +++ b/packages/core/src/plugin/command/dag-flow.txt @@ -10,17 +10,23 @@ If the content inside `` is empty or contains only whitespace, as For a non-empty task: -1. Before starting, classify the task as `brainstorm`, `review`, or `develop`, then compile only the phases and dependency edges that profile actually needs. -2. During compilation, preserve every user constraint in the graph, including named `@agent` roles, exact model selections, read-only or "Do not modify files" scope, required checks, forbidden actions, and requested deliverables. -3. Resolve capability slots against the eligible configured worker types shown in the `workflow` tool description. Do not invent a missing role or model; if a required capability cannot be resolved, do not start and report the gap. -4. Scale the graph to the task's blast radius. A small, well-bounded target gets the smallest useful dependency graph. A large or system-level target (an entire module, subsystem, or codebase) is never satisfied by a single wave of parallel opinions: stage exploration, independent analysis, evidence verification, and synthesis as separate dependent waves. Keep independent viewpoints or work packages parallel and use real fan-in nodes for synthesis, arbitration, integration, and final reporting. -5. For a large-target review or audit, require every reviewer to cite file:line evidence and to mark claims it could not verify. Insert a verification wave between the reviewers and the arbiter that checks disputed or unverified claims against the actual code, so the arbiter rules on verified findings only. Give the arbiter `report_to_parent: true` with a normalized verdict and `next_action`; on `REVISE` or `REJECT`, drive bounded concurrent deep-dive nodes into the confirmed problem areas via `control(replan)` or `extend` instead of ending the orchestration at the arbiter's report. -6. Call the `workflow` tool with `action=start` in this response. Merely printing a plan, graph, JSON, or YAML does not mean a workflow was started. -7. Do not claim the workflow is running unless the tool call succeeds. -8. On success, report the exact Workflow ID and initial state returned by the tool, then tell the user to run `/dag` for live inspection. -9. The workflow runs asynchronously and wakes this parent session when attention or a terminal result is ready. Do not poll it with `action=status`, sleep, retry, or loop merely to wait. End the current response after the brief success report. -10. On failure, state that the workflow was not started and report the actual error. Never invent a Workflow ID. -11. Do not start replacement workflows merely to repair an orchestration mistake. Report the failure and its exact cause unless the user explicitly asked for automatic retries. -12. A completed aggregate node must actually contain the requested synthesis. Never describe unresolved placeholders or an aggregate-node error message as a successful final result. +1. Before starting, classify the task as `brainstorm`, `review`, or `develop`, then select the closest project reference topology: + - design documents, requirement deep-dives, architecture decisions, or design-level debugging → `.opencode/workflows/design-decision-loop.yaml` + - end-to-end implementation with multiple modules, wiring, tests, and review → `.opencode/workflows/parallel-development-loop.yaml` + - deep review of an already-built module, subsystem, or codebase → `.opencode/workflows/deep-review-dag-module.yaml` + - a small bounded working-tree change review → saved workflow `change-review` + - no close match → compose the smallest fresh graph; do not force an unrelated reference +2. Treat the selected YAML as a reviewed topology reference, not as a script to replay blindly. Start a saved workflow by name only when its embedded target and inputs already match the request. Otherwise read the reference, derive a one-off YAML, inject the complete `/dag-flow` task into its root planning/exploration prompt, retarget its lanes, and pass that file to `workflow(action=start)`. +3. The derived graph may expand or prune non-protected lanes. Record the selected `reference_template`, every added node, and every prune as `{node, prune_reason, replacement_coverage}` in the first planning/exploration artifact; require the next fresh review gate to audit that manifest. Missing prune evidence is fail-closed. +4. Preserve the selected reference's protected spine: fresh-context local review, deterministic/evidence verification where applicable, one final arbiter, and PASS-only finalization. Gates return `PASS | LOOP | BLOCKED` with reason, evidence, minimal `loop_scope`, and `stop_reason`. `LOOP` means pause → replan new local correction/review nodes → resume; never create a cycle or restart terminal nodes. +5. During compilation, preserve every user constraint in the graph, including named `@agent` roles, exact model selections, read-only or "Do not modify files" scope, required checks, forbidden actions, and requested deliverables. +6. Resolve capability slots against the eligible configured worker types shown in the `workflow` tool description. Do not invent a missing role or model; if a required capability cannot be resolved, do not start and report the gap. +7. Scale the graph to the task's blast radius. A small, well-bounded target gets the smallest useful dependency graph. A large or system-level target (an entire module, subsystem, or codebase) is never satisfied by a single wave of parallel opinions: stage exploration, independent analysis, evidence verification, and synthesis as separate dependent waves. Keep independent viewpoints or work packages parallel and use real fan-in nodes for synthesis, arbitration, integration, and final reporting. +8. For a large-target review or audit, require every reviewer to cite file:line evidence and to mark claims it could not verify. Insert a verification wave between the reviewers and the arbiter that checks disputed, unverified, and uncovered scope against the actual code, so the arbiter rules on verified findings only. +9. Call the `workflow` tool with `action=start` in this response. Merely printing a plan, graph, JSON, or YAML does not mean a workflow was started. +10. Do not claim the workflow is running unless the tool call succeeds. On success, report the exact Workflow ID and initial state returned by the tool, then tell the user to run `/dag` for live inspection. +11. The workflow runs asynchronously and wakes this parent session when attention or a terminal result is ready. Do not poll it with `action=status`, sleep, retry, or loop merely to wait. End the current response after the brief success report. +12. On failure, state that the workflow was not started and report the actual error. Never invent a Workflow ID or start a replacement workflow unless the user explicitly asked for automatic retries. +13. A completed aggregate node must actually contain the requested synthesis. Never describe unresolved placeholders or an aggregate-node error message as a successful final result. Use the orchestration guidance below to design and manage the workflow. diff --git a/packages/core/src/plugin/command/workflow.md b/packages/core/src/plugin/command/workflow.md index 9d3042acd3..f5eab05ccc 100644 --- a/packages/core/src/plugin/command/workflow.md +++ b/packages/core/src/plugin/command/workflow.md @@ -89,12 +89,14 @@ reports the saved names with their scope, title, and node count; a name that resolves nowhere fails with the directories that were searched. Prefer a saved workflow when the user names a recurring procedure ("run the -code review workflow"): starting it is one call, and its graph has already been -reviewed. Compose a fresh spec file when the task is one-off or when the saved -graph does not fit — a path-shaped `spec_path` keeps the original -session-relative behavior. To turn a working one-off spec into a saved -workflow, move the file into one of the two directories under a descriptive -name. +code review workflow") and the saved target/inputs already match: starting it +is one call, and its graph has already been reviewed. `/dag-flow` may also read +a saved workflow as a topology reference, then derive a one-off spec that +injects the current task, retargets module lanes, and records additions/prunes. +Compose a fresh spec file when the task is one-off or no reference fits — a +path-shaped `spec_path` keeps the original session-relative behavior. To turn a +working one-off spec into a saved workflow, move the file into one of the two +directories under a descriptive name. ## Orchestration Lifecycle @@ -522,4 +524,4 @@ file-root `nodes` array, then call - No `node_complete` action — completion is automatic - No `history` action — inspect a known workflow with `status`; browsing running workflows remains TUI-only (`list` shows saved specs, not running workflows) -- No topology templates — templates are prompt fragments only; you design the graph +- No runtime-side magical topology selection — `/dag-flow` selects and adapts saved reference graphs in the parent agent; the workflow runtime executes only the resulting YAML