Training · learner work
The Pipeline Needed More Than One Person.
A small sales team needed a repeatable way to work its pipeline. Colaberry's Managing Director, working as its AI Systems Architect, built a daily outreach queue for an executive ground-transportation company: AI-assisted drafts, territory controls on the server and an explicit sending profile on the human-approved send path. The project established those controls at the API level; its browser identity flow remained unfinished when the project was sunset in September 2026. Told here as a retrospective, limits included.
verified
All student projects- Organisation
- an executive ground-transportation company
- Industry
- Transportation
- Capability
- Operational AI an outreach workflow with territory identity and feedback controls
- Status
- Paused
- Built by
- Colaberry team
- Published
- 2026-09-22
The situation
Picture one representative's morning, an illustrative example rather than a recorded one: a queue of the day's leads in the two states they own, a draft under their name for the first, a note that the third asked to be contacted on LinkedIn, and a question about a message that went out under the wrong signature. At an executive ground-transportation company, one person was the sales pipeline: finding companies, writing the first message, sending it, following up, alongside running the company. The ask was a system that finds companies, drafts the first message, keeps the next step in a daily queue and lets a small team share the work; whether that sharing was ever proven through a login is one of the limits stated below. That is a workflow problem before it is a tool problem: who sees which leads, whose name goes on a message, and what an automated change is allowed to touch.
On 14 Jun 2026 the client described who would work the pipeline: one person seeing everything, a second owning Texas, Iowa handed to a new hire, more owners expected over time. That conversation made the pipeline a multi-person problem, and the three decisions below follow from it. The last commit is 29 Jun 2026. In September 2026 the platform's own daily report read 7,786 leads and 0 emails sent, and the project was sunset; this record is written from the repository as it stands, with the builder's later local work described as local and never as deployed. The reservation-quoting side of the same platform is a separate story.
What it had to do
- Show each person only the leads in the states they own on the list, the queue, the export, the detail page and the filter chips; six routes that act on a lead by id were left unscoped.
- Put the right name and signature on each message that leaves by the human-approved send path, and refuse one that carries the wrong name; a second, dormant automated path sits outside that guard.
- Let a model apply small, reversible fixes from reported issues, and hold anything else for a person.
What constrained it
- Three people would work one pool of leads, each owning a market, with one person seeing everything.
- Mail left through Microsoft Graph as a real mailbox, so a message's name and signature had to match the mailbox it left from.
- Representatives reported problems in free text and wanted them fixed without waiting for a developer.

Decisions that made the difference
Three choices shaped the system. Each one lives at a specific point in the drawing above.
- At Daily queue by territory
Enforce territory beyond the screen
The filter bar could lock a state in the interface, but the API behind it answered for any state, so a representative could open, list or export leads outside their market.
Put the territory on the user's row as a list of states and apply it on the server: the daily queue, the lead list, the filter chips, the export and the detail page all clamp to the caller's states, and a request that would widen them is narrowed instead.
Evidence The scope module and the lead routes at the pinned commit, the commits that introduced them, and the live checklist run on 24 Jun 2026.
25 of 25live checks passed over the API on 24 Jun 2026, each user seeing only their states across the list, the queue, the export, the detail and the chips. Six outreach routes still act on a lead by id with no check, the scope lookup fails open on a read error, and every browser was signed in as one shared account, so this was proven over the API with minted tokens and never through a login.
- At Send by mail
Make the sender's identity explicit
Every draft and every signature carried one person's name whatever mailbox the message left from, and a wrong pairing could not be told apart from a right one.
Keep one profile per sending mailbox with its owner's name, title and signature; build the signature from the profile; and refuse a send whose display name or signature names a different known person than the mailbox's owner.
Evidence The sender-profile service and the guarded send path at the pinned commit, the two commits of 23 Jun 2026, the live checklist and its 24 Jun run, and the tracked count of live sends.
5 of 5identity checks of the 24 Jun 2026 live checklist passed over the API with a minted token per user: mailbox to owner, the allow-list, two signature checks and the identity guard; the three test emails of that checklist run only behind a flag. The 113 live campaign emails to 29 Jun 2026 left through Microsoft Graph as a configured mailbox and were logged to a campaign and a lead, which is activity, not proof of the name and signature in every message. At the pin a draft was still written in the campaign's sender voice, not the signed-in person's, and a second automated mail path bypasses every guard; per-user signatures and drafts as the signed-in representative exist only in an uncommitted local batch.
- At Report an issue
Bound what an automated fix may change
Representatives reported problems in free text and wanted them fixed at once, but a model proposing a change is not proof the change is safe to apply.
Let the model choose one of five actions only: add a writing rule, change one of five named settings, block a contact, move a contact to a named campaign, or hold for review. Below a confidence of 0.55, on an unknown action, on missing parameters or on a contact action without a contact, hold for review and apply nothing.
Evidence The feedback service, its audit table and its eight tests at the pinned commit, and the commit of 24 Jun 2026 that introduced them.
8 of 8tests in the feedback suite pass offline: the happy path, a model outage, no key, an unknown action, a block with and without a contact, idempotency and the mail bulkhead. Two of the five actions have no test, the fix is applied before its audit row is written, the notice goes to a global mailbox rather than the reporter, and no count of fixes applied on the deployed product exists.
Who built it
- Managing Director and AI Systems Architect at Colaberry: designed and built the outreach workflow, its territory rule, its sender identity and its bounded feedback loop

The build
- A development auto-login on every page
- A login page, the auto-login left in place
- A territory becomes a list of states
- The campaign list scoped to a user's states
- Identity, guards and server-side territory
- Territory on export, detail and chips; a live checklist
- Report an issue, triaged into a bounded fix
- The last commit: a cost loop removed, a send count made honest
Notes on 8 of the 8 steps
- A development auto-login on every page. A component that signs the browser in as one shared administrator account when no token is stored, mounted on every page; unchanged at the last commit.
- A login page, the auto-login left in place. Per-user auth helpers and a login form, prompted by the question of how much one representative used the system; the shared auto-login stayed mounted.
- A territory becomes a list of states. The fixed territory enum replaced by a list of states on the user row, the day the client described who would work the pipeline.
- The campaign list scoped to a user's states. A user sees only campaigns with at least one lead in their states, read from the user row at request time.
- Identity, guards and server-side territory. The scope module and the lead-list clamp, a profile per mailbox with an identity guard on the send path, a 20 by 5 offline release matrix and idempotent provisioning of the three sending users.
- Territory on export, detail and chips; a live checklist. Three routes that had run unscoped brought under the rule, one representative's role fixed, and a 25-point checklist run against the live API with a minted token per user.
- Report an issue, triaged into a bounded fix. In-app feedback, model triage into one of five actions, safe actions applied and the rest held, an audit row and a notification; eight tests.
- The last commit: a cost loop removed, a send count made honest. A paid extraction re-run on reservation mail pre-filtered, and the Friday briefing made to report seven-day sends beside the all-time count.

What was built
The workflow, as the code implements it at the last commit. Leads arrive when a person triggers a pull from the enrichment provider (100 at a time) or uploads a file; the system de-duplicates them by email, classifies each lead's vertical from its real industry and resolves its state at ingest, so placement is automatic and a representative is never assigned a lead by hand: the join is made at query time between the lead's state and the states on the user's row. The daily queue is that join: a user's own states win over anything the query asks for, and the same rule clamps the lead list, the filter chips, the export and the detail page on the server.
Stack
- TypeScript
- Node.js
- Express
- Next.js
- PostgreSQL
- Sequelize
- Docker
More on what was built
A draft is prepared by a model when the queue is read, from the lead, its context, the campaign's prompt, the sender's name and role, and the writing rules the feedback loop has accumulated; without a key it falls back to a template. A person reviews it: rewrites it shorter, more personal or more direct, skips, removes, blocks or moves the lead, then approves the send. By mail, the message passes four guards before Microsoft Graph sends it as the campaign's mailbox: the sender must be on the allow-list, the name and signature must belong to that mailbox's owner, the lead's real industry must match the campaign, and the address must have validated. By LinkedIn, the extension copies the draft to the clipboard and the person pastes and sends it; no LinkedIn API exists in the repository. A sent step sets the lead's next action date, and the lead re-surfaces in the queue then; no follow-up leaves without a person approving it.
What works, on the evidence: the territory rule is server-side and was verified over the API with a minted token per user, 25 of 25 checks on 24 Jun 2026; the guarded send path refuses a wrong sender, a wrong identity, a wrong category or an unvalidated address; the feedback loop records each report with the model's assessment and holds anything below its confidence floor, though it applies a permitted fix before it writes the audit row, so a fix whose row fails to write leaves no record.
What remains unresolved, on the same evidence. Every browser that opened the deployed product was signed in as one shared administrator account by a component mounted on every page, so individual logins never took and sign-out was not possible: isolation was proven over the API, never through a login. Six outreach routes act on a lead by id with no territory check, and the scope lookup fails open when the user read errors. A second mail path exists for scheduled sends through a bulk provider that passes none of the four guards; it stayed dormant because the scheduler runs only behind a flag that defaults off and the follow-up stepper ships in dry-run. The feedback loop applies its fix before it writes the audit row, notifies a global mailbox rather than the person who reported, and two of its five actions have no test. The rewrite of the auto-login into a login guard, a sign-out control, per-user signatures and drafts bound to the signed-in representative are later local work, a batch of 13 files that was never committed or deployed, whose timing relative to the sunset decision the record does not assert.
The screenshots were captured on a local copy of the platform at the pinned commit with no keys and invented rows; the times they show are Central.
Capabilities
- Lead sourcing
- Territory scoping
- Sender identity
- AI drafting
- Human review
- Bounded automation
Integrations
- Microsoft graph
- A lead enrichment provider
- A language model API
- Linkedin through a browser extension
Data stores
- PostgreSQL

The measurement
The record measures what the repository and the platform's own report can show, as separate dated readings, never a funnel. Inventory: 7,786 leads on 18 Sep 2026, 7,601 of them in the new stage that day; 7,700 valid of 7,861 active on 22 Jun. Activity: 113 live sends to 29 Jun; 0 in each weekday report received from 8 to 18 Sep, each covering the previous day; 151 leads with a recorded first touch by 19 Jun, 50 by a logged email; 9 responders; meetings: zero recorded in the reviewed snapshots. Verification: 25 of 25 live API checks on 24 Jun with minted tokens, 143 of 143 tests offline at the last commit, 245 of 257 commits with an AI co-author trailer. Each figure carries its date and its limit.
Evidence maturity: tracked counts and one recorded live checklist; no production database was read, and the browser login flow was never verified.
Full notes on all 7 metrics
7,786 leads in the pipeline on 18 Sep 2026; 7,601 of them in the new stage in that report
Leads in the pipeline on 18 Sep 2026, by the platform's own daily report
verified
- Baseline
- On 22 Jun 2026 the tracked email-validation sweep found 7,700 valid of 7,861 active leads and archived 129 dead domains.
- Sample
- Every lead row the deployed platform counted in its daily report of 18 Sep 2026.
- Methodology
- Read from the body of the platform's daily report email (the Pulse job, 7 AM Central), the same figures on every day read from 8 to 18 Sep 2026; the June figures from PROGRESS.md at the last commit.
Limitations
- An inventory of rows, not a qualified pipeline, customers or value.
- No production database was opened; the daily report is the source.
- 7,601 "new" is the stage read on the report day; the platform keeps no stage history (evidence row f-pulse-report), so whether a lead was ever worked cannot be read from it.
113 live sends all-time to 29 Jun 2026; 0 emails sent in each weekday report received from 8 to 18 Sep 2026, each covering the previous calendar day
Live campaign emails, all time to 29 Jun 2026, and in each September report read
verified
- Baseline
- 0 emails sent (cold 0, follow-up 0) on every daily report read from 8 to 18 Sep 2026.
- Sample
- All 113 outbound campaign email rows to 29 Jun 2026, every one system-sent through Microsoft Graph and logged to a campaign and a lead (PROGRESS.md line 13); and the send counter in the platform's daily report received on each weekday from 8 to 18 Sep 2026, each report covering the previous calendar day (the Pulse job, weekdays at 7 AM Central).
- Methodology
- The all-time figure from the tracked PROGRESS entry of 29 Jun 2026, which validated all 113 logged rows; the September figure read from the report body.
Limitations
- States the resting state of the product before its sunset, not demand or effort.
- 52 of the 113 all-time sends went to hand-curated recipients and 34 to an investor list, so 113 is not 113 cold prospects.
- The reports observe only the days they cover: each weekday report covers the previous calendar day, so the reports received from 8 to 18 Sep can cover only 7 to 10 and 13 to 17 Sep; no report covers a Friday or a Saturday, because their reports would fall on the weekend, when the job does not run (evidence row f-pulse-report), and days without a report were not observed.
50 of 151 leads with recorded first-touch activity had an email send logged; 101 had a LinkedIn step recorded by hand
Leads with recorded first-touch activity by 19 Jun 2026, by channel
verified
- Baseline
- None: a split of one cohort.
- Sample
- The 151 leads the tracked record counted with a first touch by 19 Jun 2026: 50 with a logged email send (51 sends), 101 with a LinkedIn step recorded by the person.
- Methodology
- PROGRESS.md lines 353 to 354 at the last commit; a LinkedIn step sets the lead's last-contacted date and writes no communication-log row.
Limitations
- The 101 rest on a manual record by the person who sent; nothing in the platform can verify a LinkedIn message was delivered.
- "Recorded first-touch activity" means a message left or a step was recorded, not a reply, and not a verified delivery.
9 responders and 17 inbound messages recorded on 20 Jun 2026; meetings, proposals and won: zero recorded in the reviewed snapshots
Replies recorded by the manual ingestion run of 20 Jun 2026
verified
- Baseline
- None recorded before that run; meetings, proposals and won were 0 on the same day and meetings booked were 0 on every daily report read in September.
- Sample
- Inbound messages the reply ingestion persisted when it was run by hand on 20 Jun 2026.
- Methodology
- PROGRESS.md line 312 at the last commit (the run), line 185 (the funnel) and the September daily reports; ingestion was never scheduled.
Limitations
- The responders were mostly investor conversations, not cold prospects.
- No reply rate is computed: reached and replied were counted on different days over different channels.
- The three zeros are what the reviewed snapshots record (the 20 Jun ingestion and the September reports); nothing establishes what happened through other channels or outside those readings.
25 of 25 live checks passed over the API with a minted token per user
Live release checklist over the API, 24 Jun 2026
verified
- Baseline
- None.
- Sample
- The 25 checks of verifyOutreachLive.ts run against the deployed API on 24 Jun 2026: authentication, permissions, list, queue, export, detail and chip isolation, mailbox ownership, signatures, the identity guard, personalisation.
- Methodology
- The script mints a JWT per user directly and calls the live API with it; the result is recorded in PROGRESS.md line 35 at the last commit.
Limitations
- API-level: the browser login flow was not exercised, and a component on every page signed every browser in as one shared account.
- One run on one day at one version; not a certification.
143 of 143 tests pass offline in the six outreach suites
Outreach tests passing offline at the last commit
verified
- Baseline
- None.
- Sample
- The six outreach suites (release matrix, sender, feedback, territory filter, queries, system mail): 143 tests.
- Methodology
- Jest with workers in a container built from the repository at the last commit with its own Dockerfile, no network and no key; the repository's own npm test flags crash the process after the first suite, which is recorded and not fixed.
Limitations
- No route handler, none of the six by-id routes, the fail-open scope lookup, the automated mail path, and two of the five feedback actions are exercised by any test.
245 of 257 commits carry an AI co-author trailer, 27 Mar to 29 Jun 2026
Commits carrying an AI co-author trailer
verified
- Baseline
- None.
- Sample
- Every commit reachable from the last commit: 257.
- Methodology
- git trailers counted on the public repository; the 12 without a trailer are dated 18 to 22 Jun 2026.
Limitations
- Counts trailers, not authorship of any line or share of effort.

What happened next
Shipped
- Territory on the server, five routes covered
- Per-representative sender identity
- Four guards on the human-approved send path
- Bounded automatic fixes from reported issues
Paused
- Sign out and a login guard in the browser
- Per-user signatures
- Drafts as the signed-in representative
Unknown
- Territory checks on the six by-id outreach routes
- A scope lookup that fails closed
- The automated mail path behind the same guards
- The audit row before the fix, and the notice to the reporter
Not pursued
- LinkedIn automation
Notes on 12 of the 12 items
- Territory on the server, five routes covered. Documented: yes. Implemented at the last commit: yes. Historically deployed: yes. Verified through the real login flow: no. Later, local only: no. Verified over the API with a minted token per user on 24 Jun 2026, 25 of 25; in the browser every visitor was signed in as one shared account, so no login-flow verification exists; the six by-id outreach routes below were left unscoped.
- Per-representative sender identity. Documented: yes. Implemented at the last commit: yes. Historically deployed: yes. Verified through the real login flow: no. Later, local only: no. A profile per mailbox, signatures built from it and an identity guard on the send path; the browser session behind it was the shared account.
- Sign out and a login guard in the browser. Documented: yes. Implemented at the last commit: no. Historically deployed: no. Verified through the real login flow: no. Later, local only: yes. At the last commit the auto-login component was still mounted on every page; the guard and the Sign out control exist only in the uncommitted local batch, never deployed.
- Per-user signatures. Documented: yes. Implemented at the last commit: no. Historically deployed: no. Verified through the real login flow: no. Later, local only: yes. At the last commit the signature came from the mailbox's profile, shared by whoever sent from it; a per-user editor and route exist only in the uncommitted local batch.
- Drafts as the signed-in representative. Documented: yes. Implemented at the last commit: no. Historically deployed: no. Verified through the real login flow: no. Later, local only: yes. At the last commit a draft was written in the campaign's sender voice; binding it to the signed-in person exists only in the uncommitted local batch.
- Four guards on the human-approved send path. Sender allow-list, identity, category and address validation, then Microsoft Graph as the campaign's mailbox, with a log row per send.
- Bounded automatic fixes from reported issues. Five actions, five settings, a confidence floor of 0.55; anything else held for review with the model's assessment stored.
- Territory checks on the six by-id outreach routes. Swap, move, advance, skip, remove and block act on a lead by id with no scope check; no decision about it is recorded.
- A scope lookup that fails closed. When the user read errors the lookup returns no restriction; no test covers it and no decision about it is recorded.
- The automated mail path behind the same guards. Scheduler to dispatcher to a bulk provider passes none of the four guards; it stayed dormant behind a flag that defaults off and a stepper in dry-run, and no decision about it is recorded.
- The audit row before the fix, and the notice to the reporter. The feedback loop applies a change, then writes its row, then emails a global mailbox; no decision about the order or the recipient is recorded.
- LinkedIn automation. Judged risky and left manual on purpose: the extension copies a draft to the clipboard and the person sends it; no server-side LinkedIn API exists.

Meet the builder
Managing Director and AI Systems Architect
Project contribution
Replaced the fixed territory enum with a list of states on the user the day the client described who would work the pipeline (14 Jun); put the territory rule on the server and made sender identity explicit in two commits on the evening of 23 Jun; brought three unscoped routes under the rule and ran a 25-point live checklist the next morning; added the bounded feedback loop the same day; and in the last commit, on 29 Jun, removed a paid extraction loop on reservation mail and made the Friday briefing report seven-day sends beside the all-time count. The auto-login that signed every browser in as one account was added on 29 Mar as a development convenience and was still mounted at the last commit; its replacement is later local work, not committed or deployed. The work ran from 27 Mar to 29 Jun 2026 in 257 commits, 245 of them carrying an AI coding assistant's co-author trailer, a count of trailers, not authorship.
Skills demonstrated
- Authorisation on the server, not the screenA territory rule on the user row, applied to the list, queue, export, detail and chips (decisions, architecture).
- Identity on outbound mailA profile per mailbox, signatures built from it, and a guard that refuses a mismatched name (decisions, build timeline).
- Bounding a model's authorityFive actions, five settings and a confidence floor before anything is applied (decisions).
- Stating what was not verifiedThe capability matrix separates API-verified isolation from the shared browser login (roadmap, measurement).
From the repository record.
What this project shows
This project shows a Managing Director working as an architect: taking a one-person pipeline and turning its decisions, who sees which leads, whose name goes on a message, what a model may change, into rules the server enforces. It also shows the discipline of saying what was verified and what was not: the controls were established and proven at the API level, never through a browser login, and the identity work that would have finished the browser flow is later local work, not committed or deployed, left unfinished when the project was sunset.
Build one of these
