Plumbline

Method

Owners take these findings into a conversation with their contractor. So the findings have to survive being argued with.

A compliance tool is only worth anything at the moment someone disputes it. That moment sets three constraints, and they are the whole design.

Every number traces to a page

A finding carries the document it was read from and the page number within it. If a broker says the umbrella is five million, the finding says which certificate said two, and where. Findings with no document behind them say so explicitly rather than quietly disappearing.

The engine is deterministic

Every rule is a SQL predicate over normalised columns. The same data produces the same findings today and in six months. There is no language model anywhere in the path that produces a finding, no confidence score, and nothing that can be re-generated into a different answer. A rule either fired or it did not, and the rule book is published.

The hard part is the history, not the rule

The naive version of the coverage rule reads the current certificate and compares its effective date to notice to proceed. It flags almost every long-running subcontract on the job, because a renewal certificate always begins after work started. The rule that is actually correct walks the whole certificate chain with a window function and looks for breaks between consecutive periods. That distinction is the difference between a tool an owner trusts and one they turn off in a week.

-- The continuity rule, in full. It is the only place in the product where
-- "is this subcontractor covered" is decided.
create or replace view v_gl_history as
select d.id, d.subcontract_id, sc.notice_to_proceed,
       d.effective_on, d.expires_on, d.source_page, d.file_name,
       lag(d.expires_on) over w as prev_expires,
       row_number()      over w as period_no
from documents d
join subcontracts sc on sc.id = d.subcontract_id
where d.kind = 'coi_gl' and d.effective_on is not null
window w as (partition by d.subcontract_id order by d.effective_on);

create or replace view v_gl_gaps as
select *, (effective_on - prev_expires - 1) as gap_days
from v_gl_history
where prev_expires is not null
  and effective_on > prev_expires + 1;

Built on

Next.js App Router with server components querying Postgres directly, Supabase for the database, Tailwind, deployed on Vercel. The derived state lives in SQL views rather than in application code, so the numbers on the screen and the numbers in a report are the same numbers by construction.

About this demonstration

The portfolio here is synthetic: six projects, forty-four subcontracts and several hundred documents, generated with a fixed seed so the same defects appear every time. Dates are stored relative to the current date, so a certificate that expires in nine days still expires in nine days whenever you open this page.