Same rules, same data, same answer. Every time.
IMTG Engine was designed for CRM, matching sales to leads, and for learning management, matching students to courses. It works from generic rows and a versioned rule profile, so nothing in the decision path knows what a lead, a course or a house is. Allocate is the sample implementation in property matching.
Property matching, end to end. Every number traceable.
Rule profiles
Every parameter is a slider with its bounds. Each section draws its own radar so a policy has a shape, and the comparison chart moves live as you tune.
Scenario modelling
The engine runs twice on the same snapshot and seed, baseline versus draft. Every difference in outcome is attributable to the policy change and nothing else.
Matches
Each match carries its score decomposition as a radar and a one-sentence reason. Approval is a human step; the engine never adjudicates.
Dashboard
Queue, stock by remoteness, status, and the next match decomposed, all from the same versioned data.
Same inputs, same answer. Provably.
Deterministic
Same rule version, same data snapshot, same seed: a bit-identical result, forever. Every allocation names the exact rule hash that produced it.
Explainable
Points, not z-scores. Every criterion yields 0 to 100 points and the score is their weighted mean. A policy officer can recompute any score on paper.
Auditable
Nothing is deleted. Exclusions are flagged rows carrying a reason. The audit log rejects updates and deletes by trigger and by revoked privilege.
Fast enough to run inline
A statewide solve of 300 localities, 3,100 supply rows and 5,000 demand rows measured at 30 ms in Node. Counterfactuals cost 0.02 ms each.
Four defects were found and fixed on the way to the claim: locale-dependent string ordering that silently reordered tied rows between containers, a float jitter tie-break the solver could out-drift, an under-determined optimum that returned a different assignment on a mere row permutation, and row-level security that was decorative until forced. Each is now covered by a test. The tie-break is an exact integer cost with a seeded superincreasing term, provably unique.
Adding a domain is inserting rows.
The mechanism is the same in every case: a pseudonymised demand file keyed on the client’s own reference, a supply file, a rule profile, and a ranked, explained shortlist back. The client re-identifies at the point of offer.
The rules the engine will not bend.
- 01Feasibility never trades off against score. A hard constraint is binary.
- 02Priority serial dictatorship, not a welfare optimiser: a misreport only shrinks that request’s own feasible set.
- 03The optimiser exists but is advisory only. It powers scenarios; it never decides.
- 04Protected attributes are unrepresentable. The rule schema is strict, so a discriminatory key fails to parse.
- 05Declare the person, infer the place. No name, date of birth or age column exists on demand.
- 06Missing data is never silently treated as fit. Condition has four states, not two.
Have a demand-to-supply problem that needs a defensible answer?
The engine is ready for a new domain. The rule profile is the only thing that changes; Allocate shows what a finished implementation looks like.