← All work

Syncareer / Engineering case study

Career tools, with context.

A career platform connecting saved opportunities, CV tailoring and interview preparation in one application record.

My contribution
Product & application engineering
Project state
Live product
Implementation
Grounding revision in source
Deployment
Revision not yet redeployed

Stack TypeScript / React + Vite / Supabase Postgres + RLS / Edge Functions (Deno) / Lovable AI gateway

02 / Project visual

The product, as it runs.

Three real captures from the live platform. The grounding revision isn’t in them yet.

Syncareer dashboard showing career readiness, applications, CV strength and interview progress for one student.

2400×1302·real screenshot·evidence

Dashboard / the record

Readiness, applications, CV strength and interview progress, drawn from the same application records.

Dashboard / the record · 2400×1302 · real artifact

Syncareer dashboard showing career readiness, applications, CV strength and interview progress for one student.

Readiness, applications, CV strength and interview progress, drawn from the same application records.

Evidence: real product screenshot, not a mockup. Source repository or live product.

Syncareer opportunities interface showing job search, match score, and interview and CV tailoring actions.

2400×1303·real screenshot·evidence

Opportunities / application workflow

Saved opportunities feed CV tailoring and interview practice. Match scores are product UI, not a hiring probability.

Opportunities / application workflow · 2400×1303 · real artifact

Syncareer opportunities interface showing job search, match score, and interview and CV tailoring actions.

Saved opportunities feed CV tailoring and interview practice. Match scores are product UI, not a hiring probability.

Evidence: real product screenshot, not a mockup. Source repository or live product.

Syncareer SynAI interface showing career guidance built from a student profile, quick actions and a message input.

2400×1302·real screenshot·evidence

SynAI / context

Profile context and quick actions in the existing platform.

SynAI / context · 2400×1302 · real artifact

Syncareer SynAI interface showing career guidance built from a student profile, quick actions and a message input.

Profile context and quick actions in the existing platform.

Evidence: real product screenshot, not a mockup. Source repository or live product.

03 / Problem

The assistant saw a bullet. Not the evidence.

Before the change, the assistant received the selected bullet and nothing else. It could polish the wording. It couldn’t know the requirement the bullet was meant to answer, or tell a job keyword from candidate evidence. Replies came back as text plus broad source ids, and new claims were never checked.

Old contract · cv.rewrite_bulletDocumented shape
requestThe selected bullet — one string, nothing else.
requirementnot sent
evidence recordsnot sent
provenancenot sent
validationnone — the reply was cast to a type, not checked

As documented in the project’s own guidance notes.

04 / Contribution

The application layer, not the model.

One path inside the product: the CV assistant that rewrites a selected bullet for a selected job requirement. The problems lived around the model — context, validation, consistency — so I worked on the application layer that surrounds it.

  • The contract — what a request may carry, and what a reply must cite before the interface can use it.
  • The checks — validation and grounding between the model and the interface, not inside a prompt.
  • The review surface — accept, edit, reject or undo stays with the person. Nothing reaches the saved CV on its own.

05 / Key decisions

Fix the contract, not the model.

This comparison is the whole investigation. The Lab runs one reply through the gate.

A request/response contract: allowlisted context in, validated and cited proposals out, and nothing applied automatically.

RequestOne selected bulletAllowlisted context with provenance, size limits, a required requirement/evidence pair
ResponseText plus broad source idskind, text and sourceContextIds from the ids actually supplied
TrustRemote JSON cast to a typeRuntime validation, a citation subset check, factual-risk checks
Four engineering decisions

Bounded, task-family server prompts

Ten tasks, each with its own server-side prompt built only from the supplied context. Job text, CV text and the instruction are treated as untrusted data.

Allowlisted context with size limits

Context enters only as allowlisted items with fixed provenance: 12 items, 8,000 characters each, 24,000 in total, 2,000 for the instruction.

Citation enforcement

Missing grounding is a refusal, not a warning. The request is checked before the model is called, the reply against the ids that request supplied.

Factual-risk checks and explicit review

New numbers, unsupported skills, employers presented as experience, coursework presented as employment, participation presented as a win, and generic filler all get flagged. A person decides what happens next.

The repair stayed in the existing career-guidance seam: React + Vite on Supabase, hosted on Lovable Cloud, no custom API server. Authorization is enforced server-side; the router’s guards are UX only.

The gate is on the Lab page. Write a bullet, choose what it cites, and watch the check decide. One example passes with four invented claims in it, which is the point.

06 / Result & status

A repaired contract. A release still pending.

A bounded request and cited-proposal contract is in source. The live model’s grounding has not been measured.

Live product
Deployed. The existing platform is public at syncareer.me, and the captures above come from it.
Grounding revision
In source, awaiting deployment. The live platform does not run it yet.

In source

  • Request contract, task/provenance allowlists and size limits contract.ts
  • Runtime validation of model JSON, with named failure codes parseModelProposal
  • Requirement/evidence citation enforcement for cv.rewrite_bullet handler.ts
  • Fail-closed ordering, with the reservation released on every failure handler.ts

07 / Limitations

What this does not show.

Not verified

The repository shows a repaired contract. It doesn’t show that the model got better.

  • No live-model evaluation and no captured before-and-after model output
  • No measured failure rate, latency, or output-quality score
  • No authenticated canary — the four workflow families have not been run against the live model
  • Stricter server prompt and citation enforcement are not live yet: the changed edge function still needs a Lovable Cloud deployment
  • Interview generation and CV parsing run in deployed-only functions, whose prompts and quotas are not auditable from the repository

The project’s own notes score five fixed examples against a six-part rubric: 8/30 for the old contract, 29/30 for the revised one. Those are marks on fixtures that compare two contract versions, not live-model scores.

08 / Sources

Check the record.

  • Live productsyncareer.meThe deployed platform the captures come from.
  • Source repositoryGitHubContract, handler, prompts and the Deno tests.
  • Contract handoffdocsThe project’s own record of what changed, what was tested, and what was not.
  • Reliability LabThis siteStage-by-stage source inspection, plus the labelled fixtures.

Files cited: contract.ts, handler.ts,parseModelProposal, index.test.ts.

Contact / The next step

Tell me what
you’re building.

A role, a project, or a hard question about making an AI feature behave. Email reaches me directly — no form, no queue.