@mmerterden/multi-agent-pipeline 12.7.0 → 12.9.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/CHANGELOG.md +207 -0
- package/install/_common.mjs +48 -0
- package/install/_dev-only-files.mjs +125 -5
- package/install/claude.mjs +14 -8
- package/install/copilot.mjs +5 -8
- package/package.json +17 -2
- package/pipeline/commands/multi-agent/analysis/SKILL.md +1 -1
- package/pipeline/lib/credential-store.sh +20 -0
- package/pipeline/multi-agent-refs/_account-picker.md +1 -1
- package/pipeline/multi-agent-refs/_dev-context.md +1 -1
- package/pipeline/multi-agent-refs/_repo-picker.md +1 -1
- package/pipeline/multi-agent-refs/features/review-multi-repo.md +65 -0
- package/pipeline/multi-agent-refs/features/url-enrichment.md +93 -0
- package/pipeline/multi-agent-refs/phases/operations.md +28 -0
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +3 -83
- package/pipeline/multi-agent-refs/phases/phase-2-planning.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +1 -2
- package/pipeline/multi-agent-refs/phases/phase-4-review.md +50 -62
- package/pipeline/schemas/prefs.schema.json +6 -0
- package/pipeline/scripts/_smoke-root.sh +61 -0
- package/pipeline/scripts/agent-guard.py +57 -3
- package/pipeline/scripts/audit-log.sh +25 -0
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +21 -7
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-1-analysis.json +0 -25
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-2-plan.json +0 -30
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/task.json +0 -12
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-2-plan.json +0 -43
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-review.json +0 -35
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-triage.json +0 -35
- package/pipeline/eval/golden-tasks/02-android-feature-compose/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/02-android-feature-compose/task.json +0 -12
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/task.json +0 -12
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-2-plan.json +0 -40
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/task.json +0 -12
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-review.json +0 -28
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-triage.json +0 -27
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/task.json +0 -12
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-2-plan.json +0 -41
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-review.json +0 -12
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-triage.json +0 -6
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/task.json +0 -12
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-review.json +0 -28
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-triage.json +0 -27
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/task.json +0 -12
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-1-analysis.json +0 -25
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-2-plan.json +0 -31
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-review.json +0 -12
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-triage.json +0 -18
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/task.json +0 -12
- package/pipeline/eval/golden-tasks/README.md +0 -65
- package/pipeline/eval/intent-cases.json +0 -40
- package/pipeline/eval/run-metrics-fixture.json +0 -93
- package/pipeline/eval/triage/01-empty-findings/expected.json +0 -6
- package/pipeline/eval/triage/01-empty-findings/input.json +0 -5
- package/pipeline/eval/triage/01-empty-findings/notes.md +0 -7
- package/pipeline/eval/triage/02-real-blocker/expected.json +0 -15
- package/pipeline/eval/triage/02-real-blocker/input.json +0 -14
- package/pipeline/eval/triage/02-real-blocker/notes.md +0 -7
- package/pipeline/eval/triage/03-out-of-scope-defer/expected.json +0 -18
- package/pipeline/eval/triage/03-out-of-scope-defer/input.json +0 -14
- package/pipeline/eval/triage/03-out-of-scope-defer/notes.md +0 -10
- package/pipeline/eval/triage/04-false-positive-reject/expected.json +0 -18
- package/pipeline/eval/triage/04-false-positive-reject/input.json +0 -14
- package/pipeline/eval/triage/04-false-positive-reject/notes.md +0 -10
- package/pipeline/eval/triage/05-mixed-classification/expected.json +0 -43
- package/pipeline/eval/triage/05-mixed-classification/input.json +0 -38
- package/pipeline/eval/triage/05-mixed-classification/notes.md +0 -17
- package/pipeline/eval/triage/06-severity-mismatch/expected.json +0 -15
- package/pipeline/eval/triage/06-severity-mismatch/input.json +0 -14
- package/pipeline/eval/triage/06-severity-mismatch/notes.md +0 -9
- package/pipeline/eval/triage/07-duplicate-reviewers/expected.json +0 -27
- package/pipeline/eval/triage/07-duplicate-reviewers/input.json +0 -22
- package/pipeline/eval/triage/07-duplicate-reviewers/notes.md +0 -9
- package/pipeline/eval/triage/08-style-misclassified/expected.json +0 -18
- package/pipeline/eval/triage/08-style-misclassified/input.json +0 -14
- package/pipeline/eval/triage/08-style-misclassified/notes.md +0 -9
- package/pipeline/eval/triage/09-cascading-finding/expected.json +0 -23
- package/pipeline/eval/triage/09-cascading-finding/input.json +0 -22
- package/pipeline/eval/triage/09-cascading-finding/notes.md +0 -9
- package/pipeline/eval/triage/10-deferred-crossref/expected.json +0 -18
- package/pipeline/eval/triage/10-deferred-crossref/input.json +0 -14
- package/pipeline/eval/triage/10-deferred-crossref/notes.md +0 -9
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/expected.json +0 -27
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/input.json +0 -22
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/notes.md +0 -14
- package/pipeline/eval/triage/README.md +0 -54
- package/pipeline/scripts/benchmark-phase-0.sh +0 -128
- package/pipeline/scripts/check-md-links.mjs +0 -88
- package/pipeline/scripts/eval-golden-tasks-live.mjs +0 -302
- package/pipeline/scripts/eval-golden-tasks.mjs +0 -224
- package/pipeline/scripts/eval-intent.mjs +0 -107
- package/pipeline/scripts/eval-mine-corpus.mjs +0 -211
- package/pipeline/scripts/eval-triage.mjs +0 -171
- package/pipeline/scripts/fixtures/diff-risk-android.diff +0 -40
- package/pipeline/scripts/fixtures/diff-risk-ios.diff +0 -48
- package/pipeline/scripts/fixtures/diff-risk-test-removal.diff +0 -40
- package/pipeline/scripts/fixtures/install-layout.tsv +0 -19
- package/pipeline/scripts/fixtures/pack-expected-count.txt +0 -1
- package/pipeline/scripts/fixtures/test-gap-node.diff +0 -30
- package/pipeline/scripts/fixtures/test-gap-python.diff +0 -32
- package/pipeline/scripts/lint-mcp-refs.mjs +0 -218
- package/pipeline/scripts/lint-skills.mjs +0 -154
- package/pipeline/scripts/run-smokes.mjs +0 -130
- package/pipeline/scripts/scorecard.mjs +0 -258
- package/pipeline/scripts/smoke-add-detail.sh +0 -137
- package/pipeline/scripts/smoke-agent-guard.sh +0 -74
- package/pipeline/scripts/smoke-agent-log-cost.sh +0 -262
- package/pipeline/scripts/smoke-agent-model-routing.sh +0 -87
- package/pipeline/scripts/smoke-ask-choice.sh +0 -42
- package/pipeline/scripts/smoke-autopilot-circuit-breaker.sh +0 -36
- package/pipeline/scripts/smoke-bitbucket-contract.sh +0 -255
- package/pipeline/scripts/smoke-changelog-version.sh +0 -47
- package/pipeline/scripts/smoke-channels-approval-gate.sh +0 -60
- package/pipeline/scripts/smoke-channels-flow.sh +0 -130
- package/pipeline/scripts/smoke-ci-workflows.sh +0 -88
- package/pipeline/scripts/smoke-clarify.sh +0 -148
- package/pipeline/scripts/smoke-command-inventory.sh +0 -81
- package/pipeline/scripts/smoke-commands-skills-parity.sh +0 -87
- package/pipeline/scripts/smoke-community-gates.sh +0 -75
- package/pipeline/scripts/smoke-compliance-skills.sh +0 -119
- package/pipeline/scripts/smoke-config-hygiene.sh +0 -58
- package/pipeline/scripts/smoke-context-budget.sh +0 -72
- package/pipeline/scripts/smoke-cost-budget.sh +0 -70
- package/pipeline/scripts/smoke-cost-summary.sh +0 -139
- package/pipeline/scripts/smoke-cross-phase-cohesion.sh +0 -128
- package/pipeline/scripts/smoke-description-tr.sh +0 -82
- package/pipeline/scripts/smoke-dev-critic.sh +0 -144
- package/pipeline/scripts/smoke-diff-explain.sh +0 -147
- package/pipeline/scripts/smoke-diff-risk.sh +0 -190
- package/pipeline/scripts/smoke-dynamic-skill-loading.sh +0 -160
- package/pipeline/scripts/smoke-eval-live.sh +0 -136
- package/pipeline/scripts/smoke-evidence-gate.sh +0 -93
- package/pipeline/scripts/smoke-extract-conventions.sh +0 -163
- package/pipeline/scripts/smoke-fetchers-offline.sh +0 -448
- package/pipeline/scripts/smoke-figma-dispatch.sh +0 -112
- package/pipeline/scripts/smoke-gate-hooks.sh +0 -74
- package/pipeline/scripts/smoke-gc-tmp.sh +0 -130
- package/pipeline/scripts/smoke-gc-worktrees.sh +0 -125
- package/pipeline/scripts/smoke-generate-issue.sh +0 -120
- package/pipeline/scripts/smoke-handoff-contract.sh +0 -92
- package/pipeline/scripts/smoke-identity-isolation.sh +0 -70
- package/pipeline/scripts/smoke-install-layout.sh +0 -248
- package/pipeline/scripts/smoke-intent-guard.sh +0 -86
- package/pipeline/scripts/smoke-issue-comment-template.sh +0 -86
- package/pipeline/scripts/smoke-issue-jira-triad.sh +0 -120
- package/pipeline/scripts/smoke-keychain.sh +0 -158
- package/pipeline/scripts/smoke-language-axis.sh +0 -109
- package/pipeline/scripts/smoke-learning-curve.sh +0 -61
- package/pipeline/scripts/smoke-learnings-ledger.sh +0 -86
- package/pipeline/scripts/smoke-lib-scripts.sh +0 -448
- package/pipeline/scripts/smoke-mcp-gate.sh +0 -68
- package/pipeline/scripts/smoke-md-links.sh +0 -8
- package/pipeline/scripts/smoke-md2confluence.sh +0 -126
- package/pipeline/scripts/smoke-metrics-cache-ratio.sh +0 -72
- package/pipeline/scripts/smoke-migrate-state.sh +0 -102
- package/pipeline/scripts/smoke-mode-dispatch-drift.sh +0 -161
- package/pipeline/scripts/smoke-model-fallback.sh +0 -89
- package/pipeline/scripts/smoke-multi-repo-integration.sh +0 -116
- package/pipeline/scripts/smoke-multi-repo-worktree.sh +0 -61
- package/pipeline/scripts/smoke-no-mcp-in-dev-phases.sh +0 -194
- package/pipeline/scripts/smoke-no-token-prompt.sh +0 -85
- package/pipeline/scripts/smoke-own-punctuation.sh +0 -103
- package/pipeline/scripts/smoke-pack-contents.sh +0 -140
- package/pipeline/scripts/smoke-pat-audit.sh +0 -128
- package/pipeline/scripts/smoke-per-repo-memory.sh +0 -156
- package/pipeline/scripts/smoke-phase-0-multi-repo.sh +0 -170
- package/pipeline/scripts/smoke-phase-6-multi.sh +0 -79
- package/pipeline/scripts/smoke-phase-banner.sh +0 -101
- package/pipeline/scripts/smoke-phase-tracker.sh +0 -324
- package/pipeline/scripts/smoke-phase0-bridge-contract.sh +0 -241
- package/pipeline/scripts/smoke-phase4-gates.sh +0 -45
- package/pipeline/scripts/smoke-phase4-triage.sh +0 -229
- package/pipeline/scripts/smoke-plan-approval-gate.sh +0 -71
- package/pipeline/scripts/smoke-plan-safety.sh +0 -139
- package/pipeline/scripts/smoke-plan-todos.sh +0 -196
- package/pipeline/scripts/smoke-pr-review-actions.sh +0 -152
- package/pipeline/scripts/smoke-pre-commit.sh +0 -170
- package/pipeline/scripts/smoke-pref-migration.sh +0 -226
- package/pipeline/scripts/smoke-prefs-language.sh +0 -134
- package/pipeline/scripts/smoke-progress-contract.sh +0 -127
- package/pipeline/scripts/smoke-prune-logs.sh +0 -137
- package/pipeline/scripts/smoke-purge.sh +0 -138
- package/pipeline/scripts/smoke-push-retry.sh +0 -75
- package/pipeline/scripts/smoke-repo-map.sh +0 -300
- package/pipeline/scripts/smoke-review-readiness.sh +0 -92
- package/pipeline/scripts/smoke-review-watch.sh +0 -146
- package/pipeline/scripts/smoke-routines.sh +0 -84
- package/pipeline/scripts/smoke-run-aggregator.sh +0 -216
- package/pipeline/scripts/smoke-run-metrics.sh +0 -50
- package/pipeline/scripts/smoke-search.sh +0 -187
- package/pipeline/scripts/smoke-shadow-git.sh +0 -224
- package/pipeline/scripts/smoke-skill-authoring.sh +0 -137
- package/pipeline/scripts/smoke-skill-language.sh +0 -83
- package/pipeline/scripts/smoke-skill-manifest.sh +0 -138
- package/pipeline/scripts/smoke-skill-scan.sh +0 -198
- package/pipeline/scripts/smoke-source-parity.sh +0 -85
- package/pipeline/scripts/smoke-subagent-validators.sh +0 -108
- package/pipeline/scripts/smoke-sync-parity.sh +0 -92
- package/pipeline/scripts/smoke-tasklist-ordering.sh +0 -112
- package/pipeline/scripts/smoke-telemetry.sh +0 -147
- package/pipeline/scripts/smoke-test-gap.sh +0 -183
- package/pipeline/scripts/smoke-token-budget.sh +0 -67
- package/pipeline/scripts/smoke-token-preflight.sh +0 -82
- package/pipeline/scripts/smoke-tracker-contract.sh +0 -191
- package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +0 -73
- package/pipeline/scripts/smoke-triage-memory.sh +0 -174
- package/pipeline/scripts/smoke-update-check.sh +0 -135
- package/pipeline/scripts/smoke-url-enrichment.sh +0 -70
- package/pipeline/scripts/smoke-validate-analysis-doc.sh +0 -161
- package/pipeline/scripts/smoke-validator-contradiction.sh +0 -67
- package/pipeline/scripts/smoke-validator-gates.sh +0 -164
- package/pipeline/scripts/smoke-vercel-deploy-redact.sh +0 -129
- package/pipeline/scripts/smoke-verify-by-test.sh +0 -148
- package/pipeline/scripts/smoke-wiki-integration.sh +0 -122
- package/pipeline/scripts/smoke-work-summary.sh +0 -163
- package/pipeline/scripts/smoke-workflow-audit.sh +0 -101
- package/pipeline/scripts/smoke-worktree-path-convention.sh +0 -86
- package/pipeline/scripts/smoke-wrapper-preservation.sh +0 -68
- package/pipeline/scripts/smoke-write-state.sh +0 -159
- package/pipeline/scripts/sync-parity-check.sh +0 -135
- package/pipeline/scripts/test-gap-rules/android.json +0 -25
- package/pipeline/scripts/test-gap-rules/ios.json +0 -34
- package/pipeline/scripts/test-gap-rules/node.json +0 -29
- package/pipeline/scripts/test-gap-rules/python.json +0 -25
- package/pipeline/scripts/validate-schemas.mjs +0 -88
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# smoke-progress-contract.sh - enforce the progress-line contract across phase docs.
|
|
3
|
-
#
|
|
4
|
-
# Verifies:
|
|
5
|
-
# 1. Contract doc exists at refs/progress-contract.md with the required sections.
|
|
6
|
-
# 2. Line shape example is present in the doc (so downstream consumers have a
|
|
7
|
-
# canonical pattern to grep).
|
|
8
|
-
# 3. progressVerbosity field exists in prefs.schema.json with enum {quiet, normal, verbose}.
|
|
9
|
-
# 4. Adoption marker `<!-- progress-contract: applied -->` count across phase docs
|
|
10
|
-
# is reported (advisory in v5.0.0 development; will flip to blocking at
|
|
11
|
-
# v5.0.0 release once every phase has opted in).
|
|
12
|
-
# 5. Phases that DO carry the marker actually emit at least one `→ <verb>` line
|
|
13
|
-
# or reference the contract explicitly.
|
|
14
|
-
|
|
15
|
-
set -euo pipefail
|
|
16
|
-
|
|
17
|
-
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
18
|
-
ROOT="$(cd "$HERE/../.." && pwd)"
|
|
19
|
-
CONTRACT="$ROOT/pipeline/multi-agent-refs/progress-contract.md"
|
|
20
|
-
PREFS="$ROOT/pipeline/schemas/prefs.schema.json"
|
|
21
|
-
PHASE_DIR="$ROOT/pipeline/multi-agent-refs/phases"
|
|
22
|
-
|
|
23
|
-
# Flip to "true" to make missing adoption markers blocking. Today: advisory.
|
|
24
|
-
BLOCKING_ADOPTION="${PROGRESS_CONTRACT_BLOCKING:-false}"
|
|
25
|
-
|
|
26
|
-
PASS=0
|
|
27
|
-
FAIL=0
|
|
28
|
-
WARN=0
|
|
29
|
-
pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
|
|
30
|
-
fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
|
|
31
|
-
warn() { WARN=$((WARN+1)); echo " ⚠ $1"; }
|
|
32
|
-
|
|
33
|
-
need() { command -v "$1" >/dev/null 2>&1 || { echo "error: $1 required" >&2; exit 127; }; }
|
|
34
|
-
need jq
|
|
35
|
-
need grep
|
|
36
|
-
|
|
37
|
-
[ -f "$CONTRACT" ] || { echo "error: contract not found at $CONTRACT" >&2; exit 1; }
|
|
38
|
-
[ -f "$PREFS" ] || { echo "error: prefs schema not found at $PREFS" >&2; exit 1; }
|
|
39
|
-
[ -d "$PHASE_DIR" ] || { echo "error: phase docs dir not found at $PHASE_DIR" >&2; exit 1; }
|
|
40
|
-
|
|
41
|
-
echo "→ 1. contract doc has required sections"
|
|
42
|
-
for section in "## Line shape" "## When to emit" "## Verbosity" "## Telemetry" "## Phase adoption marker" "## Cross-CLI parity"; do
|
|
43
|
-
if grep -Fq "$section" "$CONTRACT"; then
|
|
44
|
-
pass "section present: $section"
|
|
45
|
-
else
|
|
46
|
-
fail "section missing: $section"
|
|
47
|
-
fi
|
|
48
|
-
done
|
|
49
|
-
|
|
50
|
-
echo ""
|
|
51
|
-
echo "→ 2. canonical line-shape template present"
|
|
52
|
-
# The doc should show: ` → <verb> <object>[ <target>]`
|
|
53
|
-
if grep -qE '→ <verb> <object>' "$CONTRACT"; then
|
|
54
|
-
pass "canonical shape '→ <verb> <object>' present"
|
|
55
|
-
else
|
|
56
|
-
fail "canonical shape missing"
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
echo ""
|
|
60
|
-
echo "→ 3. prefs schema declares progressVerbosity with correct enum"
|
|
61
|
-
VERBOSITY_ENUM=$(jq -c '.properties.global.properties.progressVerbosity.enum' "$PREFS")
|
|
62
|
-
if [ "$VERBOSITY_ENUM" = '["quiet","normal","verbose"]' ]; then
|
|
63
|
-
pass "progressVerbosity.enum = [quiet, normal, verbose]"
|
|
64
|
-
else
|
|
65
|
-
fail "progressVerbosity.enum wrong: $VERBOSITY_ENUM"
|
|
66
|
-
fi
|
|
67
|
-
DEFAULT=$(jq -r '.properties.global.properties.progressVerbosity.default' "$PREFS")
|
|
68
|
-
[ "$DEFAULT" = "normal" ] && pass "default = normal" || fail "default should be normal, got '$DEFAULT'"
|
|
69
|
-
|
|
70
|
-
echo ""
|
|
71
|
-
echo "→ 4. phase adoption marker inventory"
|
|
72
|
-
TOTAL_PHASES=0
|
|
73
|
-
ADOPTED=0
|
|
74
|
-
MISSING=()
|
|
75
|
-
for doc in "$PHASE_DIR"/phase-*.md; do
|
|
76
|
-
[ -f "$doc" ] || continue
|
|
77
|
-
TOTAL_PHASES=$((TOTAL_PHASES+1))
|
|
78
|
-
if grep -Fq "<!-- progress-contract: applied -->" "$doc"; then
|
|
79
|
-
ADOPTED=$((ADOPTED+1))
|
|
80
|
-
else
|
|
81
|
-
MISSING+=("$(basename "$doc")")
|
|
82
|
-
fi
|
|
83
|
-
done
|
|
84
|
-
echo " phases scanned: $TOTAL_PHASES"
|
|
85
|
-
echo " adopted: $ADOPTED"
|
|
86
|
-
if [ "${#MISSING[@]}" -eq 0 ]; then
|
|
87
|
-
pass "all phases have the adoption marker"
|
|
88
|
-
else
|
|
89
|
-
if [ "$BLOCKING_ADOPTION" = "true" ]; then
|
|
90
|
-
fail "missing adoption in ${#MISSING[@]} phases: ${MISSING[*]}"
|
|
91
|
-
else
|
|
92
|
-
warn "advisory - missing adoption in ${#MISSING[@]} phases: ${MISSING[*]}"
|
|
93
|
-
fi
|
|
94
|
-
fi
|
|
95
|
-
|
|
96
|
-
echo ""
|
|
97
|
-
echo "→ 5. phases that DO adopt the marker actually emit progress lines"
|
|
98
|
-
BROKEN_ADOPTIONS=()
|
|
99
|
-
for doc in "$PHASE_DIR"/phase-*.md; do
|
|
100
|
-
[ -f "$doc" ] || continue
|
|
101
|
-
if grep -Fq "<!-- progress-contract: applied -->" "$doc"; then
|
|
102
|
-
# Must reference the contract OR show at least one sample `→ <verb>` line.
|
|
103
|
-
if grep -qE '→ (fetching|reading|running|writing|posting|waiting|dispatching|retrying|building|committing|checking) ' "$doc" \
|
|
104
|
-
|| grep -Fq "refs/progress-contract.md" "$doc"; then
|
|
105
|
-
pass "$(basename "$doc") carries marker + shows progress usage"
|
|
106
|
-
else
|
|
107
|
-
fail "$(basename "$doc") has marker but no sample progress line or contract link"
|
|
108
|
-
BROKEN_ADOPTIONS+=("$(basename "$doc")")
|
|
109
|
-
fi
|
|
110
|
-
fi
|
|
111
|
-
done
|
|
112
|
-
if [ "$ADOPTED" -eq 0 ]; then
|
|
113
|
-
warn "no phases have adopted yet - this is expected until WS-4/5/6 land"
|
|
114
|
-
fi
|
|
115
|
-
|
|
116
|
-
echo ""
|
|
117
|
-
echo "→ Live mirror cross-link (tracker coupling)"
|
|
118
|
-
if grep -q "Live mirror to the phase tracker" "$CONTRACT" \
|
|
119
|
-
&& grep -q "phase-tracker.sh now" "$CONTRACT"; then
|
|
120
|
-
pass "contract cross-links the tracker mirror rule"
|
|
121
|
-
else
|
|
122
|
-
fail "contract missing the live-mirror cross-link to tracker-contract.md"
|
|
123
|
-
fi
|
|
124
|
-
|
|
125
|
-
echo ""
|
|
126
|
-
echo "══ progress-contract smoke: $PASS passed, $WARN warnings, $FAIL failed ══"
|
|
127
|
-
[ "$FAIL" -eq 0 ]
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# smoke-prune-logs.sh - prune-logs.sh removes per-task log dirs, honors the
|
|
3
|
-
# project/task/age filters, is dry-run by default, NEVER deletes the audit
|
|
4
|
-
# trail or metrics corpus (even under adversarial dir names), refuses unsafe
|
|
5
|
-
# log roots, and spares active task dirs.
|
|
6
|
-
#
|
|
7
|
-
# Exit 0 = all pass, 1 = any failure.
|
|
8
|
-
|
|
9
|
-
set -uo pipefail
|
|
10
|
-
|
|
11
|
-
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
12
|
-
PL="$ROOT/pipeline/scripts/prune-logs.sh"
|
|
13
|
-
PASS=0
|
|
14
|
-
FAIL=0
|
|
15
|
-
pass() {
|
|
16
|
-
PASS=$((PASS + 1))
|
|
17
|
-
echo " ✓ $1"
|
|
18
|
-
}
|
|
19
|
-
fail() {
|
|
20
|
-
FAIL=$((FAIL + 1))
|
|
21
|
-
echo " ✗ $1"
|
|
22
|
-
}
|
|
23
|
-
[ -f "$PL" ] || {
|
|
24
|
-
echo "FAIL: prune-logs.sh missing" >&2
|
|
25
|
-
exit 1
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
LR="$(mktemp -d)"
|
|
29
|
-
trap 'rm -rf "$LR"' EXIT
|
|
30
|
-
|
|
31
|
-
seed() {
|
|
32
|
-
rm -rf "${LR:?}"/*
|
|
33
|
-
mkdir -p "$LR/my-ios-app/PROJ-1" "$LR/my-ios-app/PROJ-2" "$LR/other/PROJ-9"
|
|
34
|
-
echo '{}' >"$LR/my-ios-app/PROJ-1/agent-state.json"
|
|
35
|
-
echo '{}' >"$LR/my-ios-app/PROJ-2/tracker-state.json"
|
|
36
|
-
echo '{}' >"$LR/other/PROJ-9/agent-log.md"
|
|
37
|
-
echo 'audit' >"$LR/audit.jsonl"
|
|
38
|
-
echo 'metric' >"$LR/metrics.jsonl"
|
|
39
|
-
echo '5' >"$LR/my-ios-app/.counter"
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
echo "→ 1. dry-run lists task dirs and deletes nothing"
|
|
43
|
-
seed
|
|
44
|
-
out=$(PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" 2>&1)
|
|
45
|
-
echo "$out" | grep -q "DRY-RUN" && pass "dry-run banner shown" || fail "dry-run banner missing"
|
|
46
|
-
[ -f "$LR/my-ios-app/PROJ-1/agent-state.json" ] && pass "dry-run kept task dirs" || fail "dry-run deleted a task dir"
|
|
47
|
-
echo "$out" | grep -qi "preserved" && pass "dry-run states audit/metrics are preserved" || fail "no preservation note"
|
|
48
|
-
|
|
49
|
-
echo ""
|
|
50
|
-
echo "→ 2. --yes deletes task dirs but preserves audit + metrics + .counter"
|
|
51
|
-
seed
|
|
52
|
-
PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --yes >/dev/null 2>&1
|
|
53
|
-
[ -f "$LR/audit.jsonl" ] && pass "audit.jsonl preserved" || fail "audit.jsonl was deleted"
|
|
54
|
-
[ -f "$LR/metrics.jsonl" ] && pass "metrics.jsonl preserved" || fail "metrics.jsonl was deleted"
|
|
55
|
-
[ -f "$LR/my-ios-app/.counter" ] && pass ".counter preserved" || fail ".counter was deleted"
|
|
56
|
-
[ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "task dir PROJ-1 removed" || fail "task dir PROJ-1 survived"
|
|
57
|
-
[ ! -e "$LR/other/PROJ-9" ] && pass "task dir PROJ-9 removed" || fail "task dir PROJ-9 survived"
|
|
58
|
-
|
|
59
|
-
echo ""
|
|
60
|
-
echo "→ 3. --project scopes deletion to one project"
|
|
61
|
-
seed
|
|
62
|
-
PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --project=my-ios-app --yes >/dev/null 2>&1
|
|
63
|
-
[ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "my-ios-app task removed" || fail "my-ios-app task survived"
|
|
64
|
-
[ -f "$LR/other/PROJ-9/agent-log.md" ] && pass "other project untouched" || fail "other project was deleted"
|
|
65
|
-
|
|
66
|
-
echo ""
|
|
67
|
-
echo "→ 4. --task scopes deletion to one task dir"
|
|
68
|
-
seed
|
|
69
|
-
PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --task=PROJ-1 --yes >/dev/null 2>&1
|
|
70
|
-
[ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "PROJ-1 removed" || fail "PROJ-1 survived"
|
|
71
|
-
[ -f "$LR/my-ios-app/PROJ-2/tracker-state.json" ] && pass "PROJ-2 untouched" || fail "PROJ-2 was deleted"
|
|
72
|
-
|
|
73
|
-
echo ""
|
|
74
|
-
echo "→ 5. --older-than excludes fresh task dirs"
|
|
75
|
-
seed
|
|
76
|
-
out=$(PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --older-than=1 2>&1)
|
|
77
|
-
echo "$out" | grep -q "nothing" && pass "freshly-created dirs excluded by --older-than=1" || fail "--older-than did not exclude fresh dirs"
|
|
78
|
-
|
|
79
|
-
echo ""
|
|
80
|
-
echo "→ 6. usage errors + empty root"
|
|
81
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" --bogus >/dev/null 2>&1
|
|
82
|
-
[ "$?" = "2" ] && pass "unknown argument exits 2" || fail "unknown argument did not exit 2"
|
|
83
|
-
PRUNE_LOG_ROOT="/nonexistent-$$-dir" bash "$PL" >/dev/null 2>&1
|
|
84
|
-
[ "$?" = "0" ] && pass "missing log root exits 0 (no-op)" || fail "missing log root did not exit 0"
|
|
85
|
-
|
|
86
|
-
echo ""
|
|
87
|
-
echo "→ 7. adversarial dirs named like preserved files survive --yes"
|
|
88
|
-
rm -rf "${LR:?}"/*
|
|
89
|
-
mkdir -p "$LR/audit.jsonl" "$LR/proj/metrics.jsonl" "$LR/proj/metrics-summary.md" "$LR/proj/.counter" "$LR/proj/PROJ-5"
|
|
90
|
-
echo '{}' >"$LR/audit.jsonl/agent-state.json"
|
|
91
|
-
echo '{}' >"$LR/proj/metrics.jsonl/agent-log.md"
|
|
92
|
-
echo '{}' >"$LR/proj/metrics-summary.md/tracker-state.json"
|
|
93
|
-
echo '{}' >"$LR/proj/.counter/agent-state.json"
|
|
94
|
-
echo '{}' >"$LR/proj/PROJ-5/agent-state.json"
|
|
95
|
-
PRUNE_LOG_ROOT="$LR" PRUNE_GRACE_MIN=0 bash "$PL" --yes >/dev/null 2>&1
|
|
96
|
-
[ -d "$LR/audit.jsonl" ] && pass "dir named audit.jsonl spared" || fail "dir named audit.jsonl deleted"
|
|
97
|
-
[ -d "$LR/proj/metrics.jsonl" ] && pass "dir named metrics.jsonl spared" || fail "dir named metrics.jsonl deleted"
|
|
98
|
-
[ -d "$LR/proj/metrics-summary.md" ] && pass "dir named metrics-summary.md spared" || fail "dir named metrics-summary.md deleted"
|
|
99
|
-
[ -d "$LR/proj/.counter" ] && pass "dir named .counter spared" || fail "dir named .counter deleted"
|
|
100
|
-
[ ! -e "$LR/proj/PROJ-5" ] && pass "normal task dir beside them still removed" || fail "normal task dir survived"
|
|
101
|
-
|
|
102
|
-
echo ""
|
|
103
|
-
echo "→ 8. unsafe log roots are refused (exit 2, dry-run only)"
|
|
104
|
-
PRUNE_LOG_ROOT="$HOME" bash "$PL" >/dev/null 2>&1
|
|
105
|
-
[ "$?" = "2" ] && pass "\$HOME as log root refused" || fail "\$HOME as log root not refused"
|
|
106
|
-
GITROOT="$(mktemp -d)"
|
|
107
|
-
mkdir -p "$GITROOT/.git"
|
|
108
|
-
PRUNE_LOG_ROOT="$GITROOT" bash "$PL" --yes >/dev/null 2>&1
|
|
109
|
-
rc=$?
|
|
110
|
-
rm -rf "$GITROOT"
|
|
111
|
-
[ "$rc" = "2" ] && pass "git work tree as log root refused" || fail "git work tree as log root not refused"
|
|
112
|
-
|
|
113
|
-
echo ""
|
|
114
|
-
echo "→ 9. default grace spares freshly-touched (active) task dirs"
|
|
115
|
-
seed
|
|
116
|
-
out=$(PRUNE_LOG_ROOT="$LR" bash "$PL" --yes 2>&1)
|
|
117
|
-
rc=$?
|
|
118
|
-
[ "$rc" = "0" ] && pass "grace run exits 0" || fail "grace run exited $rc"
|
|
119
|
-
[ -f "$LR/my-ios-app/PROJ-1/agent-state.json" ] && pass "active task dir spared by default grace" || fail "default grace deleted an active task dir"
|
|
120
|
-
echo "$out" | grep -qi "spared" && pass "output mentions spared active dirs" || fail "no spared-active note in output"
|
|
121
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" --task=PROJ-1 --yes >/dev/null 2>&1
|
|
122
|
-
[ ! -e "$LR/my-ios-app/PROJ-1" ] && pass "explicit --task bypasses the grace" || fail "--task did not bypass the grace"
|
|
123
|
-
|
|
124
|
-
echo ""
|
|
125
|
-
echo "→ 10. traversal-shaped --task/--project values are rejected"
|
|
126
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=../evil" >/dev/null 2>&1
|
|
127
|
-
[ "$?" = "2" ] && pass "--task=../evil exits 2" || fail "--task=../evil accepted"
|
|
128
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=.counter" >/dev/null 2>&1
|
|
129
|
-
[ "$?" = "2" ] && pass "--task=.counter (leading dot) exits 2" || fail "--task=.counter accepted"
|
|
130
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" "--project=a/b" >/dev/null 2>&1
|
|
131
|
-
[ "$?" = "2" ] && pass "--project=a/b exits 2" || fail "--project=a/b accepted"
|
|
132
|
-
PRUNE_LOG_ROOT="$LR" bash "$PL" "--task=" >/dev/null 2>&1
|
|
133
|
-
[ "$?" = "2" ] && pass "empty --task exits 2" || fail "empty --task accepted"
|
|
134
|
-
|
|
135
|
-
echo ""
|
|
136
|
-
echo "══ prune-logs smoke: $PASS passed, $FAIL failed ══"
|
|
137
|
-
[ "$FAIL" -eq 0 ]
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# smoke-purge.sh - purge.sh wipes .worktrees/ worktrees (registered and
|
|
3
|
-
# orphaned), their local branches, and the project task counter; is dry-run
|
|
4
|
-
# by default; preserves the main worktree, protected branches, and the
|
|
5
|
-
# audit/metrics corpus; and never follows symlinks out of .worktrees/.
|
|
6
|
-
#
|
|
7
|
-
# Exit 0 = all pass, 1 = any failure.
|
|
8
|
-
|
|
9
|
-
set -uo pipefail
|
|
10
|
-
|
|
11
|
-
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
12
|
-
PG="$ROOT/pipeline/scripts/purge.sh"
|
|
13
|
-
PASS=0
|
|
14
|
-
FAIL=0
|
|
15
|
-
pass() {
|
|
16
|
-
PASS=$((PASS + 1))
|
|
17
|
-
echo " ✓ $1"
|
|
18
|
-
}
|
|
19
|
-
fail() {
|
|
20
|
-
FAIL=$((FAIL + 1))
|
|
21
|
-
echo " ✗ $1"
|
|
22
|
-
}
|
|
23
|
-
[ -f "$PG" ] || {
|
|
24
|
-
echo "FAIL: purge.sh missing" >&2
|
|
25
|
-
exit 1
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
SB="$(cd "$(mktemp -d)" && pwd -P)"
|
|
29
|
-
trap 'rm -rf "$SB"' EXIT
|
|
30
|
-
|
|
31
|
-
REPO="$SB/repo"
|
|
32
|
-
LR="$SB/logs"
|
|
33
|
-
VICTIM="$SB/victim"
|
|
34
|
-
|
|
35
|
-
seed() {
|
|
36
|
-
rm -rf "$REPO" "$LR" "$VICTIM"
|
|
37
|
-
mkdir -p "$REPO" "$LR/repo" "$VICTIM"
|
|
38
|
-
echo keep >"$VICTIM/keep.txt"
|
|
39
|
-
git -C "$REPO" init -q -b main
|
|
40
|
-
git -C "$REPO" -c user.email=t@t.t -c user.name=t commit -q --allow-empty -m init
|
|
41
|
-
git -C "$REPO" worktree add -q -b feature/PROJ-1-x "$REPO/.worktrees/PROJ-1" >/dev/null 2>&1
|
|
42
|
-
git -C "$REPO" worktree add -q -b bugfix/PROJ-2-y "$REPO/.worktrees/PROJ-2" >/dev/null 2>&1
|
|
43
|
-
mkdir -p "$REPO/.worktrees/PROJ-9" # orphan: dir git no longer registers
|
|
44
|
-
echo '{}' >"$REPO/.worktrees/PROJ-9/agent-state.json"
|
|
45
|
-
ln -s "$VICTIM" "$REPO/.worktrees/evil-link" # symlink escape attempt
|
|
46
|
-
echo '7' >"$LR/repo/.counter"
|
|
47
|
-
echo audit >"$LR/audit.jsonl"
|
|
48
|
-
echo metric >"$LR/metrics.jsonl"
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
has_branch() {
|
|
52
|
-
git -C "$REPO" show-ref --verify -q "refs/heads/$1"
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
echo "→ 1. dry-run lists everything and deletes nothing"
|
|
56
|
-
seed
|
|
57
|
-
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" 2>&1)
|
|
58
|
-
rc=$?
|
|
59
|
-
[ "$rc" = "0" ] && pass "dry-run exits 0" || fail "dry-run exited $rc"
|
|
60
|
-
echo "$out" | grep -q "DRY-RUN" && pass "dry-run banner shown" || fail "dry-run banner missing"
|
|
61
|
-
echo "$out" | grep -q "PROJ-1" && pass "worktree PROJ-1 listed" || fail "worktree PROJ-1 not listed"
|
|
62
|
-
echo "$out" | grep -q "feature/PROJ-1-x" && pass "branch listed" || fail "branch not listed"
|
|
63
|
-
echo "$out" | grep -q ".counter" && pass "counter listed" || fail "counter not listed"
|
|
64
|
-
[ -d "$REPO/.worktrees/PROJ-1" ] && pass "dry-run kept worktrees" || fail "dry-run deleted a worktree"
|
|
65
|
-
[ -f "$LR/repo/.counter" ] && pass "dry-run kept the counter" || fail "dry-run deleted the counter"
|
|
66
|
-
has_branch feature/PROJ-1-x && pass "dry-run kept branches" || fail "dry-run deleted a branch"
|
|
67
|
-
|
|
68
|
-
echo ""
|
|
69
|
-
echo "→ 2. --yes wipes worktrees + branches + counter, preserves the rest"
|
|
70
|
-
seed
|
|
71
|
-
PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --yes >/dev/null 2>&1
|
|
72
|
-
rc=$?
|
|
73
|
-
[ "$rc" = "0" ] && pass "--yes exits 0" || fail "--yes exited $rc"
|
|
74
|
-
[ ! -e "$REPO/.worktrees/PROJ-1" ] && pass "registered worktree PROJ-1 removed" || fail "PROJ-1 survived"
|
|
75
|
-
[ ! -e "$REPO/.worktrees/PROJ-2" ] && pass "registered worktree PROJ-2 removed" || fail "PROJ-2 survived"
|
|
76
|
-
[ ! -e "$REPO/.worktrees/PROJ-9" ] && pass "orphan worktree dir removed" || fail "orphan PROJ-9 survived"
|
|
77
|
-
! has_branch feature/PROJ-1-x && pass "branch feature/PROJ-1-x deleted" || fail "feature/PROJ-1-x survived"
|
|
78
|
-
! has_branch bugfix/PROJ-2-y && pass "branch bugfix/PROJ-2-y deleted" || fail "bugfix/PROJ-2-y survived"
|
|
79
|
-
has_branch main && pass "main branch preserved" || fail "main branch was deleted"
|
|
80
|
-
git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1 && pass "main worktree still a git repo" || fail "main worktree destroyed"
|
|
81
|
-
wt_count=$(git -C "$REPO" worktree list 2>/dev/null | wc -l | tr -d ' ')
|
|
82
|
-
[ "$wt_count" = "1" ] && pass "only the main worktree remains registered" || fail "expected 1 registered worktree, got $wt_count"
|
|
83
|
-
[ ! -e "$LR/repo/.counter" ] && pass "task counter removed" || fail "task counter survived"
|
|
84
|
-
[ -f "$LR/audit.jsonl" ] && pass "audit.jsonl preserved" || fail "audit.jsonl was deleted"
|
|
85
|
-
[ -f "$LR/metrics.jsonl" ] && pass "metrics.jsonl preserved" || fail "metrics.jsonl was deleted"
|
|
86
|
-
[ -f "$VICTIM/keep.txt" ] && pass "symlink target outside repo untouched" || fail "symlink target was deleted"
|
|
87
|
-
|
|
88
|
-
echo ""
|
|
89
|
-
echo "→ 3. protected branch carried by a worktree survives, worktree still removed"
|
|
90
|
-
seed
|
|
91
|
-
git -C "$REPO" worktree add -q -b develop "$REPO/.worktrees/DEV-1" >/dev/null 2>&1
|
|
92
|
-
PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --yes >/dev/null 2>&1
|
|
93
|
-
[ ! -e "$REPO/.worktrees/DEV-1" ] && pass "develop worktree removed" || fail "develop worktree survived"
|
|
94
|
-
has_branch develop && pass "develop branch preserved" || fail "develop branch was deleted"
|
|
95
|
-
|
|
96
|
-
echo ""
|
|
97
|
-
echo "→ 4. clean repo and non-repo are no-ops (exit 0)"
|
|
98
|
-
CLEAN="$SB/clean"
|
|
99
|
-
mkdir -p "$CLEAN"
|
|
100
|
-
git -C "$CLEAN" init -q -b main
|
|
101
|
-
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$CLEAN" 2>&1)
|
|
102
|
-
rc=$?
|
|
103
|
-
{ [ "$rc" = "0" ] && echo "$out" | grep -q "nothing to do"; } && pass "clean repo is a no-op" || fail "clean repo not a clean no-op (rc=$rc)"
|
|
104
|
-
PLAIN="$SB/plain"
|
|
105
|
-
mkdir -p "$PLAIN"
|
|
106
|
-
out=$(bash "$PG" --repo "$PLAIN" 2>&1)
|
|
107
|
-
rc=$?
|
|
108
|
-
{ [ "$rc" = "0" ] && echo "$out" | grep -q "not a git work tree"; } && pass "non-repo dir is a no-op" || fail "non-repo dir not a clean no-op (rc=$rc)"
|
|
109
|
-
|
|
110
|
-
echo ""
|
|
111
|
-
echo "→ 5. usage errors exit 2"
|
|
112
|
-
bash "$PG" --bogus >/dev/null 2>&1
|
|
113
|
-
[ "$?" = "2" ] && pass "unknown argument exits 2" || fail "unknown argument did not exit 2"
|
|
114
|
-
bash "$PG" --repo >/dev/null 2>&1
|
|
115
|
-
[ "$?" = "2" ] && pass "--repo without a path exits 2" || fail "--repo without a path did not exit 2"
|
|
116
|
-
|
|
117
|
-
echo ""
|
|
118
|
-
echo "→ 6. --delete-remote without a remote warns but does not fail"
|
|
119
|
-
seed
|
|
120
|
-
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --delete-remote 2>&1)
|
|
121
|
-
echo "$out" | grep -q "remote branch origin/feature/PROJ-1-x" && pass "dry-run lists remote branch deletion" || fail "dry-run missing remote branch line"
|
|
122
|
-
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO" --delete-remote --yes 2>&1)
|
|
123
|
-
rc=$?
|
|
124
|
-
[ "$rc" = "0" ] && pass "--delete-remote --yes exits 0 without a remote" || fail "--delete-remote --yes exited $rc"
|
|
125
|
-
echo "$out" | grep -qi "warning" && pass "missing remote surfaces a warning" || fail "no warning for missing remote"
|
|
126
|
-
|
|
127
|
-
echo ""
|
|
128
|
-
echo "→ 7. purge from inside a linked worktree still anchors on the main repo"
|
|
129
|
-
seed
|
|
130
|
-
out=$(PURGE_LOG_ROOT="$LR" bash "$PG" --repo "$REPO/.worktrees/PROJ-1" --yes 2>&1)
|
|
131
|
-
rc=$?
|
|
132
|
-
[ "$rc" = "0" ] && pass "run from linked worktree exits 0" || fail "run from linked worktree exited $rc"
|
|
133
|
-
[ ! -e "$REPO/.worktrees/PROJ-1" ] && pass "worktrees removed when invoked from inside one" || fail "worktrees survived"
|
|
134
|
-
git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1 && pass "main repo intact" || fail "main repo destroyed"
|
|
135
|
-
|
|
136
|
-
echo ""
|
|
137
|
-
echo "══ purge smoke: $PASS passed, $FAIL failed ══"
|
|
138
|
-
[ "$FAIL" -eq 0 ]
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# smoke-push-retry.sh - asserts the push-must-succeed policy is documented
|
|
3
|
-
# correctly in Phase 6 and gated by settings.pushMustSucceed.
|
|
4
|
-
|
|
5
|
-
set -uo pipefail
|
|
6
|
-
|
|
7
|
-
PHASE6="$HOME/.claude/multi-agent-refs/phases/phase-6-commit.md"
|
|
8
|
-
PREFS_SCHEMA="$HOME/.claude/schemas/prefs.schema.json"
|
|
9
|
-
|
|
10
|
-
PASS=0; FAIL=0
|
|
11
|
-
pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
|
|
12
|
-
fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
|
|
13
|
-
|
|
14
|
-
if [ ! -f "$PHASE6" ]; then
|
|
15
|
-
fail "phase-6-commit.md missing"; echo "══ aborted ══"; exit 2
|
|
16
|
-
fi
|
|
17
|
-
|
|
18
|
-
echo "→ 1. Push-must-succeed gate flag"
|
|
19
|
-
grep -q "settings.pushMustSucceed" "$PHASE6" \
|
|
20
|
-
&& pass "Phase 6 references settings.pushMustSucceed gate" \
|
|
21
|
-
|| fail "settings.pushMustSucceed gate missing in Phase 6"
|
|
22
|
-
[ -f "$PREFS_SCHEMA" ] && grep -q '"pushMustSucceed"' "$PREFS_SCHEMA" \
|
|
23
|
-
&& pass "Schema declares settings.pushMustSucceed" \
|
|
24
|
-
|| fail "Schema missing settings.pushMustSucceed"
|
|
25
|
-
|
|
26
|
-
echo "→ 2. Retry budget"
|
|
27
|
-
grep -q "settings.pushRetryMax" "$PHASE6" \
|
|
28
|
-
&& pass "Phase 6 references settings.pushRetryMax" \
|
|
29
|
-
|| fail "settings.pushRetryMax reference missing"
|
|
30
|
-
[ -f "$PREFS_SCHEMA" ] && grep -q '"pushRetryMax"' "$PREFS_SCHEMA" \
|
|
31
|
-
&& pass "Schema declares settings.pushRetryMax" \
|
|
32
|
-
|| fail "Schema missing settings.pushRetryMax"
|
|
33
|
-
grep -q "default 5\|default \`5\`" "$PHASE6" \
|
|
34
|
-
&& pass "Default retry budget 5 documented" \
|
|
35
|
-
|| fail "Default retry budget 5 missing"
|
|
36
|
-
|
|
37
|
-
echo "→ 3. Rebase before push"
|
|
38
|
-
grep -q "git -C \"\$WT_PATH\" fetch origin" "$PHASE6" \
|
|
39
|
-
&& pass "Re-fetch origin before push" \
|
|
40
|
-
|| fail "Re-fetch step missing"
|
|
41
|
-
grep -q "git -C \"\$WT_PATH\" rebase" "$PHASE6" \
|
|
42
|
-
&& pass "Rebase on advancing base" \
|
|
43
|
-
|| fail "Rebase step missing"
|
|
44
|
-
grep -q "rebase conflict: abort" "$PHASE6" \
|
|
45
|
-
&& pass "Rebase-conflict aborts cleanly" \
|
|
46
|
-
|| fail "Rebase-conflict abort missing"
|
|
47
|
-
|
|
48
|
-
echo "→ 4. Back-off between attempts"
|
|
49
|
-
grep -q "sleep" "$PHASE6" \
|
|
50
|
-
&& pass "Back-off sleep between push attempts" \
|
|
51
|
-
|| fail "Back-off sleep missing"
|
|
52
|
-
grep -qE "back-off:\s*2,4,6,8" "$PHASE6" \
|
|
53
|
-
&& pass "Documented back-off cadence (2,4,6,8s)" \
|
|
54
|
-
|| fail "Back-off cadence not documented"
|
|
55
|
-
|
|
56
|
-
echo "→ 5. Final-fail user prompt (4 options)"
|
|
57
|
-
for opt in "Resolve conflict manually" "different base branch" "Skip this repo" "Pause Phase 6"; do
|
|
58
|
-
grep -q "$opt" "$PHASE6" \
|
|
59
|
-
&& pass "Final-fail option present: $opt" \
|
|
60
|
-
|| fail "Final-fail option missing: $opt"
|
|
61
|
-
done
|
|
62
|
-
|
|
63
|
-
echo "→ 6. Push status persistence"
|
|
64
|
-
grep -q "state.projects\[i\].pushStatus" "$PHASE6" \
|
|
65
|
-
&& pass "pushStatus persisted to state" \
|
|
66
|
-
|| fail "pushStatus persistence missing"
|
|
67
|
-
for v in '"pushed"' '"rebase-pushed"' '"skipped"' '"paused"'; do
|
|
68
|
-
grep -q "$v" "$PHASE6" \
|
|
69
|
-
&& pass "pushStatus enum value: $v" \
|
|
70
|
-
|| fail "pushStatus enum value missing: $v"
|
|
71
|
-
done
|
|
72
|
-
|
|
73
|
-
echo ""
|
|
74
|
-
echo "══ push-retry smoke: $PASS passed, $FAIL failed ══"
|
|
75
|
-
[ "$FAIL" -eq 0 ]
|