Skip to content

chore(deps): bump zod from 4.3.6 to 4.4.3 - #67

Closed
dependabot[bot] wants to merge 195 commits into
mainfrom
dependabot/npm_and_yarn/zod-4.4.3
Closed

chore(deps): bump zod from 4.3.6 to 4.4.3#67
dependabot[bot] wants to merge 195 commits into
mainfrom
dependabot/npm_and_yarn/zod-4.4.3

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github May 11, 2026

Copy link
Copy Markdown
Contributor

Bumps zod from 4.3.6 to 4.4.3.

Release notes

Sourced from zod's releases.

v4.4.3

Commits:

  • 4c2fa95ce3f3390fbc522324e406b4e9e89b88f9 docs: use Zernio primary wordmark for gold sponsor logo
  • 2aeec83eb135e3a83756e973ef44845fc5a455d2 docs: prune lapsed gold sponsors and rebalance logo sizing
  • 7391be88ac1ee5cd02057f5ccc012a1f5df4efd0 docs: prune lapsed silver/bronze sponsors and add active ones
  • 2c703322a21b4e2b12f33f49ea8430c451a68b4f docs: normalize bronze sponsor logos to github avatar pattern
  • 9195250cab0e7950efe39c3926d6c203b4b0a170 docs: remove Mintlify from bronze sponsors (churned)
  • b8dffe9e62f17e6571e6249d05cc5102b54d94e4 docs: remove Numeric and Speakeasy (2+ missed monthly cycles)
  • 1cab69383fcdeae2a366d5e2a2fc4d8fc765d168 fix(v4): restore catch handling for absent object keys (#5937) (#5939)
  • c2be4f819064eed62c7c350a2d399b5faecd15f8 fix(v4): generalize optin/fallback to transform; restore preprocess on absent keys (#5941)
  • f3c9ec03ba7a28ae72d25cc295f38674bee0f559 4.4.3
  • 1fb56a5c18c27102dbc92260a4007c7732a0ccca docs: document release procedure in AGENTS.md

v4.4.2

Commits:

  • 0c62df0ea19fd05abdf90473e9eef7eea530fab2 Clean up docs navigation and stale labels (#5901)
  • 20cc794895cc8604fe0c87d83a5d1c3f89fad0ac chore: add security policy and refresh tooling deps
  • 6fbe07b0177efdd1bf1c0b05160e70d7a0702337 fix(docs): heading anchor links now include the hash so it doesnt scoll all the way up, follows navbar logic (#5791)
  • 4bbed1b1c73eca4ce9e59b1189ed236aa6c8b5bd Tighten discriminated union option typing
  • bbac3e567e7fccfaaf7cdc97f1ce30c295e2c908 Update PR guidance for agents
  • cf0dc942a32805c292fff59ade20a7ace980735a Merge remote-tracking branch 'origin/main' into fix-discriminated-union-key-constraint
  • 292c894a5fd2aa42e527900b83d8d7a3009a709c docs: add Zernio gold sponsor
  • 1fc9f311c28dcf80d0bb5a36b177086cbc3d8eca docs: document codec inversion
  • 1373c85da9aeff704a9762d27bc58699618aefb7 docs: remove AI disclosure guidance
  • e20d02b473c08e3a4e557bc610b1b5fac079b649 chore: ignore triage notes
  • e58ea4d91b1dfe8194b73508203213cbc7e9c936 docs: test Zod Mini tab code heights
  • 905761a5d127e8d5dd2ebb3bc88c75cb0b8149ff docs: document preprocess input type narrowing
  • bf64bac850d4dee2b7dde7e64909d5d796d32043 chore: tighten test guidance in AGENTS.md
  • 8ec4e73f4c4693b6361ad591be40fb41eb8a9f95 chore: update play.ts scratch
  • 02c2baf7d0d615872fa4528a8020603b71211702 Make z.preprocess defer optionality to inner schema (#5929)
  • 88015df8e25c44fb5385eb3ef28935119cd5edea fix(docs): drop deprecated baseUrl from tsconfig
  • c59d4474e3b4cad1b323462186cf607178ce8267 4.4.2

v4.4.1

Commits:

  • 481f7be4238c83ed58183f921b2646f340a91c6a ci: gate release publishing on full test workflow
  • 95ccab423aec720b2523c3a64cdc7e3204537cc7 test(v3): restore optional undefined expectations
  • cede2c63739a5823d6aa5093d291e9a111da943d fix(v4): reject tuple holes before required defaults (#5900)
  • edd0bf0f5ada4a8dc581c259407d7bbad0a71ea7 release: 4.4.1
  • 180d83d1dbe6a59260710cc8637a3dea2281ee56 docs: remove Jazz featured sponsor

v4.4.0

4.4.0

This is a minor release with a wide set of correctness and soundness fixes. Some fixes intentionally make Zod stricter, so code that depended on previously accepted invalid or ambiguous inputs may need small updates.

Potentially breaking bug fixes

... (truncated)

Commits
  • 1fb56a5 docs: document release procedure in AGENTS.md
  • f3c9ec0 4.4.3
  • c2be4f8 fix(v4): generalize optin/fallback to transform; restore preprocess on absent...
  • 1cab693 fix(v4): restore catch handling for absent object keys (#5937) (#5939)
  • b8dffe9 docs: remove Numeric and Speakeasy (2+ missed monthly cycles)
  • 9195250 docs: remove Mintlify from bronze sponsors (churned)
  • 2c70332 docs: normalize bronze sponsor logos to github avatar pattern
  • 7391be8 docs: prune lapsed silver/bronze sponsors and add active ones
  • 2aeec83 docs: prune lapsed gold sponsors and rebalance logo sizing
  • 4c2fa95 docs: use Zernio primary wordmark for gold sponsor logo
  • Additional commits viewable in compare view
Maintainer changes

This version was pushed to npm by GitHub Actions, a new releaser for zod since your current version.


leagames0221-sys and others added 30 commits April 22, 2026 16:13
- Root configs: package.json, pnpm-workspace.yaml, turbo.json
- Env: .env.example with per-app DB URLs + app/migrator role separation
- Infra: docker-compose (pgvector/pg16 + redis:7-alpine) + multi-db init script
- Git hygiene: .gitignore, .gitattributes (LF normalization), .nvmrc (Node 20)
- License: MIT
- Docs: 13-part design bible in docs/design/ covering Boardly + Knowlex
  - Overview, monorepo structure, requirements, ER schemas (Prisma)
  - OpenAPI specs, Week 3 daily task breakdown
  - ADR 0001-0022, STRIDE threat model, Runbook, rate limits, retention
  - RAG prompt registry + golden QA eval pipeline
  - Interview Q&A 30 + portfolio LP + demo storyboards
  - Self-review critical/high fix log
apps/
- collab (Boardly): Next.js 16 + Turbopack + TailwindCSS + TS, port 3000
- knowledge (Knowlex): Next.js 16 + Turbopack + TailwindCSS + TS, port 3001

packages/
- @craftstack/ui: shared React components entry
- @craftstack/auth: Auth.js v5 wrapper entry
- @craftstack/db: Prisma client + withTenant helper entry
- @craftstack/logger: pino + Sentry entry
- @craftstack/config: shared tsconfig.base.json + prettier.config.js
- @craftstack/api-client: OpenAPI-generated types entry

Workspace install verified (pnpm 9.15, Node 20, 355 packages).
Collab production build passes.
Shared packages (ui/auth/db/logger/api-client) had lint/typecheck scripts
pointing to tools that were not installed (eslint/tsc configs missing).
Turbo invoked them and failed with exit code 2.

Scripts will be re-added per package when actual source + configs land.
Apps (collab/knowledge) retain their Next.js-provided lint/typecheck.
- prisma + @prisma/client 7.7.0, dotenv, tsx dev deps
- prisma.config.ts: Prisma 7 native config (migrator URL resolution)
- .gitignore: /src/generated/prisma
- dotenv/config imported for env var loading
- pg_trgm extension declared for future full-text search
…ership, Invitation)

Schema follows docs/design/05_prisma_schemas.md:

Auth.js v5 adapter tables:
  - Account (provider+providerAccountId unique)
  - Session (sessionToken unique)
  - VerificationToken (identifier+token unique)

Core domain (Boardly):
  - User: email-unique identity + locale/theme preferences
  - Workspace: slug-unique tenant with owner + soft-delete
  - Membership: user x workspace with Role enum (OWNER/ADMIN/EDITOR/VIEWER)
  - Invitation: email invites with tokenHash + expiresAt + optional inviter (SetNull)

Design decisions applied:
  - onDelete cascades follow docs/design/12_critical_fixes.md C-1
  - Invitation.inviterId nullable + SetNull so invites survive user deletion
  - Indexes: email, slug, owner, deletedAt, workspace+role, workspace+email

Generator: Prisma Client 7.7 with fullTextSearchPostgres + postgresqlExtensions.
prisma format and prisma generate both pass.
…ity log

Schema additions (docs/design/05_prisma_schemas.md):

Enums:
  - ActivityAction (24 variants) for AuditLog-style append-only tracking
  - NotificationType (MENTION/ASSIGNED/DUE_SOON/INVITED/COMMENT_ON_CARD)

Kanban domain:
  - Board: workspace-scoped with color/icon/archived/position, soft delete
  - List: LexoRank position, optional WIP limit
  - Card: optimistic locking via version column (ADR-0007),
          title/description/dueDate/position, Cascade from List

Labels (many-to-many via CardLabel):
  - Label: workspace-scoped name+color, unique per workspace
  - CardLabel: composite PK (cardId, labelId)
  - CardAssignee: composite PK (cardId, userId) with assignedAt

Comments & attachments:
  - Comment: self-referential parentId for threads, soft delete
  - Mention: (commentId, userId) unique for per-user notification dispatch
  - Attachment: R2-backed (r2Key unique), uploader reference, MIME metadata

Observability:
  - ActivityLog: workspace-scoped audit trail with JSON payload,
                 actor SetNull on user delete (ADR-0010 C-1)
  - Notification + NotificationSubscription: Web Push VAPID endpoints

prisma format/validate/generate all pass.
Full monorepo lint/typecheck/build verified locally.
src/lib/db.ts exports a global-cached PrismaClient so HMR in Next.js
does not spawn a new connection pool on every module reload.

- dev: log query/error/warn
- prod: log error only (avoid PII leakage, ADR-0009 observability plan)
- globalThis-based caching gated on NODE_ENV !== production
src/lib/lexorank.ts wraps the `lexorank` npm package (Jira-compatible)
per ADR-0006 + ADR-0021.

API:
  - first(): rank placed before everything
  - last():  rank placed after everything
  - between(prev?, next?): insert between two neighbors
  - compare(a, b): stable comparator for Array.sort

Tests (src/lib/lexorank.test.ts, all passing):
  1. first() < last()
  2. between(first, last) strictly between
  3. between(null, null) yields a valid rank
  4. between(prev, undefined) places after prev
  5. between(undefined, next) places before next
  6. repeated insertions remain strictly ordered
  7. compare is antisymmetric

vitest.config.ts: node env, v8 coverage over src/lib/.
…r-pg)

Prisma 7 constructor requires either an `adapter` or `accelerateUrl`;
plain DATABASE_URL no longer auto-configures the client.

- @prisma/adapter-pg + pg + @types/pg added
- src/lib/db.ts instantiates PrismaClient({ adapter, log })
- same HMR-safe globalThis caching preserved
- production can later swap the adapter for Neon HTTP driver without
  touching call sites

Also: .gitignore the harness-local .claude/ so it does not pollute the repo.
Auth.js v5 (next-auth@5.0.0-beta.31) + @auth/prisma-adapter setup per
ADR-0003 (database session strategy for server-side revocation).

src/auth/
  - config.ts   : NextAuthConfig with PrismaAdapter + Google/GitHub
                  providers + signin page override, session callback
                  exposes internal user.id
  - index.ts    : re-exports { handlers, signIn, signOut, auth }
  - handlers.ts : thin shim for the app route handler
  - rbac.ts     : roleAtLeast / hasRole / requireRole (throws RoleError)
  - rbac.test.ts: exhaustive 4x4 hierarchy matrix (16 Vitest cases)
  - types.d.ts  : augment Session with internal user.id

vitest.config.ts updated to resolve @/ path alias and widen coverage
to src/**/*.ts (excluding app/, generated/, and *.test.ts).
…guard

src/app/api/auth/[...nextauth]/route.ts
  - Re-exports GET/POST from the Auth.js handlers

src/app/signin/page.tsx
  - Server component with async action handlers for Google/GitHub signIn
  - Inline SVG brand icons (no extra dependency)
  - Redirects to /dashboard (or callbackUrl) if already authenticated
  - Dark neutral-950 aesthetic matching the Boardly brand

src/proxy.ts
  - Next.js 16 renamed `middleware` to `proxy`
  - Default-export auth() so the proxy runtime recognizes the function
  - Matcher excludes /signin, /api/auth, and Next static assets

Verified with preview: /signin renders 200, /dashboard redirects 307
through the proxy to /signin as expected (no dashboard route yet).
- ApiError base class with status/code/message/details
- UnauthorizedError (401), ForbiddenError (403), NotFoundError (404),
  ConflictError (409), BadRequestError (400)
- Shape matches OpenAPI Error schema (docs/design/06_openapi_specs.md)
- handle(): Route Handler wrapper that turns thrown ApiErrors into
  JSON 4xx responses and unexpected errors into logged 500s
Returns every non-deleted workspace the authenticated user belongs to,
ordered by join date desc. Unauthenticated requests get a 401 JSON
payload (handled by the new errors/handle wrapper).

src/server/workspace.ts
  - listWorkspacesForUser(userId): joins Membership + Workspace,
    filters out soft-deleted workspaces, returns { id, name, slug,
    color, iconUrl, role }

src/app/api/workspaces/route.ts
  - GET handler wired through handle() so errors become proper JSON
  - auth() checked first; throws UnauthorizedError if missing session
src/app/page.tsx
  - Root '/' now acts as a session gate: authenticated -> /dashboard,
    unauthenticated -> /signin. Removes the scaffold landing content.

src/app/dashboard/page.tsx
  - Server component rendering header with user email + sign-out form
  - Workspace grid (1/2/3 columns responsive) with color swatch,
    name, /slug path, and role badge (OWNER/ADMIN/EDITOR/VIEWER)
  - Empty-state CTA when the user has no memberships
  - 'New workspace' button placeholder pointing at /workspaces/new

src/proxy.ts
  - Matcher now excludes /api/* so API routes handle their own auth
    and return 401 JSON instead of 307 redirects to /signin.
    Confirmed: GET /api/workspaces without session returns
    { code: 'UNAUTHORIZED', message: 'Authentication required' }
    with HTTP 401. Page routes still redirect as expected.
Uniform LF, double quotes, trailing commas 'all' applied across
existing source files after wiring up prettier config.
src/lib/validation.ts
  - parseCreateWorkspaceInput(raw): trims, lowercases slug, enforces
    slug regex ^[a-z0-9-]{3,32}$, 80-char name cap, #RRGGBB color
  - Aggregates every field error into BadRequestError.details.fieldErrors
    so the client can highlight individual fields

src/lib/validation.test.ts
  - 8 cases: valid body, valid color, non-object body, bad slug,
    missing name, overlong name, malformed color, slug normalization
src/server/workspace.ts
  - createWorkspace(userId, input): transactional create with owner
    Membership row; throws ConflictError('SLUG_TAKEN') on collision

src/app/api/workspaces/route.ts
  - POST handler: auth check, body parse, create, 201 with the row
  - Validation errors surface as 400 fieldErrors; slug conflict as 409

src/app/workspaces/new/page.tsx
  - Server component form with Tailwind dark-mode styling
  - Async server action that catches ApiError, rehydrates field values
    via query string, and re-renders with the error banner
  - Native HTML pattern='[a-z0-9-]{3,32}' mirrors server-side regex

Verified: POST /api/workspaces unauthenticated returns 401 JSON;
/workspaces/new unauthenticated redirects to /signin with callbackUrl.
apps/collab/next.config.ts
  - X-Content-Type-Options: nosniff
  - X-Frame-Options: DENY
  - Referrer-Policy: strict-origin-when-cross-origin
  - Permissions-Policy: camera/microphone/geolocation/payment denied
  - Strict-Transport-Security: 2 years + includeSubDomains + preload
  - poweredByHeader: false
  - reactStrictMode: true
  - CSP intentionally deferred until external origins are finalized

docs/architecture/system-overview.md
  - Mermaid graph of Edge, Vercel, Fly.io, Data, External APIs,
    Observability layers with all relationships drawn
  - Per-app resource isolation table
  - Two concrete request paths (card edit, RAG question) walking
    through the full round trip
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 4 to 6.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](pnpm/action-setup@v4...v6)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the react group with 2 updates: [react](https://github.com/facebook/react/tree/HEAD/packages/react) and [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom).


Updates `react` from 19.2.4 to 19.2.5
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.5/packages/react)

Updates `react-dom` from 19.2.4 to 19.2.5
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.5/packages/react-dom)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
/api/health
  - Cheap liveness check (no DB hit) for UptimeRobot 4-minute pings
  - Keeps the Neon free tier warm (ADR-0016)
  - Cache-Control: no-store so the poll always reaches the app

not-found.tsx
  - Branded 404 with Back to dashboard CTA

error.tsx
  - Global error boundary (client component)
  - Shows error.digest for Sentry correlation once wired
  - Try again + Go home buttons
  - Uses next/link per no-html-link-for-pages lint rule
Same X-Content-Type-Options / X-Frame-Options / Referrer-Policy /
Permissions-Policy / HSTS plus poweredByHeader=false, reactStrictMode=true.
prisma/seed.ts
  - Uses the Prisma PG driver adapter + DIRECT_DATABASE_URL (migrator)
  - Upserts 2 users, 1 workspace with 2 memberships + 3 labels
  - Creates a Welcome board with 3 LexoRank-ordered lists and 3 cards
  - Idempotent via upsert + skipDuplicates for rerun safety

pnpm --filter collab db:seed once Docker/Neon is reachable.
src/server/workspace-detail.ts
  - loadWorkspaceForMember(userId, slug): returns null for non-members
    so the caller can 404 without leaking existence
  - One round trip via nested include: boards + memberships + user
  - Skips soft-deleted workspaces and boards

src/app/w/[slug]/page.tsx
  - Header with workspace color swatch + slug crumb + back link
  - Boards grid with 'New board' CTA gated by role (OWNER/ADMIN/EDITOR)
  - Empty state when no boards exist
  - Members list with role badges and avatar initials
  - Self role displayed inline next to member count
  - Consistent RoleBadge component (also used in dashboard)
src/server/board.ts
  - createBoard: enforces role >= EDITOR via roleAtLeast() before INSERT
  - New boards are placed at the bottom of the workspace via LexoRank last()
  - Throws NotFoundError if workspace missing, ForbiddenError otherwise

src/app/w/[slug]/boards/new/page.tsx
  - Server-action form with Tailwind dark styling
  - Rehydrates prior values + error banner via query string
  - Redirects to /w/[slug]/b/[boardId] on success

src/app/w/[slug]/b/[boardId]/page.tsx
  - Workspace-scoped board query: 404 for non-members or missing board
  - Static kanban layout (lists + cards); realtime editing arrives in Week 6
  - Per-list card count with optional WIP limit display
  - Subtle board-color tint on the header gradient
leagames0221-sys and others added 14 commits April 28, 2026 17:34
…ural + 3 honest-disclose (ADR-0057) (#46)

* feat(v0.5.8): drift-audit framework completeness — 13 axes, 10 structural + 3 honest-disclose (ADR-0057)

User-side review on 2026-04-28 identified that the 6-axis framework
(v0.5.7) had at least 7 more axes uncovered, several with high-impact
failure modes. v0.5.8 ships the 13-axis complete framework: 10
structurally enforced via PR-time CI gates + smoke probes, 3 honestly
disclosed in threat-model.md as T-07/T-08/T-09.

Axis 7 — ADR-claim ↔ Implementation (highest impact, was structural blind spot):
- scripts/check-adr-claims.mjs (new) — reads docs/adr/_claims.json,
  asserts each load-bearing ADR claim against the codebase. Three
  match modes (regex/contains/exists). 22 initial entries covering
  ADR-0027 / 0034 / 0035 / 0040 / 0041 / 0046 / 0049 / 0051 / 0053 /
  0054 / 0056. PR-blocking via doc-drift-detect job.
- docs/adr/_claims.json (new) — claim inventory (JSON to avoid yaml dep)

Axis 3 — internal cross-reference (ADR ID resolution):
- scripts/check-adr-refs.mjs (new) — walks docs/code, asserts every
  ADR-NNNN reference resolves to an existing docs/adr/NNNN-*.md.
  Catches typos (transposed digits) and dangling refs.

Axis 12 — external artefact freshness:
- .github/workflows/smoke.yml — new step curl -fL --head probes
  shields.io endpoint badge, both Loom URLs, both Vercel deploys.
  4xx/5xx fails the smoke run within 6h.

Axes 8/11/13 — honest disclose:
- threat-model.md T-07 (axis 8): tests are name-defined not behavior-
  verified, mutation testing deferred to v0.7.0+
- T-08 (axis 11): decisions without ADR are not auto-detected
  (false-positive rate of feat:/fix: grep would exceed signal)
- T-09 (axis 13): live free-tier quota usage is not in
  /api/attestation; structural mitigation via ADR-0046 fail-closed

ADR-0057 — full MADR with the 13-axis matrix, decision per axis,
alternatives explicitly rejected (mutation testing, auto-decision-
detection, vendor API integration, OpenAPI contract testing).

Cross-references:
- docs/adr/README.md index entry
- ci.yml: doc-drift-detect job runs check-adr-refs.mjs +
  check-adr-claims.mjs after check-doc-drift.mjs (~1s extra)
- README + portfolio-lp + page.tsx Stat block — ADR count 55 → 56
  (jump in numbering: ADR-0055 deliberately skipped, 0057 added)
- Banner v0.5.7 → v0.5.8 in 4 status-bearing docs
- attestation-data.json regenerated (adr=56, tag=v0.5.8)

Local verification:
- node scripts/check-doc-drift.mjs → 0 failures / 0 warnings
- node scripts/check-adr-claims.mjs → 22/22 pass
- node scripts/check-adr-refs.mjs → 53 valid IDs, 0 dangling
- pnpm --filter knowledge test → 50/50 pass
- pnpm --filter knowledge typecheck/lint/build → clean
- pnpm --filter collab build → clean

* fix: remove unused imports caught by CodeQL js/unused-local-variable

- scripts/generate-attestation-data.mjs: 'dirname' from node:path unused
- scripts/check-doc-drift.mjs: 'statSync' from node:fs unused

Both were note-severity warnings but CodeQL is configured to
PR-block on any new alert. Removing the imports keeps the module
imports lean and silences the warning. No behavior change.

Local: doc-drift-detect 0 failures / 0 warnings, generate-
attestation-data still produces tag=v0.5.8 adr=56.

* chore: empty commit to trigger CodeQL re-evaluation after alert dismissal

Alerts #19 and #20 (js/unused-local-variable on already-removed
imports) were dismissed as false-positive after the underlying fix
in 1525275 — the alert tracker did not auto-close them. This empty
commit re-triggers the PR checks so the CodeQL gate sees the
dismissed state.

* chore: trigger CodeQL re-evaluation after pre-existing alerts dismissal

* fix: remove TOCTOU race in scripts/check-adr-refs.mjs (CodeQL js/file-system-race)

The walk() function called statSync(p) followed by readdirSync(p) /
readFileSync(p), which is a TOCTOU race CodeQL flagged as high-severity
js/file-system-race. Refactored to use readdirSync(p, { withFileTypes:
true }) which returns Dirent objects carrying the file-vs-directory
bit in a single syscall. processFile() handles the leaf case
(top-level paths like README.md fall through via ENOTDIR catch).

Local: still finds 56 ADRs, 53 valid refs, 0 dangling.

---------

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
…sclose ratchet on ADR-0057 (#47)

Session 265 self-audit identified two issues with the v0.5.8 13-axis
framework: (1) the framework foundation was unenforced — `main` had no
branch protection or repository ruleset, so all 10 structurally-enforced
axes rested on convention rather than policy; (2) the v0.5.8 axis 7 row
was an overclaim relative to the actual `_claims.json` coverage
(22 entries spanning 11 of 56 ADRs ≈ 20%).

v0.5.9 closes both: the foundation via a repository ruleset, and the
overclaim via an explicit Coverage honest-disclose section in ADR-0057
itself.

Branch protection — repository ruleset on `main` (ADR-0058):
- New ruleset `main-branch-protection` (id 15652440) configured via
  `gh api -X POST repos/.../rulesets`. Rules:
    - pull_request (required_approving_review_count: 0)
    - required_status_checks (strict: true) for 7 PR-time contexts
      (free-tier compliance / lint+typecheck+test+build / doc drift
      detect / knowlex integration (pgvector) / knowlex a11y gate /
      Analyze (javascript-typescript) / authed Playwright)
    - non_fast_forward (force-push to main blocked)
    - deletion (main cannot be deleted)
    - bypass_actors: [] (admin bypass disabled)
- New `.github/RULESET_DECLARED.md` — offline-auditable marker file
  mirroring the live ruleset configuration. Asserted by `_claims.json`
  (axis 7 recursive claim) so the framework defends its own foundation.
- New `docs/adr/0058-branch-protection-ci-enforcement.md` — full MADR
  with rejected-alternatives section (classic protection, no-PR-only-
  checks, required reviews ≥ 1, repository_admin bypass).

Axis 7 honest-disclose — Coverage scope explicit (ADR-0057 ratchet):
- ADR-0057 axis 7 row updated from `✅ structural` to `✅ structural
  (judged-load-bearing coverage; see § Coverage honest-disclose below)`.
- New § Coverage honest-disclose section names the actual coverage as
  22 entries spanning 11 of 56 ADRs (≈20%), lists the covered ADRs
  explicitly (0027 / 0034 / 0035 / 0040 / 0041 / 0046 / 0049 / 0051 /
  0053 / 0054 / 0056), and distinguishes ADRs with no checkable claim
  (0001 monorepo / 0002 Prisma / 0017 release-order architectural
  intent) from ADRs that could be covered but weren't in v0.5.8
  (0044 / 0045 / 0048 / 0050 / 0052). Coverage expansion is incremental
  future-work, not a v0.5.9 blocker.

Banner + Stat sync (doc-drift-detect green):
- README + portfolio-lp — ADR count 56 → 57
- portfolio-lp lead paragraph + Audit-survivable engineering paragraph
  cite ADR-0057 + ADR-0058
- interview-qa + system-overview + runbook — banner v0.5.8 → v0.5.9
- apps/collab/src/app/page.tsx Stat block — ADRs 56 → 57

`_claims.json` — ADR-0058 recursive integrity (axis 7 self-assertion):
- New entry: `.github/RULESET_DECLARED.md` exists (`match: exists`)
- New entry: ruleset id 15652440 contained in marker (`match: contains`)

Local verification:
- node scripts/check-doc-drift.mjs → 0 failures, 0 warnings
- node scripts/check-adr-claims.mjs → 24/24 pass (was 22 + 2 ADR-0058)
- node scripts/check-adr-refs.mjs → 54 valid IDs, 0 dangling
- pnpm lint → 0 errors (4 pre-existing warnings)
- pnpm typecheck → clean
- pnpm test → 216/216 (166 collab + 50 knowledge)
- pnpm build → clean

Verification post-merge:
  gh api repos/.../rulesets/15652440 \
    --jq '{enforcement, bypass_actors, current_user_can_bypass}'
  → { "enforcement": "active", "bypass_actors": [],
      "current_user_can_bypass": "never" }

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…future-drift closure + freeze (ADR-0059) (#48)

Session 265 audit identified that the v0.5.9 framework, while
structurally complete, was at risk of an audit-of-audit loop: each
session's self-audit produced new findings, each finding produced a
new ratchet, each ratchet introduced a new meta-gap. v0.5.10 escapes
the loop by (a) adopting OpenSSF Scorecard for hygiene axes the
project was duplicating, (b) closing axes 6/7 future-drift modes,
(c) freezing the framework at v1.0 with a date-bound + incident-driven
re-audit rule.

OpenSSF Scorecard (industry baseline):
- .github/workflows/scorecard.yml (new) — weekly + on push to main + on
  branch_protection_rule. Publishes SARIF to GitHub Security tab + the
  public scorecard.dev registry.
- Coverage delegated (drops self-built duplicates):
    Branch-Protection live-state / Pinned-Dependencies (Action SHA) /
    Dependency-Update-Tool / Token-Permissions / Security-Policy /
    License / Code-Review / Dangerous-Workflows / CII-Best-Practices

Axis 7 — ADR-add-without-claim PR-time block:
- scripts/check-adr-claims.mjs (modified) — new ADRs must touch
  _claims.json or carry `<!-- no-claim-needed: <reason> -->` marker.
  Closes the silent-coverage-shrink failure mode (a maintainer adds
  a new ADR but forgets the claim entry, leaving 11/N coverage).
- ADR-0059 itself uses the no-claim-needed opt-out (meta-decision,
  individual changes are claim-checked under their respective ADRs).

Axis 6 — cron stale enforcement:
- .github/workflows/smoke.yml (modified) — 6-hourly smoke now reads
  /api/attestation, fails when daysSinceLastGreenRun > 7. Threshold
  reasoning: ADR-0049 retry-contract absorbs 1-2 nights of Neon
  cold-start flake; 7 consecutive nights is unambiguously broken.

Honest-disclose TTL on T-07 / T-08 / T-09:
- docs/security/threat-model.md (modified) — each row gains a
  Re-evaluation date. T-07: v0.7.0 / 2026-Q3. T-08: v0.6.0 /
  2026-06-30. T-09: v0.7.0 / 2026-Q3. Without TTLs, an
  honest-disclose can become a permanent dodge.

Framework freeze at v1.0:
- ADR-0059 (new) declares the framework frozen at v1.0 effective
  v0.5.10 ship. Future ratchet expansion requires one of:
    1. Real incident (canonical: v0.5.0 → v0.5.2 schema-vs-prod)
    2. External reviewer feedback (NOT self-audit-driven discovery)
    3. Re-evaluation date — 2026-Q3 mandatory window (2026-09-30)
- ADR-0058 § Recursive integrity meta-gap (marker ↔ live divergence)
  is now closed by Scorecard's Branch-Protection check.

Banner + Stat sync (doc-drift-detect green):
- README + portfolio-lp — ADR count 57 → 58
- portfolio-lp + interview-qa + system-overview + runbook — banner
  v0.5.9 → v0.5.10
- apps/collab/src/app/page.tsx Stat block — ADRs 57 → 58
- SECURITY.md — Last reviewed footer updated to 2026-04-28 (v0.5.10)

Local verification:
- node scripts/check-doc-drift.mjs   → 0 failures, 0 warnings
- node scripts/check-adr-claims.mjs  → 24/24 claim(s), PR-time pass
- node scripts/check-adr-refs.mjs    → 55 valid IDs, 0 dangling
- pnpm lint / typecheck / test (216) / build → clean

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-0060) (#49)

First product-feature ship after the ADR-0059 framework v1.0 freeze.
Closes T-01 honest-disclose by migrating Boardly board fanout from
public Pusher channels (`board-<id>`) to auth-required private
channels (`private-board-<id>`). The defence is no longer
access-control-by-id-secrecy; it's a server-signed token verifying
workspace membership at subscribe time.

Server-side:
- apps/collab/src/lib/pusher.ts — refactored: getPusherServer()
  exported, new helpers boardChannelName(boardId) + parseBoardChannel(name)
  centralise the channel-name contract. broadcastBoard() uses the
  helper.
- apps/collab/src/app/api/pusher/auth/route.ts (new) — POST handler
  with four-step gate:
    1. Auth.js session verified (401 if missing)
    2. Form body parsed (socket_id + channel_name); 400 on malformed
    3. Channel name matched against private-board-<id> allow-list
       (rejects every other private-* shape — not a generic Pusher
       signing oracle); 403 UNSUPPORTED_CHANNEL otherwise
    4. Workspace-membership check via Prisma; 403 BOARD_NOT_FOUND or
       NOT_A_MEMBER on negative cases. 503 PUSHER_NOT_CONFIGURED on
       env miss (defends a misconfigured deploy from looking like
       auth denial)

Client-side:
- apps/collab/src/lib/pusher-client.ts — authEndpoint:
  '/api/pusher/auth' configured. Auth.js session cookie sent
  automatically (same-origin POST).
- apps/collab/src/app/w/[slug]/b/[boardId]/BoardClient.tsx —
  subscribes via boardChannelName() helper instead of hardcoded
  `board-${boardId}`. Single contract surface across server-emit,
  client-subscribe, and auth-route allow-list.

Tests:
- apps/collab/src/lib/pusher.test.ts (new) — 8 Vitest cases pinning
  boardChannelName round-trip + parseBoardChannel allow-list (legacy
  public name rejected, unrelated private-* rejected, separator-
  smuggling defended, empty-id rejected). Helpers are the single
  contract surface for three independent files; pinning prevents
  silent drift.

Threat-model T-01:
- Status changed from "honest scope note" to "Resolved in v0.5.11
  (ADR-0060)". First T-NN graduating from honest-disclose to
  structural closure — concrete instance of the v0.5.10
  honest-disclose TTL pattern (ADR-0059) producing closure rather
  than perpetual dodge.
- attestation script: T-01 entries removed from scope.deferred and
  honestScopeNotes; attestation-data.test.ts updated to assert
  T-01 ABSENCE (so re-introducing the public-channel scope note
  without re-shipping the migration would fail at PR time).

Numerics ratchet (doc-drift consequence of new auth route + tests):
- Vitest total 216 → 224 (174 collab + 50 knowledge); README badge
  URL + interview-qa + portfolio-lp + page.tsx Stat block +
  layout.tsx description + opengraph-image.tsx all updated
- Boardly route+page count 38 → 39 (new auth route)
- ADR count 58 → 59
- Banners 4 docs (portfolio-lp / interview-qa / system-overview /
  runbook): v0.5.10 → v0.5.11
- _claims.json: 3 ADR-0060 entries (auth route exists, private-
  prefix in pusher.ts, pusher.test.ts exists)

Local verification:
- node scripts/check-doc-drift.mjs   → 0 failures, 0 warnings
- node scripts/check-adr-claims.mjs  → 27/27 claim(s); PR-time
  integrity pass (ADR-0060 has _claims.json updates so the new-ADR
  block fires correctly)
- node scripts/check-adr-refs.mjs    → 56 valid IDs, 0 dangling
- pnpm lint / typecheck / test (224) / build → clean

Closes: T-01 (Pusher channel eavesdropping)

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…solved (ADR-0061) (#50)

Second T-NN/I-NN graduation in two ships (after ADR-0060 closing T-01).
Closes the access-control half of ADR-0047 (deferred since v0.5.0
schema-partitioning, ~6 months on the books). The ADR-0059
honest-disclose TTL pattern is producing actual closures.

Schema migration (additive only, 20260428_auth_tenancy):
- Adds 5 tables: User / Account / Session / VerificationToken
  (Auth.js v5 standard) + Membership (user × workspace × role).
- Workspace gains members Membership[] relation.
- Seeded wks_default_v050 demo workspace untouched. No column
  changes; no existing-row mutations.

Auth.js v5 setup:
- apps/knowledge/src/auth/{config,index}.ts (new) — NextAuthConfig
  with Google + GitHub OAuth, JWT session strategy, PrismaAdapter.
- apps/knowledge/src/app/api/auth/[...nextauth]/route.ts (new) —
  catch-all handlers.
- apps/knowledge/src/app/signin/page.tsx (new) — minimal signin UI.

Two-shape access layer (preserves live RAG demo brand):
- apps/knowledge/src/auth/access.ts (new):
    requireDemoOrMember (read paths) — demo workspace anonymously
      readable via allow-list; non-demo requires Membership row.
    requireMemberForWrite (write paths) — always requires session,
      even for demo workspace. Auto-grants OWNER on demo signin
      (intentional sandbox sharing). Closes anonymous-write
      cost-attack vector named in ADR-0046.
- /api/kb/ask wired with requireDemoOrMember
- /api/kb/ingest wired with requireMemberForWrite
- 15 Vitest cases pinning the access matrix
  (read/write × demo/non-demo × authed/anonymous × member/non-member)

Schema canary (axis 2) extension:
- /api/health/schema EXPECTED constant adds 5 new tables; the
  expected.test.ts cross-checks both directions so a column drop
  without an EXPECTED update fails CI.

Threat-model + ADR-0047 closure:
- I-01 status: "single-tenant honest scope note" → "Resolved in
  v0.5.12 (ADR-0061)".
- ADR-0047 § Status: Partially Accepted → Fully Accepted.
- attestation script: Auth-gated Knowlex removed from
  scope.deferred; I-01 removed from honestScopeNotes;
  attestation-data.test.ts tightened to assert both T-01 and I-01
  ABSENT (re-introduction of either disclosure without
  re-shipping the migration would fail at PR time).

Numerics ratchet:
- ADR count 59 → 60
- Vitest 224 → 239 (174 collab + 65 knowledge, +15 access.test.ts)
- Banner v0.5.11 → v0.5.12 across 4 docs

Live activation prerequisites (post-merge, knowlex Vercel project):
- AUTH_SECRET (openssl rand -base64 32)
- GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET
- GITHUB_CLIENT_ID + GITHUB_CLIENT_SECRET
Until configured: demo /api/kb/ask continues to work (no session
lookup); ingest + non-demo paths return 500. Honest-disclosed in
ADR-0061 § Negative.

Local verification:
- node scripts/check-doc-drift.mjs   → 0 failures
- node scripts/check-adr-claims.mjs  → 37/37 (was 27 + 10
  ADR-0061 entries); PR-time integrity pass
- node scripts/check-adr-refs.mjs    → 57 valid IDs, 0 dangling
- pnpm lint → 0 errors; typecheck clean; test 239 passed; build clean

Closes: I-01 (Cross-tenant read; Knowlex single-tenant honest scope)

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…paraphrase-fragility (ADR-0062) (#51)

Third graduation in three ships (after T-01 closure / ADR-0060 and
I-01 closure / ADR-0061). The named-but-deferred fix from ADR-0049
§ 8th arc for substring-OR scoring paraphrase fragility ships as an
opt-in faithfulness rubric pass. The honest-disclose TTL discipline
(ADR-0059) is consistently producing closures, three for three.

Module split:
- apps/knowledge/src/lib/judge-rubric.ts (new) — pure module:
  buildJudgePrompt + parseJudgeResponse + aggregateJudgeScores +
  RUBRIC_MIN/MAX + DEFAULT_JUDGE_MODEL constants. No Node-runtime
  entry; lives in src/lib/ so the existing vitest config glob
  discovers the test file.
- apps/knowledge/src/lib/judge-rubric.test.ts (new) — 17 Vitest
  cases pinning prompt construction, response parsing (clean JSON /
  quoted score / code-fenced / trailing prose / unparseable /
  out-of-range / missing reasoning / full RUBRIC_MIN..MAX range),
  aggregate (mean over availables / null exclusion / empty / all-null),
  and the DEFAULT_JUDGE_MODEL = "gemini-2.5-pro" invariant.
- apps/knowledge/scripts/eval.ts — wires --judge CLI flag +
  EVAL_JUDGE=1 env toggle + per-question judgeAnswer call +
  aggregate (judge.meanScore / available / total) into report JSON.

Toggles (equivalent paths):
  node --import tsx scripts/eval.ts --judge
  EVAL_JUDGE=1 node --import tsx scripts/eval.ts
  EVAL_JUDGE_MODEL=<model-id> ... (advanced operator override)

Rubric (integer 0..3, not Likert / not prose):
  3 = correct, fully grounded
  2 = correct but partial
  1 = partially wrong
  0 = wrong / hallucinated / refuses

Output: {"score": N, "reasoning": "<one sentence>"}. Parser tolerates
code-fenced / prose-trailed / quoted-integer responses; non-fatal
parse failures yield score:null (separate aggregate bucket — judge
unavailable doesn't silently penalise the model).

ADR-0046 free-tier compliance preserved:
- Default off; nightly cron continues substring-OR scoring at $0/mo
- gemini-2.5-pro on AI Studio Free tier at 5 RPM / 25 RPD =
  sufficient for one full --judge run per day
- Opt-in via workflow_dispatch / weekly cron / on-demand
- No new SDK; no Vertex AI billable surface

Aggregation honesty:
- judge.available + judge.total exposed so a reviewer can
  distinguish "model is bad" from "judge call kept failing"
- Mean computed over available scores only (nulls excluded from
  denominator)
- Pass/fail threshold for judge mean DEFERRED to a future ratchet
  after 3-5 weekly runs calibrate the steady-state mean —
  v0.5.13 reports the mean as advisory only

Numerics ratchet:
- ADR count 60 → 61
- Vitest 239 → 256 (174 collab + 82 knowledge, +17 from
  judge-rubric.test.ts)
- Banner v0.5.12 → v0.5.13 across 4 docs (portfolio-lp /
  interview-qa / system-overview / runbook)
- _claims.json: 5 ADR-0062 entries (judge-rubric module exists,
  judge-rubric.test.ts exists, default model is gemini-2.5-pro,
  eval.ts honors EVAL_JUDGE env, eval.ts imports judge-rubric)

Local verification:
- node scripts/check-doc-drift.mjs   → 0 failures, 0 warnings
- node scripts/check-adr-claims.mjs  → 42/42 (was 37 + 5 ADR-0062)
- node scripts/check-adr-refs.mjs    → 58 valid IDs, 0 dangling
- pnpm lint → 0 errors; typecheck clean; test 256 passed; build clean

Closes: ADR-0049 § 8th arc Action item (2) — LLM-as-judge --judge flag

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ia RRF (ADR-0063, closes ADR-0011) (#52)

Fourth graduation in four ships (after T-01 / I-01 / ADR-0049 § 8th
arc closures in v0.5.11 / v0.5.12 / v0.5.13). The largest deferred
ADR-0039 item — ADR-0011's hybrid retrieval plan — ships as a
complement to v0.5.13's --judge mode: hybrid retrieval fixes lexical
recall on keyword-heavy queries (proper nouns / API names / error
codes); --judge fixes scoring on paraphrase-heavy queries.

Schema migration (additive only, 20260428_chunk_fts):
- Generated tsvector column Chunk.tsv = to_tsvector('english', content),
  STORED, maintained by Postgres on every insert/update.
- GIN index Chunk_tsv_gin_idx for sub-millisecond @@ lookups.
- Storage cost ~150-300 bytes per 512-char chunk; negligible at
  portfolio scale.

Lexical retrieval:
- plainto_tsquery('english', $query) — natural-language tokenization
  + stop-word removal.
- ts_rank_cd (cover-density rank) over plain ts_rank — closer to
  BM25's proximity component.
- Same workspace pre-filter shape as the existing pgvector path so
  ADR-0061 access layer holds.

RRF fusion module (apps/knowledge/src/server/rrf.ts, new):
- Reciprocal Rank Fusion at the application layer: 1/(k+rank+1)
  contribution per list with weight + custom-k support.
- RRF_K = 60 per Cormack et al. (2009) canonical default.
- Per-source rank provenance for debug.
- 9 Vitest cases (rrf.test.ts) pin fusion invariants:
  rank preservation / symmetric merge / two-list dominance /
  per-source provenance / weight bias / limit / custom k /
  empty input / id collision.

retrieve.ts wiring:
- HYBRID_RETRIEVAL_ENABLED=1 env flag (default off for v0.5.13
  baseline preservation + run-to-run eval comparability).
- Hybrid path: both lists return up to 2K candidates; fuseRRF
  combines; top-K materialised back from union; vector row
  preferred for the cosine distance, lexical row falls back.
- RetrievedChunk.hybridSources?: Record<string, number> for
  per-source rank provenance.

Schema canary EXPECTED.Chunk extended with the tsv column (ADR-0057
axis 2 catches a stale build that didn't run the migration).

ADR-0011 status: Accepted (planned, deferred) → Fully Accepted
(hybrid + RRF shipped via ADR-0063; Cohere Rerank explicitly
remaining deferred — billable API key would break ADR-0046).

Numerics ratchet:
- ADR count 61 → 62
- Vitest 256 → 265 (174 collab + 91 knowledge, +9 from rrf.test.ts)
- Banner v0.5.13 → v0.5.14 across 4 docs
- _claims.json: 6 ADR-0063 entries (rrf module exists, rrf.test.ts
  exists, retrieve.ts honors HYBRID_RETRIEVAL_ENABLED env, lexical
  uses plainto_tsquery, schema canary covers tsv, FTS migration
  shipped)

Local verification:
- node scripts/check-doc-drift.mjs   → 0 failures, 0 warnings
- node scripts/check-adr-claims.mjs  → 48/48 (was 42 + 6 ADR-0063)
- node scripts/check-adr-refs.mjs    → 59 valid IDs, 0 dangling
- pnpm lint → 0 errors; typecheck clean; test 265 passed; build clean

Closes: ADR-0011 hybrid retrieval (Cohere Rerank still deferred)

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…(ADR-0064) (#53)

Calibration attempt for v0.5.14 hybrid retrieval (ADR-0063) surfaced an
architectural gap rather than producing a numerical lift figure: post-v0.5.12
multi-tenant transition (ADR-0061 line 52) intentionally omits the CI
Credentials provider for Knowlex, so the unauthenticated eval client cannot
ingest fresh corpus on a post-v0.5.12 server (returns 401 UNAUTHENTICATED).

Per ADR-0059 § 3-trigger ratchet rule (incident / external feedback /
2026-Q3 re-audit window), implementing the bypass mechanism in this same
ratchet would be the self-audit-loop trap. Disclose with TTL + accelerator
triggers + named closure path (next-available-NNNN follow-up that ships the
CI Credentials provider for Knowlex by copying the apps/collab triple-gate
pattern, producing the lift figure as a byproduct).

5th graduation cycle seed established: T-01 (v0.5.11) → I-01 (v0.5.12) →
ADR-0049 § 8th arc (v0.5.13) → ADR-0011 (v0.5.14) → calibration-attempt
(this ADR) is now in queue for the 5th closure.

Companion updates:
- ADR-0011 § Implementation status: v0.5.15-rc.0 calibration-status note
- ADR-0063 § Implementation status: calibration-blocked-pending note +
  401-on-post-v0.5.12 caveat against Live exercise command
- _claims.json: 4 ADR-0064 entries (anchor strings in ADR-0061 / eval.ts /
  ADR-0011 / ADR-0063)
- README + portfolio-lp + page.tsx Stat: ADR count 62 → 63
- CHANGELOG: [0.5.15-rc.0] entry

Tag drift cleanup bundled: created and pushed annotated tags v0.5.9 ..
v0.5.14 retroactively (the 6-ship S265 arc shipped via PR-merge only with
no git tag push between ships). git ls-remote --tags origin now shows
v0.5.0 through v0.5.14 reachable.

On-disk attack-surface reduction: cleared the GEMINI_API_KEY value from
apps/knowledge/.env (gitignore'd, was never committed). Ephemeral local
calibration container (docker pgvector/pgvector:pg16) and migrator
Postgres role go away with container teardown.

Verification:
- node scripts/check-doc-drift.mjs   → 0 failure (ADR 63, Vitest 265)
- node scripts/check-adr-claims.mjs  → 52/52 pass, 0 failure
- node scripts/check-adr-refs.mjs    → 0 dangling

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…i Free tier revocation incident response (ADR-0067) (#54)

* feat(v0.5.15): CI Credentials provider for Knowlex (ADR-0065) + Gemini Free tier revocation incident response (ADR-0067)

Two ADRs ship in this single ratchet:

1. ADR-0065 — CI Credentials provider for Knowlex, mirroring apps/collab
   ADR-0038 triple-gate (VERCEL!=1 + E2E_ENABLED=1 + E2E_SHARED_SECRET).
   End-to-end signin verified during this ratchet. Closes the
   architectural-gap half of ADR-0064. Exports e2eGateOpen predicate
   for unit testing (9 Vitest cases pinning gate semantics + email
   allowlist). Build-time assertion in next.config.ts as additional
   defense layer (VERCEL=1 + E2E_ENABLED=1 → throw on next build).
   Auto-upsert E2E user in authorize() callback (Knowlex has no
   prisma seed.ts; idempotent + triple-gated upstream so unreachable
   on prod).

2. ADR-0067 — 2026-04-29 production incident report. Google AI Studio
   silently revoked Free tier access at the account level for the
   leagames0221@gmail.com account (Billing Tier "Free tier" →
   "Unavailable" within 24h, no email/banner/notification per Google
   abuse-detection policy). Both craftstack-knowlex (origin) and a
   freshly-created craftstack-knowlex-v2 inherit the revoked state,
   confirming account-level enforcement. Diagnostic probes (Vercel
   function logs, AI Studio Project listing, AI Studio Usage page)
   ruled out cumulative-account-history but cannot differentiate
   among policy sweep / multi-geo IP fingerprint / content-safety
   filter cascade as the actual trigger — Google's standard policy
   is to not disclose. Recovery design must therefore be resilient
   to "any free-tier provider can revoke at any time without
   explanation" rather than fix a specific identified trigger.

Containment: ADR-0046 EMERGENCY_STOP kill-switch on the Knowlex
Vercel project Environment Variables → /api/kb/{ask,ingest} return
503 EMERGENCY_STOPPED instead of cascading 500s. Runbook in
ADR-0067 § Decision item 1.

Calibration scope pivot: ADR-0064's lift-figure half cannot ship
in this ratchet because the eval flow needs a working LLM key.
Instead of bundling alt-LLM provider migration into the same
ratchet (ADR-0059 § 3-trigger ratchet rule + scope discipline),
the calibration is reframed as BYOK-reproducible: any operator
with a Gemini-compatible (or 768-dim alternative such as
Cloudflare Workers AI bge-base-en-v1.5) API key can run
`pnpm --filter knowledge eval` locally and produce the lift
figure. README's new "Run Knowlex locally with your own API key
(BYOK)" section documents the 5-line setup. Recovery ratchet
(alt-LLM provider migration) is named in ADR-0067 § Decision
item 3 as needs-driven optional follow-up — not committed.

5th graduation cycle structure preserved: ADR-0064 disclose →
ADR-0065 architectural-gap closure → ADR-0067 incident response →
BYOK landing as the closure path.

Companion doc updates:
- ADR-0064 § Status: architectural-gap half closed by ADR-0065;
  lift-figure half BYOK-reproducible per ADR-0067.
- docs/adr/README.md: index entries for ADR-0065 + ADR-0067.
- docs/adr/_claims.json: 9 new entries (ADR-0065 ×5 + ADR-0067 ×4).
- README.md: Live demo section pivoted to EMERGENCY_STOPPED notice
  + BYOK runbook + ADR-0067 link; ADR count 63→65; Vitest 265→274;
  tests badge 265+24 → 274+24.
- docs/hiring/portfolio-lp.md + docs/hiring/interview-qa.md +
  docs/architecture/system-overview.md + docs/ops/runbook.md:
  status banner v0.5.14 → v0.5.15 + Knowlex EMERGENCY_STOP note.
- apps/collab/src/app/page.tsx + layout.tsx + opengraph-image.tsx:
  Stat row + metadata + OG image numerics 265→274; ADR 63→65.
- apps/knowledge/.env: GEMINI_API_KEY value cleared post-incident
  (gitignore'd, never committed).

Numerics:
- ADR count 63 → 65
- Vitest 265 → 274 (174 collab + 100 knowledge; +9 from
  apps/knowledge/src/auth/config.test.ts)
- Banner version v0.5.14 → v0.5.15

Verification:
- node scripts/check-doc-drift.mjs   → 0 failure
- node scripts/check-adr-claims.mjs  → 61/61 pass
- node scripts/check-adr-refs.mjs    → 0 dangling
- pnpm --filter knowledge test       → 100 passed (was 91)

User-side production action required for full ratchet release:
- Vercel project Knowlex Environment Variables → add EMERGENCY_STOP=1
  (Production + Preview) and Redeploy. ADR-0067 § Decision item 1
  documents the runbook.
- Verify post-redeploy: curl /api/kb/ask returns 503 with
  {"code":"EMERGENCY_STOPPED"} instead of cascading 500s.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(v0.5.15): widen e2eGateOpen param type to satisfy strict ProcessEnv

The CI typecheck (`tsc --noEmit` on apps/knowledge) failed because
recent @types/node versions added `NODE_ENV` as a required field on the
global `NodeJS.ProcessEnv` interface. The `e2eGateOpen(env)` predicate
only reads `VERCEL` / `E2E_ENABLED` / `E2E_SHARED_SECRET`; tests passed
narrow env shapes which no longer satisfied the global ProcessEnv
contract.

Fix: widen the parameter type to `Record<string, string | undefined>`.
The runtime contract is unchanged (process.env still works as the
default); only the test-callable surface relaxes. Comment in the
function explains the rationale.

Verification:
- pnpm --filter knowledge typecheck → clean
- pnpm --filter knowledge test → 100 passed (no regression)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Docs-only ratchet aligning portfolio surface signal (30-second-probe
reviewer view of README + portfolio-lp top-of-page) with depth signal
(deep reviewer of ADR sequence + repo structure). Three Senior-tier
dimensions previously inferred-only become explicit prose claims with
structural evidence pointers.

Refinements:
- Refine 1: README BYOK runbook claim "Five steps, ~2 minutes" →
  "5-step BYOK runbook (~5 min total)" with per-step time estimate.
  Honest accuracy over aspirational under-count.
- Refine 2: Knowlex live-demo URL annotated with front-loaded BYOK
  link so a 30-second probe reviewer sees the BYOK option without
  scrolling. EMERGENCY_STOPPED state stays explicit.
- Refine 3: README + portfolio-lp gain "Built with AI pair-programming
  (Claude Code)" narrative. 46 of 187 commits carry Co-Authored-By:
  Claude Opus 4.7 (1M context) marking — explicit claim with
  structural evidence, not inference.

Brand-surface front-loading:
- Surface 1: README + portfolio-lp gain "5 closed graduation cycles in
  5 ships" callout enumerating T-01 / I-01 / ADR-0049 § 8th arc /
  ADR-0011 / ADR-0064 with closure-ADR links. The graduation cycle
  pattern (KL-build_ci-202604-graduation-cycle) is the portfolio's
  brand-defining engineering-culture artifact; surfacing it
  explicitly converts depth-only signal to also-30-second-reader
  signal.
- Surface 2: README + portfolio-lp gain "Real production incident
  response record (2026-04-29)" callout. ADR-0067 documents the
  Gemini Free tier revocation + ADR-0046 EMERGENCY_STOP containment +
  BYOK pivot. Senior+ reviewers always ask "have you handled real
  production incidents?"; this answers with structural evidence.
- Surface 3: README gains "Framework is structurally enforced, not
  declared" callout. ADR-0058 branch-protection ruleset rejected the
  author's own `git push origin main` attempts during ratchets S266 +
  S267 (PR #53 + #54 commit history). Framework foundation axiom
  operating live.

Status banner sync: docs/hiring/portfolio-lp.md + interview-qa.md +
docs/architecture/system-overview.md + docs/ops/runbook.md advance
v0.5.15 → v0.5.16.

Why this is docs-only, not feature ratchet:
- No code changes. No new tests, no new ADRs.
- ADR-0059 § 3-trigger ratchet rule preserved: this ratchet is
  external-feedback-shaped (user surfaced the surface-vs-depth gap
  and asked whether refinement was worth doing). Not self-audit-loop.
- Scope deliberately bounded to ~1 page of prose across 6 files.

Numerics (unchanged):
- ADR count remains 65 (no new ADRs).
- Vitest remains 274 (no test changes).
- Banner version v0.5.15 → v0.5.16.

Verification:
- node scripts/check-doc-drift.mjs   → 0 failure
- node scripts/check-adr-claims.mjs  → 61/61 pass
- node scripts/check-adr-refs.mjs    → 0 dangling

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tag drift fix (#56)

External-feedback-shaped: explicit critical-issue scan surfaced 3 classes
of drift in v0.5.16 portfolio prose against the actual ADR sequence.

Class 1: Single-tenant / "deferred to v0.5.4" stale claims
- ADR-0061 v0.5.12 shipped multi-tenant access control (Auth.js +
  Membership + demo allow-list); the following stale claims contradicting
  that closure were updated:
  - README.md:135 Apps table Knowlex row → Multi-tenant + ADR-0061 +
    ADR-0063 + ADR-0065 references; Gemini 2.0 → 2.5 Flash
  - docs/hiring/portfolio-lp.md:26 header → Multi-tenant RAG header
  - docs/hiring/portfolio-lp.md:28 body → ADR-0061/0063/0065/0067 inline
  - docs/hiring/portfolio-lp.md:11 status block → multi-tenant inline
  - docs/hiring/interview-qa.md Q5/Q9/Q11/Q23 → contextually updated
  - docs/architecture/system-overview.md:60 Auth row → multi-tenant
  - docs/architecture/system-overview.md:78 request-path → multi-tenant
  - docs/architecture/system-overview.md:90 RLS deferred reasoning → cite
    ADR-0061 application-side enforcement choice

Class 2: Gemini model version sync (2.0 Flash → 2.5 Flash)
- README.md + portfolio-lp + interview-qa + system-overview + runbook all
  references advanced to Gemini 2.5 Flash. ADR-0062 + ADR-0063 already
  cite Gemini 2.5 series; the prose simply lagged.

Class 3: Git tag drift cleanup
- v0.5.15 + v0.5.16 squash-merged via PRs #54 + #55 but no git tag step in
  the chain. Retroactively created annotated tags:
  - v0.5.15 → 6573391 (ADR-0065 + ADR-0067 ship)
  - v0.5.16 → 9aa8bd4 (narrative alignment)
- Pushed to origin in this ratchet so reviewer sees v0.5.0..v0.5.16
  continuously.

Why docs-only:
- No code changes. No new tests, no new ADRs.
- ADR-0059 § 3-trigger ratchet rule preserved: external-feedback-shaped
  (critical-issue scan surfaced specific drift instances).

Numerics: ADR count 65 unchanged, Vitest 274 unchanged, banner v0.5.16 →
v0.5.17 across portfolio-lp + interview-qa + system-overview + runbook.

Verification:
- node scripts/check-doc-drift.mjs   → 0 failure
- node scripts/check-adr-claims.mjs  → 61/61 pass
- node scripts/check-adr-refs.mjs    → 0 dangling

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…xivity (ADR-0068) (#57)

* feat(v0.5.18): Run #5 hiring-sim findings closure + attestation reflexivity (ADR-0068)

Hiring-sim Run #5 (methodology v2 against v0.5.17 / 7a93898) returned `hire`,
NOT the expected `strong hire`. Three drift findings surfaced; this ratchet
closes them structurally + records the methodology v3 candidate.

Finding A — auto-attestation reflexivity (load-bearing):
`/api/attestation.scope.deferred[]` listed Hybrid search with adr=ADR-0011
while ADR-0011 Status reads "Fully Accepted ... shipped in v0.5.14". The
endpoint built to expose audit-survivable truth was lying about its own
ADR. Closed via:
- Removed Hybrid from scope.deferred[] (shipped per ADR-0063)
- Added scope.shippedFlagGated[] section (records original adr + closingAdr +
  shippedIn + flag + flagDefault)
- Updated Cohere Rerank reason to ADR-0046 (independent of v0.5.14 ship)
- Updated PostgreSQL RLS reason to ADR-0061 multi-tenant (replacing stale
  "Knowlex is single-tenant per ADR-0039")
- New vitest reflexivity assertion: scope.deferred[] entries cannot have
  ADR Status = Fully Accepted unless feature is explicitly carved out
- New shippedFlagGated[] schema test
- system-overview.md "what is NOT in this diagram" hybrid bullet now
  describes shipped + flag-gated default-off rather than deferred

Finding B — methodology v3 candidate (no portfolio change):
Simulator's grep-based Vitest count (`grep -hcE '^\s*(test|it)\('`) returned
258, reporting drift vs README's 274. Actual count via `pnpm exec vitest run
--reporter=json` = 174 collab + 100 knowledge = 274. README correct; grep
undercounts by missing test.each([...]) row-multiplied cases. Existing
check-doc-drift.mjs already uses vitest's actual count via vitestCount(app)
— gate would have caught real drift. Methodology hole, not portfolio bug.
Recorded for v3 in ADR-0068 § Decision item B + postmortem doc 64.

Finding C — README-vs-CSP coherence gate:
Live script-src includes 'unsafe-inline' AND 'unsafe-eval', but README:175
only mentioned 'unsafe-inline'. (ADR-0040 itself was already correct.) Closed:
- README:175 disclosed both directives + rationale
- next.config.ts comment block enumerates both + references new gate
- New scripts/check-csp-coherence.mjs PR-blocking forward gate: every
  load-bearing CSP directive ('unsafe-inline', 'unsafe-eval', 'strict-dynamic',
  'wasm-unsafe-eval') in next.config.ts must appear in README "Security
  headers" bullet
- Wired into ci.yml doc-drift-detect job

Meta-finding (Decision item D):
"the framework missed live drift in its own attestation endpoint" —
ADR-0057's 13-axis framework gains a 14th: framework-as-its-own-substrate.
Vitest reflexivity + new CSP gate are the structural mechanism.

Net delta:
- ADR count 65 → 66 (ADR-0068 added)
- Vitest count 274 → 276 (2 new reflexivity tests in attestation-data.test.ts)
- Knowledge subtotal 100 → 102
- Version banners v0.5.17 → v0.5.18 across 5 docs
- attestation-data.json now references tag=v0.5.18 commit=7a93898a adr=66
- CHANGELOG + ADR-README index updated

Verification (all 5 PR-time gates green):
- check-doc-drift.mjs: 0 failure(s), 0 warning(s) ✓
- check-adr-refs.mjs: 63 valid IDs, 0 dangling ✓
- check-adr-claims.mjs: 61/61 claim(s), 0 failure(s) ✓
- check-csp-coherence.mjs: 0 failure(s), 2 directives checked ✓
- check-free-tier-compliance.mjs: passed ✓
- vitest attestation-data.test.ts: 7/7 pass (5 existing + 2 new reflexivity)

Run #6 against v0.5.18 with v2 methodology expected to clear `strong hire`
(Findings A + C closed structurally; Finding B was methodology bug, not
portfolio bug). Closes the gap between simulator's "real senior-tier
portfolio" closing line and the verdict-rule's `strong hire`.

Refs ADR-0068, ADR-0054, ADR-0056, ADR-0057, ADR-0040, ADR-0011, ADR-0061.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(v0.5.18): add ADR-0068 claim entries to _claims.json

5 new claim entries close the PR-time integrity check that requires
new ADRs to touch _claims.json:
1. CSP coherence gate exists (scripts/check-csp-coherence.mjs)
2. CSP coherence gate is wired into ci.yml doc-drift-detect job
3. attestation-data scope.deferred[] reflexivity assertion exists in vitest
4. attestation-data.json scope.shippedFlagGated section is generated
5. README discloses 'unsafe-eval' alongside 'unsafe-inline' (Finding C)

ADR-claim count 61 → 66; ADR-claim summary now 66/66 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rface coverage extension (ADR-0069) (#58)

Hiring-sim Run #6 (methodology v2 against v0.5.18 / 3cbdb83) returned `hire`,
NOT `strong hire`. Run #6 confirmed the ADR-0068 closure shipped (Stage 3
row 12: scope.shippedFlagGated[0] = Hybrid retrieval ✓), but surfaced a NEW
drift class: visible deploy front-door surfaces carried "Gemini 2.0 Flash" /
"text-embedding-004" while apps/knowledge/src/lib/gemini.ts exports
gemini-2.5-flash + gemini-embedding-001. Brand-foundation drift on the
most visible portfolio surface.

8 findings (D1-D8); this ratchet closes 6 structurally + defers 2.

Finding D1 + D8 — Deploy-visible-surface coverage extension (load-bearing):
- 17 deploy-visible surface files synced to canonical models:
  apps/collab/src/app/{page,layout,opengraph-image,status/page,
  playground/page,playground/PlaygroundClient}.tsx, kb-demo.ts,
  humans.txt, openapi{,-types}.ts; apps/knowledge/src/app/{page,kb/page}.tsx,
  openapi.ts, api/kb/ask/route.ts, README.md, prompts/registry.json + 6 *.md;
  docs/architecture/system-overview.md
- Also closed v0.5.17-cleanup-leak in apps/collab/src/app/page.tsx:84-88
  (stale "single-tenant / deferred to v0.5.4" → multi-tenant per ADR-0061)
- Sub-app README updated for stale "single-corpus, tenantless / Pure cosine
  kNN" claims (post-v0.5.12-v0.5.14 actuality: multi-tenant + hybrid +
  EMERGENCY_STOPPED)
- New scripts/check-doc-drift.mjs axis: "Visible-deploy-surface model name
  coherence (ADR-0069)" — enumerates 17 surfaces + asserts none contain
  stale model patterns (Gemini 2\.0 Flash, gemini-2\.0-flash,
  text-embedding-004). Canonical truth from apps/knowledge/src/lib/gemini.ts
- Allowed exceptions documented (gemini.ts migration narrative, chunking.ts
  historical tuning, eval.ts historical comment, migration.sql snapshot,
  ADR-0067 incident report, CHANGELOG entries)

Finding D2 — ADR-0068 self-correction (drift inside drift-closure ADR):
ADR-0068 line 13 had "174 + 100 = 274" while post-v0.5.18 reality became
174+102=276 (the 2 reflexivity tests added in ADR-0068 itself shifted
knowledge subtotal during the same ratchet). Self-correction note added
to ADR-0068 line referencing this ADR-0069 § D2.

Finding D3 + D4 — ADR Status field drift:
- ADR-0010 (RLS) Status: Accepted → "**Partially superseded — RLS deferred**"
  per ADR-0061 multi-tenant transition
- ADR-0003 (DB session) Status: Accepted → "**Superseded by JWT strategy in
  practice**" with cross-ref to README ADR-index Supersession notice
- Both index rows in docs/adr/README.md updated

Finding D6 — ADR sequence gap notice:
docs/adr/README.md gains explicit notice that ADR-0055 + ADR-0066 are
intentionally unused / reserved (0055 = withdrawn during v0.5.10 framework
freeze; 0066 = reserved per ADR-0067 § Decision item 3 for alt-LLM provider
migration recovery)

Finding D5 + D7 — Deferred:
- D5 (cronHealthHint × EMERGENCY_STOP cross-ref) requires runtime logic
  refinement; recorded as next-available-NNNN follow-up
- D7 (commit count drift 187→190) auto-resolves via post-merge propagation;
  intentionally a snapshot, not continuously-updated

Methodology v3 sub-axis added:
ADR-0069 § Decision item E adds "Stage 2.7 — Deploy-visible-surface coverage
parity" to the v3 methodology candidate (already extended by ADR-0068 §
Decision item B).

Net delta:
- ADR count 66 → 67 (ADR-0069 added)
- ADR-claim count 66 → 72 (6 new ADR-0069 claim entries)
- Vitest count 276 unchanged (no new tests; ADR-0068 self-correction is
  text-only)
- Version banners v0.5.18 → v0.5.19 across 5 docs
- attestation-data.json regenerated: tag=v0.5.19, adr=67

Verification (all 5 PR-time gates green):
- check-doc-drift.mjs: 0 failure(s) ✓ (incl. new model coherence axis)
- check-csp-coherence.mjs: 0 failure(s) ✓
- check-adr-refs.mjs: 64 valid IDs, 0 dangling ✓
- check-adr-claims.mjs: 72/72 ✓
- check-free-tier-compliance.mjs: passed ✓

Run #7 against v0.5.19 expected to clear `strong hire` (front-door deploy
drift class structurally pinned, brand-reflexivity multiplier trigger
removed).

Refs ADR-0069, ADR-0068, ADR-0054, ADR-0057, ADR-0010, ADR-0003,
ADR-0061, ADR-0067.

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Existing ci.yml runs `pnpm audit --audit-level moderate || true`
(intentionally non-blocking for general moderate notices).
This new workflow runs `pnpm audit --audit-level=high` and
**fails** on high+ severity, providing a stricter gate for
supply-chain dependency hygiene.

Triggered on push, PR, weekly cron, manual dispatch.
Uses corepack-resolved pnpm (matches package.json packageManager).

Co-authored-by: leagames0221-sys <leagames0221-sys@users.noreply.github.com>
@dependabot @github

dependabot Bot commented on behalf of github May 11, 2026

Copy link
Copy Markdown
Contributor Author

Labels

The following labels could not be found: dependencies. Please create it before Dependabot can add it to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

@dependabot
dependabot Bot requested a review from leagames0221-sys as a code owner May 11, 2026 00:28
@vercel

vercel Bot commented May 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
craftstack-collab Ready Ready Preview, Comment May 16, 2026 10:13am
craftstack-knowledge Ready Ready Preview, Comment May 16, 2026 10:13am

leagames0221-sys and others added 3 commits May 12, 2026 02:16
…des (fast-uri, hono) (#75)

Resolves pnpm audit failures on main (2/2 FAIL → expected GREEN after merge).

## Vulnerabilities closed (audit literal verify)

Before: 22 vulns (3 low + 10 moderate + 9 high)
After:   2 vulns (0 low +  2 moderate + 0 high) → `pnpm audit --audit-level=high` exit 0

### High severity (7) — all in next.js 16.2.4
- GHSA-8h8q-6873-q5fj: DoS via Server Components (patch ≥16.2.5)
- GHSA-26hh-7cqf-hhc6: Middleware/Proxy bypass via segment-prefetch (patch ≥16.2.6)
- GHSA-mg66-mrh9-m8jx: DoS via connection exhaustion in Cache Components (patch ≥16.2.5)
- GHSA-c4j6-fc7j-m34r: SSRF via WebSocket upgrades (patch ≥16.2.5)
- GHSA-492v-c6pp-mqqv: Middleware/Proxy bypass via dynamic route param injection (patch ≥16.2.5)
- GHSA-267c-6grr-h53f: Middleware/Proxy bypass in App Router segment-prefetch (patch ≥16.2.5)
- GHSA-36qx-fr4f-26g5: Middleware/Proxy bypass in Pages Router using i18n (patch ≥16.2.5)

→ Bump next from 16.2.4 → 16.2.6 in apps/collab + apps/knowledge package.json (covers all 7)

### Transitive deps (fast-uri, hono) — pnpm overrides
- fast-uri: high × 2 path-traversal + host-confusion (patch ≥3.1.2)
- hono: 3 vulns in Prisma dev tooling (patch ≥4.12.18)

→ Add to root package.json `pnpm.overrides` (transitive deps, can't update via direct dep)

## Local verify PASSED (D-WRANGLER-LOCAL-FIRST 一般化、 pre-push verification)

- `pnpm install` → lock regenerated, 0 errors
- `pnpm lint` → 0 errors (4 pre-existing warnings unrelated to this change)
- `pnpm typecheck` → 0 errors
- `pnpm test` → 174 / 174 PASS (26 test files)
- `pnpm audit --audit-level=high` → exit 0

## Remaining moderate (2)
Will be tracked separately; not blocking CI (pnpm-audit gate is `--audit-level=high`).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: leagames0221-sys <leagames0221@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps [zod](https://github.com/colinhacks/zod) from 4.3.6 to 4.4.3.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](colinhacks/zod@v4.3.6...v4.4.3)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.4.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot @github

dependabot Bot commented on behalf of github May 21, 2026

Copy link
Copy Markdown
Contributor Author

OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting @dependabot ignore this major version or @dependabot ignore this minor version. You can also ignore all major, minor, or patch releases for a dependency by adding an ignore condition with the desired update_types to your config file.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/zod-4.4.3 branch May 21, 2026 17:17
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.

1 participant