Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Pipeline Plan 364

ezigus edited this page Apr 13, 2026 · 1 revision

Plan written to .claude/pipeline-artifacts/plan.md. Here's the summary:

2 files to modify (no new files):

  • scripts/lib/pipeline-quality-checks.sh — add SHA helpers + stamp all 5 artifact write paths
  • scripts/lib/pipeline-intelligence.sh — guard all read paths + cycle file cleanup

11 tasks, split into two parts:

Part 1 — SHA anchoring (Tasks 1-8):

  • New _pipeline_head_sha() + pipeline_artifact_is_current() functions
  • Stamp created_at_commit in all 5 artifacts (JSON uses per-finding stamp matching compound-audit.sh:556; MD/log uses first-line comment)
  • Guard all reads in _extract_blocking_items() and convergence detection with SHA freshness checks
  • Backward compatible: artifacts without SHA pass through

Part 2 — Cycle file cleanup (Tasks 9-10):

  • _cleanup_cycle_files() removes negative-review-cycle*.md at stage entry and all exit paths

Key design decision: Per-finding SHA stamp for JSON (Approach A) — keeps the array format intact so all existing .[] | select(...) reads work unchanged. Rejected wrapper-object approach (B) due to 3+ read site breakage. eated_at_commit, findings: [...]}| Clean top-level field | Breaks all.[] | select(...)reads (3+ sites); larger blast radius | Rejected | | C | Sidecar.sha` files | Zero format change | Doubles file count; race conditions; orphan risk | Rejected |

Risk Assessment

Risk Mitigation
Detached HEAD / shallow clone git rev-parse --short HEAD with fallback to empty string; empty = pass-through
Old artifacts without SHA pipeline_artifact_is_current() returns 0 when no SHA found
jq unavailable Already a project dependency; guarded with 2>/dev/null
JSON array read sites Per-finding stamp keeps array format; .[0].created_at_commit for validation

Component Diagram

pipeline-quality-checks.sh (WRITERS)
+-- _pipeline_head_sha() [NEW helper]
+-- pipeline_artifact_is_current() [NEW validator]
+-- quality_check_security() -> security-audit.log (+ "# created_at_commit: <sha>" header)
+-- quality_check_adversarial() -> adversarial-review.json (+ per-finding created_at_commit)
| -> adversarial-review.md (+ "created_at_commit: <sha>" line 1)
+-- quality_check_negative() -> negative-review.md (+ "created_at_commit: <sha>" line 1)
+-- quality_check_dod() -> dod-audit.md (+ "created_at_commit: <sha>" line 1)
pipeline-intelligence.sh (READERS + CLEANUP)
+-- _extract_blocking_items() -> guards each artifact read with is_current()
+-- convergence detection (1822-71) -> guards adversarial + negative reads with is_current()
+-- _cleanup_cycle_files() [NEW helper]
+-- stage_compound_quality() -> calls _cleanup_cycle_files() before every return
compound-audit.sh (READ-ONLY REFERENCE)
+-- line 556: existing created_at_commit pattern (per-finding jq stamp)

Interface Contracts

# Returns HEAD short SHA (8 chars), or "" on failure. Never errors.
_pipeline_head_sha() -> string
# Returns 0 if artifact SHA matches HEAD. Pass-through when SHA absent.
# JSON: reads .[0].created_at_commit (per-finding stamp).
# MD: reads "created_at_commit: <sha>" from first 5 lines.
# LOG: reads "# created_at_commit: <sha>" from first 3 lines.
pipeline_artifact_is_current(file: path, [sha_field: string]) -> 0|1
# Removes negative-review-cycle*.md from ARTIFACTS_DIR. No-op if none exist.
_cleanup_cycle_files() -> void

Data Flow

  1. Write path: quality_check_*() calls _pipeline_head_sha() -> stamps SHA into artifact
  2. Read path: _extract_blocking_items() calls pipeline_artifact_is_current() before reading each artifact -> skips if stale
  3. Convergence: Same SHA guard before counting issues from adversarial-review.* and negative-review.md
  4. Cleanup: stage_compound_quality() removes negative-review-cycle*.md at all exit points

Error Boundaries

  • _pipeline_head_sha() never fails -- returns empty string on error
  • pipeline_artifact_is_current() returns 0 (pass-through) when SHA is empty or field is missing
  • JSON artifacts: jq extraction with 2>/dev/null || true
  • Markdown artifacts: sed extraction with || true

Files to Modify

File What Changes
scripts/lib/pipeline-quality-checks.sh Add _pipeline_head_sha() + pipeline_artifact_is_current() (after line 74). Stamp SHA in quality_check_security (~line 102), quality_check_adversarial (~lines 659, 675, 726), quality_check_negative (~line 815), quality_check_dod (~line 962)
scripts/lib/pipeline-intelligence.sh Guard reads in _extract_blocking_items() (lines 1051, 1060, 1070, 1079, 1085, 1094). Guard convergence reads (lines 1826, 1831, 1836). Add _cleanup_cycle_files(). Call cleanup before returns at lines ~2175, ~2204, ~2216

No new files. compound-audit.sh is untouched.

Implementation Steps

Step 1: Add _pipeline_head_sha() + pipeline_artifact_is_current() to pipeline-quality-checks.sh

Insert after pipeline_artifact_is_fresh() (line 74). The validation function:

  • For .json: reads .[0].created_at_commit via jq (per-finding stamp pattern from compound-audit.sh)
  • For .md: reads created_at_commit: <sha> from first 5 lines via sed
  • For .log: reads # created_at_commit: <sha> from first 3 lines via sed
  • Returns 0 (pass-through) when no SHA found in artifact or HEAD unavailable
  • Compares with prefix matching (short SHA lengths may vary)

Step 2: Stamp SHA in quality_check_security() (pipeline-quality-checks.sh ~line 102-110)

After tee "$audit_log" completes, prepend a # created_at_commit: <sha> header line. Use portable prepend: { echo "# created_at_commit: $sha"; cat "$audit_log"; } > tmp && mv tmp "$audit_log"

Step 3: Stamp SHA in quality_check_adversarial() (pipeline-quality-checks.sh)

JSON path (line 659): After writing adversarial-review.json, stamp each finding with jq --arg c "$sha" '[.[] | . + {created_at_commit: $c}]' (matches compound-audit.sh:556 pattern exactly).

MD path (lines 675 and 726): After writing adversarial-review.md, prepend created_at_commit: <sha> line.

Step 4: Stamp SHA in quality_check_negative() (pipeline-quality-checks.sh ~line 815)

After echo "$review_output" > negative-review.md, prepend created_at_commit: <sha> line.

Step 5: Stamp SHA in quality_check_dod() (pipeline-quality-checks.sh ~line 962)

After echo -e ... > dod-audit.md, prepend created_at_commit: <sha> line.

Step 6: Guard reads in _extract_blocking_items() (pipeline-intelligence.sh lines 1050-1100)

Add && pipeline_artifact_is_current "$ARTIFACTS_DIR/<file>" to each -f check for all 6 artifacts.

Step 7: Guard convergence detection reads (pipeline-intelligence.sh lines 1826-1864)

Add && pipeline_artifact_is_current to the -f checks for adversarial-review.md (1826), adversarial-review.json (1831), and negative-review.md (1836).

Step 8: Add _cleanup_cycle_files() helper (pipeline-intelligence.sh)

Simple function: rm -f "$ARTIFACTS_DIR"/negative-review-cycle*.md 2>/dev/null || true

Step 9: Wire _cleanup_cycle_files() into stage_compound_quality() exit paths

Call at:

  • Stage entry (clean stale files from prior runs)
  • Line ~2175 (quality gate failed return)
  • Line ~2204 (quality gate passed return)
  • Line ~2216 (exhausted cycles return)

Step 10: Run tests

./scripts/sw-pipeline-test.sh and npm test

Task Checklist

  • Task 1: Add _pipeline_head_sha() helper to pipeline-quality-checks.sh (after line 74)
  • Task 2: Add pipeline_artifact_is_current() validator to pipeline-quality-checks.sh
  • Task 3: Stamp SHA in quality_check_security() -- prepend comment to security-audit.log
  • Task 4: Stamp SHA in quality_check_adversarial() -- per-finding stamp in JSON, prepend in MD
  • Task 5: Stamp SHA in quality_check_negative() -- prepend line in negative-review.md
  • Task 6: Stamp SHA in quality_check_dod() -- prepend line in dod-audit.md
  • Task 7: Guard all 6 artifact reads in _extract_blocking_items() with pipeline_artifact_is_current()
  • Task 8: Guard convergence detection reads (lines 1826-1864) with pipeline_artifact_is_current()
  • Task 9: Add _cleanup_cycle_files() helper to pipeline-intelligence.sh
  • Task 10: Wire _cleanup_cycle_files() into all stage_compound_quality() exit paths + entry
  • Task 11: Run tests -- ./scripts/sw-pipeline-test.sh and npm test

Testing Approach

  1. Unit-level: Run ./scripts/sw-pipeline-test.sh -- existing pipeline tests exercise stage_compound_quality, _extract_blocking_items, and quality checks
  2. Manual verification:
    • Run a compound_quality cycle; inspect artifacts for created_at_commit field/line
    • Manually commit after artifact creation, verify pipeline_artifact_is_current returns 1
    • Verify no negative-review-cycle*.md files remain after stage completion
  3. Backward compat: Test with artifacts that lack SHA stamps -- should pass through (return 0)

Definition of Done

  • _pipeline_head_sha() returns 8-char short SHA or empty string
  • pipeline_artifact_is_current() correctly validates SHA for .json, .md, .log formats
  • pipeline_artifact_is_current() returns 0 (pass-through) for artifacts without SHA field
  • All 5 artifact write paths stamp created_at_commit
  • _extract_blocking_items() skips stale artifacts
  • Convergence detection skips stale artifacts
  • negative-review-cycle*.md files are cleaned up at stage entry and all exit paths
  • ./scripts/sw-pipeline-test.sh passes
  • npm test passes
  • No breaking changes to existing artifact consumers (backward compat)

STRIDE Threat Model (Security Audit)

Threat Applies? Analysis
Spoofing No SHA is read from local git, not user input
Tampering Low Attacker with artifact write access already has repo access
Repudiation No Event logging already covers audit trail
Info Disclosure No SHA is not sensitive
DoS No SHA check adds negligible overhead
Elevation No No auth/authz boundaries affected

Auth Flow, Input Validation, Security Checklist: Not applicable -- internal pipeline plumbing with no user input, no network boundaries, no credentials.

API/Frontend Specification

Not applicable -- shell script infrastructure change, no API/UI components.

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /