shipwright-cli 3.1.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 +22 -8
- 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/config/defaults.json +25 -2
- package/config/policy.json +1 -1
- package/dashboard/middleware/auth.ts +134 -0
- package/dashboard/middleware/constants.ts +21 -0
- package/dashboard/public/index.html +8 -6
- package/dashboard/public/styles.css +176 -97
- package/dashboard/routes/auth.ts +38 -0
- package/dashboard/server.ts +117 -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/api.ts +5 -0
- 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 +12 -1
- package/dashboard/src/views/activity.ts +2 -1
- package/dashboard/src/views/metrics.ts +69 -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 +14 -2
- package/scripts/lib/daemon-dispatch.sh +106 -17
- package/scripts/lib/daemon-failure.sh +34 -4
- package/scripts/lib/daemon-patrol.sh +25 -4
- 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 +119 -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 +180 -5
- 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 +101 -3
- 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 +104 -1138
- package/scripts/lib/pipeline-quality-bash-compat.sh +182 -0
- package/scripts/lib/pipeline-quality-checks.sh +17 -711
- 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 +161 -2901
- 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 -8
- package/scripts/sw-adaptive.sh +8 -7
- 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 +15 -6
- package/scripts/sw-cleanup.sh +4 -26
- package/scripts/sw-code-review.sh +45 -20
- package/scripts/sw-connect.sh +2 -1
- package/scripts/sw-context.sh +2 -1
- package/scripts/sw-cost.sh +107 -5
- package/scripts/sw-daemon.sh +71 -11
- package/scripts/sw-dashboard.sh +3 -1
- package/scripts/sw-db.sh +71 -20
- 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 +378 -5
- 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 +12 -7
- package/scripts/sw-e2e-orchestrator.sh +17 -16
- package/scripts/sw-eventbus.sh +13 -4
- 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 +9 -4
- package/scripts/sw-fleet.sh +5 -1
- package/scripts/sw-github-app.sh +18 -4
- 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 +10 -3
- package/scripts/sw-incident.sh +273 -5
- package/scripts/sw-init.sh +18 -2
- package/scripts/sw-instrument.sh +10 -2
- package/scripts/sw-intelligence.sh +44 -7
- 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 +436 -1076
- package/scripts/sw-memory.sh +357 -3
- package/scripts/sw-mission-control.sh +6 -1
- package/scripts/sw-model-router.sh +483 -27
- package/scripts/sw-otel.sh +15 -4
- package/scripts/sw-oversight.sh +14 -5
- package/scripts/sw-patrol-meta.sh +334 -0
- package/scripts/sw-pipeline-composer.sh +7 -1
- package/scripts/sw-pipeline-vitals.sh +12 -6
- package/scripts/sw-pipeline.sh +54 -2653
- package/scripts/sw-pm.sh +16 -8
- package/scripts/sw-pr-lifecycle.sh +2 -1
- package/scripts/sw-predictive.sh +17 -5
- package/scripts/sw-prep.sh +185 -2
- package/scripts/sw-ps.sh +5 -25
- package/scripts/sw-public-dashboard.sh +17 -4
- package/scripts/sw-quality.sh +14 -6
- 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 +14 -5
- package/scripts/sw-security-audit.sh +6 -1
- package/scripts/sw-self-optimize.sh +173 -6
- 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 +14 -6
- package/scripts/sw-stream.sh +13 -4
- package/scripts/sw-swarm.sh +20 -7
- package/scripts/sw-team-stages.sh +13 -6
- package/scripts/sw-templates.sh +7 -31
- package/scripts/sw-testgen.sh +17 -6
- 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 +37 -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 +3 -2
- package/scripts/sw-upgrade.sh +3 -1
- package/scripts/sw-ux.sh +5 -2
- package/scripts/sw-webhook.sh +5 -2
- package/scripts/sw-widgets.sh +9 -4
- 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,409 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════════════
|
|
3
|
+
# intent-analysis.sh — Issue intent analysis and acceptance criteria
|
|
4
|
+
# Source from pipeline-stages-intake.sh. Requires helpers, artifacts.
|
|
5
|
+
# ═══════════════════════════════════════════════════════════════════
|
|
6
|
+
|
|
7
|
+
[[ -n "${_INTENT_ANALYSIS_LOADED:-}" ]] && return 0
|
|
8
|
+
_INTENT_ANALYSIS_LOADED=1
|
|
9
|
+
|
|
10
|
+
# ─── Acceptance Criteria JSON Schema ──────────────────────────────
|
|
11
|
+
# Each criterion has: id, description, verifiable (boolean), type
|
|
12
|
+
# Types: functional, nonfunctional, constraint, acceptance_test
|
|
13
|
+
_ACCEPTANCE_CRITERIA_SCHEMA='{
|
|
14
|
+
"version": 1,
|
|
15
|
+
"goal": "string",
|
|
16
|
+
"generated_at": "ISO-8601",
|
|
17
|
+
"who_benefits": "string",
|
|
18
|
+
"what_changes": "string",
|
|
19
|
+
"why_matters": "string",
|
|
20
|
+
"how_know_worked": "string",
|
|
21
|
+
"out_of_scope": "string",
|
|
22
|
+
"criteria": [
|
|
23
|
+
{
|
|
24
|
+
"id": "ac-1",
|
|
25
|
+
"description": "string",
|
|
26
|
+
"type": "functional|nonfunctional|constraint|acceptance_test",
|
|
27
|
+
"verifiable": true
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}'
|
|
31
|
+
|
|
32
|
+
# Analyze issue intent and generate acceptance criteria JSON
|
|
33
|
+
# Reads issue metadata (title, body, labels) and quality profile
|
|
34
|
+
# Outputs acceptance-criteria.json to artifacts dir
|
|
35
|
+
# Usage: analyze_intent "$title" "$body" "$labels" "$artifacts_dir"
|
|
36
|
+
analyze_intent() {
|
|
37
|
+
local title="$1"
|
|
38
|
+
local body="${2:-}"
|
|
39
|
+
local labels="${3:-}"
|
|
40
|
+
local artifacts_dir="${4:-.claude/pipeline-artifacts}"
|
|
41
|
+
|
|
42
|
+
mkdir -p "$artifacts_dir" || return 1
|
|
43
|
+
|
|
44
|
+
# Load quality profile if available for architecture context
|
|
45
|
+
local quality_profile="${PROJECT_ROOT:-.}/.claude/quality-profile.json"
|
|
46
|
+
local arch_context=""
|
|
47
|
+
if [[ -f "$quality_profile" ]]; then
|
|
48
|
+
arch_context=$(jq -r '.architecture // {}' "$quality_profile" 2>/dev/null || true)
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Build intent analysis prompt
|
|
52
|
+
local intent_prompt="Analyze this issue deeply to understand what success looks like.
|
|
53
|
+
|
|
54
|
+
## Issue Metadata
|
|
55
|
+
Title: ${title}
|
|
56
|
+
Labels: ${labels}
|
|
57
|
+
|
|
58
|
+
## Issue Description
|
|
59
|
+
${body}
|
|
60
|
+
"
|
|
61
|
+
|
|
62
|
+
# Add architecture context if available
|
|
63
|
+
if [[ -n "$arch_context" && "$arch_context" != "{}" ]]; then
|
|
64
|
+
intent_prompt="${intent_prompt}
|
|
65
|
+
## Project Architecture
|
|
66
|
+
$(echo "$arch_context" | jq -c . 2>/dev/null || echo "$arch_context")
|
|
67
|
+
"
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
intent_prompt="${intent_prompt}
|
|
71
|
+
|
|
72
|
+
## Your Analysis
|
|
73
|
+
|
|
74
|
+
Deeply analyze this issue before any implementation planning. Answer these questions:
|
|
75
|
+
|
|
76
|
+
1. **WHO benefits?** (end user / developer / ops / CI / customer)
|
|
77
|
+
2. **WHAT changes?** (concrete before→after behavior, with specific examples)
|
|
78
|
+
3. **WHY does this matter?** (pain it solves or capability it unlocks)
|
|
79
|
+
4. **HOW will we know it worked?** (observable signals — specific, testable, measurable)
|
|
80
|
+
5. **WHAT SHOULD WE NOT DO?** (explicit out-of-scope boundaries and non-goals)
|
|
81
|
+
|
|
82
|
+
## Acceptance Criteria
|
|
83
|
+
|
|
84
|
+
Generate 3-7 machine-verifiable criteria. Each criterion must:
|
|
85
|
+
- Be testable (not vague)
|
|
86
|
+
- Reference the specific change or capability
|
|
87
|
+
- Include how to verify it passes
|
|
88
|
+
|
|
89
|
+
Format your response as JSON matching this schema (output ONLY the JSON, no markdown):
|
|
90
|
+
${_ACCEPTANCE_CRITERIA_SCHEMA}
|
|
91
|
+
"
|
|
92
|
+
|
|
93
|
+
# Call Claude to analyze intent
|
|
94
|
+
local intent_file="${artifacts_dir}/.intent-analysis.tmp"
|
|
95
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
96
|
+
# Fallback: generate basic acceptance criteria without Claude
|
|
97
|
+
_generate_default_acceptance_criteria "$title" "$body" "$artifacts_dir"
|
|
98
|
+
return 0
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Use Claude to analyze intent
|
|
102
|
+
local _token_log="${artifacts_dir}/.claude-tokens-intent.log"
|
|
103
|
+
claude --print --output-format json -p "$intent_prompt" < /dev/null > "$intent_file" 2>"$_token_log" || {
|
|
104
|
+
# Fall back to defaults if Claude fails
|
|
105
|
+
_generate_default_acceptance_criteria "$title" "$body" "$artifacts_dir"
|
|
106
|
+
return 0
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# Validate JSON output
|
|
110
|
+
if ! jq empty "$intent_file" 2>/dev/null; then
|
|
111
|
+
# Claude output wasn't valid JSON — generate defaults
|
|
112
|
+
_generate_default_acceptance_criteria "$title" "$body" "$artifacts_dir"
|
|
113
|
+
rm -f "$intent_file"
|
|
114
|
+
return 0
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
# Move to final location atomically
|
|
118
|
+
local criteria_file="${artifacts_dir}/acceptance-criteria.json"
|
|
119
|
+
mv "$intent_file" "$criteria_file" 2>/dev/null || {
|
|
120
|
+
_generate_default_acceptance_criteria "$title" "$body" "$artifacts_dir"
|
|
121
|
+
return 1
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return 0
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Generate default acceptance criteria when Claude is unavailable
|
|
128
|
+
# Extracts basic requirements from title and body
|
|
129
|
+
_generate_default_acceptance_criteria() {
|
|
130
|
+
local title="$1"
|
|
131
|
+
local body="$2"
|
|
132
|
+
local artifacts_dir="$3"
|
|
133
|
+
|
|
134
|
+
# Extract key requirements from title and body
|
|
135
|
+
local description="${title}"
|
|
136
|
+
[[ -n "$body" ]] && description="${description} — ${body:0:200}"
|
|
137
|
+
|
|
138
|
+
# Build minimal but valid JSON
|
|
139
|
+
local json
|
|
140
|
+
json=$(jq -n \
|
|
141
|
+
--arg goal "$title" \
|
|
142
|
+
--arg desc "$description" \
|
|
143
|
+
--arg now "$(date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "unknown")" \
|
|
144
|
+
'{
|
|
145
|
+
version: 1,
|
|
146
|
+
goal: $goal,
|
|
147
|
+
generated_at: $now,
|
|
148
|
+
who_benefits: "project stakeholders",
|
|
149
|
+
what_changes: $desc,
|
|
150
|
+
why_matters: "addresses the issue",
|
|
151
|
+
how_know_worked: "issue is resolved and verified",
|
|
152
|
+
out_of_scope: "unspecified",
|
|
153
|
+
criteria: [
|
|
154
|
+
{
|
|
155
|
+
id: "ac-1",
|
|
156
|
+
description: ("Implement: " + $goal),
|
|
157
|
+
type: "functional",
|
|
158
|
+
verifiable: true
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
id: "ac-2",
|
|
162
|
+
description: "All tests pass",
|
|
163
|
+
type: "acceptance_test",
|
|
164
|
+
verifiable: true
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: "ac-3",
|
|
168
|
+
description: "Code is reviewed and approved",
|
|
169
|
+
type: "constraint",
|
|
170
|
+
verifiable: true
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
}')
|
|
174
|
+
|
|
175
|
+
# Write atomically
|
|
176
|
+
local criteria_file="${artifacts_dir}/acceptance-criteria.json"
|
|
177
|
+
echo "$json" > "$criteria_file" 2>/dev/null || return 1
|
|
178
|
+
return 0
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
# Load acceptance criteria from artifacts
|
|
182
|
+
# Returns the full JSON object
|
|
183
|
+
# Usage: load_acceptance_criteria "$artifacts_dir"
|
|
184
|
+
load_acceptance_criteria() {
|
|
185
|
+
local artifacts_dir="${1:-.claude/pipeline-artifacts}"
|
|
186
|
+
local criteria_file="${artifacts_dir}/acceptance-criteria.json"
|
|
187
|
+
|
|
188
|
+
if [[ ! -f "$criteria_file" ]]; then
|
|
189
|
+
echo "{}"
|
|
190
|
+
return 0
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
# Validate and return JSON
|
|
194
|
+
if jq empty "$criteria_file" 2>/dev/null; then
|
|
195
|
+
cat "$criteria_file"
|
|
196
|
+
return 0
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Corrupt file — return empty
|
|
200
|
+
echo "{}"
|
|
201
|
+
return 1
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
# Format acceptance criteria for injection into prompts
|
|
205
|
+
# Outputs human-readable markdown
|
|
206
|
+
# Usage: format_acceptance_criteria_for_prompt "$artifacts_dir"
|
|
207
|
+
format_acceptance_criteria_for_prompt() {
|
|
208
|
+
local artifacts_dir="${1:-.claude/pipeline-artifacts}"
|
|
209
|
+
local criteria_json
|
|
210
|
+
criteria_json=$(load_acceptance_criteria "$artifacts_dir")
|
|
211
|
+
|
|
212
|
+
if [[ -z "$criteria_json" || "$criteria_json" == "{}" ]]; then
|
|
213
|
+
echo "No acceptance criteria defined."
|
|
214
|
+
return 0
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
# Extract and format criteria
|
|
218
|
+
local output=""
|
|
219
|
+
output+="## Definition of Success
|
|
220
|
+
|
|
221
|
+
"
|
|
222
|
+
|
|
223
|
+
# Add who/what/why/how if present
|
|
224
|
+
local who why what how
|
|
225
|
+
who=$(echo "$criteria_json" | jq -r '.who_benefits // empty' 2>/dev/null || true)
|
|
226
|
+
what=$(echo "$criteria_json" | jq -r '.what_changes // empty' 2>/dev/null || true)
|
|
227
|
+
why=$(echo "$criteria_json" | jq -r '.why_matters // empty' 2>/dev/null || true)
|
|
228
|
+
how=$(echo "$criteria_json" | jq -r '.how_know_worked // empty' 2>/dev/null || true)
|
|
229
|
+
|
|
230
|
+
[[ -n "$who" ]] && output+="**Who benefits**: ${who}
|
|
231
|
+
"
|
|
232
|
+
[[ -n "$what" ]] && output+="**What changes**: ${what}
|
|
233
|
+
"
|
|
234
|
+
[[ -n "$why" ]] && output+="**Why it matters**: ${why}
|
|
235
|
+
"
|
|
236
|
+
[[ -n "$how" ]] && output+="**How we'll know it worked**: ${how}
|
|
237
|
+
"
|
|
238
|
+
|
|
239
|
+
# Add structured criteria
|
|
240
|
+
output+="
|
|
241
|
+
### Acceptance Criteria
|
|
242
|
+
|
|
243
|
+
"
|
|
244
|
+
local count=0
|
|
245
|
+
local ids=""
|
|
246
|
+
echo "$criteria_json" | jq -r '.criteria[]? | "\(.id)|\(.description)|\(.type)|\(.verifiable)"' 2>/dev/null | while IFS='|' read -r id desc type verifiable; do
|
|
247
|
+
[[ -z "$id" ]] && continue
|
|
248
|
+
count=$((count + 1))
|
|
249
|
+
output+="- [\`${id}\`] ${desc} (${type}, verifiable: ${verifiable})
|
|
250
|
+
"
|
|
251
|
+
done
|
|
252
|
+
|
|
253
|
+
echo -n "$output"
|
|
254
|
+
return 0
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
# Inject failure mode analysis requirement into plan prompt
|
|
258
|
+
# Uses architecture rules from quality profile
|
|
259
|
+
# Usage: inject_failure_mode_analysis "$plan_prompt" "$quality_profile_path"
|
|
260
|
+
inject_failure_mode_analysis() {
|
|
261
|
+
local plan_prompt="$1"
|
|
262
|
+
local quality_profile="${2:-.claude/quality-profile.json}"
|
|
263
|
+
|
|
264
|
+
# Load architecture rules if available
|
|
265
|
+
local arch_rules=""
|
|
266
|
+
if [[ -f "$quality_profile" ]]; then
|
|
267
|
+
arch_rules=$(jq -r '.architecture.rules[]? // empty' "$quality_profile" 2>/dev/null | sed 's/^/ - /' || true)
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
# Build failure mode injection section
|
|
271
|
+
local injection="
|
|
272
|
+
## Mandatory Failure Mode Analysis
|
|
273
|
+
|
|
274
|
+
After your implementation plan, you MUST include a section titled:
|
|
275
|
+
|
|
276
|
+
### Failure Mode Analysis
|
|
277
|
+
|
|
278
|
+
For each major component or decision in your plan:
|
|
279
|
+
|
|
280
|
+
1. **Runtime Failures**: What happens when dependencies are unavailable, network timeouts occur, or external services fail?
|
|
281
|
+
2. **Concurrency Risks**: Race conditions, stale state, duplicate processing, or inconsistent updates?
|
|
282
|
+
3. **Scale Risks**: What breaks when data grows 10x, dependencies are slow, or memory pressure increases?
|
|
283
|
+
4. **Rollback Story**: Can we revert this change safely? Is there data migration risk?
|
|
284
|
+
|
|
285
|
+
You MUST identify at least 3 concrete failure modes specific to this codebase and task.
|
|
286
|
+
|
|
287
|
+
"
|
|
288
|
+
|
|
289
|
+
# Add architecture rules context if available
|
|
290
|
+
if [[ -n "$arch_rules" ]]; then
|
|
291
|
+
injection+="Consider these architecture constraints:
|
|
292
|
+
${arch_rules}
|
|
293
|
+
|
|
294
|
+
"
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
injection+="After listing failure modes, address the most critical one in your implementation plan."
|
|
298
|
+
|
|
299
|
+
echo "${plan_prompt}${injection}"
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
# Validate plan has adequate failure mode analysis
|
|
303
|
+
# Returns 0 if valid, 1 if missing/shallow
|
|
304
|
+
# Checks: section exists, at least 3 items, project-specific references
|
|
305
|
+
# Usage: validate_failure_modes "$plan_file"
|
|
306
|
+
validate_failure_modes() {
|
|
307
|
+
local plan_file="$1"
|
|
308
|
+
|
|
309
|
+
[[ ! -f "$plan_file" ]] && return 1
|
|
310
|
+
|
|
311
|
+
# Check if failure mode section exists (case-insensitive)
|
|
312
|
+
if ! grep -qi "failure mode" "$plan_file"; then
|
|
313
|
+
return 1 # Section not found
|
|
314
|
+
fi
|
|
315
|
+
|
|
316
|
+
# Extract the section
|
|
317
|
+
local fma_section
|
|
318
|
+
fma_section=$(sed -n '/[Ff]ailure [Mm]ode/,/^##\|^#[^#]/p' "$plan_file" 2>/dev/null || true)
|
|
319
|
+
|
|
320
|
+
# Count items (lines starting with 1., 2., 3., etc. or bullet points)
|
|
321
|
+
local item_count
|
|
322
|
+
item_count=$(echo "$fma_section" | grep -E '^\s*[0-9]+\.|^\s*-' | wc -l | tr -d ' ')
|
|
323
|
+
|
|
324
|
+
if [[ -z "$item_count" ]] || [[ "$item_count" -lt 3 ]]; then
|
|
325
|
+
return 1 # Fewer than 3 items
|
|
326
|
+
fi
|
|
327
|
+
|
|
328
|
+
# Check for project-specific references (not just generic platitudes)
|
|
329
|
+
# Look for: file names, function names, design patterns, architectural concepts
|
|
330
|
+
local has_specificity=false
|
|
331
|
+
|
|
332
|
+
if echo "$fma_section" | grep -qEi '(\.js|\.ts|\.py|\.go|\.rs|\.java|\.cpp|\.c|\.rb|\.php)(\)|:|,|"|\s)'; then
|
|
333
|
+
has_specificity=true # References file extensions
|
|
334
|
+
fi
|
|
335
|
+
|
|
336
|
+
if echo "$fma_section" | grep -qEi '(function|class|module|component|service|database|cache|queue|api|endpoint)'; then
|
|
337
|
+
has_specificity=true # References architectural components
|
|
338
|
+
fi
|
|
339
|
+
|
|
340
|
+
if echo "$fma_section" | grep -qEi '(race condition|deadlock|stale|timeout|overflow|leak|injection|validate|sanitize)'; then
|
|
341
|
+
has_specificity=true # References specific failure modes
|
|
342
|
+
fi
|
|
343
|
+
|
|
344
|
+
# Also accept if failure modes reference specific project concepts from plan
|
|
345
|
+
# (e.g., mentions of specific modules/patterns discussed in the plan itself)
|
|
346
|
+
if echo "$fma_section" | grep -qi "dependency\|rollback\|revert\|transaction"; then
|
|
347
|
+
has_specificity=true
|
|
348
|
+
fi
|
|
349
|
+
|
|
350
|
+
if [[ "$has_specificity" == "true" ]]; then
|
|
351
|
+
return 0 # Valid failure mode analysis
|
|
352
|
+
fi
|
|
353
|
+
|
|
354
|
+
return 1 # Generic/shallow analysis
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
# Helper to extract failure mode analysis section from plan
|
|
358
|
+
# Usage: extract_failure_modes "$plan_file"
|
|
359
|
+
extract_failure_modes() {
|
|
360
|
+
local plan_file="$1"
|
|
361
|
+
|
|
362
|
+
[[ ! -f "$plan_file" ]] && return 1
|
|
363
|
+
|
|
364
|
+
sed -n '/[Ff]ailure [Mm]ode/,/^##\|^#[^#]/p' "$plan_file" 2>/dev/null | head -50 || true
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
# Helper to return a validation status for plan rejection
|
|
368
|
+
# Usage: get_failure_mode_validation_status "$plan_file"
|
|
369
|
+
# Returns: "valid", "missing_section", "too_few_items", "too_generic"
|
|
370
|
+
get_failure_mode_validation_status() {
|
|
371
|
+
local plan_file="$1"
|
|
372
|
+
|
|
373
|
+
[[ ! -f "$plan_file" ]] && {
|
|
374
|
+
echo "missing_file"
|
|
375
|
+
return 1
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
# Check if failure mode section exists
|
|
379
|
+
if ! grep -qi "failure mode" "$plan_file"; then
|
|
380
|
+
echo "missing_section"
|
|
381
|
+
return 1
|
|
382
|
+
fi
|
|
383
|
+
|
|
384
|
+
local fma_section
|
|
385
|
+
fma_section=$(sed -n '/[Ff]ailure [Mm]ode/,/^##\|^#[^#]/p' "$plan_file" 2>/dev/null || true)
|
|
386
|
+
|
|
387
|
+
# Count items
|
|
388
|
+
local item_count
|
|
389
|
+
item_count=$(echo "$fma_section" | grep -E '^\s*[0-9]+\.|^\s*-' | wc -l | tr -d ' ')
|
|
390
|
+
|
|
391
|
+
if [[ -z "$item_count" ]] || [[ "$item_count" -lt 3 ]]; then
|
|
392
|
+
echo "too_few_items"
|
|
393
|
+
return 1
|
|
394
|
+
fi
|
|
395
|
+
|
|
396
|
+
# Check for specificity
|
|
397
|
+
local has_specificity=false
|
|
398
|
+
if echo "$fma_section" | grep -qEi '\.(js|ts|py|go|rs|java|cpp|c|rb|php)(\)|:|,|"|\s)|function|class|module|component|service|database|cache|queue|api|endpoint'; then
|
|
399
|
+
has_specificity=true
|
|
400
|
+
fi
|
|
401
|
+
|
|
402
|
+
if [[ "$has_specificity" != "true" ]]; then
|
|
403
|
+
echo "too_generic"
|
|
404
|
+
return 1
|
|
405
|
+
fi
|
|
406
|
+
|
|
407
|
+
echo "valid"
|
|
408
|
+
return 0
|
|
409
|
+
}
|