Skip to content

fix(install): brownfield CI-orphan WARN names every missing gate + check:lintstaged CI-wiring — #521 - #522

Merged
artyhoo merged 4 commits into
stagingfrom
claude/festive-margulis-163cc2
Jun 14, 2026
Merged

fix(install): brownfield CI-orphan WARN names every missing gate + check:lintstaged CI-wiring — #521#522
artyhoo merged 4 commits into
stagingfrom
claude/festive-margulis-163cc2

Conversation

@artyhoo

@artyhoo artyhoo commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Fixes the two defects reported in #521 plus the validate≠CI drift found during design.

Problem (#521)

On a brownfield repo (pre-existing .github/workflows/ci.yml), install.sh keeps the consumer's CI verbatim (copy_safe skips existing files), so the framework's enforcement gates run in no CI job — the only non-bypassable channel. Two defects:

  1. WARN under-reported — the §6c CI-orphan WARN grepped only check:globs, silently omitting arch:check (R3) and audit:docs. A dev who wired only the named gate still shipped R3 un-enforced.
  2. --force too coarse — the only "automatic" remedy overwrote all kept files, not just the workflow.

Also found during design: check:lintstaged was missing from the shipped greenfield CI templates too — validate ran 4 gates, the shipped ci.yml wired 3.

Change

  • Change 1 — check:lintstaged → both shipped CI templates (templates/ts-server/github-actions-ci.yml, packages/preset-next-15-canonical/templates/github-actions-ci-ui.yml). Greenfield CI now runs the full validate set. CI-safe (the gate skips without node_modules, runs after npm ci).
  • Change 2 — rewrite install.sh §6c WARN into a per-gate loop: for each of the 4 gates whose enforcing artifact is installed, if no kept workflow references it, name it (with what it enforces) and print a ready-to-paste - run: step. --force is reworded honestly about overwriting all kept files. Non-destructive, rc=0, no YAML parser, no new dependency, no auto-edit of the consumer's workflow (a silent auto-wire could land a step in the wrong job on a monorepo → false-green CI, the worst failure for a "no check → no rule" framework).

Establishes the invariant {WARN-named} = {greenfield CI} = {validate} = 4 gates, zero drift.

Out of scope (deferred, by design)

  • --wire-ci flag (issue's "optionally") — YAGNI; it still requires editing the consumer's YAML, just behind a flag. Recorded with a revisit trigger in the spec.

Tests / verification

  • tests/install-sh/r2-glob-reach.test.sh extended: #1 rewritten with POS-all (none wired → names all 4 + paste-block), POS-partial (only globs wired → names the other 3, NOT check:globs — proves per-gate accuracy), NEG (greenfield → all 4 wired → no warn); #4 added (both templates wire check:lintstaged).
  • Full tests/install-sh/* suite green locally (28/28).
  • Greenfield-green empirically confirmed: a fresh ts-server install with deps → check-lintstaged-resolves.sh = OK, rc=0, all 6 lint-staged commands resolve (the one read-unverifiable claim, discharged by a real run, not fabricated).

Two-stage subagent review (spec + code-quality) per task, plus a holistic final review confirming both #521 defects close and the invariant holds.

Process notes

  • Design spec + implementation plan committed under docs/superpowers/ (brainstorming → writing-plans → subagent-driven execution).
  • Branch pushed via the GitHub Git Data API (local SSH transport unavailable), rebased onto the current staging tip — a 3-way merge preserved staging's #516 test additions to the same test file (no clobber; diff is exactly the 6 intended files).

Closes #521.

artyhoo added 4 commits June 14, 2026 19:08
#521 design

Approved brainstorming design for GH #521: broaden install.sh §6c CI-orphan WARN
to detect+name every enforcement gate absent from a kept brownfield workflow
(check:globs/arch:check/audit:docs/check:lintstaged) + print a paste-block; wire
check:lintstaged into both shipped CI templates so greenfield CI == validate ==
WARN-named set. No YAML auto-merge (rejected: false-green risk + BFR). Test plan
extends r2-glob-reach.test.sh with a per-gate-accuracy POS-partial case.

Prior-art: skipped — doc-only design spec, no new capability (brainstorming artefact for #521).
…521

3-task TDD plan: (1) wire check:lintstaged into both shipped CI templates;
(2) rewrite install.sh §6c WARN as a per-gate loop + paste-block (POS-partial
test proves per-gate accuracy); (3) full-suite verify + greenfield-green
acceptance with a no-fabrication guard. Full bash/YAML in every step, no placeholders.

Prior-art: skipped — doc-only implementation plan, no new capability (#521 brainstorming→plan).
…Change 1

Greenfield ci.yml ran 3 of validate's 4 gates; check:lintstaged lived only in the
validate script. Add it to both shipped CI lint jobs so greenfield CI == validate.
CI-safe: the gate skips without node_modules, runs after npm ci.

Prior-art: skipped — wiring an existing gate into shipped CI templates, no new capability.
…ste-block — #521

§6c warned only about check:globs; arch:check (R3), audit:docs, check:lintstaged were
silently unwarned. Rewrite as a per-gate loop: for each gate whose artifact is installed
and that no kept workflow references, name it (with what it enforces) and print a paste
step. Non-destructive, rc=0, no YAML parser. POS-partial test proves per-gate accuracy.

Prior-art: skipped — WARN-completeness fix on an existing block, no new capability.
@artyhoo
artyhoo force-pushed the claude/festive-margulis-163cc2 branch from db98ac0 to 42033ce Compare June 14, 2026 16:09
@artyhoo artyhoo changed the title docs(spec): brownfield CI WARN completeness + check:lintstaged wiring — #521 design (SPEC-ONLY) fix(install): brownfield CI-orphan WARN names every missing gate + check:lintstaged CI-wiring — #521 Jun 14, 2026
@artyhoo
artyhoo merged commit 48f75a4 into staging Jun 14, 2026
22 checks passed
artyhoo added a commit that referenced this pull request Jun 14, 2026
#521 Stage P (#526)

universalization-fix-s3 Stage P implements the REFERENCE half of the HYBRID
verdict (SSOT #117): an opt-in --wire-ci flag (or interactive [y/N], default No)
that, when yq is present, idempotently appends the missing rule-enforcement gates
(check:globs / arch:check / audit:docs / check:lintstaged) into the consumer's
kept .github/workflows/*.yml job, re-detects, and suppresses the WARN on success
(merge-then-no-warn). The BUILD half (broadened WARN + paste-block) shipped via
#522/#525; the default path stays non-destructive (writes nothing). yq is
used-if-present, never installed/pinned by us (companion-install-principle.md §1;
BFR §1.1 shipped-axis — integrate, never hard-depend); absent/declined → falls
through to the unchanged WARN + paste-block.

- install.sh §6c: --wire-ci flag + detect-first yq auto-wire; job/workflow
  detection via yq; idempotent unique_by(.run) append; bash-3.2-safe array
  expansion under set -u. Preserves the #525 check:globs shadowed-package Note.
- tests/install-sh/s3-wire-ci.test.sh (wired into audit-self.yml): paired-negative
  — NEG (load-bearing): default install leaves the workflow byte-identical
  (opt-in proven); POS (yq arm — CI-verified, GH runners ship yq, local prints
  SKIP): appends all 4, suppresses WARN, idempotent re-run, valid job path;
  comment-preservation is an OBSERVATION (yq best-effort), not a flaky gate.
- prior-art-evaluations.md: SSOT #117 (HYBRID); 11-build-first-reuse-default
  VERDICTS extended with HYBRID per its line-47 "extend VERDICTS" instruction.

Prior-art: prior-art-evaluations.md#117 (HYBRID — REFERENCE mikefarah/yq opt-in --wire-ci auto-wirer + BUILD the zero-dep broadened WARN/paste-block; no new package.json dependency, yq detect-first/never-installed; Stage P of universalization-fix-s3, GH #521).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant