Skip to Content
StatusWhere we are

Where we are

Source: SOURCE-OF-TRUTH.md · synced 2026-06-12

For each step: the design, the implementation plan, where the code lives, and current status. Sub-steps (decimal-numbered, e.g. Step 5.1, Step 5.1.1) sit inside each step.

Status words used:

WordMeaning
Built — shippedCode is written, tested, and merged. Done for now.
Built — awaiting next stepCode is written and tested. Waiting on a later step to use it.
Design done — build not startedA design document exists. No code yet.
Plan approvedThe plan or amendment has been signed off. Ready to consume.
Plan drafted — awaiting approvalA first-draft plan exists. Needs review before build.
Blocked — gating later stepsThis phase must ship before downstream steps can move.
Not started — no plan yetNo design, no implementation plan, no code. Earliest stage.
LiveAn ongoing piece (docs site, sync pipeline) that is in production now and continues to receive small updates.

Step 1 — JD ingested (raw upload + text extraction)

Step 2 — JD parsed (Claude tool-use → structured ParsedJD)

Step 3 — JD normalised + tagged (3-level taxonomy, bootstrapped vocab)

  • Step 3.1 — Tag-vocab bootstrap (run a lean LLM-driven match across all 41 JDs × ~107 CVs (raw text, no normalisation yet). Cluster the categorical terms Claude keeps using to describe fits. Cluster + name → locked tag vocab.)

    • Design: plans/step-3.1-vocab-bootstrap-design.md — plan approved.
    • Implementation plan: plans/step-3.1-vocab-bootstrap-impl.md — Tasks 1–10 built; Task 11 (live pipeline run, ~USD 5–10 in API costs) and Task 12 (Calibre-team ratification session) still to run.
    • Code: calibre-app/feat/vocab-bootstrap branch — src/lib/vocab-bootstrap/ + scripts/run-vocab-bootstrap.ts + scripts/review-vocab-candidate.ts. 19 files, 47 tests passing.
    • Status: Built — awaiting live run + ratification session. This is the critical path — once the vocabulary is locked, Step 3.2, Step 5.2, and Step 6.1 all unblock in parallel.
  • Step 3.2 — JD normaliser build (Claude tool-use call: ParsedJD → NormalisedJD with function, vertical, tag list, seniority tier, must-have tags, nice-to-have tags)

Step 4 — Sourcing (candidate + employer scraping)

  • Step 4.1 — Apify candidate scraping

  • Step 4.2 — Apollo enrichment

  • Step 4.3 — Anymail Finder

  • Step 4.4 — Employer-side BD scraping (sourcing the other side — hiring agencies)

  • Design: grant/scope.md §“AI-Powered Resourcing” — scope only, not detailed.

  • Implementation plan: Not written yet.

  • Code: Not built.

  • Status: ⏸️ Deferred 2026-06-11. Design plan exists at plans/pipeline-4-sourcing-design.md. Build deferred — orchestrate against existing 41 JDs × 107 CVs first. Opens after the matching engine (Steps 5–8) proves itself end-to-end on existing data.

Step 5.0 — Candidate-record merge (bridge between sourcing and parsing)

Surfaced 2026-06-11. Sits between Step 4 (scraping) and Step 5.1.1 (CV parsing). Merges (a) scraped LinkedIn / Apollo profile JSON with (b) any uploaded CV file blob into one CandidateRecord that downstream sub-steps consume. Without this, Step 5.1.1 only knows how to parse file blobs — scraped JSON has no defined ingestion path.

  • Step 5.0 — Candidate-record merge
    • Design: Not written yet. Open: define conflict resolution (which side wins when CV vs scrape disagree on current employer / title / etc.) + source-of-truth rules.
    • Implementation plan: Not written yet.
    • Code: Not built. Target: calibre-app/src/lib/candidate-merge/.
    • Status: Not started — no plan yet. New gap, surfaced this session.

Step 5 — CV parsed + normalised + matched 1:1 to JD

  • Step 5.1.1 — CV parser core (extracts raw fields)

  • Step 5.1.2 — CV parser hardening (BOM handling, stale-CV detection, career-gap signals, short-tenure clusters)

  • Step 5.2 — CV normaliser (raw fields → controlled taxonomy)

  • Step 5.3 — Industry-expert filter Renumbered 2026-06-12 → Step 6.0 + Step 6.2. The Step 5 numeric ID misrepresented runtime order (it never touched CVs at parse time — it gated and adjusted Layer 1 scoring). drop gates now fire at 6.0 (before Layer 1); boost/penalty + L2 flags at 6.2 (after Layer 1). See Step 6 below. Design filename keeps the 5.3 prefix: plans/step-5.3-industry-filter-design.md.

Step 6 — Hard-fit filter (gates + Layer 1 + overlay — deterministic, composite ≥4 passes)

Restructured 2026-06-12 into three sub-steps in execution order: 6.0 entry gates → 6.1 rubric scoring → 6.2 rules overlay. The former Step 5.3 industry-expert filter was split into 6.0 + 6.2.

Layer 1 fires rubrics at the sub-vertical granularity defined in §3b — an LNG energy operator and a fertilizer agri operator both fall under cargo-ops but score against different weights and signals. 22 sub-vertical rubric configs will be emitted by the extended bootstrap mine per plans/amendment-3.1+5.3+6.1-bootstrap-rubric-extension.md. The 4 grant-vertical stub configs that used to sit at reference/rubric-configs/{commodities,maritime,offshore,tech-gaming}.json were archived 2026-06-11 to _archive/2026-06-11-rubric-stubs-4-vertical/.

Rubric config keying: the rubric file is selected by (function, vertical). Examples:

  • cargo-ops.energy → energy rubric (LNG / LPG / crude / petrochem signals)
  • cargo-ops.agri → agri rubric (grain / sugar / cocoa signals)
  • ship-ops.tanker → tanker rubric (chemical / LNG / LPG carrier signals)

Each rubric produces a 4-dimension hard-fit score with default weights tag overlap 0.40 / seniority delta 0.20 / years of experience 0.20 / red-flag penalty 0.20 (Dan tunes per sub-vertical at ratification). Sub-function match is NOT a weighted dimension — it is the 6.0 entry gate (locked 2026-06-12; as a binary 5-or-0 with a drop on 0, weighting it added no discrimination). Composite ≥ 4 after the 6.2 overlay → passes to Step 7.

  • Step 6.0 — Entry gates (new 2026-06-12)

    • What: Sub-function gate (JD vs CV sub_function must match; adjacency may salvage) + ratified drop-type rules from the mined ruleset. Fires BEFORE any rubric scoring — eliminates non-starters with rule id as drop reason.
    • Design: plans/step-5.3-industry-filter-design.md (rules) + matching-engine design (gate semantics).
    • Code: Not built. Target: calibre-app/src/lib/matching/entry-gates.ts.
    • Status: Content drafted (bootstrap xlsx) — awaiting ratification. xlsx needs re-emit: drop rules split from L2-flag rules.
  • Step 6.1 — Rubric loader + composite scorer

  • Step 6.2 — Rules overlay (new 2026-06-12)

    • What: Fires AFTER the Layer 1 composite. (1) Boost/penalty rules — per-rule deltas sum, then clip to net ±0.5 on the composite (locked 2026-06-12: rules nudge borderline candidates, never overturn the rubric — anything stronger belongs as an L1 dimension). (2) Attaches block_at_l2 / require_evidence flags consumed by Step 7.2. (3) Threshold re-check: adjusted composite < 4.0 → drop with reason composite_below_4_after_rules.
    • Design: plans/step-5.3-industry-filter-design.md (rules) + matching-engine design.
    • Code: Not built. Target: calibre-app/src/lib/matching/rules-overlay.ts.
    • Status: Content drafted (bootstrap xlsx) — awaiting ratification. xlsx delta values need update for the ±0.5 net cap (was ±0.3–1.5).

Step 7 — Deep assessment (Layer 2 — qualitative, evidence-grounded)

Step 8 — Shortlist (four fit groups by composite score)

Locked 2026-06-11:

BandScore rangeWhat happens
Strong yes≥ 4.5Primary recommendation → Step 9 outreach
Soft yes4.0–4.49Backup → Step 9 outreach
Soft no3.5–3.99Skips Step 7 LLM verification. Parked, re-pool for future JDs.
Strong no< 3.5Parked. No re-pool by default.

Step 9 — Personalised outreach

  • Step 9.1 — Personalisation engine

  • Step 9.2 — Email send

  • Step 9.3 — LinkedIn sequencing

  • Step 9.4 — Response handling

  • Design: grant/scope.md §“AI-Driven Candidate Outreach” — scope only.

  • Implementation plan: Not written yet.

  • Code: Not built.

  • Status: Not started — no plan yet. Opens after Step 8 ships shortlists.

Step 10 — Productisation surface (the product Calibre uses and sells)

  • Step 10.1 — Multi-tenant database (Supabase row-level security)

  • Step 10.2 — Marketing landing page

  • Step 10.3 — Signup + onboarding wizard

  • Step 10.4 — Stripe checkout (test mode is acceptable for audit)

  • Step 10.5 — Demo tenant(s) — at least one fictional agency tenant to defend the “marketable to other agencies” claim

  • Step 10.6 — Admin (super-admin for 3NMP to manage tenants)

  • Design: grant/architecture.md §“Dual-surface architecture” — high-level only.

  • Implementation plan: Not written yet.

  • Code: Not built.

  • Status: Not started — only the architecture sketch exists. Opens after Steps 7 + 8 prove the matching engine end-to-end.

Step 11 — Audit prep (the deliverables EnterpriseSG reviews)

  • Step 11.1 — Project report on Calibre letterhead

  • Step 11.2 — Training materials

  • Step 11.3 — Recordings + attendance log

  • Step 11.4 — Productivity measurement (before / after metric for audit)

  • Design: grant/deliverable-checklist.md.

  • Implementation plan: Not written yet.

  • Code: N/A — this step produces documents, not code.

  • Status: Not started. Opens October 2026.

Step 12 — Infra (the project tooling that ships everything else)

  • Step 12.1 — Docs site (docs-site/ → calibredocs.3nm.io)

  • Step 12.2 — Manifest → sync pipeline (scripts/inventory-site-manifest.py + scripts/sync-docs-site.py)

  • Step 12.3 — Dev environment (branches, agent skills, CI)

  • Step 12.4 — Documentation governance (this file, PLANS-LOG, STATE-LOG, CLAUDE.md, the project → docs-site routing map at _internal/workspace-to-docs-site-map.md)

  • Status: Live. The manifest → sync pipeline has been running since 2026-06-01. Documentation governance was overhauled on 2026-06-03 (nomenclature unification + docs-site outside-in rewrite).


Last updated on