Skip to content

Open-source readiness: full codeyam alignment, the OSS document set, and CI - #1

Merged
jaredcosulich merged 7 commits into
mainfrom
open-source-release
Jul 16, 2026
Merged

jaredcosulich merged 7 commits into
mainfrom
open-source-release

Conversation

@jaredcosulich

Copy link
Copy Markdown
Contributor

Brings el-carot to a clean, contributable public repository. Two halves: aligning
the repo (audit 61 findings → 0, first ever whole-repo finalize) and adding what a
public project needs (CI, CONTRIBUTING, SECURITY, templates).

Nothing here changes what the app does. The only behavioural edits are two React
correctness fixes, both verified against the running app and both re-rendering
byte-identical scenarios.

Why it was needed

lastFullFinalizeSha was null — this repo had never had a whole-repo
finalize. Every commit was gated diff-only via Fast Commit, so debt in untouched
files was never discharged. Along the way that surfaced several things that were
simply broken:

Found Reality
npm run lint Died on startup. eslint-config-next pinned to ^15 while next is ^16; it had never run.
tsc 7 errors from an ungenerated Prisma client.
AUTH_PATTERNS.md + AUTH_UPGRADE.md 623 lines documenting an app/lib/auth.ts that does not exist. This app has no user auth.
DATABASE.md Said SQLite and walked through a Postgres migration the project had already done.
.env.example The README told you to copy it. It didn't exist — and .env* would have swallowed it.
8 runtime-state files Committed (step pointers, timing history, an auth verdict).
stack.json Declared prisma-sqlite while running Postgres.

Alignment (61 → 0 findings)

  • Glossary +22 (48 → 70). Pure helpers cite a real testFile; DB boundaries use
    platform-glue; one-line context re-exports use trivial-wrapper.
  • Tests 26 → 37. New lib/geo.test.ts (header parsing, UTC-day identity at
    boundaries) and data/cards.test.ts (ES/EN resolution, English fallback,
    non-empty text for all 22 arcana in both languages).
  • Scenarios +12 (49 total). Isolation routes and component scenarios for
    HomeDeckStrip, HomeTitle, NavRightCluster, StatsLogin, Section,
    MenuProvider, plus an application scenario for the /stats password gate.

The two React fixes

Lint, once it ran, found 3 real errors (the other 25 were inside .codeyam/ —
editor-generated cache, now ignored like node_modules).

  • MessageIntro read startX.current during render to choose between
    animating and tracking the finger. Now mirrored in state. Verified live: the
    transition is 0.34s at rest, 0s mid-drag, 0.34s on release, and a swipe
    still advances the deck 12 → 13.
  • CardReading reset the flip and the interpretation with synchronous
    setState inside effects (cascading renders). Both now use React's documented
    adjust state during render pattern; the effects keep only the timer and the
    fetch. All five affected scenarios re-render byte-identical.

Lint is now a blocking CI step at zero errors — it broke in the first place
precisely because nothing ran it.

CI

Every step was reproduced locally with no .env and no DATABASE_URL — the
environment CI actually gets — so the badge is green on its first run. No Postgres
service needed: no test touches the database, and next build doesn't either.

Reviewing this

187 files, but most are editor-managed. The human-sized surface is:

  • components/CardReading.tsx, components/MessageIntro.tsx — the two fixes
  • eslint.config.mjs, .github/workflows/ci.yml — lint repair + CI
  • DATABASE.md, CONTRIBUTING.md, SECURITY.md, README.md, .env.example — docs
  • app/stats/page.tsx — one added export so Section can be isolated

🤖 Generated with Claude Code

https://claude.ai/code/session_01Etkh5xsDjHQqzCdR65gcj5

jaredcosulich and others added 7 commits July 16, 2026 14:12
…ease

Drives the whole-repo audit from 61 findings to 0. This branch had never had a
full branch-wide finalize (lastFullFinalizeSha was null) — every commit was
gated diff-only via Fast Commit, so whole-repo debt in untouched files was
never discharged.

Glossary (22 new entries, 48 -> 70)
- Registers every unregistered top-level entity. Pure helpers cite a real
  testFile; DB boundaries use platform-glue; one-line context re-exports and
  presentational formatters use trivial-wrapper.

Tests (26 -> 37)
- lib/geo.test.ts: geoFromHeaders header/null handling, utcDateKey UTC-day
  identity at boundaries.
- data/cards.test.ts: cardText ES/EN resolution, English fallback, and
  non-empty text for all 22 arcana in both languages.

Scenarios (12 new, 49 total)
- Component scenarios + isolation routes for HomeDeckStrip, HomeTitle,
  NavRightCluster, StatsLogin, Section, MenuProvider; an application scenario
  for the /stats password gate.
