CareerOS

Notices when you ship, and drafts résumé and LinkedIn lines from evidence it can cite.

Role
Sole developer: product, design, web app, worker, database, public API and SDK, deployment script
Dates
Oct 2026 – present
Status
Private pilot live
Stack
Next.js, PostgreSQL · 529 tests
CareerOS on a laptop and a phone: a review screen with a drafted résumé line for a v1.3.0 release, the evidence it cites and an Approve button.
  • CareerOS’s Start here queue with two numbered items, each with a Review button and what needs confirming.
  • A CareerOS draft beside the evidence it cites.
  • CareerOS on a laptop and a phone: a review screen for “Released Recitation coach v1.3.0” with the drafted résumé line, what each change would update, and an Approve 3 texts button.
  • CareerOS’s LinkedIn hand-off: a caption to copy and a generated share card.
  • Three phone screens of CareerOS: Desk, Review and Channels.

Technical decisions

DecisionWhat I choseInstead of
Strict gating when drafted lines lack verified evidenceHalt automated export and flag unsupported claims for explicit human reviewPublishing unverified drafts automatically or silently omitting dubious claims

Results

tests passing
529
checks on every draft
7
unsupported claims in 20 drafts
0

From the 21 October 2026 handoff. Demo account with fictional data.

Full engineering notes

7 sections, about 3 minutes to read

Summary

CareerOS is an evidence-first career record. It notices when you ship, through GitHub releases and merged pull requests, and drafts résumé lines, site news, GitHub README text and LinkedIn captions only from facts it can cite. Nothing is published until you approve it. Seven code-level checks run before a draft reaches you: numbers, attribution, citations, privacy, links, length and style, and anything the AI inferred stays marked until confirmed. I built the whole thing: a Next.js web app, a worker, the core and database packages, a public API and SDK, and a web component for a portfolio site. It is live as a private pilot on Google Cloud in Singapore, with the landing, sign-in and sign-up pages, a health check and background jobs running, and it is not open to the public yet.

The problem

A résumé, a portfolio, a GitHub profile and a LinkedIn page all go stale the moment you ship something, and updating four places by memory means the numbers drift.

  • Work you ship leaves evidence (releases, merged pull requests) that nobody turns into résumé lines.
  • Generated career text invents numbers and claims, so every draft needs a check against its source.
  • Nothing about a person’s record should go public without their approval.
  • CareerOS currently prepares a caption and share card for the user to publish manually, keeping the user in full control of their feed rather than posting directly via the LinkedIn API.

My role

What I owned

  • The product: a “Start here” queue that says why each item is there, with no scores or streaks, and a review screen with approve, snooze and dismiss.
  • The draft pipeline and its seven checks, with a 20-draft evaluation that measures unsupported claims.
  • The pnpm monorepo: web app, worker, core, db, server and SDK packages, plus a public API, feeds and a portfolio web component.
  • The LinkedIn hand-off with a generated share card and ready-to-copy caption for manual publishing, a managed GitHub README block and résumé export.
  • The Google Cloud deploy script and the private pilot it runs in Singapore.

What I did not own

  • Next.js, Postgres, Drizzle, Better Auth and the other open-source tools it is built on.
  • Nobody outside the pilot has used it yet; the screenshots use a demo account with fictional data.
  • “CareerOS” is a working name, not a final brand.

Why I made each decision

Strict gating when drafted lines lack verified evidence

Because

AI drafts frequently hallucinate metrics or overstate responsibilities. When a drafted résumé or LinkedIn claim cannot be mapped to an explicit fact in merged commits or release notes, the pipeline blocks publication, highlights the unverified claim with a warning badge, and requires manual confirmation or deletion.

Trade-off

Users must manually review and resolve flagged items before exporting, trading zero-click automation for 100% verifiable fidelity.

Testing

On 21 October 2026, 529 tests in 59 files passed, with typecheck clean across 7 packages and lint at 0 errors. The last full browser run passed 54 end-to-end tests.

Tests passing
529
Playwright end-to-end tests
54
Unsupported claims in 20 drafts
0

Results in detail

  • Drafts that cite their evidence

    Every draft links to the release or pull request it came from and passes seven checks before review. In an evaluation across 20 synthetic drafts constructed from fictional development histories, relevance precision and recall were 1.00, the unsupported-claim rate was 0.00 (any drafted fact, metric, or role without explicit backing in the source commit/PR was flagged as unsupported), and the gate caught all 22 of 22 planted adversarial hallucinations.

  • Live as a private pilot

    A one-command Google Cloud deploy put the web app, database and scheduler live in Singapore. The landing, sign-in, sign-up and share-card pages load, background jobs run every minute and the job route refuses calls without its secret. One fix came out of checking it: the jobs wrote a database row every minute that was never cleaned up, now fixed and redeployed.

Stack and release record

  • Platforms

    Web (responsive down to 320 px, light and dark)

  • Built with

    TypeScript, Next.js 16, pnpm monorepo, PostgreSQL with Drizzle, Better Auth, Playwright, axe, Vitest, Docker Compose, Optional Anthropic API with a template fallback

  • Status in full

    Live as a private pilot on Google Cloud in Singapore: the app, database and scheduler run, security headers are on and the health check is green. Email currently reaches only the owner’s address, the GitHub App is not registered, and the résumé analyzer and phone app are not built. The address is not public yet.

Hiring interns for January 2027?

I’m available full-time from 25 January to 23 April 2027.