Skip to content

feat(agent): multi-step plan DAG tools (#783)#849

Merged
JSONbored merged 1 commit into
mainfrom
feat/agent-plan-dag-783
Jun 18, 2026
Merged

feat(agent): multi-step plan DAG tools (#783)#849
JSONbored merged 1 commit into
mainfrom
feat/agent-plan-dag-783

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Closes #783

What & why

Phase 2 (#770). Track a miner's multi-step plan ("close 1 stale PR → land 2 → open a new direct PR") with per-step state, retries, and resume. Per the agreed contract: stateless — the harness holds the plan and passes it back each call, so gittensory keeps no record of the miner's plan (boundary-aligned) and "resume" is just re-sending it.

How

  • src/services/plan-dag.ts — pure DAG state machine:
    • buildPlanDag (normalize defaults, clamp maxAttempts to [1,10], drop self/duplicate deps)
    • validatePlanDag (duplicate ids, missing deps, cycles via DFS coloring)
    • nextReadySteps (pending steps whose deps are all done)
    • markStepRunning
    • applyStepResult (completed/skipped terminal; failed retries until maxAttempts then fails terminally)
    • planProgress (counts + overall pending/running/completed/failed/blocked)
  • src/mcp/server.ts — three stateless tools: gittensory_build_plan, gittensory_plan_status, gittensory_record_step_result — each surfaces progress + the next ready steps.

Tests

The full state machine (normalize, validation incl. cycle/missing-dep, ready-step gating, retry-then-fail, lifecycle + blocked/empty status) and the MCP round-trip driving a 2-step plan to completion + a retry-to-failure. New code 100% covered; MCP discovery/output-schema meta-tests green; full suite green (2117 passed).

Phase 2: track a miner's multi-step plan ('close 1 stale PR → land 2 → open a
new direct PR') with per-step state, retries, and resume. STATELESS — the
harness holds the plan and passes it back each call, so gittensory keeps no
record of the miner's plan (boundary-aligned) and resume is just re-sending it.

- src/services/plan-dag.ts: pure DAG state machine — buildPlanDag (normalize +
  clamp + drop self/dup deps), validatePlanDag (dup ids, missing deps, cycles
  via DFS coloring), nextReadySteps (deps satisfied), markStepRunning,
  applyStepResult (completed/skipped terminal; failed retries until maxAttempts
  then fails), planProgress (counts + overall pending/running/completed/failed/
  blocked).
- src/mcp/server.ts: three stateless tools — gittensory_build_plan,
  gittensory_plan_status, gittensory_record_step_result.

Tests: the full state machine + the MCP round-trip driving a 2-step plan to
completion + retry-to-failure. New code 100% covered; full suite green (2117).
@dosubot dosubot Bot added the size:L label Jun 18, 2026
@ghost

ghost commented Jun 18, 2026

Copy link
Copy Markdown

Note

Gittensory Gate skipped

PR closed before full evaluation. No late first comment was created.

Signal Result Evidence Action
Gate result ⚠️ Skipped #849 is no longer open. No action.

💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

@ghost ghost added the gittensory:reviewed label Jun 18, 2026
@ghost

ghost commented Jun 18, 2026

Copy link
Copy Markdown

gittensory · advisory review

Reviewed 4 changed file(s) — two independent AI reviewers.

Changed files: src/mcp/server.ts, src/services/plan-dag.ts, test/unit/mcp-plan-dag.test.ts, test/unit/plan-dag.test.ts

Suggested action: 🛠️ Request changes. (reviewers split: request changes / merge) Address the suggestions below before merging.

Reviewer A · gpt-oss-120b — recommends 🛠️ request changes
The PR adds a pure, stateless plan DAG service with accompanying MCP tools and comprehensive unit/integration tests. The implementation is clean and well‑tested, but the error field returned in public tool output could expose forbidden or sensitive terms, violating the public/private boundary.

Suggestions

  • Sanitize or filter the error string before including it in the public planView output (e.g., reuse sanitizePublicComment or enforce a whitelist).
  • Add a test verifying that forbidden words in an error are removed or cause a validation error.
  • Document that the error field is considered private and will not be exposed publicly.

Worth double-checking

  • Public tool output may leak forbidden terms or sensitive information via the error field.
  • If the new tools are called with malformed data, schema validation should still protect against injection.

Reviewer B · nemotron-3-120b-a12b — recommends ✅ merge
The PR adds a multi-step plan DAG feature with stateless MCP tools for building plans, checking status, and recording step results. The implementation is pure, deterministic, and well-tested with unit and integration tests. It follows project conventions (TypeScript strict, clear comments, proper validation) and introduces no public-facing changes that could violate the public/private boundary.

Suggestions

  • Consider adding a TypeScript comment in hasCycle to clarify why the byId.get(id)?.dependsOn fallback is defensive (since we only call hasCycle on IDs known to exist in the plan).
  • In applyStepResult, the fallback error message 'step failed' is hardcoded; consider making it configurable or deriving from the error input for better debugging, though the current approach is acceptable.
  • Ensure the new MCP tools are documented in the project's MCP tool reference (if such a document exists) for discoverability.

Worth double-checking

  • The stateless design relies on the caller (harness) correctly passing the plan back and forth; a bug in the harness could cause state loss, but this is by design and the harness is outside this PR's scope.
  • The cycle detection uses recursion; while unlikely to hit stack limits given the max 100 steps, it's worth noting for extremely large plans (though the schema limits steps to 100).
  • The planView function casts PlanDag to Record<string, unknown>; while safe due to Zod validation, a future change to PlanDag could break this if the cast becomes invalid.

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.59155% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 96.68%. Comparing base (32b1e87) to head (c1d0f6d).

Files with missing lines Patch % Lines
src/mcp/server.ts 95.65% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #849   +/-   ##
=======================================
  Coverage   96.67%   96.68%           
=======================================
  Files         107      108    +1     
  Lines       14538    14609   +71     
  Branches     5274     5288   +14     
=======================================
+ Hits        14055    14125   +70     
  Misses        105      105           
- Partials      378      379    +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JSONbored
JSONbored merged commit e111622 into main Jun 18, 2026
20 checks passed
@JSONbored
JSONbored deleted the feat/agent-plan-dag-783 branch June 18, 2026 00:46
@github-actions github-actions Bot mentioned this pull request Jun 18, 2026
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): multi-step action DAG executor

1 participant