The `test` step has failed on every `next` pipeline since #1017 on exactly one assertion, and it is the same one on unrelated PRs: FAIL: host provides 'pi' in the system path; missing-binary cases are not measurable here (framework/tools/fleet/test-start-agent-session.sh:103) Measured 2026-08-16 across pipelines 2444 (#1256), 2438 (#1240) and 2441 (#1017-quality): exactly one FAIL line in each full log, identical, this line. Control `zzz-not-present-zzz` -> 0 on all three. Cause. #1241 (5c35a250) added the guard: the suite shims fake mosaic/pi/npm into $FAKE_BIN, but the constructed PANE_PATH always ends in the real system path, so on a host that installs those binaries the missing-binary cases cannot be measured and a green run would mean nothing. The guard says so instead of passing. Its own pipeline 2430 was green only because the suite was CI-excluded at the time, so the guard had never run in CI. #1017 (c56483eb) then enumerated it and dropped the exclusion. The CI image installs @earendil-works/[email protected].1 on purpose, so the precondition is unsatisfiable there. Both commits are mine. The guard is correct and is not being softened. A check that cannot measure its property and reports success is the failure mode this repo has been cataloguing all week; the error was wiring the suite into an image that violates its precondition, so the wiring is what gets reverted. Second effect, which is the reason this cost a day rather than an hour: test:framework-shell is one && chain and this sat at position 44 of 48, so glpi/test-list-http-status.sh, orchestrator/test-board-roll.sh, woodpecker/test-ci-wait-exit-matrix.sh and _scripts/test-fleet-transport-check.sh have not run at all since the merge. The pipeline reported one failure, never "one failure plus four unrun". All four are green when run directly on sb-it-1-dt, so the mask hid nothing broken -- but that is a local result on one host, not a CI-image result. Verification, with controls: - enumeration guard OK (population 52, enumerated 36, signed-excluded 16). - control A, exclusion line removed while unwired -> FAIL UNENUMERATED. - control B, exclusion line kept while rewired -> FAIL CONTRADICTORY EXCLUSION. The gate discriminates in both directions, so its OK is load-bearing. - the four formerly-masked suites: rc=0 each, run directly. - the full chain cannot be run to completion on sb-it-1-dt: it stops earlier, at the lease-broker Invariant R test, because this host carries the quarantined operator-global pi 0.84.2 against a measured 0.84.1. That is host-specific and out of scope here -- CI pins 0.84.1, and the single FAIL line in those three pipelines proves positions 1-43 passed there. Burn-down is to control the tail of PANE_PATH inside the test, not to remove pi from the image. Recorded in the exclusion reason and in #1269.
Quality Rails
Portable quality enforcement for TypeScript, Python, and Node.js projects.
🎯 What This Prevents
Based on real-world validation of 50 issues in a production codebase:
- ❌ Hardcoded passwords
- ❌ SQL injection vulnerabilities
- ❌ Type safety violations (
anytypes) - ❌ Missing test coverage
- ❌ Build failures
- ❌ Dependency vulnerabilities
70% of these issues are prevented mechanically with quality-rails.
⚡ Quick Start (Mosaic)
New Project
# Apply template from Mosaic
~/.config/mosaic/bin/mosaic-quality-apply --template typescript-node --target /path/to/project
# Install dependencies
cd /path/to/project
npm install
# Initialize git hooks
npx husky install
# Verify enforcement is working
~/.config/mosaic/bin/mosaic-quality-verify --target /path/to/project
Existing Project
# Same as above - works for new or existing projects
~/.config/mosaic/bin/mosaic-quality-apply --template typescript-node --target /path/to/existing-project
🛡️ What You Get
✅ TypeScript strict mode - All type checks enabled
✅ ESLint blocking any types - no-explicit-any: error
✅ Pre-commit hooks - Type check + lint + format before commit
✅ Secret scanning (gitleaks) - Block hardcoded passwords/API keys (pre-commit + CI)
✅ CI/CD templates - Woodpecker, GitHub Actions, GitLab
✅ Test coverage enforcement - 80% threshold
✅ Security scanning - npm audit, OWASP checks
📦 Available Templates
| Template | Language | Framework | Status |
|---|---|---|---|
typescript-node |
TypeScript | Node.js | ✅ Ready |
typescript-nextjs |
TypeScript | Next.js | ✅ Ready |
monorepo |
TypeScript | TurboRepo + pnpm | ✅ Ready |
python |
Python | - | 🚧 Coming Soon |
Monorepo Template
Perfect for projects combining Next.js frontend + NestJS backend in one repository.
Features:
- 🎯 Multi-package aware - lint-staged only checks changed packages
- ⚡ TurboRepo caching - Faster builds and tests
- 🔀 Parallel dev servers - Run web + API simultaneously
- 📦 pnpm workspaces - Efficient dependency management
- 🛡️ Package-specific rules - Next.js and NestJS get appropriate ESLint configs
Example structure:
monorepo/
├── apps/
│ ├── web/ # Next.js frontend
│ └── api/ # NestJS backend
└── packages/
├── shared-types/
├── ui/
└── config/
🧪 How It Works
Pre-Commit (Local Enforcement)
# You try to commit code with a type error
git commit -m "Add feature"
# Quality rails blocks it:
❌ Type error: Type 'number' is not assignable to type 'string'
❌ ESLint: Unexpected any. Specify a different type.
✋ Commit blocked - fix errors and try again
CI/CD (Remote Enforcement)
# Woodpecker pipeline runs:
✓ gitleaks (secret scanning — parallel, no deps)
✓ npm audit (dependency security)
✓ eslint (code quality)
✓ tsc --noEmit (type checking)
✓ jest --coverage (tests + coverage)
✓ npm run build (compilation — gates on all above)
# If any step fails, merge is blocked
🎓 Philosophy
Process compliance doesn't work.
Instructing AI agents to "do code review" or "run tests" fails. They claim to follow processes but output quality doesn't match claims.
Mechanical enforcement works.
Quality rails don't ask agents to follow processes. They block commits that don't pass automated checks.
- Type errors? → Commit blocked
- Hardcoded secrets? → Commit blocked
- Test failures? → Commit blocked
- Missing coverage? → Commit blocked
This works for any agent runtime (Codex, Claude, OpenCode, Gemini, etc.) because enforcement is mechanical, not instructional.
📖 Documentation
🔧 Scripts
| Script | Purpose |
|---|---|
scripts/install.sh |
Install template to project (Linux/Mac) |
scripts/install.ps1 |
Install template to project (Windows) |
scripts/verify.sh |
Verify enforcement is working (Linux/Mac) |
scripts/verify.ps1 |
Verify enforcement is working (Windows) |
🚀 Roadmap
- TypeScript/Node template
- Pre-commit enforcement (husky + lint-staged)
- CI/CD templates (Woodpecker, GitHub Actions)
- Installation scripts
- Verification testing
- Next.js template
- Monorepo template
- Python template
- Coverage visualization
- IDE integration (VSCode extension)
🤝 Contributing
Quality Rails is based on lessons learned from real production codebases. Contributions welcome!
📝 License
MIT License - See LICENSE file for details
🙏 Credits
Built to solve real problems discovered in AI-assisted development workflows.
Based on validation findings from a production patch milestone.