Plan 011: Integrate ts-qa-ci QA/CI pipeline - #3
Merged
Conversation
Mirrors lts/php-qa-ci for TypeScript projects: orchestrated QA pipeline, component-driven-development ESLint rule tier, Claude Code integration tooling, dogfooded on lts-commerce-site before external rollout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds untracked/ec-site as a parallel TS-native research target alongside php-qa-ci (it already implements most of this plan's CDD/orchestrator ambitions), corrects the CI baseline premise (build+deploy only today, no lint/format/test gate), scopes the CDD "no ad hoc HTML" rule to JSX only with articles.ts explicitly exempt, and brings variant-prop catalogue construction into Phase 4 scope rather than quietly descoping it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Follow-up to 85b1e5d, which flipped README.md's index entry but missed staging the PLAN.md file itself. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Phase 1 research (12-agent workflow + Opus review) finished cleanly: concept-extraction report and review verdict READY FOR PHASE 2, both retained under untracked/ (gitignored). Folds in headline findings and adds a blocking Task 3.0 gate requiring the maintainer's sign-off before any ec-site code is lifted into the publishable package. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ete Phase 2 Supporting docs (concept report, all Opus reviews, Phase 2 design) were written to gitignored untracked/ instead of the plan folder per PlanWorkflow.md's own convention (supporting analysis lives alongside PLAN.md) - moved and re-linked. Phase 2 (tool selection, orchestrator CLI spec, dependency/CDD/deploy/CI decisions) complete. First Opus review pass (Task 2.7) returned NEEDS REVISION on one blocking finding: the config cascade's wholesale first-match-wins semantics would let a consumer's own eslint.config.js silently drop the entire always-on CDD tier, defeating Decision 4's estate-wide guarantee. Fixed with a dedicated resolveEslintConfig() merge-not-replace resolver. Also resolved: testing tools as peerDependencies, markdown external-link checking descoped from v1, and Decision 6 (ts-qa-ci repo will be public, unblocking the git- dependency CI install mechanism). Phase 3 is gated on Task 3.0 (Decision 5: maintainer sign-off before any ec-site code is lifted). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The array-level merge-not-replace fix from the Task 2.7 Opus review did not actually stop per-rule Tier A overrides (ESLint flat config resolves rule severity last-entry-wins, not per-array) - ec-site's own config does exactly this to its flagship CDD rule. Replace it with a rule-level override guard plus a tier-a-exemptions.json sanctioned-exception mechanism, logged on every run. Also fixes the audit's other findings: Task 3.0's sign-off gate now requires a dated evidence artifact and covers all ec-site-derived code (not just "rules"); adds a budgeted Task 4.5 for the repo's first test suite (renumbering Phase 4 tasks 4.5-4.8 to 4.6-4.9); resolves the no-eslint-disable/suppression-comment governance conflict; reverses Prettier to peerDependency to avoid a format ping-pong with this repo's own Prettier; and several minor consistency fixes. The plan-splitting recommendation (finding S5) is deliberately left open for the maintainer's decision. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The plan folder had accumulated verbatim ec-site source-code quotes (exact config lines, file/line citations), a full 54-row rule catalogue with ec-site's real filenames and business-specific descriptions (contact whitelists, case-study/tech-logo registries, copywriting policy), and an internal-vocabulary count. ec-site is a private client codebase - none of that belongs in this repo's tracked git history. Moved the full unredacted detail to untracked/plan-011-ecsite-detail- REFERENCE.md (gitignored, still usable as a Phase 3 working reference). Tracked docs now carry only the generic, decision- relevant summary: tier verdicts, counts, and the portable design lessons - everything actually needed to build ts-qa-ci, none of the client-identifying specifics. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… 012 Maintainer confirmed ec-site code may be lifted into ts-qa-ci under the already-designed tier system, with private/brand rules staying in ec-site via the project-override layer - recorded as the Task 3.0 evidence artifact. Task 3.0 complete, Decision 5 resolved, Phase 3 unblocked. The maintainer also directed that ec-site itself be migrated onto ts-qa-ci. Tracked as new Plan 012 rather than folded into Plan 011, applying the pass-2 Fable audit's own S5 finding that Plan 011 already carries more than one project's worth of scope. Plan 012 is gated on Plan 011 reaching a usable, installable state. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
….1-3.3) Scaffolded the package in untracked/repos/ts-qa-ci/ with a full working orchestrator, all 11 tool runners, and all 10 CDD/Tier A ESLint rules. Verified with a real build (0 TS errors after fixing several genuine bugs) and an end-to-end CLI smoke test, not just written and assumed correct. Two maintainer-directed design changes folded in: - peerDependency floors were stale guesses; reset to current major versions verified live via npm view, with an inline policy note so they don't go stale again. - Added Decision 7: a new Phase 0 "Fast Fail" gate running oxlint, carrying over php-qa-ci's verified cheap-before-expensive tool ordering (confirmed directly against its own bin/qa). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Deploy-skills and init commands implemented and smoke-tested against a scratch consumer directory (hooks-daemon detection, idempotent project-handler generation, tsQaConfig scaffolding). Full docs set written. Task 3.6 (push to GitHub) deliberately left undone per its own design - Phase 4 hasn't started, so nothing needs the pushed ref yet, and creating a new public repo is a real external action worth surfacing rather than doing silently. Phase 3 is now substantively complete; Phase 4 (dogfooding) is a different kind of work - it modifies this repo's own tracked source rather than an isolated untracked/ scaffold, so it's called out as a checkpoint in the plan notes before starting. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Installs @longtermsupport/ts-qa-ci as a git-dependency devDependency and migrates this repo's QA tooling onto it (Task 4.1-4.4, 4.6). Dependency floor corrections (verified via real ecosystem checks, not guessed): typescript 5.6->6.0 (7.x unsupported by typescript-eslint), eslint 9.15->9.39 (10.x unsupported by eslint-plugin-react), vite 6->8, prettier/vitest/playwright/@vitejs/plugin-react bumped to current major. rollup-plugin-visualizer bumped to 7.x for Vite 8/rolldown compat, with an explicit Plugin-type cast where its own types still lag. Removed 5 dead/ redundant devDependencies (@types/highlight.js, @types/react-router-dom, @typescript-eslint/eslint-plugin+parser, eslint-plugin-react - all either superseded by first-party types or covered transitively by the typescript-eslint wrapper); added the genuinely-used-but-undeclared flowbite-react (tailwind.config.ts would have broken on npm ci). Migrated eslint.config.js into tsQaConfig/eslint.config.js (project additions layer, merged under ts-qa-ci's Tier A base) - dropped the two locally-duplicated rules (no-placeholder, no-eslint-disable) now covered by Tier A. Added tsQaConfig/knip.json, .oxlintrc.json, remark-ignore.json, tier-a-exemptions.json for the config cascade. Fixed real code issues the pipeline surfaced: 9 missing Props exports, 2 genuine SSR hydration bugs (Footer.tsx's clock read during render, Page.tsx mutating document.title synchronously in the render body - both moved into useEffect), 6 redundant duplicate default+named exports, one confirmed-dead component (Prose.tsx, superseded by ArticleContent.tsx), obsolete tsconfig.json baseUrl (deprecated ahead of TS 7), 3 SEO metadata length violations, 2 missing type annotations. Downgraded react-hooks/set-state- in-effect to warn - a new rule from the react-hooks 5->7 bump that flags legitimate external-system-sync effects (embla carousel, animation timers) as violations; redesigning those components is tracked, separate work. Authored the initial test suite (Task 4.5): Vitest smoke tests for all six page routes plus an ArticleDetail not-found case, and Playwright E2E smoke tests against the real prerendered build (all page routes + client-side 404 handling), with playwright.config.ts scoping E2E away from src/**/*.test.tsx so the two runners don't collide. Wired ts-qa into .github/workflows/ci.yml for the first time (Task 4.7) - runs after build since Playwright serves the real dist/ output via `npm run preview`, not a mock. Verified end-to-end with GITHUB_ACTIONS=true locally: full pipeline exits 0 across all 10 tools. Note: an early Phase 1 run (before tsQaConfig/../.prettierignore existed) reformatted content outside src/ (ARCHIVE/, .claude/, root docs) - cosmetic whitespace/markdown formatting only, kept per maintainer sign-off rather than reverted. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ran ts-qa deploy-skills against this repo's real hooks-daemon install. Found and fixed two real bugs in ts-qa-ci's project-handler generation during verification (wrong directory, missing Handler ABC methods) - tracked in ts-qa-ci's own commit history. The handler now loads cleanly: `validate-project-handlers` reports Status: OK. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Phase 3 (Task 3.6) and all of Phase 4 (Tasks 4.1-4.9) done. Recorded the full commit chain across both repos and the two most significant findings (resolveEslintConfig() never wired into the real eslint invocation; no-ad-hoc-html's exemption logic had zero working exemptions before this session, inflating the initial violation count from a real 0 to 320). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…an marked Complete Fixes CI-failing Prettier drift on CLAUDE.md and PLAN.md picked up by the ts-qa pipeline itself (Task 5.2 doc updates landed unformatted). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@longtermsupport/ts-qa-cias this repo's QA/CI system of record (Plan 011, Phases 1-4)tsconfig.json's deprecatedbaseUrlts-qainto CI for the first time (lint, format, type-check, structural checks, tests)See
CLAUDE/Plan/011-ts-qa-ci-package/PLAN.mdfor full plan detail and decision log.Test plan
npx ts-qaexits 0 locally (all 10 tools: oxlint, prettier, eslintFix, eslintReport, remarkValidateLinks, knip, tsc, dependencyCruiser, vitest, playwright)GITHUB_ACTIONS=true CI=true) - also exits 0npm run buildsucceeds, all 49 routes pre-render🤖 Generated with Claude Code