feat: source build system, CI pipeline, Containerfile#23
Conversation
- install.sh: full rewrite with step-by-step colored UI, source build, prereq checks, --update flag, auto-clone, troubleshooting guide - scripts/dogfood-build.sh: provenance-checked build with GIT_SHA injection - scripts/validate-agents.sh: lint agent MD files - scripts/fmt.sh: unified Rust + Python formatter - .github/workflows/ci.yml: PR gate with fmt, clippy, test, Windows smoke - Containerfile: Docker/Podman image for reproducible source builds - Makefile: dogfood, container, validate, fmt-check targets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (3)
📝 WalkthroughWalkthrough
Changes빌드 시스템 업그레이드
Rust 코드 스타일 정렬
Sequence Diagram(s)sequenceDiagram
participant user as 사용자
participant install as install.sh
participant git as git clone/pull
participant cargo as cargo build
participant fs as 파일시스템
user->>install: bash install.sh [옵션]
install->>install: OS/WSL 감지, 필수 명령 점검
install->>git: agents/00-orchestrator.md 없으면 repo 클론
git-->>install: REPO_DIR 확정
install->>cargo: cargo build --workspace
cargo-->>install: claude-tools 바이너리
install->>fs: 바이너리 BIN_DIR 복사
install->>fs: agents/*.md → CLAUDE_HOME/agents
install->>fs: commands/*.md → CLAUDE_HOME/commands
install->>fs: tools/*.py → BIN_DIR
install->>install: claude-tools --version 검증
install-->>user: 완료 요약 + PATH 안내
sequenceDiagram
participant ci as GitHub Actions
participant validate as validate-agents
participant fmt as fmt
participant clippy as clippy
participant test as test
participant dogfood as dogfood
participant windows as windows-smoke
ci->>validate: scripts/validate-agents.sh
ci->>fmt: cargo fmt --all --check
ci->>clippy: cargo clippy --workspace -- -D warnings
ci->>test: cargo test --workspace
ci->>windows: cargo build (debug) + .exe 확인
fmt-->>dogfood: needs 완료
clippy-->>dogfood: needs 완료
test-->>dogfood: needs 완료
dogfood->>dogfood: dogfood-build.sh + validate-agents.sh
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
…mode - colors.rs: convert one-liner functions to multi-line (rustfmt requirement) - cost.rs: remove column-alignment spaces in PRICING, AGENT_MODELS, OUTPUT_RATIO tuples - ci.yml: remove --strict from validate-agents (agent files use varied section names) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (6)
install.sh (2)
329-329: ⚡ Quick win
ls대신find사용을 권장합니다.
ls로 파일 개수를 세면 특수 문자가 포함된 파일명에서 예상치 못한 결과가 발생할 수 있습니다.find가 더 견고합니다.♻️ 제안
-INSTALLED_AGENTS=$(ls "${CLAUDE_HOME}/agents/"*.md 2>/dev/null | wc -l | tr -d ' ') +INSTALLED_AGENTS=$(find "${CLAUDE_HOME}/agents/" -maxdepth 1 -name '*.md' 2>/dev/null | wc -l | tr -d ' ')또는 Bash 배열을 사용하는 방법:
shopt -s nullglob agent_files=("${CLAUDE_HOME}/agents/"*.md) INSTALLED_AGENTS=${`#agent_files`[@]}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@install.sh` at line 329, The INSTALLED_AGENTS variable assignment uses `ls` to count files, which can produce incorrect results when filenames contain special characters. Replace this approach by using a Bash array method instead: enable nullglob shell option, assign matching .md files from the agents directory to an array, and then set INSTALLED_AGENTS to the array length using the ${`#array`[@]} syntax. This is more robust and handles edge cases with special characters in filenames correctly.
194-223: 💤 Low value
MISSING변수가 초기화 후 수정되지 않아 의미 없는 검사가 됩니다.
MISSING=0이 설정되지만 아무 곳에서도 증가되지 않습니다. 따라서 라인 223의[ "$MISSING" -eq 0 ]검사는 항상 참이 됩니다.또한 라인 196-197의
A && B || C패턴은ok()함수가 실패하면 (stdout 닫힘 등) 명령어가 존재해도warn()이 실행될 수 있습니다.♻️ 제안: 사용하지 않는 MISSING 변수 제거 또는 적절히 활용
-MISSING=0 - -need_cmd git && ok "git $(git --version 2>/dev/null)" || { warn "git not found (some features may degrade)"; } -need_cmd python3 && ok "python3 $(python3 --version 2>/dev/null)" || warn "python3 not found — Python tools won't install" +if need_cmd git; then + ok "git $(git --version 2>/dev/null)" +else + warn "git not found (some features may degrade)" +fi + +if need_cmd python3; then + ok "python3 $(python3 --version 2>/dev/null)" +else + warn "python3 not found — Python tools won't install" +fi라인 223의 무의미한 검사도 제거하세요:
-[ "$MISSING" -eq 0 ] && ok "Prerequisites satisfied" +ok "Prerequisites satisfied"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@install.sh` around lines 194 - 223, The MISSING variable is initialized to 0 but is never incremented anywhere in the script, making the final check at line 223 ([ "$MISSING" -eq 0 ]) always true and therefore meaningless. Remove both the MISSING=0 initialization and the final check [ "$MISSING" -eq 0 ] && ok "Prerequisites satisfied" since they serve no purpose. Alternatively, if you want to properly track missing prerequisites, you would need to increment the MISSING counter whenever a need_cmd check fails or a warn condition is detected, but given the current structure, removing these unused lines is the simplest solution..github/workflows/ci.yml (3)
1-158: ⚡ Quick win워크플로우 권한을 최소화하세요.
워크플로우가
permissions:블록을 지정하지 않아 기본 권한을 상속받습니다. 보안 모범 사례에 따라 최소 권한 원칙을 적용하는 것이 좋습니다.제안하는 권한 설정
워크플로우 최상단에 추가:
name: CI permissions: contents: read on: push:이렇게 하면 읽기 전용 저장소 접근만 허용하고, 다른 모든 권한은 거부됩니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/ci.yml around lines 1 - 158, The CI workflow does not explicitly define a permissions block, which means it inherits default permissions instead of following the principle of least privilege. Add a permissions block after the name field (at the top of the workflow before the on section) and set it to contents: read to restrict the workflow to read-only repository access and deny all other permissions by default, improving the security posture of the workflow.Source: Linters/SAST tools
48-48: ⚡ Quick win자격 증명 지속성을 비활성화하는 것을 고려하세요.
actions/checkout은 기본적으로 후속 단계에서 사용할 수 있도록 자격 증명을 지속합니다. 이 워크플로우는 푸시를 수행하지 않으므로, 보안 강화를 위해persist-credentials: false를 설정하는 것이 좋습니다.제안하는 수정
모든 checkout 단계에 추가:
- uses: actions/checkout@v4 + with: + persist-credentials: falseAlso applies to: 58-58, 76-76, 94-94, 114-114, 144-144
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/ci.yml at line 48, The GitHub Actions workflow uses actions/checkout@v4 at multiple locations without disabling credential persistence. Since this workflow does not perform any git pushes, credentials should not be persisted in memory for security reasons. Add the parameter persist-credentials: false to all instances of actions/checkout@v4 throughout the CI workflow to enhance security by preventing unnecessary credential retention after the checkout action completes.Source: Linters/SAST tools
48-48: ⚖️ Poor tradeoff액션을 SHA로 고정하는 것에 대한 참고사항
정적 분석 도구가 액션이 커밋 SHA로 고정되지 않았다고 플래그를 지정했습니다. SHA 고정은 더 강력한 보안을 제공하지만, 버전 태그(
@v4,@v2)도 많은 프로젝트에서 허용되는 관행입니다.SHA 고정의 장단점:
- 장점: 업스트림 태그 변조 방지, 재현 가능한 빌드
- 단점: 수동 업데이트 필요, Dependabot 통합 감소, 가독성 저하
현재 사용 중인 액션들(
actions/checkout,dtolnay/rust-toolchain,Swatinem/rust-cache)은 신뢰할 수 있는 출처이므로, 버전 태그를 사용하는 것이 대부분의 프로젝트에 적합합니다. 높은 보안 요구사항이 있는 경우에만 SHA 고정을 고려하세요.Also applies to: 58-58, 60-60, 64-64, 76-76, 78-78, 82-82, 94-94, 96-96, 98-98, 114-114, 116-116, 118-118, 144-144, 146-146, 148-148
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/ci.yml at line 48, The static analysis tool has flagged that GitHub Actions are not pinned to commit SHAs but rather use version tags (such as `@v4`, `@v2`). To address this security recommendation, replace the version tag references in the actions/checkout, dtolnay/rust-toolchain, and Swatinem/rust-cache action uses statements with their corresponding full commit SHAs (for example, replace `@v4` with the actual commit hash like `@abc1234def5678`...). This applies to all occurrences noted in the comment across lines 48, 58, 60, 64, 76, 78, 82, 94, 96, 98, 114, 116, 118, 144, 146, and 148. Note that this is a security hardening measure, though version tags remain acceptable for most projects with standard security requirements.Source: Linters/SAST tools
scripts/validate-agents.sh (1)
19-19: ⚡ Quick win인자 파싱이 취약합니다.
[ "$*" = "--strict" ]는--strict가 유일한 인자일 때만 동작합니다. 추가 인자나 공백이 있으면 매칭되지 않습니다.더 견고한 인자 파싱
-[ "$*" = "--strict" ] && STRICT=1 +for arg in "$@"; do + case "$arg" in + --strict) STRICT=1 ;; + *) echo "Unknown argument: $arg" >&2; exit 1 ;; + esac +done🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/validate-agents.sh` at line 19, The argument parsing condition `[ "$*" = "--strict" ]` is fragile because it only matches when `--strict` is the sole argument with no additional arguments or whitespace variations. Instead, modify this condition to check if the `--strict` flag is present among the arguments by either iterating through the arguments using a for loop with `"$@"` or using a pattern matching operator like `[[ $* =~ --strict ]]` to robustly detect the presence of the `--strict` flag regardless of other arguments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Line 51: The validate-agents script is being called with inconsistent flags
across the CI workflow. The validate-agents job on line 51 uses the --strict
flag when running bash scripts/validate-agents.sh, but the dogfood job on line
157 runs the same script without the --strict flag. To fix this inconsistency,
either add the --strict flag to the dogfood job's validate-agents invocation to
ensure both jobs perform validation at the same level, or remove it from line 51
if lenient validation is intentional for the validate-agents job. Choose the
approach based on whether strict validation should be required for both jobs or
only one.
- Around line 126-133: The Windows smoke test script currently prints a message
and exits successfully when the claude-tools.exe binary is not found, which
allows the test to pass even if the build fails to generate the binary. Change
the else block in the PowerShell script to exit with a failure code instead of
just printing a message. When Test-Path returns false for the $bin variable, use
exit 1 or throw to cause the workflow step to fail, ensuring that missing
binaries are properly detected as build failures rather than allowed to silently
pass.
In `@install.sh`:
- Around line 281-285: The STEP_TOTAL counter is being decremented after the
step() function call when SKIP_BINARY is true, causing the progress counter to
display an incorrect total in subsequent steps. Move the STEP_TOTAL decrement to
occur earlier in the script, specifically after all prerequisite checks (where
rustc and cargo availability are verified and SKIP_BINARY may be automatically
set), rather than inside the conditional block after the step() call. This
ensures the correct total is established before any progress messages are
displayed. Remove the duplicate STEP_TOTAL decrement from the current location
in the else block to avoid reducing the counter twice.
In `@scripts/dogfood-build.sh`:
- Around line 51-55: The BINARY_SHA variable assignment treats all failures
(command execution errors, SHA parsing failures) identically by falling back to
"null", and then the subsequent conditional only logs a warning instead of
failing the build. This allows potential security issues to bypass the CI gate.
Modify the script to detect when the $BINARY version command fails or produces
no SHA output, and in those cases exit with a non-zero status code to fail the
build immediately, rather than continuing with just a warning message. The
provenance check should be a blocking requirement, not optional.
In `@scripts/fmt.sh`:
- Around line 48-49: The ruff format command in the non-check mode section
(around line 48) only prints success messages but does not track failures when
ruff format fails. Unlike the CHECK mode section above it (lines 40-46), there
is no explicit failure counting. Modify the ruff format command to check the
exit status and increment the FAILURES counter when the command fails, similar
to how failure tracking is implemented in the CHECK mode section. This ensures
that a failed format operation is properly recorded and reflected in the final
exit code.
In `@scripts/validate-agents.sh`:
- Around line 4-8: The comment on line 8 indicates that the script should
validate that agent numbers match an expected numbering sequence (check `#4`), but
the current implementation only validates for duplicate agent numbers and does
not include logic to verify the sequence. Add validation logic to check that the
agent files follow a continuous numbering sequence (for example 01, 02, 03, etc.
without gaps). Extract all agent numbers from the NN-name.md filenames, sort
them, and verify they form a consecutive sequence starting from the expected
beginning number. Report an error message if any gaps or unexpected numbers are
found in the sequence.
- Line 22: The warn() function in strict mode exits immediately on the first
warning due to the `[ "$STRICT" -eq 0 ] || exit 1` condition, preventing the
script from collecting all validation issues before terminating. Instead of
exiting immediately, implement a warning counter mechanism similar to how the
fail() function handles failures (accumulating a count), and increment this
counter each time warn() is called in strict mode. Then at the end of the
script, check the accumulated warning counter and exit with an appropriate
status code if warnings were found, allowing users to see all validation
problems at once rather than stopping on the first one.
- Around line 1-77: Each agent markdown file in the agents/ directory is missing
one or both of the required sections that the validation script checks for. For
each file matching the [0-9][0-9]-*.md pattern, ensure at least one Role/Name
section header exists (## Role, ## Name, ## Identity, or ## 에이전트) and at least
one Instructions section header exists (## Instructions, ## Core Rules, ##
Rules, ## 규칙, or ## 지침). Add these missing section headers to all 11 agent files
so the validation checks in the grep statements checking for '^##
(Role|Name|Identity|에이전트)' and '^## (Instructions|Core Rules|Rules|규칙|지침)'
patterns will pass.
---
Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 1-158: The CI workflow does not explicitly define a permissions
block, which means it inherits default permissions instead of following the
principle of least privilege. Add a permissions block after the name field (at
the top of the workflow before the on section) and set it to contents: read to
restrict the workflow to read-only repository access and deny all other
permissions by default, improving the security posture of the workflow.
- Line 48: The GitHub Actions workflow uses actions/checkout@v4 at multiple
locations without disabling credential persistence. Since this workflow does not
perform any git pushes, credentials should not be persisted in memory for
security reasons. Add the parameter persist-credentials: false to all instances
of actions/checkout@v4 throughout the CI workflow to enhance security by
preventing unnecessary credential retention after the checkout action completes.
- Line 48: The static analysis tool has flagged that GitHub Actions are not
pinned to commit SHAs but rather use version tags (such as `@v4`, `@v2`). To address
this security recommendation, replace the version tag references in the
actions/checkout, dtolnay/rust-toolchain, and Swatinem/rust-cache action uses
statements with their corresponding full commit SHAs (for example, replace `@v4`
with the actual commit hash like `@abc1234def5678`...). This applies to all
occurrences noted in the comment across lines 48, 58, 60, 64, 76, 78, 82, 94,
96, 98, 114, 116, 118, 144, 146, and 148. Note that this is a security hardening
measure, though version tags remain acceptable for most projects with standard
security requirements.
In `@install.sh`:
- Line 329: The INSTALLED_AGENTS variable assignment uses `ls` to count files,
which can produce incorrect results when filenames contain special characters.
Replace this approach by using a Bash array method instead: enable nullglob
shell option, assign matching .md files from the agents directory to an array,
and then set INSTALLED_AGENTS to the array length using the ${`#array`[@]} syntax.
This is more robust and handles edge cases with special characters in filenames
correctly.
- Around line 194-223: The MISSING variable is initialized to 0 but is never
incremented anywhere in the script, making the final check at line 223 ([
"$MISSING" -eq 0 ]) always true and therefore meaningless. Remove both the
MISSING=0 initialization and the final check [ "$MISSING" -eq 0 ] && ok
"Prerequisites satisfied" since they serve no purpose. Alternatively, if you
want to properly track missing prerequisites, you would need to increment the
MISSING counter whenever a need_cmd check fails or a warn condition is detected,
but given the current structure, removing these unused lines is the simplest
solution.
In `@scripts/validate-agents.sh`:
- Line 19: The argument parsing condition `[ "$*" = "--strict" ]` is fragile
because it only matches when `--strict` is the sole argument with no additional
arguments or whitespace variations. Instead, modify this condition to check if
the `--strict` flag is present among the arguments by either iterating through
the arguments using a for loop with `"$@"` or using a pattern matching operator
like `[[ $* =~ --strict ]]` to robustly detect the presence of the `--strict`
flag regardless of other arguments.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e11288b4-5b6a-4539-8d2d-b237330102d1
📒 Files selected for processing (7)
.github/workflows/ci.ymlContainerfileMakefileinstall.shscripts/dogfood-build.shscripts/fmt.shscripts/validate-agents.sh
| run: | | ||
| $bin = "target\debug\claude-tools.exe" | ||
| if (Test-Path $bin) { | ||
| & $bin --version | ||
| Write-Host "claude-tools binary OK" | ||
| } else { | ||
| Write-Host "No claude-tools binary found (workspace may not include binary crate yet)" | ||
| } |
There was a problem hiding this comment.
Windows 스모크 테스트가 바이너리 누락 시 실패하지 않습니다.
PowerShell 스크립트는 claude-tools.exe가 없을 때 메시지만 출력하고 정상 종료됩니다. 이는 빌드가 바이너리를 생성하지 못해도 테스트가 통과하는 것을 의미하며, 빌드 실패를 감지하지 못할 수 있습니다.
주석에 "workspace may not include binary crate yet"라고 명시되어 있지만, PR 목표에 따르면 바이너리 크레이트가 존재해야 합니다. 바이너리가 누락되면 테스트가 실패해야 합니다.
제안하는 수정
- name: Smoke test binary
run: |
$bin = "target\debug\claude-tools.exe"
if (Test-Path $bin) {
& $bin --version
Write-Host "claude-tools binary OK"
} else {
- Write-Host "No claude-tools binary found (workspace may not include binary crate yet)"
+ Write-Error "claude-tools binary not found at $bin"
+ exit 1
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| run: | | |
| $bin = "target\debug\claude-tools.exe" | |
| if (Test-Path $bin) { | |
| & $bin --version | |
| Write-Host "claude-tools binary OK" | |
| } else { | |
| Write-Host "No claude-tools binary found (workspace may not include binary crate yet)" | |
| } | |
| run: | | |
| $bin = "target\debug\claude-tools.exe" | |
| if (Test-Path $bin) { | |
| & $bin --version | |
| Write-Host "claude-tools binary OK" | |
| } else { | |
| Write-Error "claude-tools binary not found at $bin" | |
| exit 1 | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci.yml around lines 126 - 133, The Windows smoke test
script currently prints a message and exits successfully when the
claude-tools.exe binary is not found, which allows the test to pass even if the
build fails to generate the binary. Change the else block in the PowerShell
script to exit with a failure code instead of just printing a message. When
Test-Path returns false for the $bin variable, use exit 1 or throw to cause the
workflow step to fail, ensuring that missing binaries are properly detected as
build failures rather than allowed to silently pass.
| else | ||
| step "Skipping Rust build (--no-binary)" | ||
| info "claude-tools binary will not be installed" | ||
| STEP_TOTAL=$((STEP_TOTAL - 1)) | ||
| fi |
There was a problem hiding this comment.
단계 카운터 오버플로우 버그: STEP_TOTAL 감소가 너무 늦게 발생합니다.
SKIP_BINARY=1일 때 step() 호출 이후에 STEP_TOTAL이 감소합니다. 이로 인해:
- 라인 282:
step()호출 →[4/7]표시 - 라인 284:
STEP_TOTAL=6으로 감소 - 이후 단계들:
[5/6],[6/6],[7/6]← 마지막 단계에서 7/6 오버플로우
🐛 수정: 스크립트 초반에 STEP_TOTAL 조정
라인 199의 SKIP_BINARY 체크 이전, 또는 인자 파싱 직후에 조정하세요:
# ── Step 2: Check prerequisites ──────────────────────────────────────────────
step "Checking prerequisites"
+# Adjust step count early if binary build will be skipped
+if [ "$SKIP_BINARY" = "1" ]; then
+ STEP_TOTAL=$((STEP_TOTAL - 1))
+fi
+
-MISSING=0그리고 라인 284의 중복 감소를 제거하세요:
else
step "Skipping Rust build (--no-binary)"
info "claude-tools binary will not be installed"
- STEP_TOTAL=$((STEP_TOTAL - 1))
fi단, rustc/cargo 미설치로 인한 자동 SKIP_BINARY=1 설정(라인 205, 211) 케이스도 고려해야 합니다. prerequisites 체크 이후에 한 번만 조정하는 것이 안전합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@install.sh` around lines 281 - 285, The STEP_TOTAL counter is being
decremented after the step() function call when SKIP_BINARY is true, causing the
progress counter to display an incorrect total in subsequent steps. Move the
STEP_TOTAL decrement to occur earlier in the script, specifically after all
prerequisite checks (where rustc and cargo availability are verified and
SKIP_BINARY may be automatically set), rather than inside the conditional block
after the step() call. This ensures the correct total is established before any
progress messages are displayed. Remove the duplicate STEP_TOTAL decrement from
the current location in the else block to avoid reducing the counter twice.
| BINARY_SHA=$("$BINARY" version 2>/dev/null | grep -o 'sha:[a-f0-9]*' | cut -d: -f2 || echo "null") | ||
|
|
||
| if [[ "$BINARY_SHA" == "null" || -z "$BINARY_SHA" ]]; then | ||
| echo " ⚠ Provenance check skipped (binary has no SHA output)" >&2 | ||
| else |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n scripts/dogfood-build.sh | sed -n '40,70p'Repository: BcKmini/claude-code-use
Length of output: 1267
🏁 Script executed:
cat -n scripts/dogfood-build.sh | sed -n '1,40p'Repository: BcKmini/claude-code-use
Length of output: 1622
프로비넌스 검증이 실패 대신 우회될 수 있습니다.
$BINARY version 실행 실패, SHA 파싱 실패, 또는 파이프라인 오류가 모두 "null"로 처리되어 경고만 출력하고 성공 종료합니다. 이 경우 SHA 주입 회귀나 바이너리 손상이 CI 게이트를 통과할 수 있습니다. 버전 조회 실패와 SHA 미검출은 즉시 실패로 처리해야 합니다.
수정 제안
-BINARY_SHA=$("$BINARY" version 2>/dev/null | grep -o 'sha:[a-f0-9]*' | cut -d: -f2 || echo "null")
-
-if [[ "$BINARY_SHA" == "null" || -z "$BINARY_SHA" ]]; then
- echo " ⚠ Provenance check skipped (binary has no SHA output)" >&2
-else
- if [[ "$BINARY_SHA" != "$EXPECTED_SHA" ]]; then
- echo " Provenance mismatch: binary=${BINARY_SHA}, HEAD=${EXPECTED_SHA}" >&2
- exit 1
- fi
- echo " Binary verified: ${BINARY_SHA} == HEAD" >&2
-fi
+VERSION_OUT="$("$BINARY" version 2>/dev/null)" || {
+ echo " Provenance check failed: unable to read binary version output" >&2
+ exit 1
+}
+BINARY_SHA="$(printf '%s\n' "$VERSION_OUT" | grep -o 'sha:[a-f0-9][a-f0-9]*' | cut -d: -f2 | head -n1)"
+[[ -n "$BINARY_SHA" ]] || {
+ echo " Provenance check failed: SHA not found in version output" >&2
+ exit 1
+}
+if [[ "$BINARY_SHA" != "$EXPECTED_SHA" ]]; then
+ echo " Provenance mismatch: binary=${BINARY_SHA}, HEAD=${EXPECTED_SHA}" >&2
+ exit 1
+fi
+echo " Binary verified: ${BINARY_SHA} == HEAD" >&2🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/dogfood-build.sh` around lines 51 - 55, The BINARY_SHA variable
assignment treats all failures (command execution errors, SHA parsing failures)
identically by falling back to "null", and then the subsequent conditional only
logs a warning instead of failing the build. This allows potential security
issues to bypass the CI gate. Modify the script to detect when the $BINARY
version command fails or produces no SHA output, and in those cases exit with a
non-zero status code to fail the build immediately, rather than continuing with
just a warning message. The provenance check should be a blocking requirement,
not optional.
| ruff format "$REPO_ROOT/tools/" 2>/dev/null && ok "Python: ruff format applied" | ||
| fi |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n scripts/fmt.shRepository: BcKmini/claude-code-use
Length of output: 2053
🏁 Script executed:
# 파일 크기 확인
wc -l scripts/fmt.shRepository: BcKmini/claude-code-use
Length of output: 85
비 check 모드에서 Python 포맷 실패가 누락됩니다.
ruff format이 실패해도 &&로만 연결되어 있어서 FAILURES가 증가하지 않아, 최종 종료 코드가 성공(0)으로 반환될 수 있습니다. CHECK 모드(40-46줄)처럼 명시적으로 실패를 집계해 주세요.
수정 제안
else
- ruff format "$REPO_ROOT/tools/" 2>/dev/null && ok "Python: ruff format applied"
+ if ruff format "$REPO_ROOT/tools/" 2>/dev/null; then
+ ok "Python: ruff format applied"
+ else
+ fail "Python: ruff format failed"
+ FAILURES=$((FAILURES+1))
+ fi
fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ruff format "$REPO_ROOT/tools/" 2>/dev/null && ok "Python: ruff format applied" | |
| fi | |
| else | |
| if ruff format "$REPO_ROOT/tools/" 2>/dev/null; then | |
| ok "Python: ruff format applied" | |
| else | |
| fail "Python: ruff format failed" | |
| FAILURES=$((FAILURES+1)) | |
| fi | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/fmt.sh` around lines 48 - 49, The ruff format command in the
non-check mode section (around line 48) only prints success messages but does
not track failures when ruff format fails. Unlike the CHECK mode section above
it (lines 40-46), there is no explicit failure counting. Modify the ruff format
command to check the exit status and increment the FAILURES counter when the
command fails, similar to how failure tracking is implemented in the CHECK mode
section. This ensures that a failed format operation is properly recorded and
reflected in the final exit code.
| #!/usr/bin/env bash | ||
| # validate-agents.sh — Verify agent MD files are well-formed. | ||
| # | ||
| # Checks: | ||
| # 1. Every NN-name.md file is non-empty | ||
| # 2. Required sections exist (## Role, ## Instructions or ## Core Rules) | ||
| # 3. No duplicate agent numbers | ||
| # 4. Agent names match the expected numbering sequence | ||
| # | ||
| # Usage: | ||
| # bash scripts/validate-agents.sh | ||
| # bash scripts/validate-agents.sh --strict # exit 1 on warnings too | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| AGENTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/agents" | ||
| STRICT=0 | ||
|
|
||
| [ "$*" = "--strict" ] && STRICT=1 | ||
|
|
||
| ok() { printf '\033[32m ✓\033[0m %s\n' "$*"; } | ||
| warn() { printf '\033[33m ⚠\033[0m %s\n' "$*"; [ "$STRICT" -eq 0 ] || exit 1; } | ||
| fail() { printf '\033[31m ✗\033[0m %s\n' "$*"; FAILURES=$((FAILURES+1)); } | ||
|
|
||
| FAILURES=0 | ||
|
|
||
| if [ ! -d "$AGENTS_DIR" ]; then | ||
| fail "agents/ directory not found at $AGENTS_DIR" | ||
| exit 1 | ||
| fi | ||
|
|
||
| declare -A SEEN_NUMS | ||
|
|
||
| for f in "$AGENTS_DIR"/[0-9][0-9]-*.md; do | ||
| [ -f "$f" ] || { warn "No agent files found in $AGENTS_DIR"; break; } | ||
|
|
||
| base="$(basename "$f")" | ||
| num="${base:0:2}" | ||
|
|
||
| # Duplicate number check | ||
| if [ "${SEEN_NUMS[$num]+x}" ]; then | ||
| fail "Duplicate agent number: $num (${SEEN_NUMS[$num]} and $base)" | ||
| fi | ||
| SEEN_NUMS[$num]="$base" | ||
|
|
||
| # Non-empty | ||
| if [ ! -s "$f" ]; then | ||
| fail "Empty agent file: $base" | ||
| continue | ||
| fi | ||
|
|
||
| # Required sections | ||
| if ! grep -q '^## ' "$f"; then | ||
| fail "$base: No H2 sections found" | ||
| continue | ||
| fi | ||
|
|
||
| # Role or name header | ||
| if ! grep -qiE '^## (Role|Name|Identity|에이전트)' "$f"; then | ||
| warn "$base: No '## Role' or '## Name' section found" | ||
| fi | ||
|
|
||
| # Instructions section | ||
| if ! grep -qiE '^## (Instructions|Core Rules|Rules|규칙|지침)' "$f"; then | ||
| warn "$base: No '## Instructions' / '## Core Rules' section found" | ||
| fi | ||
|
|
||
| ok "$base" | ||
| done | ||
|
|
||
| echo "" | ||
| if [ "$FAILURES" -gt 0 ]; then | ||
| printf '\033[31m %d validation failure(s)\033[0m\n\n' "$FAILURES" | ||
| exit 1 | ||
| else | ||
| printf '\033[32m All agents valid\033[0m\n\n' | ||
| fi |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check agent files for validation issues
echo "=== Agent files in agents/ directory ==="
fd -e md . agents/ -x echo "File: {}"
echo -e "\n=== Checking for Role/Name sections ==="
fd -e md . agents/ -x bash -c 'echo "File: {}"; grep -iE "^## (Role|Name|Identity|에이전트)" "{}" || echo " ⚠ Missing Role/Name section"'
echo -e "\n=== Checking for Instructions sections ==="
fd -e md . agents/ -x bash -c 'echo "File: {}"; grep -iE "^## (Instructions|Core Rules|Rules|규칙|지침)" "{}" || echo " ⚠ Missing Instructions section"'
echo -e "\n=== Checking for H2 sections ==="
fd -e md . agents/ -x bash -c 'echo "File: {}"; grep "^## " "{}" | head -n 3 || echo " ✗ No H2 sections"'
echo -e "\n=== Checking for empty files ==="
fd -e md . agents/ -x bash -c '[ -s "{}" ] || echo " ✗ Empty: {}"'Repository: BcKmini/claude-code-use
Length of output: 3350
agents/ 디렉터리의 모든 에이전트 파일에서 필수 섹션이 누락되었습니다.
실제 검증 결과, 11개의 에이전트 파일 모두에서 다음이 누락되어 있습니다:
- Role/Name 섹션:
## Role,## Name,## Identity,## 에이전트중 하나가 필요 - Instructions 섹션:
## Instructions,## Core Rules,## Rules,## 규칙,## 지침중 하나가 필요
--strict 모드에서 warn() 함수는 즉시 종료 코드 1로 끝나므로, 각 파일의 첫 번째 경고에서 스크립트가 중단됩니다. 스크립트 로직은 정상이며, 각 에이전트 파일에 위 두 섹션을 추가해야 합니다.
🧰 Tools
🪛 GitHub Actions: CI / 4_Validate agent files.txt
[error] 1-1: Command failed. 'bash scripts/validate-agents.sh --strict' exited with code 1.
🪛 GitHub Actions: CI / Validate agent files
[error] 1-1: Command failed. 'bash scripts/validate-agents.sh --strict' exited with code 1.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-agents.sh` around lines 1 - 77, Each agent markdown file in
the agents/ directory is missing one or both of the required sections that the
validation script checks for. For each file matching the [0-9][0-9]-*.md
pattern, ensure at least one Role/Name section header exists (## Role, ## Name,
## Identity, or ## 에이전트) and at least one Instructions section header exists (##
Instructions, ## Core Rules, ## Rules, ## 규칙, or ## 지침). Add these missing
section headers to all 11 agent files so the validation checks in the grep
statements checking for '^## (Role|Name|Identity|에이전트)' and '^##
(Instructions|Core Rules|Rules|규칙|지침)' patterns will pass.
| # Checks: | ||
| # 1. Every NN-name.md file is non-empty | ||
| # 2. Required sections exist (## Role, ## Instructions or ## Core Rules) | ||
| # 3. No duplicate agent numbers | ||
| # 4. Agent names match the expected numbering sequence |
There was a problem hiding this comment.
주석이 구현되지 않은 검증을 언급합니다.
8번 줄의 주석은 "Agent names match the expected numbering sequence"를 검사한다고 명시하지만, 실제 코드에는 번호 순서를 검증하는 로직이 없습니다. 중복 번호만 검사합니다.
제안하는 수정
# Checks:
# 1. Every NN-name.md file is non-empty
# 2. Required sections exist (## Role, ## Instructions or ## Core Rules)
# 3. No duplicate agent numbers
-# 4. Agent names match the expected numbering sequence🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-agents.sh` around lines 4 - 8, The comment on line 8
indicates that the script should validate that agent numbers match an expected
numbering sequence (check `#4`), but the current implementation only validates for
duplicate agent numbers and does not include logic to verify the sequence. Add
validation logic to check that the agent files follow a continuous numbering
sequence (for example 01, 02, 03, etc. without gaps). Extract all agent numbers
from the NN-name.md filenames, sort them, and verify they form a consecutive
sequence starting from the expected beginning number. Report an error message if
any gaps or unexpected numbers are found in the sequence.
| [ "$*" = "--strict" ] && STRICT=1 | ||
|
|
||
| ok() { printf '\033[32m ✓\033[0m %s\n' "$*"; } | ||
| warn() { printf '\033[33m ⚠\033[0m %s\n' "$*"; [ "$STRICT" -eq 0 ] || exit 1; } |
There was a problem hiding this comment.
strict 모드에서 warn() 함수가 첫 경고 발생 시 즉시 종료합니다.
warn() 함수는 strict 모드에서 exit 1을 즉시 호출하므로, 첫 번째 경고가 발생하면 스크립트가 종료되어 이후의 경고나 실패를 수집하지 못합니다. 이는 fail() 함수가 실패 카운터를 누적하는 방식과 일관성이 없으며, 사용자가 모든 검증 문제를 한 번에 확인할 수 없게 만듭니다.
제안하는 수정 사항
-warn() { printf '\033[33m ⚠\033[0m %s\n' "$*"; [ "$STRICT" -eq 0 ] || exit 1; }
-fail() { printf '\033[31m ✗\033[0m %s\n' "$*"; FAILURES=$((FAILURES+1)); }
+warn() { printf '\033[33m ⚠\033[0m %s\n' "$*"; [ "$STRICT" -eq 0 ] || FAILURES=$((FAILURES+1)); }
+fail() { printf '\033[31m ✗\033[0m %s\n' "$*"; FAILURES=$((FAILURES+1)); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/validate-agents.sh` at line 22, The warn() function in strict mode
exits immediately on the first warning due to the `[ "$STRICT" -eq 0 ] || exit
1` condition, preventing the script from collecting all validation issues before
terminating. Instead of exiting immediately, implement a warning counter
mechanism similar to how the fail() function handles failures (accumulating a
count), and increment this counter each time warn() is called in strict mode.
Then at the end of the script, check the accumulated warning counter and exit
with an appropriate status code if warnings were found, allowing users to see
all validation problems at once rather than stopping on the first one.
- cost.rs: run cargo fmt (method chains, else blocks, #[arg] attrs, long lines) - env.rs: remove unnecessary .into_owned() (clippy::unnecessary_to_owned) - snippet.rs: sort_by -> sort_by_key with Reverse (clippy::unnecessary_sort_by) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Replaces binary-download install with a local source build, adds a full CI quality gate, and introduces a
scripts/utility folder.install.shrewritten: 7-step colored progress UI, builds binary fromrust/viacargo build --workspace, auto-clone when run via curl,--updateflag, prerequisite checks, built-in troubleshooting guidescripts/dogfood-build.sh: build with GIT_SHA provenance verification — fails loudly with full output if SHA mismatchesscripts/validate-agents.sh: lint all agent MD files (non-empty, required sections, no duplicate IDs)scripts/fmt.sh: unifiedcargo fmt+ruff formatrunner with--checkmode for CI.github/workflows/ci.yml: PR gate — validate-agents → fmt → clippy → test → Windows smoke → dogfood build (Swatinem/rust-cache+cancel-in-progress)Containerfile: Docker/Podman image for reproducible builds (rust:bookwormbase)Makefile:dogfood,container,validate,fmt-checktargetsCloses #21
Test plan
bash install.sh --no-binarycompletes without error on macOS/Linuxbash scripts/validate-agents.shpasses for all existing agentsbash scripts/fmt.sh --checkexits 0 (skips gracefully when no Rust workspace yet)feat/**and all jobs passmake dogfoodworks once arust/workspace is presentSummary by CodeRabbit
릴리스 노트
새로운 기능
install.sh에--release/--debug,--update,--no-binary,--no-verify등 설치/검증 옵션이 추가되었습니다.Chores
fmt-check,validate,container등)이 추가되었습니다.