Move two
A stage that anything can enter isn’t a stage. It’s a label.
Funnel One is a GTM platform for running a B2B funnel under one set of rules, from first touch to closed-won. Move two is the rulebook. You write what has to be true before a record may enter each stage, and the system refuses moves that do not meet it. Not a warning banner. Not a validation someone dismisses at four o’clock on a Friday. The record stays where it was, and the person moving it is told which condition failed.
The mechanism
The move is checked at the instant it is made.
Each stage carries its own entry conditions, and the gate reads that stage’s contract rather than a global setting. A stage can require fields on the company, on the related contact, or both. It can be marked as entered automatically, in which case nobody moves a record into it by hand at all. Backward moves are allowed or blocked at your discretion, once, for the whole org. And a move into Closed Lost or Disqualified asks for a reason from your list, before the move goes through, not after.
- Required fields, per stage. An ordered list, each entry a real field with a real control. The refusal names them; the drawer fills them.
- Related-record conditions. A stage can require something of the company’s contacts — an email on at least one of them, say. Zero contacts is an unsatisfied condition, not an edge case.
- Backward moves. One switch. Off means a record cannot go to an earlier stage, and an explicit undo is the only thing that bypasses it.
- A reason before the move. Chosen from a list you maintain. Some reasons can require a note, and then the note is required too.
- Owner assigned
owner_id is not nullOn - Qualification recorded
qualification.answered = trueOn - Meeting confirmed by owner
meeting.status = 'confirmed'On - Enrichment complete
company.firmographics != nullOff
One gate
A rule that only applies to one path isn’t a rule.
A rep dragging a card, an automatic rule firing, an AI worker acting on its own, two hundred records selected at once — the conditions are the same conditions. The bulk path resolves the stage’s contract once for the batch and applies it to every record in it, then reports back which ones it would not move and why, rather than moving them and leaving you to find out. The reason gate is literally the same function on both paths, which is the reason the two cannot drift apart over time.
Finish required fields
Northwind Logistics
- Owner assigned Priya Raman Pass
- Qualification recorded Budget confirmed Pass
- Meeting confirmed by owner Required to enter Qualified Blocked
Can't move here yet. Qualified requires a meeting confirmed by the owner. Confirm it and the move completes; until then the record stays in Working.
The record
Every move that happens is written down, and we can’t edit it either.
A transition row carries the record, the stage it left, the stage it entered, who moved it, what kind of actor they were — a person, a rule, a scheduled job, an AI worker — the reason given and when it happened. It is append-only, and not as a policy. The application’s database role is granted select and insert on that table and has had update and delete revoked, so Postgres itself refuses to rewrite history. That applies to our code exactly as it applies to yours.
What you cannot do yet is browse that history in the app. The record is written and it is reachable through the API; the timeline view is not built. We would rather say that than show you a screenshot of it.
Precision
Stage moves are refused. Other things are recorded.
Being exact about this matters more than sounding sweeping. Stage transitions are gated — including the disqualified, closed-lost and closed-won paths. Scoring changes, routing assignments and SLA clocks are recorded rather than refused: they are facts about what happened, not decisions asking permission. A sharp evaluator will look for this line. It is better that they read it from us.
Questions
What happens when the rules are wrong?
You change them. Rules are configuration rather than code, so there is no deploy and no ticket. Two things make that safer than it sounds. Nothing already recorded changes when you change a rule, so the history stays honest about what the rules were at the time. And you find out quickly, because a wrong rule refuses a move a rep is actively trying to make, and they will tell you within the hour. A rule that refuses is a rule you can debug.
Doesn’t this slow reps down?
It moves work rather than adding it. Today a rep moves a card and then does the five things that were meant to happen with it: fills the fields, logs the reason, tells the next owner. Or they do not, and somebody reconciles it on Thursday. Here the conditions are attached to the stage, so the rep sees exactly what is needed, fills it in the drawer, and the move completes. The moves that do get refused are the ones that were going to produce bad pipeline. Slowing those is the point.
Move two
You stop being the enforcement layer.
The rules move out of your head and into the stages, where the system applies them the same way every time — to a rep, to a bulk update, to an AI worker.