On the self-hosted QNAP runner, restoring the pnpm store from actions/cache
produces ~260 "Cannot change mode to rwxr-xr-x: Bad address" tar errors,
leaving the store partially extracted. pnpm install still reports success but
produces broken symlinks (e.g. @vitest/coverage-v8 missing at runtime), which
crashes the engine test suite with ERR_LOAD_URL.
QNAP runner disk persists across runs anyway; the cache layer only adds risk.
CI unit-test runs vitest run --coverage in each workspace package, but only
apps/web declared the coverage-v8 dep. In pnpm workspaces deps aren't
hoisted across packages, so engine/staffing/api/application/shared need it
directly.
The build job also needs REDIS_URL because collecting page data for
/api/perf imports a module that throws if REDIS_URL is missing under
NODE_ENV=production. A placeholder value satisfies the check (no actual
Redis connection is made at build time).
act_runner sometimes checks out moving tag @v4 without the built dist/
output, breaking all jobs with MODULE_NOT_FOUND on setup/index.js.
Pinning to a tagged release avoids the incomplete checkout.
- Remove host port mappings from postgres/redis services in ci.yml;
QNAP runner already occupies 5432. Use service DNS names
(postgres/redis) instead of localhost for DB/Redis URLs.
- Track packages/api/src/lib/read-only-prisma.ts which was imported
by assistant-tools.ts but never committed, breaking check:imports.
Collapses ci.yml, release-image.yml, and deploy-test.yml from three
parallel push-triggered workflows into one orchestrated pipeline:
- release-image.yml: converted to reusable workflow (workflow_call +
workflow_dispatch). No longer triggers on push directly.
- deploy-test.yml: deleted, content inlined into ci.yml as the
docker-deploy-test job with needs: [build].
- ci.yml: adds docker-deploy-test job and release-images job. The
release-images job calls release-image.yml via uses: and is gated
to push events on main, so PRs do not publish images.
- check-architecture-guardrails.mjs: updated to enforce the new
reusable-workflow shape (workflow_call trigger, ci.yml chains
release-image.yml, main-push gating).
One run per commit, clear Success/Failure status, no wasted image
builds when CI fails.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds paths-ignore filters so changes under docs/, .gitea/, *.md, and
LICENSE don't trigger the full CI matrix, image builds, or test-deploy
on Gitea Actions. Saves ~30+ minutes per docs commit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add pnpm audit --audit-level=high to CI guardrails job so vulnerable
packages are caught before merge, not just in nightly scans
- Add CODEOWNERS for review routing on infra, schema, and auth changes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move CI_AUTH_SECRET from plaintext to ${{ secrets.CI_AUTH_SECRET }}
- Wrap password reset (update + session kill + token mark) in $transaction
to prevent stale sessions on partial failure (CWE-613)
- Rate limiter Redis fallback now uses stricter degraded limits
(maxRequests/10) and logs at error level instead of warn
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Install husky v9 + lint-staged: pre-commit runs eslint --fix and prettier on staged files
- Tighten ESLint base config: no-console→error, ban-ts-comment (ts-ignore banned, ts-expect-error with description allowed), reportUnusedDisableDirectives→error
- Migrate web app from deprecated `next lint` to `eslint src/` with flat config and react-hooks plugin
- Convert all 5 @ts-ignore to @ts-expect-error with descriptions, remove stale disable comments
- Add NEXT_PUBLIC_SENTRY_DSN to docker-compose.prod.yml and .env.example
- Add coverage artifact upload step to CI test job
- Pre-existing violations (102 warnings) downgraded to warn in web config for Phase 2 cleanup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allocation bars that have active optimistic overrides (post-drag,
awaiting server confirmation) now pulse subtly via animate-pulse.
The pending set is derived from the existing optimisticAllocations
map keys, requiring no additional state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>