Skip to content

ci(B-0106): add lint-tsc-tools gate job — tsc --noEmit on tsconfig.json#890

Merged
AceHack merged 1 commit intomainfrom
ci/B-0106-lint-tsc-tools-job-2026-04-30
Apr 30, 2026
Merged

ci(B-0106): add lint-tsc-tools gate job — tsc --noEmit on tsconfig.json#890
AceHack merged 1 commit intomainfrom
ci/B-0106-lint-tsc-tools-job-2026-04-30

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 30, 2026

Summary

Implements B-0106 — adds a lint (tsc tools) job to gate.yml that runs bun --bun tsc --noEmit -p tsconfig.json.

Why

ESLint with typed-linting catches most TypeScript issues but not all assignability narrowings. Slice 9 (#882) shipped a real TS2322 error to main because gate.yml runs dotnet build for F#/C# but had no tsc step for tools/**/*.ts. The bug was found post-merge during slice-12 verification (#887 fixed the local instance; this PR closes the structural gap).

Same shape as the round-30 semgrep elevation: codified rules (tsconfig strict mode) without a gate aren't a control.

Implementation

Modeled after lint-shell + lint-markdown:

  1. Cache install.sh outputs (mise + bun + dotnet tools).
  2. install.sh with 5-attempt retry/backoff (bun-1.3.13 transient 502 mitigation).
  3. bun install --frozen-lockfile → materializes node_modules/typescript@6.0.3.
  4. bun --bun tsc --noEmit -p tsconfig.json — strict typecheck.

Pinned to ubuntu-24.04, 5-min timeout. ~70 lines of YAML.

Test plan

Composes with

🤖 Generated with Claude Code

Closes the CI gap surfaced during slice-9 #882 post-merge audit.
ESLint with typed-linting catches most TS issues but not all
assignability narrowings; PR #887 documented the specific bug class
(TS2322 in audit-agencysignature-main-tip.ts:124 shipped to main
because gate.yml had `dotnet build` for F#/C# but no tsc step for
tools/**/*.ts).

Implementation modeled after lint-shell + lint-markdown:
1. Cache install.sh outputs (mise + bun + dotnet tools).
2. install.sh with 5-attempt retry/backoff for transient CDN 502s.
3. `bun install --frozen-lockfile` to materialize node_modules with
   typescript@6.0.3 + eslint stack from package.json.
4. `bun --bun tsc --noEmit -p tsconfig.json` — strict typecheck.

Pinned to ubuntu-24.04 (OS-independent typecheck), 5-min timeout
(matches lint-markdown's runtime budget).

Same shape as round-30 semgrep elevation: codified rules
(tsconfig strict mode) without a gate aren't a control.

Updates B-0106 status from open → in-progress.
Copilot AI review requested due to automatic review settings April 30, 2026 05:09
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@AceHack AceHack enabled auto-merge (squash) April 30, 2026 05:09
@AceHack AceHack merged commit 9ca9ed9 into main Apr 30, 2026
27 checks passed
@AceHack AceHack deleted the ci/B-0106-lint-tsc-tools-job-2026-04-30 branch April 30, 2026 05:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new CI gate to ensure TypeScript tooling in the repo is strictly typechecked during gate.yml, closing the gap that allowed a TS compile error to merge previously (B-0106).

Changes:

  • Mark backlog item B-0106 as in-progress.
  • Add a new lint (tsc tools) job to .github/workflows/gate.yml that installs toolchain + npm deps and runs tsc --noEmit against tsconfig.json.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
docs/backlog/P2/B-0106-tsc-noemit-gate-job-for-ts-tools-2026-04-30.md Updates backlog status to reflect active work on the CI gate.
.github/workflows/gate.yml Introduces a new job to run strict TS typechecking in CI.

# mismatches, etc.) that eslint typed-linting may miss. Per
# the .tsconfig.json strictness profile (verbatimModuleSyntax,
# noUncheckedIndexedAccess, exactOptionalPropertyTypes).
run: bun --bun tsc --noEmit -p tsconfig.json
AceHack added a commit that referenced this pull request Apr 30, 2026
…row (#891)

- B-0106 status: in-progress → closed; closed_in: PR #890 commit 9ca9ed9.
- Tick row at 2026-04-30T05:11:00Z covers the B-0106 implementation
  merge (PR #890), the full bug-class loop closure (find→fix→file→
  implement), and observations on the semgrep-elevation-shape pattern
  applied to tsc.
AceHack added a commit that referenced this pull request Apr 30, 2026
…tion (#894)

* ts(slice-14, wip 1/N): port budget/snapshot-burn (.sh→.ts)

First script of slice 14. Captures point-in-time LFG cost/burn
snapshot via gh API + appends one JSON line to
`docs/budget-history/snapshots.jsonl`. Composes with project-runway +
daily-cost-report (Aaron's #287 visibility deadline).

Byte-equivalent on argument-validation paths (--note, --help).
Live --dry-run verified against GitHub API: produces snapshot with
all the same fields as bash original.

Mechanical changes:
- bash `gh api ... | jq` pipelines → ghJson helper wrapping spawnSync
- bash `mapfile` workaround (while-read for macOS bash 3.2 compat)
  → straightforward TS for-loop
- bash heredoc `jq -n` snapshot composition → typed Snapshot interface
  + JSON.stringify
- bash JSONL append (`printf '%s\n' >> "$out"`) → appendFileSync
- Per-repo aggregation extracted into aggregateTimings + summarizePulls
  helpers under cognitive-complexity threshold
- Optional fields elided via spread+conditional for
  exactOptionalPropertyTypes compliance

Lint-clean: bun --bun tsc --noEmit + eslint strictTypeChecked +
sonarjs all pass. The new lint (tsc tools) gate from #890 will
validate this in CI.

* trajectory(ts-bun): slice 14 audit substrate + RESUME tracker

- slice-audits.md: append slice-14 audit (1 port — budget/snapshot-burn).
  Also flip slice-13 from PR-pending to merged-with-PR-number.
- RESUME.md: bump slice-12-merged → slice-13-merged (#892, commit e9dc894).
  Milestone 34 → 35 (34 ported + 1 in-flight in slice-14). Bucket B 9 → 8.
  Bucket D ported list grew to 34 entries.
AceHack added a commit that referenced this pull request Apr 30, 2026
…gration (#896)

* ts(slice-15, wip 1/N): port peer-call/grok (.sh→.ts)

First script of slice 15. Otto's harness-side caller for invoking
Grok via cursor-agent as a peer reviewer. Opens the peer-call
cluster — sibling ports (gemini + codex) follow the same shape.

Byte-equivalent on argument-validation paths. LLM-response
equivalence is non-deterministic; only structural/UX equivalence
verified.

Mechanical changes:
- bash arg-parse loop → classifyFlag helper + MutableArgState
  (main parseArgs stays under cognitive-complexity 15)
- bash 'eval "$context_cmd" 2>&1 | head -c 20000' →
  spawnSync('/bin/sh', ['-c', contextCmd]) + slice to CTX_HEAD_BYTES
- bash file-head read → readFileSync + Buffer.subarray
- bash 'cursor-agent --print ...' → spawnSync with stdio:'inherit'
  (preserves live LLM-streaming UX)
- PREAMBLE preserved verbatim (Otto's contribution to the
  four-ferry consensus protocol convention)
- eslint-disable for no-os-command-from-path placed on the literal
  next line per directive-placement pattern from #892 review

Lint-clean: bun --bun tsc --noEmit + eslint strictTypeChecked +
sonarjs all pass. The lint (tsc tools) gate from #890 will validate
this in CI.

* trajectory(ts-bun): slice 15 audit substrate + RESUME tracker

EOF
AceHack added a commit that referenced this pull request Apr 30, 2026
…tion (#902)

Closes the budget cluster: snapshot-burn (slice 14) +
daily-cost-report (slice 18) + project-runway (this slice) are
now all TS. Once this lands, daily-cost-report.ts can switch
from spawning project-runway.sh to project-runway.ts.

Behavioural improvements over bash original (deliberate, not drift):

- File-existence check uses statSync().isFile() + try/catch
  rather than existsSync — bash `-f` rejects directories,
  existsSync accepts them (slice-18 mirror).
- JSONL parsing is native (readFileSync + split + JSON.parse)
  rather than per-line jq spawn-out — projection script reads
  already-persisted JSON, so jq is a heavy dependency for what
  is structurally a typed reduce. snapshot-burn.ts still needs
  gh api for capture; this is projection only.
- requireInt validation matches bash `case '$val' in
  ''|*[!0-9]*) ...` with TS `requireInt(flag, val)` returning
  `number | ArgError` — same exit code 2, same error wording
  (Codex P2 NM59qF00 + NM59qH2H, Copilot P1 NM59qGJ- on the
  bash original).

Byte-equivalence verified on this repo state:
  diff <(bun tools/budget/project-runway.ts) \
       <(./tools/budget/project-runway.sh)        # empty
  diff <(bun tools/budget/project-runway.ts --json) \
       <(./tools/budget/project-runway.sh --json) # empty

Error paths verified equivalent: --stages abc → exit 2 with
matching message; --file <missing> → exit 1; --bogus → exit 2.

Tools used: tsc --noEmit clean; eslint clean per the existing
tsc-tools CI gate (#890).

Composes with:
  - tools/budget/snapshot-burn.ts (slice 14, #894)
  - tools/budget/daily-cost-report.ts (slice 18, #901)
  - docs/trajectories/typescript-bun-migration/RESUME.md
  - docs/trajectories/typescript-bun-migration/slice-audits.md

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants