Skip to content

lint: enumerate every tracked shell file for bash -n and shellcheck; clear the first-run backlog (dev#53) - #35

Open
shojikumaru wants to merge 1 commit into
mainfrom
fix/53-shellcheck-coverage
Open

shojikumaru wants to merge 1 commit into
mainfrom
fix/53-shellcheck-coverage

Conversation

@shojikumaru

@shojikumaru shojikumaru commented Sep 13, 2026

Copy link
Copy Markdown
Member

Closes caty-ai/alpha-nightshift-dev#53 (lint: shellcheck covered 15 of 68 shell files; all of lib/ unchecked).

What changed

  • Makefile lint: one NUL-delimited manifest = git ls-files -z '*.sh' + LINT_BASH_EXECUTABLES (the five extensionless Bash entry points in bin/, audited by first-line shebang over every tracked file). The same manifest feeds bash -n (one file per invocation) and shellcheck -e SC2015. No path exclusions, no -x, no new -e codes. Runner-parity recipe byte-identical to before.
  • .github/workflows/ci.yml: the "Bash syntax" and "ShellCheck changed publisher surface" hand lists are replaced by command -v make && make lint. Job id guard unchanged (branch protection). The standalone runner-parity step is kept.
  • First-run backlog (131 findings, ShellCheck 0.11.0) cleared without runtime changes: 27× SC1007 CDPATH= cdCDPATH='' cd; 27× SC1091 via static # shellcheck source= annotations; 29 # shellcheck disable= each with # reason: on the same line (SC2016 ×12 fixture text, SC2034 ×7, SC2094 ×2, SC2031 ×1 file-level, SC2329 ×3, SC2086 ×3 intentional word splitting of fixed fixture strings / jq integer counts, SC2006 ×1 adversarial fixture); SC2295 / SC2269 / SC2209 / SC1003 fixed.
  • docs/engineering.md / docs/engineering.ja.md: CI description updated (EN/JA in sync).

Coverage: 15 hand-listed files → 91 tracked *.sh + 5 entry points = 96 files in both lanes.

完了記録 (L1-7)

候補 commit SHA: b95e1af (PR head; base origin/main = b5deeb4).

Done when (dev#53 proposed work) result evidence (2026-09-13, dev MBP, HEAD b95e1af)
1. Enumerate instead of list (Makefile + ci.yml use git ls-files '*.sh') PASS git ls-files '*.sh' | wc -l → 91; manifest traced with xargs -0 -t = 96 paths (91 + 5 bins), single shellcheck invocation; ci.yml now make lint (Kimi F1 / GLM F1 / Opus F1, all PASS with the same count)
2. First-run backlog fixed or disabled with reason PASS make lint → exit 0 (alpha re-run after commit; tail = runner-parity block, no findings). All 29 disables enumerated and reasons verified by all three seats (Opus removed the SC2031 file-level disable and re-ran: 9 live hits, so the disable is needed)
3. bash -n covers the same file set PASS same manifest → xargs -0 -n 1 bash -n; Opus injected a dangling if into bin/budget-probe-stubmake lint exit 2
4. Guard against re-drift (every tracked *.sh linted or declared exempt) PASS for *.sh by construction (no list exists to drift; exemptions live only as in-file disable lines with reasons). Residual: the 5-entry LINT_BASH_EXECUTABLES list for extensionless scripts is hand-maintained — Opus N1 + Kimi N2 converge on this; tracked as a follow-up issue (see below), not blocking
Mutation proof (red → green) PASS Codex r2: append echo $unquoted to lib/ledger.sh → exit 2 (SC2086 at ledger.sh:371/372); restore (sha256 1303e334… identical) → exit 0. Reproduced independently by GLM and Kimi in cp -R scratch copies and by Opus (exit 2 with In lib/ledger.sh line 371)
Full suite PASS make test on b95e1af: Tests: 45 passed, 0 failed / suites: declared=45 executed=45 skipped=0 / exit 0 (/tmp/make-test-53.log, 2026-09-13 12:37 +07)
Fixtures exemption declared, not hidden PASS tests/fixtures/** stay in the manifest; the one intentionally odd fixture (tests/fixtures/triage/repo/base/app/render.sh) carries # shellcheck disable=SC2006 # reason: adversarial fixture deliberately retains legacy backtick source text

触ったファイル一覧 vs git diff --stat origin/main...b95e1af (34 files, +105 −149; declared set in dev#53 WIP r2 = Makefile, ci.yml, lib/, lanes/, guard/, bin/, tests/, docs/engineering{,.ja}.md — every diff path is inside it):
.github/workflows/ci.yml, Makefile, bin/nightshift-dispatch, bin/verdict-sync, docs/engineering.md, docs/engineering.ja.md, guard/preflight.sh, guard/render-sandbox.sh, guard/scan.sh, guard/text-policy.sh, lanes/metsuke/check-readiness.sh, lanes/metsuke/run.sh, lib/budget.sh, lib/common.sh, lib/evidence.sh, lib/lane-env.sh, tests/fixtures/triage/repo/base/app/render.sh, and 17 tests/test_*.sh.

身元: implementer = Codex (gpt-6-astra, two rounds via sitter-run; reports /tmp/codex-53-report{,-r2}.md), committed by alpha. Reviewers (blind, read-only, fresh context; full reviews in ~/.buzz/.scratch/seats-53/{glm,kimi,opus}.md on the dev MBP):

seat model verdict blocking non-blocking (headline)
GLM glm-5.3 GO-WITH-NITS 0 untracked new *.sh not linted until git add (matches the issue's "tracked" wording); parity runs twice in CI; source= rewrite inert without -x
Kimi kimi-code/k3 (effort high) GO-WITH-NITS 0 N1 single shellcheck batch is load-bearing (splitting would resurface SC1091, fail-closed direction); N2 extensionless list can drift; N3 empty-list NUL edge; N4 file-level SC2016 breadth
Opus claude-opus-5 (effort high) GO-WITH-NITS 0 N1 (MEDIUM) extensionless list hand-maintained; N2 (MEDIUM) single-batch source-following is load-bearing — make it explicit; N3 @ hides the file count in CI log

Model/agent of implementer (Codex) differs from every reviewer (L1-3 / L1-10). Alpha (Fable) did not vote.

CI (head b95e1af, 2026-09-13): guard pass (23m08s, run 34741078302) · test-lint / test-macos pass (12m47s, run 34741078503) · gitleaks / history-check / repo-state / watch pass. Red by design until the owner labels: pr-size (needs size-exempt, 34 files) and risk-review-gate (needs risk-reviewed, guard/ is a risk path).

release: v0.7.1(lint ゲートの範囲変更=規範変更なので出荷相当扱い・merge 後に annotated tag + GitHub Release を alpha が実施・T-5)
previous release: v0.7.0(PR #33・tag + GitHub Release 2026-09-07 履行済み)

Follow-up (not blocking)

Derive LINT_BASH_EXECUTABLES from a shebang scan (or assert the hand list against one) and document that the single-batch shellcheck invocation is load-bearing — Opus N1/N2 + Kimi N1/N2. Filed as caty-ai/alpha-nightshift-dev follow-up issue (linked from dev#53).

🤖 Generated with Claude Code

…clear the first-run backlog (dev#53)

Makefile `lint` now materialises `git ls-files -z '*.sh'` plus the five
extensionless Bash entry points in bin/ into one NUL-delimited manifest and
feeds the same manifest to `bash -n` (one file per invocation) and
`shellcheck -e SC2015`. CI calls `make lint` instead of keeping its own hand
list, so the two lanes cannot drift; the job name and the runner-parity
recipe are unchanged. Coverage goes from 15 hand-listed files to 91 tracked
.sh files + 5 entry points, with no path exclusions and no `-x`.

First-run backlog (131 findings, ShellCheck 0.11.0) cleared without runtime
changes: 27 x SC1007 `CDPATH= cd` -> `CDPATH='' cd`; 27 x SC1091 resolved with
static `# shellcheck source=` annotations; SC2016 in test fixture text and
SC2034/SC2094/SC2031/SC2329 disables each carry a `# reason:` on the same line;
three SC2086 disabled with reasons (intentional word splitting of fixed fixture strings and jq integer counts); SC2295/SC2269/SC2209 fixed. Mutation proof: `echo
$unquoted` appended to lib/ledger.sh -> `make lint` exit 2; restored -> exit 0.

Written by Codex (astra) in two rounds; committed by alpha.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added the needs-risk-review 高リスク領域に触れた PR (機械が自動付与) label Sep 13, 2026
@shojikumaru shojikumaru added the ball:human Waiting on a human decision (owner). Alpha removes it after the decision comment. label Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ball:human Waiting on a human decision (owner). Alpha removes it after the decision comment. needs-risk-review 高リスク領域に触れた PR (機械が自動付与)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant