Turn feature requests into reviewed, shipped code.
ShipFlow holds every change accountable to the spec. A clarified request becomes a PRD with numbered acceptance criteria, then dual-AI review checks the real diff against each one — with full traceability from request to ship.
Seven stages. One flow that holds the work to the spec.
Every request runs the same track — from intake to a senior-approved ship. Nothing advances until the stage before it is satisfied.
From a sentence to a spec with numbered criteria.
An AI discovery conversation pins down scope and intent, then drafts a structured PRD. Every requirement becomes an explicit, numbered acceptance criterion — the contract the rest of the pipeline is measured against.
Bulk CSV import for contacts
- AC-1Reject files over 5 MB with a typed error.
- AC-2Validate the header row before any row is parsed.
- AC-3Deduplicate incoming rows on normalized email.
Two independent passes, checked against the spec.
When a PR opens, the engine fetches the real diff and reviews it twice. Findings carry a severity, a category, and quoted code evidence. Blocking findings route the PR back to the developer; a clean pass advances it.
Implementation critic
Reads the diff against every acceptance criterion and flags anything the change fails to satisfy — missing behavior, wrong behavior, unmet criteria.
Adversarial QA
Hunts for security holes, edge cases, and regressions the diff could introduce — independent of the spec, looking for what could break.
Dedup runs before validation, so invalid rows survive
AC-3 dedupes on normalized email, but normalization happens after the dedup pass — duplicates with differing casing slip through.
const rows = parseCsv(file)- const unique = dedupe(rows, r => r.email)+ const cleaned = rows.map(normalizeEmail)+ const unique = dedupe(cleaned, r => r.email)Size check reads the whole file into memory first
AC-1 is met, but the 5 MB guard runs after readFileSync — large uploads are buffered before being rejected. Prefer the stream's byte length.
- const buf = await file.arrayBuffer()- if (buf.byteLength > MAX) throw new TooLarge()+ if (file.size > MAX) throw new TooLarge()Every line traces back to what was asked for.
Request, criterion, task, pull request, finding, ship — one unbroken lineage. Open any shipped change and walk it back to the sentence that started it.
audit-logged · workspace-scoped · immutable lineage
A portal for every role, scoped to the workspace.
Client
Submits requests in plain language and tracks each ticket to ship.
Product Manager
Owns the PRD and approves acceptance criteria before work starts.
Developer
Picks up tasks on a kanban board and opens the pull request.
Senior Engineer
Reviews AI findings, clears or escalates, and approves the ship.
Hold your delivery pipeline accountable to the spec.
ShipFlow is invite-only. Sign in with your workspace, or request access for your team.