Skip to content

feat: add phased decision report to orchestrator#45

Open
WellDunDun wants to merge 1 commit intodevfrom
WellDunDun/orchestrator-explain
Open

feat: add phased decision report to orchestrator#45
WellDunDun wants to merge 1 commit intodevfrom
WellDunDun/orchestrator-explain

Conversation

@WellDunDun
Copy link
Collaborator

Replace the bare-bones numeric summary with a structured decision report that explains each orchestration phase (sync, status, decisions, evolve, watch). Operators can now see exactly which skills were considered, which were skipped, and why — along with evolution results and watch alerts.

Changes

  • formatOrchestrateReport(): New pure function builds a 5-phase decision report from OrchestrateResult
  • JSON output: Now includes decisions array with per-skill action, reason, and outcome (deployed/validation/alert details)
  • Human output: Replaces bare summary with full report showing sync sources, status breakdown, per-skill decisions, evolution results, and watch phase
  • Test coverage: 11 new tests covering all report phases

Safe defaults remain intact; no changes to core telemetry semantics.

🤖 Generated with Claude Code

Replace the bare-bones numeric summary with a structured decision report
that explains each orchestration phase (sync, status, decisions, evolve,
watch) so operators can understand what the loop did and why.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced CLI orchestration reporting with dual output: structured JSON containing per-skill decisions and results on stdout, and a formatted human-readable decision report on stderr.
  • Tests

    • Added extensive test coverage for report generation, validating formatting across all phases and scenarios.

Walkthrough

This PR adds human-readable report formatting to the orchestration CLI. It introduces helper functions to render phase-specific decision reports and exports a new formatOrchestrateReport function that converts orchestration results to formatted text. CLI output is restructured to emit JSON to stdout and formatted reports to stderr, with comprehensive test coverage validating formatting across various orchestration states.

Changes

Cohort / File(s) Summary
CLI Reporting Functions
cli/selftune/orchestrate.ts
Added formatOrchestrateReport and phase-specific helper functions (formatSyncPhase, formatStatusPhase, formatDecisionPhase, formatEvolutionPhase, formatWatchPhase). Restructured CLI output to emit JSON object with decisions array to stdout and human-readable formatted report to stderr. Replaced inline summary printing.
Test Coverage
tests/orchestrate.test.ts
Added comprehensive tests for formatOrchestrateReport covering dry-run/auto-approve modes, sync source availability, repair info, status breakdown, per-skill decisions, evolution/watch results, and summary counts. Introduced makeOrchestrateResult helper function for test construction.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • selftune#40: Directly modifies the same cli/selftune/orchestrate.ts CLI output path and exports, introducing the JSON stdout + stderr report structure that this PR tests and refines.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Title follows conventional commits format with 'feat:' prefix and accurately describes the main change of adding a phased decision report to the orchestrator.
Description check ✅ Passed Description is directly related to the changeset, detailing the new formatOrchestrateReport function, JSON output enhancements, human-readable output changes, and test coverage additions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch WellDunDun/orchestrator-explain
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cli/selftune/orchestrate.ts`:
- Around line 165-179: In formatWatchPhase, avoid appending empty parentheses
when c.watchResult?.snapshot is missing by building a stats string only when
snapshot exists: compute passInfo and baseInfo from snap, join them into a
non-empty statsPart, and then only append ` (${statsPart})` to the line when
statsPart is truthy; leave alertTag and reason formatting unchanged. Ensure you
reference formatWatchPhase, the watched variable, c.watchResult?.snapshot
(snap), passInfo/baseInfo, and alertTag when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 37e0b1ca-27e1-400d-921e-5fd71478d03b

📥 Commits

Reviewing files that changed from the base of the PR and between aec5f4f and 9a0e025.

📒 Files selected for processing (2)
  • cli/selftune/orchestrate.ts
  • tests/orchestrate.test.ts

Comment on lines +165 to +179
function formatWatchPhase(candidates: SkillAction[]): string[] {
const watched = candidates.filter((c) => c.action === "watch");
if (watched.length === 0) return [];

const lines: string[] = ["Phase 5: Watch"];
for (const c of watched) {
const snap = c.watchResult?.snapshot;
const passInfo = snap ? `pass_rate=${snap.pass_rate.toFixed(2)}` : "";
const baseInfo = snap ? `, baseline=${snap.baseline_pass_rate.toFixed(2)}` : "";
const alertTag = c.watchResult?.alert ? " [ALERT]" : "";
lines.push(` ${c.skill.padEnd(20)} ${c.reason}${alertTag} (${passInfo}${baseInfo})`);
}

return lines;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Empty parentheses appended when snapshot is missing.

If c.watchResult?.snapshot is undefined (snap falsy), passInfo and baseInfo are both empty strings, resulting in output like "SkillName reason ()". Consider omitting the parentheses entirely when there's no snapshot data.

Proposed fix
   const snap = c.watchResult?.snapshot;
   const passInfo = snap ? `pass_rate=${snap.pass_rate.toFixed(2)}` : "";
   const baseInfo = snap ? `, baseline=${snap.baseline_pass_rate.toFixed(2)}` : "";
   const alertTag = c.watchResult?.alert ? " [ALERT]" : "";
-  lines.push(`  ${c.skill.padEnd(20)} ${c.reason}${alertTag} (${passInfo}${baseInfo})`);
+  const metrics = snap ? ` (${passInfo}${baseInfo})` : "";
+  lines.push(`  ${c.skill.padEnd(20)} ${c.reason}${alertTag}${metrics}`);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cli/selftune/orchestrate.ts` around lines 165 - 179, In formatWatchPhase,
avoid appending empty parentheses when c.watchResult?.snapshot is missing by
building a stats string only when snapshot exists: compute passInfo and baseInfo
from snap, join them into a non-empty statsPart, and then only append `
(${statsPart})` to the line when statsPart is truthy; leave alertTag and reason
formatting unchanged. Ensure you reference formatWatchPhase, the watched
variable, c.watchResult?.snapshot (snap), passInfo/baseInfo, and alertTag when
making the change.

WellDunDun added a commit that referenced this pull request Mar 14, 2026
Orchestrate output now explains each decision clearly so users can trust
the autonomous loop. Adds formatOrchestrateReport() with 5-phase human
report (sync, status, decisions, evolution, watch) and enriched JSON
with per-skill decisions array. Supersedes PR #45.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant