Phase 2 · deployment domain · the parking lot
Work in progress — this page is scoped, not planned. It holds shape and dependency order, not milestones, estimates or exit gates. Nothing here is committed to and nothing here is binding on a build session.
It exists so the delivery plan can be read as what it actually is: a phase 1 document. Phase 1 replaces HubSpot and builds the CRM. Everything that depends on deployment data, and everything cut from phase 1 for scope rather than for principle, lives here instead of cluttering that plan with work nobody has agreed to do.
This is also the parking lot. When something is deferred out of phase 1, it lands in §04 with the reason attached. A deferred feature with no written reason comes back six months later as an argument.
01 · Why separate
Phase 2 used to be two sections at the back of the delivery plan. That was fine while it was a sketch nobody read. It stopped being fine once the plan started being used to run build sessions: a prompt-driven session that scrolls past unbuilt work tends to build some of it.
Two things now live here that were previously mixed into a phase 1 document.
Nothing on this page is binding. The architecture is binding on structure and the delivery plan is binding on phase 1 scope. This page records intent and reasons. When a stage here is planned properly it gets its own numbered document and stops living in a list.
02 · Scope
Almost everything phase 1 deferred was deferred for the same reason: it depends on deployment data that phase 1 does not own. Phase 2 is the phase that owns it, so the list resolves in one move rather than piecemeal.
Quote lines carry a location from the start. A quote line that represents a deployable system is the thing a future ConnectIQ object is born from. Phase 1 writes that column and nothing reads it — it is the single cheapest piece of forward compatibility available, and retrofitting it after a migration means reconstructing intent from history.
While locations were an Airtable mirror, a quote line pointing at one was a cross-prefix reference into a table a nightly sweep could mark absent — and the object's immutable cl_location_id made that worse, not better. With locations settled as cl_ master data owned by ConnectIQ, the quote-line location is an ordinary foreign key into owned data, and the object anchors to something that cannot vanish. The forward-compatibility argument survived the decision; the risk attached to it did not.
03 · Shape
Not milestones — stages, in the only order their dependencies allow. Each is a candidate for its own numbered plan when this phase is written up properly.
The inv_ domain and the persistent object the whole phase hangs off. Nothing else can be modelled until what-is-installed-where has a home. The only stage that could safely start before cutover, if there is pressure to overlap.
owned_by — company or customer, which changes the rules around a placement without changing its mechanics.Blocked on · DR-10 · DR-12 · DR-35 · DR-41
The ops_ domain. Jobs act on objects from S1, so this cannot precede it. Field-service partners and workers land here.
The plan_ domain — the bridge phase 1 deliberately left unbuilt, and the piece the conceptual model has already specified in full.
Blocked on · DR-11 · DR-12
The sup_ and mon_ domains. Both attach to objects and locations, so both follow S1. Device health is separable and could run in parallel.
Per-table, not big-bang. Each table is migrated as its domain takes ownership, using the same freeze–reconcile–flip sequence as the HubSpot cutover.
Blocked on · DR-36
This stage used to read "each mirror is retired as its domain takes ownership" — because phase 1 was going to build an Airtable read sync and leave a warm copy of every operational table sitting in ConnectIQ. It is not, and there will be no mirrors. Every table S5 touches is migrated cold, straight from the Airtable API, with no prior reconciliation to lean on. That is a real cost of the phase 1 simplification and it is paid here.
HubSpot had a clean boundary, a well-understood export and a data model that mapped almost one-to-one onto Accounts. Airtable has none of those things: it is load-bearing for daily operations, its schema has grown by accretion, and it is being used while it is being replaced. Expect the per-table retirement in S5 to take longer than the whole of M7 did.
04 · Parked
Each entry states what was cut, why, and what would bring it back. An item with no trigger is not deferred, it is declined — and should be written as declined so nobody re-litigates it.
Phase 1 was to pull a defined set of Airtable tables into int_*_mirror read copies — 15-minute incremental, nightly full reconcile, soft deletes via absent_since, stale-data banners, two-failure alerting. The whole pipeline is cut. Once DR-01 moved locations into ConnectIQ, its only remaining payload was a display-only view of jobs and installed objects, which is not required for phase 1's stated goal — a sales team can run a full week without opening HubSpot. The goal names HubSpot, not Airtable.
Brings it back: a phase 1 screen that genuinely cannot be used without live operational data. Watch for it during M3 and M5. If one appears, the pipeline is a milestone of its own and phase 1 gets longer — it does not get bolted onto whichever milestone noticed.
A read-only window in ConnectIQ onto what Airtable knows about jobs and installed kit. Nice, and not load-bearing. Without the sync there is nothing to render.
Accepted cost, state it plainly: through the whole of phase 1, a rep who wants to know what is installed at a site opens Airtable. Brings it back: S1, which builds the real thing rather than a mirror of somebody else's.
Deferred to S3 by precedence, but only the screen. Phase 1 still ships the line-to-location assignment table and its constraint in M5 — that part is not parked, and S3 depends on it existing.
Inbox sync has left this list. It was assumed optional for phase 1 — a compose link and an outbound record only — and named here as the most likely cause of a rep saying the new system is worse than the old one. Sales said no, so the trigger fired: DR-31 answered not optional, and connected email is now M7 on the phase 1 plan, shipping before cutover — exactly the outcome this entry described. Calendar sync stays parked. Brings it back: meetings needing to appear on a record without anyone typing them in.
Plausible once deployment data exists. A separate product decision with its own access model, and the architecture already forbids it reading a raw domain table under any circumstance. Brings it back: a customer asking, and someone owning the access model.
Phase 1 defines a signed quote as a status change made by a person, with a signed date and an attachment. That definition is what the whole DR-02 cascade fires off. An integration replaces the trigger, not the cascade.
Reporting over the activity timeline. Cannot be scoped until DR-15 says which domain owns activities and whether the four-way link survives intact.
Invoicing and Xero. An unassigned domain in the architecture, claimed by neither phase. Do not let phase 2 absorb it quietly — if subscriptions are expected to produce invoices, that is a third phase or a phase 1 extension.
05 · Decisions
These continue the register in §19 of the delivery plan and keep their original numbers — the series is global, not per-document. They moved here because none of them blocks a phase 1 milestone, and leaving them in a phase 1 register made six blockers look like thirty.
These five are deliberately thinner than the phase 1 entries. That register now carries a recommended answer on every open row; these do not, because recommending an answer to a question this phase has not yet gathered evidence for is how a scoped phase turns into a planned one by accident. DR-12 and DR-41 in particular want a measurement, not an argument — how often a site actually receives more than one system.
The object model says quote confirmation, so the install job is born with a target rather than floating and being retro-linked. The conceptual model's gate is handover, because objects fan out per quote line and a line's location assignments are not complete until readiness. Both arguments are good and point at different events.
Decide with DR-41 — what creates an object and how many it creates are one conversation. Listed before S1 rather than before M5, because M5 only has to name the events, not consume them.
Needs · Sky + operations · before S1
The two documents disagree, and the CRM lacks the concept that would settle it. The object model says each quote line "names a location and a system" and instantiates one object. The conceptual model says a line is assigned across any number of locations with a quantity each — fifty players over thirty sites is one line, thirty assignments. So objects are counted from the assignment, not the line.
What one assignment yields is the open part: one object per site, one per assignment, or one per system per site. The last is what the object model intends — a site can hold a monitoring system and an access-control system — but nothing in a quote line says which product anchors a system. Closing it that way needs a flag on the catalogue.
Safe to defer — the assignment table M5 builds supports all three answers, and the catalogue flag is a one-column migration if it is ever wanted. Both this and DR-12 want the same evidence: how often a site actually receives more than one system.
Needs · Sky + operations · before S1
Assumed: strictly after cutover. Running them concurrently means building the deployment domain against a CRM whose schema is still moving, and splitting a small team across two migrations at once. If there is pressure to overlap, S1 is the only stage that could safely start early.
Needs · Sky · before phase 2 is planned
Assumed: retired entirely, per table, over the course of phase 2. A permanent partial Airtable is a legitimate alternative — some operational tables may never be worth rebuilding — but it is a different phase 2 and should be chosen deliberately rather than arrived at by running out of appetite.
Weightier since DR-01. Phase 1 now builds no Airtable integration at all, so "keep some tables indefinitely" no longer means "keep the mirrors running" — it means a permanent second system with no connection to the first.
Needs · operations + Sky · before S5
Assumed: nobody yet. Invoicing and Xero are an unassigned domain in the architecture, and neither phase claims them. If subscriptions are expected to produce invoices, that is a third phase or a phase 1 extension — not something phase 2 absorbs quietly.
Needs · finance + Sky · unscheduled
DR-10 (what a subscription hangs off) and DR-11 (handover — phase 1 or phase 2) stay in the phase 1 register. Both are decided during phase 1 even though they are felt in phase 2: DR-10 decides whether a nullable anchor column ships in M6 or is backfilled in S1, and DR-11 has already been answered for the part that matters — the assignment table ships in M5, only the screen is deferred.
06 · Build prompts
These are the S-prompts, in phase-2/prompts/. They are deliberately thinner than the M-prompts — the phase is scoped, not planned, and a prompt that pretends otherwise invents detail nobody agreed. Read S0 before any of the others.
Unless DR-35 has been answered to allow an overlap — and even then, S1 is the only stage that could safely start early. Building the deployment domain against a CRM whose schema is still moving is how both phases get slower.
crm/prompts/00-standing-context.md.
This phase gets planned first. 1. Answer DR-35 — it decides whether phase 2 exists yet. 2. Answer DR-12 and DR-41 together, with evidence rather than argument. 3. Give each stage its own document, with exit criteria, the way M1–M8 have. 4. Until then these prompts scope work; they do not authorise it.