shipwright-cli 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/code-reviewer.md +2 -0
- package/.claude/agents/devops-engineer.md +2 -0
- package/.claude/agents/doc-fleet-agent.md +2 -0
- package/.claude/agents/pipeline-agent.md +2 -0
- package/.claude/agents/shell-script-specialist.md +2 -0
- package/.claude/agents/test-specialist.md +2 -0
- package/.claude/hooks/agent-crash-capture.sh +32 -0
- package/.claude/hooks/post-tool-use.sh +3 -2
- package/.claude/hooks/pre-tool-use.sh +35 -3
- package/README.md +4 -4
- package/claude-code/hooks/config-change.sh +18 -0
- package/claude-code/hooks/instructions-reloaded.sh +7 -0
- package/claude-code/hooks/worktree-create.sh +25 -0
- package/claude-code/hooks/worktree-remove.sh +20 -0
- package/config/code-constitution.json +130 -0
- package/dashboard/middleware/auth.ts +134 -0
- package/dashboard/middleware/constants.ts +21 -0
- package/dashboard/public/index.html +2 -6
- package/dashboard/public/styles.css +100 -97
- package/dashboard/routes/auth.ts +38 -0
- package/dashboard/server.ts +66 -25
- package/dashboard/services/config.ts +26 -0
- package/dashboard/services/db.ts +118 -0
- package/dashboard/src/canvas/pixel-agent.ts +298 -0
- package/dashboard/src/canvas/pixel-sprites.ts +440 -0
- package/dashboard/src/canvas/shipyard-effects.ts +367 -0
- package/dashboard/src/canvas/shipyard-scene.ts +616 -0
- package/dashboard/src/canvas/submarine-layout.ts +267 -0
- package/dashboard/src/components/header.ts +8 -7
- package/dashboard/src/core/router.ts +1 -0
- package/dashboard/src/design/submarine-theme.ts +253 -0
- package/dashboard/src/main.ts +2 -0
- package/dashboard/src/types/api.ts +2 -1
- package/dashboard/src/views/activity.ts +2 -1
- package/dashboard/src/views/shipyard.ts +39 -0
- package/dashboard/types/index.ts +166 -0
- package/docs/plans/2026-02-28-compound-audit-and-shipyard-design.md +186 -0
- package/docs/plans/2026-02-28-skipper-shipwright-implementation-plan.md +1182 -0
- package/docs/plans/2026-02-28-skipper-shipwright-integration-design.md +531 -0
- package/docs/plans/2026-03-01-ai-powered-skill-injection-design.md +298 -0
- package/docs/plans/2026-03-01-ai-powered-skill-injection-plan.md +1109 -0
- package/docs/plans/2026-03-01-capabilities-cleanup-plan.md +658 -0
- package/docs/plans/2026-03-01-clean-architecture-plan.md +924 -0
- package/docs/plans/2026-03-01-compound-audit-cascade-design.md +191 -0
- package/docs/plans/2026-03-01-compound-audit-cascade-plan.md +921 -0
- package/docs/plans/2026-03-01-deep-integration-plan.md +851 -0
- package/docs/plans/2026-03-01-pipeline-audit-trail-design.md +145 -0
- package/docs/plans/2026-03-01-pipeline-audit-trail-plan.md +770 -0
- package/docs/plans/2026-03-01-refined-depths-brand-design.md +382 -0
- package/docs/plans/2026-03-01-refined-depths-implementation.md +599 -0
- package/docs/plans/2026-03-01-skipper-kernel-integration-design.md +203 -0
- package/docs/plans/2026-03-01-unified-platform-design.md +272 -0
- package/docs/plans/2026-03-07-claude-code-feature-integration-design.md +189 -0
- package/docs/plans/2026-03-07-claude-code-feature-integration-plan.md +1165 -0
- package/docs/research/BACKLOG_QUICK_REFERENCE.md +352 -0
- package/docs/research/CUTTING_EDGE_RESEARCH_2026.md +546 -0
- package/docs/research/RESEARCH_INDEX.md +439 -0
- package/docs/research/RESEARCH_SOURCES.md +440 -0
- package/docs/research/RESEARCH_SUMMARY.txt +275 -0
- package/docs/superpowers/specs/2026-03-10-pipeline-quality-revolution-design.md +341 -0
- package/package.json +2 -2
- package/scripts/lib/adaptive-model.sh +427 -0
- package/scripts/lib/adaptive-timeout.sh +316 -0
- package/scripts/lib/audit-trail.sh +309 -0
- package/scripts/lib/auto-recovery.sh +471 -0
- package/scripts/lib/bandit-selector.sh +431 -0
- package/scripts/lib/bootstrap.sh +104 -2
- package/scripts/lib/causal-graph.sh +455 -0
- package/scripts/lib/compat.sh +126 -0
- package/scripts/lib/compound-audit.sh +337 -0
- package/scripts/lib/constitutional.sh +454 -0
- package/scripts/lib/context-budget.sh +359 -0
- package/scripts/lib/convergence.sh +594 -0
- package/scripts/lib/cost-optimizer.sh +634 -0
- package/scripts/lib/daemon-adaptive.sh +10 -0
- package/scripts/lib/daemon-dispatch.sh +106 -17
- package/scripts/lib/daemon-failure.sh +34 -4
- package/scripts/lib/daemon-patrol.sh +23 -2
- package/scripts/lib/daemon-poll-github.sh +361 -0
- package/scripts/lib/daemon-poll-health.sh +299 -0
- package/scripts/lib/daemon-poll.sh +27 -611
- package/scripts/lib/daemon-state.sh +112 -66
- package/scripts/lib/daemon-triage.sh +10 -0
- package/scripts/lib/dod-scorecard.sh +442 -0
- package/scripts/lib/error-actionability.sh +300 -0
- package/scripts/lib/formal-spec.sh +461 -0
- package/scripts/lib/helpers.sh +177 -4
- package/scripts/lib/intent-analysis.sh +409 -0
- package/scripts/lib/loop-convergence.sh +350 -0
- package/scripts/lib/loop-iteration.sh +682 -0
- package/scripts/lib/loop-progress.sh +48 -0
- package/scripts/lib/loop-restart.sh +185 -0
- package/scripts/lib/memory-effectiveness.sh +506 -0
- package/scripts/lib/mutation-executor.sh +352 -0
- package/scripts/lib/outcome-feedback.sh +521 -0
- package/scripts/lib/pipeline-cli.sh +336 -0
- package/scripts/lib/pipeline-commands.sh +1216 -0
- package/scripts/lib/pipeline-detection.sh +100 -2
- package/scripts/lib/pipeline-execution.sh +897 -0
- package/scripts/lib/pipeline-github.sh +28 -3
- package/scripts/lib/pipeline-intelligence-compound.sh +431 -0
- package/scripts/lib/pipeline-intelligence-scoring.sh +407 -0
- package/scripts/lib/pipeline-intelligence-skip.sh +181 -0
- package/scripts/lib/pipeline-intelligence.sh +100 -1136
- package/scripts/lib/pipeline-quality-bash-compat.sh +182 -0
- package/scripts/lib/pipeline-quality-checks.sh +17 -715
- package/scripts/lib/pipeline-quality-gates.sh +563 -0
- package/scripts/lib/pipeline-stages-build.sh +730 -0
- package/scripts/lib/pipeline-stages-delivery.sh +965 -0
- package/scripts/lib/pipeline-stages-intake.sh +1133 -0
- package/scripts/lib/pipeline-stages-monitor.sh +407 -0
- package/scripts/lib/pipeline-stages-review.sh +1022 -0
- package/scripts/lib/pipeline-stages.sh +59 -2929
- package/scripts/lib/pipeline-state.sh +36 -5
- package/scripts/lib/pipeline-util.sh +487 -0
- package/scripts/lib/policy-learner.sh +438 -0
- package/scripts/lib/process-reward.sh +493 -0
- package/scripts/lib/project-detect.sh +649 -0
- package/scripts/lib/quality-profile.sh +334 -0
- package/scripts/lib/recruit-commands.sh +885 -0
- package/scripts/lib/recruit-learning.sh +739 -0
- package/scripts/lib/recruit-roles.sh +648 -0
- package/scripts/lib/reward-aggregator.sh +458 -0
- package/scripts/lib/rl-optimizer.sh +362 -0
- package/scripts/lib/root-cause.sh +427 -0
- package/scripts/lib/scope-enforcement.sh +445 -0
- package/scripts/lib/session-restart.sh +493 -0
- package/scripts/lib/skill-memory.sh +300 -0
- package/scripts/lib/skill-registry.sh +775 -0
- package/scripts/lib/spec-driven.sh +476 -0
- package/scripts/lib/test-helpers.sh +18 -7
- package/scripts/lib/test-holdout.sh +429 -0
- package/scripts/lib/test-optimizer.sh +511 -0
- package/scripts/shipwright-file-suggest.sh +45 -0
- package/scripts/skills/adversarial-quality.md +61 -0
- package/scripts/skills/api-design.md +44 -0
- package/scripts/skills/architecture-design.md +50 -0
- package/scripts/skills/brainstorming.md +43 -0
- package/scripts/skills/data-pipeline.md +44 -0
- package/scripts/skills/deploy-safety.md +64 -0
- package/scripts/skills/documentation.md +38 -0
- package/scripts/skills/frontend-design.md +45 -0
- package/scripts/skills/generated/.gitkeep +0 -0
- package/scripts/skills/generated/_refinements/.gitkeep +0 -0
- package/scripts/skills/generated/_refinements/adversarial-quality.patch.md +3 -0
- package/scripts/skills/generated/_refinements/architecture-design.patch.md +3 -0
- package/scripts/skills/generated/_refinements/brainstorming.patch.md +3 -0
- package/scripts/skills/generated/cli-version-management.md +29 -0
- package/scripts/skills/generated/collection-system-validation.md +99 -0
- package/scripts/skills/generated/large-scale-c-refactoring-coordination.md +97 -0
- package/scripts/skills/generated/pattern-matching-similarity-scoring.md +195 -0
- package/scripts/skills/generated/test-parallelization-detection.md +65 -0
- package/scripts/skills/observability.md +79 -0
- package/scripts/skills/performance.md +48 -0
- package/scripts/skills/pr-quality.md +49 -0
- package/scripts/skills/product-thinking.md +43 -0
- package/scripts/skills/security-audit.md +49 -0
- package/scripts/skills/systematic-debugging.md +40 -0
- package/scripts/skills/testing-strategy.md +47 -0
- package/scripts/skills/two-stage-review.md +52 -0
- package/scripts/skills/validation-thoroughness.md +55 -0
- package/scripts/sw +9 -3
- package/scripts/sw-activity.sh +9 -2
- package/scripts/sw-adaptive.sh +2 -1
- package/scripts/sw-adversarial.sh +2 -1
- package/scripts/sw-architecture-enforcer.sh +3 -1
- package/scripts/sw-auth.sh +12 -2
- package/scripts/sw-autonomous.sh +5 -1
- package/scripts/sw-changelog.sh +4 -1
- package/scripts/sw-checkpoint.sh +2 -1
- package/scripts/sw-ci.sh +5 -1
- package/scripts/sw-cleanup.sh +4 -26
- package/scripts/sw-code-review.sh +10 -4
- package/scripts/sw-connect.sh +2 -1
- package/scripts/sw-context.sh +2 -1
- package/scripts/sw-cost.sh +48 -3
- package/scripts/sw-daemon.sh +66 -9
- package/scripts/sw-dashboard.sh +3 -1
- package/scripts/sw-db.sh +59 -16
- package/scripts/sw-decide.sh +8 -2
- package/scripts/sw-decompose.sh +360 -17
- package/scripts/sw-deps.sh +4 -1
- package/scripts/sw-developer-simulation.sh +4 -1
- package/scripts/sw-discovery.sh +325 -2
- package/scripts/sw-doc-fleet.sh +4 -1
- package/scripts/sw-docs-agent.sh +3 -1
- package/scripts/sw-docs.sh +2 -1
- package/scripts/sw-doctor.sh +453 -2
- package/scripts/sw-dora.sh +4 -1
- package/scripts/sw-durable.sh +4 -3
- package/scripts/sw-e2e-orchestrator.sh +17 -16
- package/scripts/sw-eventbus.sh +7 -1
- package/scripts/sw-evidence.sh +364 -12
- package/scripts/sw-feedback.sh +550 -9
- package/scripts/sw-fix.sh +20 -1
- package/scripts/sw-fleet-discover.sh +6 -2
- package/scripts/sw-fleet-viz.sh +4 -1
- package/scripts/sw-fleet.sh +5 -1
- package/scripts/sw-github-app.sh +16 -3
- package/scripts/sw-github-checks.sh +3 -2
- package/scripts/sw-github-deploy.sh +3 -2
- package/scripts/sw-github-graphql.sh +18 -7
- package/scripts/sw-guild.sh +5 -1
- package/scripts/sw-heartbeat.sh +5 -30
- package/scripts/sw-hello.sh +67 -0
- package/scripts/sw-hygiene.sh +6 -1
- package/scripts/sw-incident.sh +265 -1
- package/scripts/sw-init.sh +18 -2
- package/scripts/sw-instrument.sh +10 -2
- package/scripts/sw-intelligence.sh +42 -6
- package/scripts/sw-jira.sh +5 -1
- package/scripts/sw-launchd.sh +2 -1
- package/scripts/sw-linear.sh +4 -1
- package/scripts/sw-logs.sh +4 -1
- package/scripts/sw-loop.sh +432 -1128
- package/scripts/sw-memory.sh +356 -2
- package/scripts/sw-mission-control.sh +6 -1
- package/scripts/sw-model-router.sh +481 -26
- package/scripts/sw-otel.sh +13 -4
- package/scripts/sw-oversight.sh +14 -5
- package/scripts/sw-patrol-meta.sh +334 -0
- package/scripts/sw-pipeline-composer.sh +5 -1
- package/scripts/sw-pipeline-vitals.sh +2 -1
- package/scripts/sw-pipeline.sh +53 -2664
- package/scripts/sw-pm.sh +12 -5
- package/scripts/sw-pr-lifecycle.sh +2 -1
- package/scripts/sw-predictive.sh +7 -1
- package/scripts/sw-prep.sh +185 -2
- package/scripts/sw-ps.sh +5 -25
- package/scripts/sw-public-dashboard.sh +15 -3
- package/scripts/sw-quality.sh +2 -1
- package/scripts/sw-reaper.sh +8 -25
- package/scripts/sw-recruit.sh +156 -2303
- package/scripts/sw-regression.sh +19 -12
- package/scripts/sw-release-manager.sh +3 -1
- package/scripts/sw-release.sh +4 -1
- package/scripts/sw-remote.sh +3 -1
- package/scripts/sw-replay.sh +7 -1
- package/scripts/sw-retro.sh +158 -1
- package/scripts/sw-review-rerun.sh +3 -1
- package/scripts/sw-scale.sh +10 -3
- package/scripts/sw-security-audit.sh +6 -1
- package/scripts/sw-self-optimize.sh +6 -3
- package/scripts/sw-session.sh +9 -3
- package/scripts/sw-setup.sh +3 -1
- package/scripts/sw-stall-detector.sh +406 -0
- package/scripts/sw-standup.sh +15 -7
- package/scripts/sw-status.sh +3 -1
- package/scripts/sw-strategic.sh +4 -1
- package/scripts/sw-stream.sh +7 -1
- package/scripts/sw-swarm.sh +18 -6
- package/scripts/sw-team-stages.sh +13 -6
- package/scripts/sw-templates.sh +5 -29
- package/scripts/sw-testgen.sh +7 -1
- package/scripts/sw-tmux-pipeline.sh +4 -1
- package/scripts/sw-tmux-role-color.sh +2 -0
- package/scripts/sw-tmux-status.sh +1 -1
- package/scripts/sw-tmux.sh +3 -1
- package/scripts/sw-trace.sh +3 -1
- package/scripts/sw-tracker-github.sh +3 -0
- package/scripts/sw-tracker-jira.sh +3 -0
- package/scripts/sw-tracker-linear.sh +3 -0
- package/scripts/sw-tracker.sh +3 -1
- package/scripts/sw-triage.sh +2 -1
- package/scripts/sw-upgrade.sh +3 -1
- package/scripts/sw-ux.sh +5 -2
- package/scripts/sw-webhook.sh +3 -1
- package/scripts/sw-widgets.sh +3 -1
- package/scripts/sw-worktree.sh +15 -3
- package/scripts/test-skill-injection.sh +1233 -0
- package/templates/pipelines/autonomous.json +27 -3
- package/templates/pipelines/cost-aware.json +34 -8
- package/templates/pipelines/deployed.json +12 -0
- package/templates/pipelines/enterprise.json +12 -0
- package/templates/pipelines/fast.json +6 -0
- package/templates/pipelines/full.json +27 -3
- package/templates/pipelines/hotfix.json +6 -0
- package/templates/pipelines/standard.json +12 -0
- package/templates/pipelines/tdd.json +12 -0
|
@@ -0,0 +1,1182 @@
|
|
|
1
|
+
# Skipper-Shipwright Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Port Shipwright's complete autonomous software delivery system into a single `skipper-shipwright` crate within a fork of Skipper, creating a "Software Engineering Hand."
|
|
6
|
+
|
|
7
|
+
**Architecture:** Single Rust crate (`skipper-shipwright`) added to Skipper's Cargo workspace. Contains 7 modules (pipeline, decision, memory, fleet, github, intelligence, config) plus Hand definition files. Integrates with Skipper's kernel for scheduling/RBAC/metering, memory crate for vector search, and channels for notifications.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Rust 1.75+, tokio async, serde/toml for config, reqwest for GitHub API, rusqlite for persistence, axum for API routes, clap for CLI, thiserror for errors.
|
|
10
|
+
|
|
11
|
+
**Design Doc:** `docs/plans/2026-02-28-skipper-shipwright-integration-design.md`
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
Before starting, complete these one-time setup steps:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 1. Fork Skipper
|
|
21
|
+
gh repo fork RightNow-AI/skipper --clone --remote
|
|
22
|
+
|
|
23
|
+
# 2. Verify build
|
|
24
|
+
cd skipper
|
|
25
|
+
cargo build --workspace --lib
|
|
26
|
+
cargo test --workspace
|
|
27
|
+
cargo clippy --workspace --all-targets -- -D warnings
|
|
28
|
+
|
|
29
|
+
# 3. Create feature branch
|
|
30
|
+
git checkout -b feat/shipwright-hand
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Task 1: Scaffold Crate & Config Module
|
|
36
|
+
|
|
37
|
+
**Files:**
|
|
38
|
+
|
|
39
|
+
- Create: `crates/skipper-shipwright/Cargo.toml`
|
|
40
|
+
- Create: `crates/skipper-shipwright/src/lib.rs`
|
|
41
|
+
- Create: `crates/skipper-shipwright/src/config.rs`
|
|
42
|
+
- Modify: `Cargo.toml` (workspace root — add member)
|
|
43
|
+
|
|
44
|
+
**Step 1: Add crate to workspace**
|
|
45
|
+
|
|
46
|
+
In the root `Cargo.toml`, add `"crates/skipper-shipwright"` to `workspace.members`.
|
|
47
|
+
|
|
48
|
+
**Step 2: Create crate Cargo.toml**
|
|
49
|
+
|
|
50
|
+
```toml
|
|
51
|
+
[package]
|
|
52
|
+
name = "skipper-shipwright"
|
|
53
|
+
version.workspace = true
|
|
54
|
+
edition.workspace = true
|
|
55
|
+
rust-version.workspace = true
|
|
56
|
+
license.workspace = true
|
|
57
|
+
description = "Software Engineering Hand — autonomous delivery pipelines"
|
|
58
|
+
|
|
59
|
+
[dependencies]
|
|
60
|
+
skipper-types = { path = "../skipper-types" }
|
|
61
|
+
skipper-memory = { path = "../skipper-memory" }
|
|
62
|
+
skipper-runtime = { path = "../skipper-runtime" }
|
|
63
|
+
|
|
64
|
+
serde = { workspace = true, features = ["derive"] }
|
|
65
|
+
serde_json = { workspace = true }
|
|
66
|
+
toml = { workspace = true }
|
|
67
|
+
thiserror = { workspace = true }
|
|
68
|
+
tokio = { workspace = true, features = ["full"] }
|
|
69
|
+
chrono = { workspace = true, features = ["serde"] }
|
|
70
|
+
uuid = { workspace = true, features = ["v4"] }
|
|
71
|
+
tracing = { workspace = true }
|
|
72
|
+
reqwest = { workspace = true, features = ["json"] }
|
|
73
|
+
rusqlite = { workspace = true }
|
|
74
|
+
dashmap = { workspace = true }
|
|
75
|
+
|
|
76
|
+
[dev-dependencies]
|
|
77
|
+
tokio = { workspace = true, features = ["test-util", "macros"] }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Step 3: Create lib.rs**
|
|
81
|
+
|
|
82
|
+
```rust
|
|
83
|
+
//! Skipper Shipwright — Software Engineering Hand
|
|
84
|
+
//!
|
|
85
|
+
//! Autonomous delivery pipelines: Issue → Plan → Build → Test → PR → Deploy.
|
|
86
|
+
//! Integrates with Skipper kernel for scheduling, RBAC, metering,
|
|
87
|
+
//! and cross-Hand intelligence via Collector, Researcher, and Predictor.
|
|
88
|
+
|
|
89
|
+
pub mod config;
|
|
90
|
+
|
|
91
|
+
pub use config::ShipwrightConfig;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Step 4: Create config.rs**
|
|
95
|
+
|
|
96
|
+
```rust
|
|
97
|
+
//! Shipwright configuration types.
|
|
98
|
+
//!
|
|
99
|
+
//! Parsed from `[shipwright]` section in `skipper.toml`.
|
|
100
|
+
|
|
101
|
+
use serde::{Deserialize, Serialize};
|
|
102
|
+
use std::path::PathBuf;
|
|
103
|
+
|
|
104
|
+
/// Top-level Shipwright configuration.
|
|
105
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
106
|
+
#[serde(default)]
|
|
107
|
+
pub struct ShipwrightConfig {
|
|
108
|
+
pub enabled: bool,
|
|
109
|
+
pub default_template: PipelineTemplateName,
|
|
110
|
+
pub fleet: FleetConfig,
|
|
111
|
+
pub decision: DecisionConfig,
|
|
112
|
+
pub intelligence: IntelligenceConfig,
|
|
113
|
+
pub github: GitHubConfig,
|
|
114
|
+
pub repos: Vec<RepoConfig>,
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
impl Default for ShipwrightConfig {
|
|
118
|
+
fn default() -> Self {
|
|
119
|
+
Self {
|
|
120
|
+
enabled: false,
|
|
121
|
+
default_template: PipelineTemplateName::Standard,
|
|
122
|
+
fleet: FleetConfig::default(),
|
|
123
|
+
decision: DecisionConfig::default(),
|
|
124
|
+
intelligence: IntelligenceConfig::default(),
|
|
125
|
+
github: GitHubConfig::default(),
|
|
126
|
+
repos: vec![],
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/// Pipeline template selection.
|
|
132
|
+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
133
|
+
#[serde(rename_all = "lowercase")]
|
|
134
|
+
pub enum PipelineTemplateName {
|
|
135
|
+
Fast,
|
|
136
|
+
Standard,
|
|
137
|
+
Full,
|
|
138
|
+
Hotfix,
|
|
139
|
+
Autonomous,
|
|
140
|
+
CostAware,
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
impl Default for PipelineTemplateName {
|
|
144
|
+
fn default() -> Self {
|
|
145
|
+
Self::Standard
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/// Fleet/daemon worker configuration.
|
|
150
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
151
|
+
#[serde(default)]
|
|
152
|
+
pub struct FleetConfig {
|
|
153
|
+
pub poll_interval_seconds: u64,
|
|
154
|
+
pub auto_scale: bool,
|
|
155
|
+
pub max_workers: u32,
|
|
156
|
+
pub min_workers: u32,
|
|
157
|
+
pub worker_mem_gb: u32,
|
|
158
|
+
pub cost_per_job_usd: f64,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
impl Default for FleetConfig {
|
|
162
|
+
fn default() -> Self {
|
|
163
|
+
Self {
|
|
164
|
+
poll_interval_seconds: 60,
|
|
165
|
+
auto_scale: false,
|
|
166
|
+
max_workers: 8,
|
|
167
|
+
min_workers: 1,
|
|
168
|
+
worker_mem_gb: 4,
|
|
169
|
+
cost_per_job_usd: 5.0,
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/// Decision engine configuration.
|
|
175
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
176
|
+
#[serde(default)]
|
|
177
|
+
pub struct DecisionConfig {
|
|
178
|
+
pub enabled: bool,
|
|
179
|
+
pub cycle_interval_seconds: u64,
|
|
180
|
+
pub max_issues_per_day: u32,
|
|
181
|
+
pub max_cost_per_day_usd: f64,
|
|
182
|
+
pub cooldown_seconds: u64,
|
|
183
|
+
pub halt_after_failures: u32,
|
|
184
|
+
pub outcome_learning: bool,
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
impl Default for DecisionConfig {
|
|
188
|
+
fn default() -> Self {
|
|
189
|
+
Self {
|
|
190
|
+
enabled: false,
|
|
191
|
+
cycle_interval_seconds: 1800,
|
|
192
|
+
max_issues_per_day: 15,
|
|
193
|
+
max_cost_per_day_usd: 25.0,
|
|
194
|
+
cooldown_seconds: 300,
|
|
195
|
+
halt_after_failures: 3,
|
|
196
|
+
outcome_learning: true,
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/// Intelligence layer configuration.
|
|
202
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
203
|
+
#[serde(default)]
|
|
204
|
+
pub struct IntelligenceConfig {
|
|
205
|
+
pub cache_ttl_seconds: u64,
|
|
206
|
+
pub prediction_enabled: bool,
|
|
207
|
+
pub adversarial_enabled: bool,
|
|
208
|
+
pub architecture_enabled: bool,
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
impl Default for IntelligenceConfig {
|
|
212
|
+
fn default() -> Self {
|
|
213
|
+
Self {
|
|
214
|
+
cache_ttl_seconds: 3600,
|
|
215
|
+
prediction_enabled: true,
|
|
216
|
+
adversarial_enabled: false,
|
|
217
|
+
architecture_enabled: false,
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/// GitHub integration configuration.
|
|
223
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
224
|
+
#[serde(default)]
|
|
225
|
+
pub struct GitHubConfig {
|
|
226
|
+
pub watch_labels: Vec<String>,
|
|
227
|
+
pub auto_merge: bool,
|
|
228
|
+
pub check_runs_enabled: bool,
|
|
229
|
+
pub deployment_tracking: bool,
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
impl Default for GitHubConfig {
|
|
233
|
+
fn default() -> Self {
|
|
234
|
+
Self {
|
|
235
|
+
watch_labels: vec!["shipwright".into(), "ready-to-build".into()],
|
|
236
|
+
auto_merge: false,
|
|
237
|
+
check_runs_enabled: true,
|
|
238
|
+
deployment_tracking: true,
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/// Per-repository configuration.
|
|
244
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
245
|
+
pub struct RepoConfig {
|
|
246
|
+
pub path: PathBuf,
|
|
247
|
+
pub owner: String,
|
|
248
|
+
pub repo: String,
|
|
249
|
+
#[serde(default = "default_template")]
|
|
250
|
+
pub template: PipelineTemplateName,
|
|
251
|
+
#[serde(default = "default_max_parallel")]
|
|
252
|
+
pub max_parallel: u32,
|
|
253
|
+
#[serde(default)]
|
|
254
|
+
pub auto_merge: bool,
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
fn default_template() -> PipelineTemplateName {
|
|
258
|
+
PipelineTemplateName::Standard
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
fn default_max_parallel() -> u32 {
|
|
262
|
+
2
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
#[cfg(test)]
|
|
266
|
+
mod tests {
|
|
267
|
+
use super::*;
|
|
268
|
+
|
|
269
|
+
#[test]
|
|
270
|
+
fn test_default_config_serializes() {
|
|
271
|
+
let config = ShipwrightConfig::default();
|
|
272
|
+
let toml_str = toml::to_string_pretty(&config).unwrap();
|
|
273
|
+
assert!(toml_str.contains("enabled = false"));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
#[test]
|
|
277
|
+
fn test_config_round_trip() {
|
|
278
|
+
let config = ShipwrightConfig {
|
|
279
|
+
enabled: true,
|
|
280
|
+
default_template: PipelineTemplateName::Autonomous,
|
|
281
|
+
repos: vec![RepoConfig {
|
|
282
|
+
path: "/tmp/test".into(),
|
|
283
|
+
owner: "myorg".into(),
|
|
284
|
+
repo: "myrepo".into(),
|
|
285
|
+
template: PipelineTemplateName::Full,
|
|
286
|
+
max_parallel: 3,
|
|
287
|
+
auto_merge: true,
|
|
288
|
+
}],
|
|
289
|
+
..Default::default()
|
|
290
|
+
};
|
|
291
|
+
let toml_str = toml::to_string_pretty(&config).unwrap();
|
|
292
|
+
let parsed: ShipwrightConfig = toml::from_str(&toml_str).unwrap();
|
|
293
|
+
assert!(parsed.enabled);
|
|
294
|
+
assert_eq!(parsed.repos.len(), 1);
|
|
295
|
+
assert_eq!(parsed.repos[0].max_parallel, 3);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
#[test]
|
|
299
|
+
fn test_defaults_are_sane() {
|
|
300
|
+
let config = ShipwrightConfig::default();
|
|
301
|
+
assert!(!config.enabled);
|
|
302
|
+
assert_eq!(config.fleet.max_workers, 8);
|
|
303
|
+
assert_eq!(config.decision.max_issues_per_day, 15);
|
|
304
|
+
assert_eq!(config.intelligence.cache_ttl_seconds, 3600);
|
|
305
|
+
assert_eq!(config.github.watch_labels, vec!["shipwright", "ready-to-build"]);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
#[test]
|
|
309
|
+
fn test_partial_toml_uses_defaults() {
|
|
310
|
+
let toml_str = r#"
|
|
311
|
+
enabled = true
|
|
312
|
+
[fleet]
|
|
313
|
+
max_workers = 4
|
|
314
|
+
"#;
|
|
315
|
+
let config: ShipwrightConfig = toml::from_str(toml_str).unwrap();
|
|
316
|
+
assert!(config.enabled);
|
|
317
|
+
assert_eq!(config.fleet.max_workers, 4);
|
|
318
|
+
assert_eq!(config.fleet.poll_interval_seconds, 60); // default
|
|
319
|
+
assert!(!config.decision.enabled); // default
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Step 5: Verify it compiles**
|
|
325
|
+
|
|
326
|
+
Run: `cargo build -p skipper-shipwright`
|
|
327
|
+
Expected: Compiles with zero warnings
|
|
328
|
+
|
|
329
|
+
**Step 6: Run tests**
|
|
330
|
+
|
|
331
|
+
Run: `cargo test -p skipper-shipwright`
|
|
332
|
+
Expected: 4 tests pass
|
|
333
|
+
|
|
334
|
+
**Step 7: Clippy**
|
|
335
|
+
|
|
336
|
+
Run: `cargo clippy -p skipper-shipwright -- -D warnings`
|
|
337
|
+
Expected: Zero warnings
|
|
338
|
+
|
|
339
|
+
**Step 8: Commit**
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
git add crates/skipper-shipwright/ Cargo.toml
|
|
343
|
+
git commit -m "feat(shipwright): scaffold crate with config module"
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Task 2: GitHub API Client
|
|
349
|
+
|
|
350
|
+
**Files:**
|
|
351
|
+
|
|
352
|
+
- Create: `crates/skipper-shipwright/src/github/mod.rs`
|
|
353
|
+
- Create: `crates/skipper-shipwright/src/github/graphql.rs`
|
|
354
|
+
- Create: `crates/skipper-shipwright/src/github/checks.rs`
|
|
355
|
+
- Create: `crates/skipper-shipwright/src/github/deployments.rs`
|
|
356
|
+
- Create: `crates/skipper-shipwright/src/github/pr.rs`
|
|
357
|
+
- Modify: `crates/skipper-shipwright/src/lib.rs` (add `pub mod github`)
|
|
358
|
+
|
|
359
|
+
**Step 1: Write tests for GitHub client**
|
|
360
|
+
|
|
361
|
+
In `github/mod.rs`, write tests that verify:
|
|
362
|
+
|
|
363
|
+
- `GitHubClient::new()` reads token from env
|
|
364
|
+
- `list_issues()` parses mock JSON response into `Vec<Issue>`
|
|
365
|
+
- `create_check_run()` sends correct POST payload
|
|
366
|
+
- `create_pr()` constructs correct body
|
|
367
|
+
- `select_reviewers()` deduplicates and limits to 3
|
|
368
|
+
- GraphQL cache returns cached result within TTL, fetches fresh after TTL
|
|
369
|
+
|
|
370
|
+
Use `mockito` or hand-built mock server for HTTP assertions.
|
|
371
|
+
|
|
372
|
+
**Step 2: Implement GitHub client**
|
|
373
|
+
|
|
374
|
+
Port from Shipwright's `scripts/lib/pipeline-github.sh` and `scripts/sw-github-graphql.sh`:
|
|
375
|
+
|
|
376
|
+
- `GitHubClient` struct with `reqwest::Client`, token, cache (`DashMap`)
|
|
377
|
+
- `list_issues(owner, repo, labels)` → REST GET `/repos/{owner}/{repo}/issues`
|
|
378
|
+
- `create_issue(owner, repo, title, body, labels)` → REST POST
|
|
379
|
+
- `add_label(owner, repo, issue, label)` → REST POST
|
|
380
|
+
- GraphQL queries: `file_change_frequency`, `blame_data`, `security_alerts`, `codeowners`, `similar_issues`
|
|
381
|
+
- Checks API: `create_check_run`, `update_check_run`
|
|
382
|
+
- Deployments API: `create_deployment`, `update_deployment_status`
|
|
383
|
+
- PR lifecycle: `create_pr`, `select_reviewers`, `auto_merge`
|
|
384
|
+
|
|
385
|
+
**Step 3: Verify tests pass**
|
|
386
|
+
|
|
387
|
+
Run: `cargo test -p skipper-shipwright -- github`
|
|
388
|
+
Expected: All tests pass
|
|
389
|
+
|
|
390
|
+
**Step 4: Commit**
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
git add crates/skipper-shipwright/src/github/
|
|
394
|
+
git commit -m "feat(shipwright): GitHub API client with GraphQL, Checks, Deployments, PR"
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Task 3: Memory System
|
|
400
|
+
|
|
401
|
+
**Files:**
|
|
402
|
+
|
|
403
|
+
- Create: `crates/skipper-shipwright/src/memory/mod.rs`
|
|
404
|
+
- Create: `crates/skipper-shipwright/src/memory/patterns.rs`
|
|
405
|
+
- Create: `crates/skipper-shipwright/src/memory/architecture.rs`
|
|
406
|
+
- Create: `crates/skipper-shipwright/src/memory/learning.rs`
|
|
407
|
+
- Modify: `crates/skipper-shipwright/src/lib.rs` (add `pub mod memory`)
|
|
408
|
+
|
|
409
|
+
**Step 1: Write tests for failure pattern storage**
|
|
410
|
+
|
|
411
|
+
In `memory/patterns.rs`, write tests:
|
|
412
|
+
|
|
413
|
+
- `store_failure()` inserts a `FailurePattern` into SQLite
|
|
414
|
+
- `search_similar_failures("undefined property")` returns semantically similar patterns (not just keyword match)
|
|
415
|
+
- `compose_context()` formats multiple patterns into agent-readable text
|
|
416
|
+
- Empty database returns empty results (no panic)
|
|
417
|
+
|
|
418
|
+
**Step 2: Write tests for architecture rules**
|
|
419
|
+
|
|
420
|
+
In `memory/architecture.rs`, write tests:
|
|
421
|
+
|
|
422
|
+
- `store_architecture()` persists layer definitions and dependency rules
|
|
423
|
+
- `check_violation("api", "db")` returns violation when direct api→db dependency exists
|
|
424
|
+
- `get_hotspots(repo, limit=5)` returns top 5 files by change frequency
|
|
425
|
+
|
|
426
|
+
**Step 3: Write tests for learning**
|
|
427
|
+
|
|
428
|
+
In `memory/learning.rs`, write tests:
|
|
429
|
+
|
|
430
|
+
- `record_outcome()` appends to outcomes table
|
|
431
|
+
- `adjust_weights()` with 10+ successful outcomes shifts weight toward that signal
|
|
432
|
+
- `ab_assign_group()` returns consistent group for same key
|
|
433
|
+
- `ab_report()` computes control vs treatment metrics
|
|
434
|
+
|
|
435
|
+
**Step 4: Implement memory module**
|
|
436
|
+
|
|
437
|
+
Port from Shipwright's `scripts/sw-memory.sh`:
|
|
438
|
+
|
|
439
|
+
- `ShipwrightMemory` wraps `skipper_memory::MemoryStore`
|
|
440
|
+
- `FailurePattern` struct with all fields from design doc
|
|
441
|
+
- `ArchitectureRule` struct with layers, dependency_rules, hotspots
|
|
442
|
+
- `Outcome` struct for decision learning
|
|
443
|
+
- `migrate_jsonl_memory(path)` reads Shipwright JSONL files and imports into SQLite with embeddings
|
|
444
|
+
- Semantic search via `store.vector_search()` on sqlite-vec
|
|
445
|
+
|
|
446
|
+
**Step 5: Verify tests pass**
|
|
447
|
+
|
|
448
|
+
Run: `cargo test -p skipper-shipwright -- memory`
|
|
449
|
+
Expected: All tests pass
|
|
450
|
+
|
|
451
|
+
**Step 6: Commit**
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
git add crates/skipper-shipwright/src/memory/
|
|
455
|
+
git commit -m "feat(shipwright): memory system with vector search, patterns, architecture, learning"
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Task 4: Pipeline Engine
|
|
461
|
+
|
|
462
|
+
**Files:**
|
|
463
|
+
|
|
464
|
+
- Create: `crates/skipper-shipwright/src/pipeline/mod.rs`
|
|
465
|
+
- Create: `crates/skipper-shipwright/src/pipeline/stages.rs`
|
|
466
|
+
- Create: `crates/skipper-shipwright/src/pipeline/templates.rs`
|
|
467
|
+
- Create: `crates/skipper-shipwright/src/pipeline/composer.rs`
|
|
468
|
+
- Create: `crates/skipper-shipwright/src/pipeline/self_healing.rs`
|
|
469
|
+
- Modify: `crates/skipper-shipwright/src/lib.rs` (add `pub mod pipeline`)
|
|
470
|
+
|
|
471
|
+
**Step 1: Write tests for stage state machine**
|
|
472
|
+
|
|
473
|
+
In `pipeline/stages.rs`, write tests:
|
|
474
|
+
|
|
475
|
+
- `Stage::all()` returns 12 stages in order
|
|
476
|
+
- `Pipeline::advance()` transitions `Running{Build}` → `Running{Test}`
|
|
477
|
+
- `Pipeline::fail()` transitions to `Failed` with retry count
|
|
478
|
+
- `Pipeline::pause()` transitions to `Paused` with gate reason
|
|
479
|
+
- Invalid transition (e.g., `Completed` → `Running`) returns error
|
|
480
|
+
|
|
481
|
+
**Step 2: Write tests for templates**
|
|
482
|
+
|
|
483
|
+
In `pipeline/templates.rs`, write tests:
|
|
484
|
+
|
|
485
|
+
- `PipelineTemplate::Fast` enables only Intake, Build, Test, Pr
|
|
486
|
+
- `PipelineTemplate::Full` enables all 12 stages
|
|
487
|
+
- `PipelineTemplate::CostAware` sets model routing (haiku for intake, opus for design)
|
|
488
|
+
- Template stages match the table in design doc
|
|
489
|
+
|
|
490
|
+
**Step 3: Write tests for self-healing build loop**
|
|
491
|
+
|
|
492
|
+
In `pipeline/self_healing.rs`, write tests:
|
|
493
|
+
|
|
494
|
+
- `BuildLoop::evaluate()` returns `TestsPassing` when test command succeeds
|
|
495
|
+
- `BuildLoop::evaluate()` returns `Converging` when error count drops >50%
|
|
496
|
+
- `BuildLoop::evaluate()` returns `Diverging` when error count increases
|
|
497
|
+
- `BuildLoop::evaluate()` returns `Exhausted` after `max_iterations`
|
|
498
|
+
- Convergence detection uses sliding window of size `convergence_window`
|
|
499
|
+
|
|
500
|
+
**Step 4: Write tests for dynamic composition**
|
|
501
|
+
|
|
502
|
+
In `pipeline/composer.rs`, write tests:
|
|
503
|
+
|
|
504
|
+
- `compose()` adjusts iterations based on complexity score
|
|
505
|
+
- `compose()` routes models based on stage type
|
|
506
|
+
- `compose()` respects intelligence overrides (risky_areas, test_intensity)
|
|
507
|
+
|
|
508
|
+
**Step 5: Implement pipeline engine**
|
|
509
|
+
|
|
510
|
+
Port from Shipwright's `scripts/sw-pipeline.sh`, `scripts/lib/pipeline-stages.sh`, `scripts/sw-loop.sh`:
|
|
511
|
+
|
|
512
|
+
- `Stage` enum with 12 variants
|
|
513
|
+
- `Pipeline` struct with state machine (`PipelineState`)
|
|
514
|
+
- `StageConfig` with gate, model, timeout, iterations
|
|
515
|
+
- `PipelineTemplate` enum → `Vec<StageConfig>` conversion
|
|
516
|
+
- `BuildLoop` with convergence detection, backtracking, restart logic
|
|
517
|
+
- `PipelineComposer` that adjusts template based on intelligence output
|
|
518
|
+
- Channel notifications via kernel on state transitions
|
|
519
|
+
|
|
520
|
+
**Step 6: Verify tests pass**
|
|
521
|
+
|
|
522
|
+
Run: `cargo test -p skipper-shipwright -- pipeline`
|
|
523
|
+
Expected: All tests pass
|
|
524
|
+
|
|
525
|
+
**Step 7: Commit**
|
|
526
|
+
|
|
527
|
+
```bash
|
|
528
|
+
git add crates/skipper-shipwright/src/pipeline/
|
|
529
|
+
git commit -m "feat(shipwright): 12-stage pipeline engine with templates, self-healing, composition"
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## Task 5: Decision Engine
|
|
535
|
+
|
|
536
|
+
**Files:**
|
|
537
|
+
|
|
538
|
+
- Create: `crates/skipper-shipwright/src/decision/mod.rs`
|
|
539
|
+
- Create: `crates/skipper-shipwright/src/decision/signals.rs`
|
|
540
|
+
- Create: `crates/skipper-shipwright/src/decision/scoring.rs`
|
|
541
|
+
- Create: `crates/skipper-shipwright/src/decision/autonomy.rs`
|
|
542
|
+
- Modify: `crates/skipper-shipwright/src/lib.rs` (add `pub mod decision`)
|
|
543
|
+
|
|
544
|
+
**Step 1: Write tests for signal collection**
|
|
545
|
+
|
|
546
|
+
In `decision/signals.rs`, write tests:
|
|
547
|
+
|
|
548
|
+
- `SecurityCollector::collect()` parses `npm audit --json` output into candidates
|
|
549
|
+
- `DependencyCollector::collect()` classifies bump type (patch/minor/major)
|
|
550
|
+
- `CoverageCollector::collect()` detects coverage below threshold
|
|
551
|
+
- `HandSignalCollector::collect()` queries mock Collector/Researcher/Predictor Hands
|
|
552
|
+
- All collectors set `dedup_key` for idempotency
|
|
553
|
+
- Each candidate has valid `risk_score` (0-100) and `confidence` (0.0-1.0)
|
|
554
|
+
|
|
555
|
+
**Step 2: Write tests for scoring**
|
|
556
|
+
|
|
557
|
+
In `decision/scoring.rs`, write tests:
|
|
558
|
+
|
|
559
|
+
- Formula: `value = (impact * 0.30) + (urgency * 0.25) + (effort * 0.20) + (confidence * 0.15) - (risk * 0.10)`
|
|
560
|
+
- `score_candidate()` with critical CVE returns value > 80
|
|
561
|
+
- `score_candidate()` with style nit returns value < 30
|
|
562
|
+
- Custom weights from `ScoringWeights` override defaults
|
|
563
|
+
- `adjust_weights()` via EMA shifts weights toward consistently successful signals
|
|
564
|
+
|
|
565
|
+
**Step 3: Write tests for autonomy**
|
|
566
|
+
|
|
567
|
+
In `decision/autonomy.rs`, write tests:
|
|
568
|
+
|
|
569
|
+
- `resolve_tier("security_patch")` returns `Auto`
|
|
570
|
+
- `resolve_tier("refactor_hotspot")` returns `Propose`
|
|
571
|
+
- `resolve_tier("new_feature")` returns `Draft`
|
|
572
|
+
- `check_budget()` returns false after 15 issues/day
|
|
573
|
+
- `check_rate_limit()` returns false within 300s cooldown
|
|
574
|
+
- `check_halt()` returns true when halt flag is set
|
|
575
|
+
- `record_decision()` appends to daily log
|
|
576
|
+
- `halt()` + `resume()` round-trip
|
|
577
|
+
|
|
578
|
+
**Step 4: Implement decision engine**
|
|
579
|
+
|
|
580
|
+
Port from Shipwright's `scripts/sw-decide.sh`, `scripts/lib/decide-*.sh`:
|
|
581
|
+
|
|
582
|
+
- `SignalCollector` trait with `name()` and `collect()` methods
|
|
583
|
+
- 10+ built-in collectors (Security, Dependency, Coverage, DeadCode, etc.)
|
|
584
|
+
- `HandSignalCollector` that queries Skipper kernel for Hand results
|
|
585
|
+
- `Candidate` struct with all fields from design doc
|
|
586
|
+
- `score_candidate()` function with configurable weights
|
|
587
|
+
- `AutonomyTier` enum with tier resolution from category rules
|
|
588
|
+
- `DecisionLimits` with budget, rate, and halt enforcement
|
|
589
|
+
- `DecisionEngine::run_cycle()` orchestrating collect → dedup → score → tier → execute
|
|
590
|
+
- Deduplication against open GitHub issues and recent decisions (7d window)
|
|
591
|
+
|
|
592
|
+
**Step 5: Verify tests pass**
|
|
593
|
+
|
|
594
|
+
Run: `cargo test -p skipper-shipwright -- decision`
|
|
595
|
+
Expected: All tests pass
|
|
596
|
+
|
|
597
|
+
**Step 6: Commit**
|
|
598
|
+
|
|
599
|
+
```bash
|
|
600
|
+
git add crates/skipper-shipwright/src/decision/
|
|
601
|
+
git commit -m "feat(shipwright): decision engine with signals, scoring, autonomy tiers, Hand cross-pollination"
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
## Task 6: Intelligence Layer
|
|
607
|
+
|
|
608
|
+
**Files:**
|
|
609
|
+
|
|
610
|
+
- Create: `crates/skipper-shipwright/src/intelligence/mod.rs`
|
|
611
|
+
- Create: `crates/skipper-shipwright/src/intelligence/prediction.rs`
|
|
612
|
+
- Create: `crates/skipper-shipwright/src/intelligence/dora.rs`
|
|
613
|
+
- Create: `crates/skipper-shipwright/src/intelligence/optimization.rs`
|
|
614
|
+
- Modify: `crates/skipper-shipwright/src/lib.rs` (add `pub mod intelligence`)
|
|
615
|
+
|
|
616
|
+
**Step 1: Write tests for DORA metrics**
|
|
617
|
+
|
|
618
|
+
In `intelligence/dora.rs`, write tests:
|
|
619
|
+
|
|
620
|
+
- `calculate_lead_time()` computes hours from first commit to deploy
|
|
621
|
+
- `calculate_deploy_frequency()` counts deploys per day over window
|
|
622
|
+
- `calculate_change_failure_rate()` is ratio of failed to total deploys
|
|
623
|
+
- `calculate_mttr()` averages time from failure to recovery
|
|
624
|
+
- `dora_level()` classifies as Elite/High/Medium/Low per DORA benchmarks
|
|
625
|
+
|
|
626
|
+
**Step 2: Write tests for prediction**
|
|
627
|
+
|
|
628
|
+
In `intelligence/prediction.rs`, write tests:
|
|
629
|
+
|
|
630
|
+
- `predict_risk(issue)` returns 0-100 based on file hotspots + complexity
|
|
631
|
+
- `detect_anomaly(metrics, threshold)` flags values > N standard deviations
|
|
632
|
+
- `recommend_model(risk)` returns Opus for risk>70, Sonnet for risk<30
|
|
633
|
+
|
|
634
|
+
**Step 3: Write tests for self-optimization**
|
|
635
|
+
|
|
636
|
+
In `intelligence/optimization.rs`, write tests:
|
|
637
|
+
|
|
638
|
+
- `suggest_config_change(dora_metrics)` recommends max_workers increase if lead time is high
|
|
639
|
+
- `adaptive_cycles(base, stage, current, previous)` extends cycles on convergence
|
|
640
|
+
- Self-optimization respects limits (never exceed 6 cycles, never reduce below 1)
|
|
641
|
+
|
|
642
|
+
**Step 4: Implement intelligence layer**
|
|
643
|
+
|
|
644
|
+
Port from Shipwright's `scripts/sw-intelligence.sh`, `scripts/sw-predictive.sh`, `scripts/sw-dora.sh`, `scripts/sw-self-optimize.sh`:
|
|
645
|
+
|
|
646
|
+
- DORA metrics calculator with GitHub deployment history
|
|
647
|
+
- Risk prediction using file hotspots from `github/graphql.rs`
|
|
648
|
+
- Anomaly detection with z-score threshold
|
|
649
|
+
- Self-optimization that adjusts config based on DORA trends
|
|
650
|
+
- Adaptive cycle count based on convergence/divergence patterns
|
|
651
|
+
|
|
652
|
+
**Step 5: Verify tests pass**
|
|
653
|
+
|
|
654
|
+
Run: `cargo test -p skipper-shipwright -- intelligence`
|
|
655
|
+
Expected: All tests pass
|
|
656
|
+
|
|
657
|
+
**Step 6: Commit**
|
|
658
|
+
|
|
659
|
+
```bash
|
|
660
|
+
git add crates/skipper-shipwright/src/intelligence/
|
|
661
|
+
git commit -m "feat(shipwright): intelligence layer with DORA, prediction, self-optimization"
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## Task 7: Fleet & Daemon
|
|
667
|
+
|
|
668
|
+
**Files:**
|
|
669
|
+
|
|
670
|
+
- Create: `crates/skipper-shipwright/src/fleet/mod.rs`
|
|
671
|
+
- Create: `crates/skipper-shipwright/src/fleet/daemon.rs`
|
|
672
|
+
- Create: `crates/skipper-shipwright/src/fleet/dispatch.rs`
|
|
673
|
+
- Create: `crates/skipper-shipwright/src/fleet/patrol.rs`
|
|
674
|
+
- Modify: `crates/skipper-shipwright/src/lib.rs` (add `pub mod fleet`)
|
|
675
|
+
|
|
676
|
+
**Step 1: Write tests for worker pool**
|
|
677
|
+
|
|
678
|
+
In `fleet/dispatch.rs`, write tests:
|
|
679
|
+
|
|
680
|
+
- `WorkerPool::has_capacity(repo)` returns true when workers < max_parallel
|
|
681
|
+
- `WorkerPool::claim(repo, agent_id)` decrements available
|
|
682
|
+
- `WorkerPool::release(agent_id)` increments available
|
|
683
|
+
- Auto-scaling formula: `min(cpu*0.75, mem/worker_mem, budget/cost)`
|
|
684
|
+
- `WorkerPool::rebalance()` distributes proportionally to queue depth
|
|
685
|
+
|
|
686
|
+
**Step 2: Write tests for daemon poll cycle**
|
|
687
|
+
|
|
688
|
+
In `fleet/daemon.rs`, write tests:
|
|
689
|
+
|
|
690
|
+
- `poll_cycle()` with 3 labeled issues dispatches up to `max_parallel`
|
|
691
|
+
- `poll_cycle()` skips issues already claimed
|
|
692
|
+
- `poll_cycle()` respects worker pool capacity
|
|
693
|
+
- Triage scores issues: p0 > p1 > unlabeled
|
|
694
|
+
- Issues with `shipwright:proposed` label require approval before dispatch
|
|
695
|
+
|
|
696
|
+
**Step 3: Write tests for patrol**
|
|
697
|
+
|
|
698
|
+
In `fleet/patrol.rs`, write tests:
|
|
699
|
+
|
|
700
|
+
- `run_patrol()` detects outdated dependencies
|
|
701
|
+
- `run_patrol()` detects security vulnerabilities
|
|
702
|
+
- `run_patrol()` detects coverage regression
|
|
703
|
+
- `run_patrol()` detects DORA metric degradation
|
|
704
|
+
- Patrol results feed into decision engine as candidates
|
|
705
|
+
|
|
706
|
+
**Step 4: Implement fleet module**
|
|
707
|
+
|
|
708
|
+
Port from Shipwright's `scripts/sw-daemon.sh`, `scripts/lib/daemon-*.sh`, `scripts/sw-fleet.sh`:
|
|
709
|
+
|
|
710
|
+
- `FleetManager` struct with kernel handle, repos, worker pool
|
|
711
|
+
- `poll_cycle()` as async kernel-scheduled job
|
|
712
|
+
- `WorkerPool` with static and auto-scaling strategies
|
|
713
|
+
- `Dispatcher` that spawns pipelines as Skipper agents
|
|
714
|
+
- `Patrol` that runs periodic checks and feeds decision engine
|
|
715
|
+
- Replace bash PID/flock with kernel agent registry
|
|
716
|
+
- Replace tmux with kernel agent management
|
|
717
|
+
|
|
718
|
+
**Step 5: Verify tests pass**
|
|
719
|
+
|
|
720
|
+
Run: `cargo test -p skipper-shipwright -- fleet`
|
|
721
|
+
Expected: All tests pass
|
|
722
|
+
|
|
723
|
+
**Step 6: Commit**
|
|
724
|
+
|
|
725
|
+
```bash
|
|
726
|
+
git add crates/skipper-shipwright/src/fleet/
|
|
727
|
+
git commit -m "feat(shipwright): fleet manager with daemon, auto-scaling, patrol"
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
---
|
|
731
|
+
|
|
732
|
+
## Task 8: Hand Definition
|
|
733
|
+
|
|
734
|
+
**Files:**
|
|
735
|
+
|
|
736
|
+
- Create: `crates/skipper-shipwright/src/hand.rs`
|
|
737
|
+
- Create: `crates/skipper-shipwright/agents/shipwright/HAND.toml`
|
|
738
|
+
- Create: `crates/skipper-shipwright/agents/shipwright/SKILL.md`
|
|
739
|
+
- Create: `crates/skipper-shipwright/agents/shipwright/system_prompt.md`
|
|
740
|
+
- Modify: `crates/skipper-shipwright/src/lib.rs` (add `pub mod hand`)
|
|
741
|
+
|
|
742
|
+
**Step 1: Create HAND.toml**
|
|
743
|
+
|
|
744
|
+
Follow the researcher hand pattern:
|
|
745
|
+
|
|
746
|
+
```toml
|
|
747
|
+
[hand]
|
|
748
|
+
id = "shipwright"
|
|
749
|
+
name = "Shipwright Hand"
|
|
750
|
+
description = "Autonomous software delivery — Issue to PR to Production"
|
|
751
|
+
category = "development"
|
|
752
|
+
icon = "⚓"
|
|
753
|
+
|
|
754
|
+
[config]
|
|
755
|
+
temperature = 0.2
|
|
756
|
+
max_tokens = 16384
|
|
757
|
+
max_iterations = 120
|
|
758
|
+
module = "builtin:chat"
|
|
759
|
+
|
|
760
|
+
[[tools]]
|
|
761
|
+
name = "shell"
|
|
762
|
+
[[tools]]
|
|
763
|
+
name = "read_file"
|
|
764
|
+
[[tools]]
|
|
765
|
+
name = "write_file"
|
|
766
|
+
[[tools]]
|
|
767
|
+
name = "web_search"
|
|
768
|
+
[[tools]]
|
|
769
|
+
name = "read_url"
|
|
770
|
+
[[tools]]
|
|
771
|
+
name = "schedule"
|
|
772
|
+
[[tools]]
|
|
773
|
+
name = "memory_store"
|
|
774
|
+
[[tools]]
|
|
775
|
+
name = "memory_query"
|
|
776
|
+
[[tools]]
|
|
777
|
+
name = "event_publish"
|
|
778
|
+
[[tools]]
|
|
779
|
+
name = "knowledge_graph"
|
|
780
|
+
|
|
781
|
+
[[settings]]
|
|
782
|
+
type = "select"
|
|
783
|
+
name = "pipeline_template"
|
|
784
|
+
label = "Pipeline Template"
|
|
785
|
+
description = "Which pipeline template to use for builds"
|
|
786
|
+
default = "standard"
|
|
787
|
+
[[settings.options]]
|
|
788
|
+
value = "fast"
|
|
789
|
+
label = "Fast (skip review)"
|
|
790
|
+
[[settings.options]]
|
|
791
|
+
value = "standard"
|
|
792
|
+
label = "Standard (with review)"
|
|
793
|
+
[[settings.options]]
|
|
794
|
+
value = "full"
|
|
795
|
+
label = "Full (all stages)"
|
|
796
|
+
[[settings.options]]
|
|
797
|
+
value = "autonomous"
|
|
798
|
+
label = "Autonomous (all auto)"
|
|
799
|
+
|
|
800
|
+
[[settings]]
|
|
801
|
+
type = "select"
|
|
802
|
+
name = "auto_merge"
|
|
803
|
+
label = "Auto-Merge PRs"
|
|
804
|
+
default = "false"
|
|
805
|
+
[[settings.options]]
|
|
806
|
+
value = "true"
|
|
807
|
+
label = "Yes"
|
|
808
|
+
[[settings.options]]
|
|
809
|
+
value = "false"
|
|
810
|
+
label = "No"
|
|
811
|
+
|
|
812
|
+
[[settings]]
|
|
813
|
+
type = "select"
|
|
814
|
+
name = "decision_engine"
|
|
815
|
+
label = "Decision Engine"
|
|
816
|
+
description = "Autonomous what-to-build decisions"
|
|
817
|
+
default = "off"
|
|
818
|
+
[[settings.options]]
|
|
819
|
+
value = "off"
|
|
820
|
+
label = "Off"
|
|
821
|
+
[[settings.options]]
|
|
822
|
+
value = "propose"
|
|
823
|
+
label = "Propose only"
|
|
824
|
+
[[settings.options]]
|
|
825
|
+
value = "auto"
|
|
826
|
+
label = "Fully autonomous"
|
|
827
|
+
|
|
828
|
+
[dashboard]
|
|
829
|
+
[[dashboard.metrics]]
|
|
830
|
+
name = "pipelines_completed"
|
|
831
|
+
label = "Pipelines Completed"
|
|
832
|
+
type = "counter"
|
|
833
|
+
[[dashboard.metrics]]
|
|
834
|
+
name = "pr_success_rate"
|
|
835
|
+
label = "PR Success Rate"
|
|
836
|
+
type = "percentage"
|
|
837
|
+
[[dashboard.metrics]]
|
|
838
|
+
name = "avg_lead_time_hours"
|
|
839
|
+
label = "Avg Lead Time"
|
|
840
|
+
type = "gauge"
|
|
841
|
+
[[dashboard.metrics]]
|
|
842
|
+
name = "active_workers"
|
|
843
|
+
label = "Active Workers"
|
|
844
|
+
type = "gauge"
|
|
845
|
+
|
|
846
|
+
[[requirements]]
|
|
847
|
+
type = "binary"
|
|
848
|
+
name = "git"
|
|
849
|
+
[[requirements]]
|
|
850
|
+
type = "env"
|
|
851
|
+
name = "GITHUB_TOKEN"
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
**Step 2: Create SKILL.md**
|
|
855
|
+
|
|
856
|
+
Write domain expertise content covering:
|
|
857
|
+
|
|
858
|
+
- Pipeline stage conventions (what each stage does, expected inputs/outputs)
|
|
859
|
+
- Build loop patterns (convergence detection, when to backtrack vs restart)
|
|
860
|
+
- GitHub workflow conventions (PR formatting, label semantics, reviewer selection)
|
|
861
|
+
- Test strategy (when to use fast tests vs full suite)
|
|
862
|
+
- Memory usage (how to search and store failure patterns)
|
|
863
|
+
- DORA metrics interpretation
|
|
864
|
+
|
|
865
|
+
**Step 3: Create system_prompt.md**
|
|
866
|
+
|
|
867
|
+
Multi-phase operational playbook:
|
|
868
|
+
|
|
869
|
+
1. Platform detection (repo structure, test framework, build system)
|
|
870
|
+
2. Issue analysis (decomposition, complexity scoring)
|
|
871
|
+
3. Pipeline execution (stage-by-stage with gate checks)
|
|
872
|
+
4. Build loop (iterative code generation with self-healing)
|
|
873
|
+
5. Quality assurance (adversarial review, architecture check)
|
|
874
|
+
6. PR creation (reviewer selection, description generation)
|
|
875
|
+
7. Post-merge (deployment tracking, monitoring)
|
|
876
|
+
|
|
877
|
+
**Step 4: Implement hand.rs**
|
|
878
|
+
|
|
879
|
+
Wire the Hand definition to load bundled files and register with Skipper's hand registry:
|
|
880
|
+
|
|
881
|
+
```rust
|
|
882
|
+
//! Shipwright Hand definition and registration.
|
|
883
|
+
|
|
884
|
+
use crate::config::ShipwrightConfig;
|
|
885
|
+
|
|
886
|
+
/// Hand definition metadata embedded at compile time.
|
|
887
|
+
pub const HAND_TOML: &str = include_str!("../agents/shipwright/HAND.toml");
|
|
888
|
+
pub const SKILL_MD: &str = include_str!("../agents/shipwright/SKILL.md");
|
|
889
|
+
pub const SYSTEM_PROMPT: &str = include_str!("../agents/shipwright/system_prompt.md");
|
|
890
|
+
|
|
891
|
+
/// Register the Shipwright hand with Skipper's hand registry.
|
|
892
|
+
pub fn register(/* registry: &mut HandRegistry */) {
|
|
893
|
+
// Parse HAND.toml, attach SKILL.md, register definition
|
|
894
|
+
// Follows same pattern as skipper-hands/src/bundled.rs
|
|
895
|
+
}
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
**Step 5: Verify compilation**
|
|
899
|
+
|
|
900
|
+
Run: `cargo build -p skipper-shipwright`
|
|
901
|
+
Expected: Compiles, Hand files embedded
|
|
902
|
+
|
|
903
|
+
**Step 6: Commit**
|
|
904
|
+
|
|
905
|
+
```bash
|
|
906
|
+
git add crates/skipper-shipwright/src/hand.rs crates/skipper-shipwright/agents/
|
|
907
|
+
git commit -m "feat(shipwright): Hand definition with HAND.toml, SKILL.md, system prompt"
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
---
|
|
911
|
+
|
|
912
|
+
## Task 9: CLI & API Routes
|
|
913
|
+
|
|
914
|
+
**Files:**
|
|
915
|
+
|
|
916
|
+
- Create: `crates/skipper-shipwright/src/cli.rs`
|
|
917
|
+
- Create: `crates/skipper-shipwright/src/api.rs`
|
|
918
|
+
- Modify: `crates/skipper-shipwright/src/lib.rs` (add `pub mod cli; pub mod api`)
|
|
919
|
+
- Modify: `crates/skipper-api/src/server.rs` (register Shipwright routes)
|
|
920
|
+
- Modify: `crates/skipper-cli/src/main.rs` (register `shipwright` subcommand)
|
|
921
|
+
|
|
922
|
+
**Step 1: Implement CLI subcommands**
|
|
923
|
+
|
|
924
|
+
Using clap, define the `shipwright` subcommand group:
|
|
925
|
+
|
|
926
|
+
```rust
|
|
927
|
+
#[derive(clap::Subcommand)]
|
|
928
|
+
pub enum ShipwrightCommand {
|
|
929
|
+
Pipeline {
|
|
930
|
+
#[command(subcommand)]
|
|
931
|
+
cmd: PipelineCmd,
|
|
932
|
+
},
|
|
933
|
+
Decide {
|
|
934
|
+
#[command(subcommand)]
|
|
935
|
+
cmd: DecideCmd,
|
|
936
|
+
},
|
|
937
|
+
Fleet {
|
|
938
|
+
#[command(subcommand)]
|
|
939
|
+
cmd: FleetCmd,
|
|
940
|
+
},
|
|
941
|
+
Memory {
|
|
942
|
+
#[command(subcommand)]
|
|
943
|
+
cmd: MemoryCmd,
|
|
944
|
+
},
|
|
945
|
+
Dora,
|
|
946
|
+
Cost,
|
|
947
|
+
Doctor,
|
|
948
|
+
}
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
**Step 2: Implement API routes**
|
|
952
|
+
|
|
953
|
+
Using axum, define Shipwright routes:
|
|
954
|
+
|
|
955
|
+
- `GET /api/shipwright/pipelines` → list active/completed pipelines
|
|
956
|
+
- `POST /api/shipwright/pipelines` → start new pipeline
|
|
957
|
+
- `GET /api/shipwright/pipelines/:id` → pipeline detail with stage status
|
|
958
|
+
- `GET /api/shipwright/pipelines/:id/ws` → WebSocket for real-time stage updates
|
|
959
|
+
- `POST /api/shipwright/decide/run` → trigger decision cycle
|
|
960
|
+
- `GET /api/shipwright/decide/candidates` → list current candidates
|
|
961
|
+
- `GET /api/shipwright/fleet/status` → fleet overview
|
|
962
|
+
- `GET /api/shipwright/dora/:repo` → DORA metrics for repo
|
|
963
|
+
- `GET /api/shipwright/memory/search` → semantic memory search
|
|
964
|
+
|
|
965
|
+
**Step 3: Register routes in Skipper API server**
|
|
966
|
+
|
|
967
|
+
Add Shipwright router to `server.rs`:
|
|
968
|
+
|
|
969
|
+
```rust
|
|
970
|
+
.nest("/api/shipwright", skipper_shipwright::api::router(state.clone()))
|
|
971
|
+
```
|
|
972
|
+
|
|
973
|
+
**Step 4: Register CLI in Skipper CLI**
|
|
974
|
+
|
|
975
|
+
Add `Shipwright` variant to main CLI enum, dispatch to `skipper_shipwright::cli::run()`.
|
|
976
|
+
|
|
977
|
+
**Step 5: Verify CLI works**
|
|
978
|
+
|
|
979
|
+
Run: `cargo build --release -p skipper-cli`
|
|
980
|
+
Run: `target/release/skipper shipwright --help`
|
|
981
|
+
Expected: Shows pipeline, decide, fleet, memory, dora, cost, doctor subcommands
|
|
982
|
+
|
|
983
|
+
**Step 6: Commit**
|
|
984
|
+
|
|
985
|
+
```bash
|
|
986
|
+
git add crates/skipper-shipwright/src/cli.rs crates/skipper-shipwright/src/api.rs
|
|
987
|
+
git add crates/skipper-api/src/server.rs crates/skipper-cli/src/main.rs
|
|
988
|
+
git commit -m "feat(shipwright): CLI subcommands and API routes"
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
---
|
|
992
|
+
|
|
993
|
+
## Task 10: Dashboard Pages
|
|
994
|
+
|
|
995
|
+
**Files:**
|
|
996
|
+
|
|
997
|
+
- Modify: `crates/skipper-api/static/index.html` (add Shipwright nav + pages)
|
|
998
|
+
- Modify: `crates/skipper-api/static/app.js` (add Shipwright page logic)
|
|
999
|
+
|
|
1000
|
+
**Step 1: Add navigation**
|
|
1001
|
+
|
|
1002
|
+
Add "Shipwright" section to dashboard sidebar with 6 sub-pages:
|
|
1003
|
+
Pipelines, Fleet, Decisions, DORA, Memory, Intelligence.
|
|
1004
|
+
|
|
1005
|
+
**Step 2: Implement Pipelines page**
|
|
1006
|
+
|
|
1007
|
+
- Fetch `GET /api/shipwright/pipelines`
|
|
1008
|
+
- Render table: ID, issue, template, current stage, status, cost, duration
|
|
1009
|
+
- Stage progress bar (12 segments, color-coded: green=done, blue=running, gray=pending, red=failed)
|
|
1010
|
+
- WebSocket connection for real-time updates
|
|
1011
|
+
|
|
1012
|
+
**Step 3: Implement Fleet page**
|
|
1013
|
+
|
|
1014
|
+
- Fetch `GET /api/shipwright/fleet/status`
|
|
1015
|
+
- Worker pool visualization (allocated vs available)
|
|
1016
|
+
- Per-repo queue depth and active pipelines
|
|
1017
|
+
- Auto-scaling metrics (CPU, memory, budget)
|
|
1018
|
+
|
|
1019
|
+
**Step 4: Implement Decisions page**
|
|
1020
|
+
|
|
1021
|
+
- Fetch `GET /api/shipwright/decide/candidates`
|
|
1022
|
+
- Candidate table: ID, signal, title, score, tier, status
|
|
1023
|
+
- Score breakdown visualization (impact, urgency, effort, confidence, risk)
|
|
1024
|
+
- Outcome history chart
|
|
1025
|
+
|
|
1026
|
+
**Step 5: Implement DORA page**
|
|
1027
|
+
|
|
1028
|
+
- Fetch `GET /api/shipwright/dora/:repo`
|
|
1029
|
+
- Four metric cards: Lead Time, Deploy Frequency, CFR, MTTR
|
|
1030
|
+
- Trend charts over 30/90 day windows
|
|
1031
|
+
- DORA level badge (Elite/High/Medium/Low)
|
|
1032
|
+
|
|
1033
|
+
**Step 6: Implement Memory page**
|
|
1034
|
+
|
|
1035
|
+
- Search bar → `GET /api/shipwright/memory/search?q=...`
|
|
1036
|
+
- Failure pattern cards with root cause, fix, similarity score
|
|
1037
|
+
- Architecture rule viewer
|
|
1038
|
+
|
|
1039
|
+
**Step 7: Implement Intelligence page**
|
|
1040
|
+
|
|
1041
|
+
- Risk heatmap by file
|
|
1042
|
+
- Anomaly detection alerts
|
|
1043
|
+
- Self-optimization suggestion log
|
|
1044
|
+
|
|
1045
|
+
**Step 8: Live integration test**
|
|
1046
|
+
|
|
1047
|
+
Run: `cargo build --release -p skipper-cli`
|
|
1048
|
+
Run: `target/release/skipper start &`
|
|
1049
|
+
Navigate to `http://localhost:4200/shipwright/pipelines`
|
|
1050
|
+
Verify: All 6 pages render, API calls succeed, WebSocket connects
|
|
1051
|
+
|
|
1052
|
+
**Step 9: Commit**
|
|
1053
|
+
|
|
1054
|
+
```bash
|
|
1055
|
+
git add crates/skipper-api/static/
|
|
1056
|
+
git commit -m "feat(shipwright): dashboard with 6 pages — pipelines, fleet, decisions, DORA, memory, intelligence"
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
---
|
|
1060
|
+
|
|
1061
|
+
## Task 11: Integration Tests
|
|
1062
|
+
|
|
1063
|
+
**Files:**
|
|
1064
|
+
|
|
1065
|
+
- Create: `crates/skipper-shipwright/tests/pipeline_tests.rs`
|
|
1066
|
+
- Create: `crates/skipper-shipwright/tests/decision_tests.rs`
|
|
1067
|
+
- Create: `crates/skipper-shipwright/tests/memory_tests.rs`
|
|
1068
|
+
- Create: `crates/skipper-shipwright/tests/fleet_tests.rs`
|
|
1069
|
+
- Create: `crates/skipper-shipwright/tests/integration_tests.rs`
|
|
1070
|
+
|
|
1071
|
+
**Step 1: Pipeline integration test**
|
|
1072
|
+
|
|
1073
|
+
Test full pipeline lifecycle: create → run stages → build loop (mock LLM) → self-heal → complete → PR created.
|
|
1074
|
+
|
|
1075
|
+
**Step 2: Decision integration test**
|
|
1076
|
+
|
|
1077
|
+
Test: collect signals (mock npm audit, mock Hand responses) → score → resolve tier → dedup → create issue.
|
|
1078
|
+
|
|
1079
|
+
**Step 3: Memory integration test**
|
|
1080
|
+
|
|
1081
|
+
Test: store failure → import JSONL → semantic search → compose context → verify relevance.
|
|
1082
|
+
|
|
1083
|
+
**Step 4: Fleet integration test**
|
|
1084
|
+
|
|
1085
|
+
Test: configure 2 repos → poll cycle → dispatch within worker limit → auto-scale up → rebalance.
|
|
1086
|
+
|
|
1087
|
+
**Step 5: End-to-end integration test**
|
|
1088
|
+
|
|
1089
|
+
Test: Skipper Collector Hand finds CVE → Decision engine scores it → Pipeline spawned → Build loop runs → PR created → Outcome recorded → Weights adjusted.
|
|
1090
|
+
|
|
1091
|
+
**Step 6: Run full test suite**
|
|
1092
|
+
|
|
1093
|
+
Run: `cargo test --workspace`
|
|
1094
|
+
Expected: All existing Skipper tests pass + all new Shipwright tests pass
|
|
1095
|
+
|
|
1096
|
+
Run: `cargo clippy --workspace --all-targets -- -D warnings`
|
|
1097
|
+
Expected: Zero warnings
|
|
1098
|
+
|
|
1099
|
+
**Step 7: Commit**
|
|
1100
|
+
|
|
1101
|
+
```bash
|
|
1102
|
+
git add crates/skipper-shipwright/tests/
|
|
1103
|
+
git commit -m "test(shipwright): integration tests for pipeline, decision, memory, fleet, and e2e"
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
---
|
|
1107
|
+
|
|
1108
|
+
## Task 12: Documentation & Final Verification
|
|
1109
|
+
|
|
1110
|
+
**Files:**
|
|
1111
|
+
|
|
1112
|
+
- Modify: `README.md` (add Shipwright Hand section)
|
|
1113
|
+
- Modify: `CHANGELOG.md` (add entry)
|
|
1114
|
+
|
|
1115
|
+
**Step 1: Update README**
|
|
1116
|
+
|
|
1117
|
+
Add section describing the Shipwright Hand — what it does, how to activate, configuration reference.
|
|
1118
|
+
|
|
1119
|
+
**Step 2: Update CHANGELOG**
|
|
1120
|
+
|
|
1121
|
+
```markdown
|
|
1122
|
+
## [Unreleased]
|
|
1123
|
+
|
|
1124
|
+
### Added
|
|
1125
|
+
|
|
1126
|
+
- **Shipwright Hand**: Autonomous software delivery pipeline
|
|
1127
|
+
- 12-stage pipeline engine with 6 templates
|
|
1128
|
+
- Decision engine with 18 signal collectors + Skipper Hand cross-pollination
|
|
1129
|
+
- Vector memory with semantic failure pattern search
|
|
1130
|
+
- Fleet manager with auto-scaling worker pool
|
|
1131
|
+
- GitHub integration (GraphQL, Checks, Deployments, PR lifecycle)
|
|
1132
|
+
- Intelligence layer (DORA metrics, risk prediction, self-optimization)
|
|
1133
|
+
- CLI subcommands: `skipper shipwright {pipeline,decide,fleet,memory,dora,cost,doctor}`
|
|
1134
|
+
- 9 API endpoints with WebSocket real-time updates
|
|
1135
|
+
- 6 dashboard pages
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
**Step 3: Final verification**
|
|
1139
|
+
|
|
1140
|
+
```bash
|
|
1141
|
+
cargo build --workspace --lib
|
|
1142
|
+
cargo test --workspace
|
|
1143
|
+
cargo clippy --workspace --all-targets -- -D warnings
|
|
1144
|
+
```
|
|
1145
|
+
|
|
1146
|
+
All three must pass with zero errors, zero warnings.
|
|
1147
|
+
|
|
1148
|
+
**Step 4: Commit**
|
|
1149
|
+
|
|
1150
|
+
```bash
|
|
1151
|
+
git add README.md CHANGELOG.md
|
|
1152
|
+
git commit -m "docs(shipwright): README and CHANGELOG for Shipwright Hand"
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
**Step 5: Create PR**
|
|
1156
|
+
|
|
1157
|
+
```bash
|
|
1158
|
+
git push origin feat/shipwright-hand
|
|
1159
|
+
gh pr create --title "feat: Shipwright Hand — autonomous software delivery" \
|
|
1160
|
+
--body "Ports Shipwright into skipper-shipwright crate. See docs/plans/2026-02-28-skipper-shipwright-integration-design.md"
|
|
1161
|
+
```
|
|
1162
|
+
|
|
1163
|
+
---
|
|
1164
|
+
|
|
1165
|
+
## Summary
|
|
1166
|
+
|
|
1167
|
+
| Task | Module | Tests | Commit |
|
|
1168
|
+
| ---- | ----------------------- | --------------------- | ----------------------------------------------------- |
|
|
1169
|
+
| 1 | Crate scaffold + config | 4 unit tests | `feat(shipwright): scaffold crate with config module` |
|
|
1170
|
+
| 2 | GitHub API client | ~15 unit tests | `feat(shipwright): GitHub API client` |
|
|
1171
|
+
| 3 | Memory system | ~12 unit tests | `feat(shipwright): memory system with vector search` |
|
|
1172
|
+
| 4 | Pipeline engine | ~15 unit tests | `feat(shipwright): 12-stage pipeline engine` |
|
|
1173
|
+
| 5 | Decision engine | ~18 unit tests | `feat(shipwright): decision engine` |
|
|
1174
|
+
| 6 | Intelligence layer | ~12 unit tests | `feat(shipwright): intelligence layer` |
|
|
1175
|
+
| 7 | Fleet & daemon | ~12 unit tests | `feat(shipwright): fleet manager` |
|
|
1176
|
+
| 8 | Hand definition | Compile check | `feat(shipwright): Hand definition` |
|
|
1177
|
+
| 9 | CLI & API | CLI smoke test | `feat(shipwright): CLI and API routes` |
|
|
1178
|
+
| 10 | Dashboard | Live test | `feat(shipwright): dashboard pages` |
|
|
1179
|
+
| 11 | Integration tests | ~10 integration tests | `test(shipwright): integration tests` |
|
|
1180
|
+
| 12 | Documentation | Final verification | `docs(shipwright): README and CHANGELOG` |
|
|
1181
|
+
|
|
1182
|
+
**Total: 12 tasks, ~100+ tests, 12 commits**
|