- Section is now exported so it can be isolated (it is the stats page's table
  block; isolate can only import a module's default export otherwise).
- StatsLogin captures set expectedConsoleErrors: the capture harness runs in a
  cross-origin subframe, where the browser blocks the password field's
  autoFocus. That is a harness artifact, not an app defect.

Docs
- Deletes AUTH_PATTERNS.md, AUTH_UPGRADE.md, FEATURE_PATTERNS.md: 623 lines of
  project-template docs describing an app/lib/auth.ts that does not exist. This
  app has no user auth (models are Comment, DailyCard, Question, Visit).
- Rewrites DATABASE.md, which described SQLite and walked through a
  "upgrade to Postgres" migration this project already completed. It now
  documents the real setup: Prisma 7 on PostgreSQL via @prisma/adapter-pg,
  and calls out that `prisma db push` does not generate the client.
- package.json: adds "license": "MIT" to match LICENSE, renames the scaffold
  placeholder "codeyam-project" to "el-carot".

Fixes
- .codeyam/stack.json declared seedAdapterType "prisma-sqlite" while the
  project runs Postgres.
- Untracks ui/stepLabels.generated.ts (editor artifact, nothing imports it) and
  8 codeyam runtime-state files that must not be committed.
- Redacts a collaborator's absolute path from a journal entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Etkh5xsDjHQqzCdR65gcj5
session-finalize's own `chore: update codeyam state` commit picked up
.codeyam/.locks/session-finalize.lock while the lock was held; it then showed
as a deletion the moment the lock released. A transient runtime lock should
never be tracked. Ignored below the codeyam-editor marker so install-hooks'
canonical-list sync can't clobber the entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Etkh5xsDjHQqzCdR65gcj5
Adds what a public repo needs, and repairs two things the additions surfaced.

CI (.github/workflows/ci.yml)
- Typecheck, lint, test, build on every push and PR. Every step was reproduced
  locally with no .env and no DATABASE_URL — the environment CI actually gets —
  so the badge is green on its first run. No Postgres service is needed: no test
  touches the database, and `next build` does not either.
- Generates the Prisma client explicitly; without it tsc fails with
  "Module '@prisma/client' has no exported member 'PrismaClient'".

Lint was completely broken, and is now enforced
- eslint-config-next was pinned to ^15 while next is ^16. v15 exported legacy
  eslintrc objects from the subpaths eslint.config.mjs imports, so `npm run lint`
  died on startup ("nextVitals is not iterable") and had never run.
- Aligning it to ^16 made lint run, revealing 87 problems. 25 of the 28 errors
  were inside .codeyam/ — the editor's generated capture scripts and design
  bundle, which are internal cache state, not app source. Ignoring that directory
  (as node_modules already is) leaves 3 real errors, all fixed:
    * MessageIntro read `startX.current` during render to choose between
      animating and tracking the finger. A ref read during render isn't
      guaranteed to re-render when it changes (react-hooks/refs); the drag is now
      mirrored in state. Verified against the running app: the transition is
      0.34s at rest, 0s mid-drag, and 0.34s again on release, and a swipe still
      advances the deck.
    * CardReading reset the flip and the interpretation with synchronous
      setState inside effects, triggering cascading renders
      (react-hooks/set-state-in-effect). Both now use React's documented
      "adjust state during render" pattern; the effects keep only the timer and
      the fetch. All five affected scenarios re-render byte-identical.
  Lint is now a blocking CI step at zero errors — it broke in the first place
  precisely because nothing ran it.

Documents
- CONTRIBUTING.md: real setup and the four checks, including the prisma-generate
  gotcha and how to recapture scenarios (with the 2x preview-env trap).
- CODE_OF_CONDUCT.md: canonical Contributor Covenant 2.1, contact support@codeyam.com.
- SECURITY.md: private reporting, with scope naming the coarse-geo contract.
- Issue forms + PR template tied to the gates CI actually runs.
- README: CI and license badges, a hero screenshot, a contributing pointer, and
  an env table that no longer lists DATABASE_URL_UNPOOLED — nothing reads it.

.env.example
- The README already told contributors to `cp .env.example .env`, but the file
  did not exist and the `.env*` rule would have swallowed it. Adds the annotated
  template and a `!.env.example` negation, keeping real .env ignored.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Etkh5xsDjHQqzCdR65gcj5
@jaredcosulich
jaredcosulich merged commit f5f6d32 into main Jul 16, 2026
1 check passed
@jaredcosulich
jaredcosulich deleted the open-source-release branch July 16, 2026 21:19
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