Compound Labs
Get the newsletter
THE STANDUPAnthropic fixes Claude 5.1 error spikesERROR SPIKES, FIX DEPLOYEDCOMPOUND MASTODONSkillWorks records inactive files beside their roster status22 INACTIVE FILES STILL LOADCTXWINDOWContext Window tracks AI lab changes and filters their evidenceFILTERS KEEP EVIDENCE TOGETHERAGENTWIREmicrosoft/agent-governance-toolkit - AI Agent Governance ToolkitPOLICY ENFORCEMENT FOR AI AGENTSCOMPOUND FACEBOOKCompound Portfolio restores its sweep after a missing module stops desk dataSWEEP RESTORED, DESK DATA WRITTENBLOCKDEXBlockDex shows no destination for captured rows with rejected slash names31 ROWS, NO DESTINATIONCONTEXT WINDOWOpenAI adds 1024p image pricing: $0.50 and $0.251024P IMAGE, $0.50 AND $0.25COMPOUND BLUESKYCompound Labs renamed job labels so job-run finds breaker stateBREAKER STATE, NOW FINDABLECTXWINDOWContext Window tracks document changes but failed mobileMOBILE WORKFLOW, ONE COLUMNAGENTWIREMineDojo Voyager: Open-Ended Embodied AgentOPEN-ENDED EMBODIED AGENTFOUNDER BLUESKYdeploy.sh now fails false Vercel production landingsFALSE LANDINGS NOW FAILCOMPOUNDlast known fixes redirect tracking after migrationSTUDIO SOURCES NOW SAY COMPOUNDCONTEXT WINDOWOpenAI adds sora-2-pro pricing720P VIDEO, $0.15, $0.30FOUNDER LINKEDINdeploy.sh now stops failed promotes from marking production landedFAILED PROMOTES NO LONGER LANDUSINGITUPUsing It Up records a receipt fixing a wobbling wooden tableONE RECEIPT, TABLE STAYED LEVELCOMPOUNDpnpm v12.4.2POSIX BIN SHIMS REPLACEDFOUNDER PEERLISTCompound Labs' deploy runner rejects failed promotesFAILED PROMOTES NO LONGER LANDTRUSTDESKTrustDesk fixes host migration redirects while keeping /api/ outOLD HOST, 308; API STAYS LIVE
Independent product R&D labFounded and run by Isaiah Kim, @kyisaiah47Newest commit Sep 16, 2026, AgentwireNewest writing Sep 16, 2026Site changelog Sep 16, 2026
Aug 22, 20264 min read

A scanned checkbox needs three states, and two of them send the identical email

A tree crew drops a limb through a clubhouse roof. Whether the homeowners association pays for that or the tree company's insurer does can turn on a quarter-inch tick box, in a column headed...

A tree crew drops a limb through a clubhouse roof. Whether the homeowners association pays for that or the tree company's insurer does can turn on a quarter-inch tick box, in a column headed ADDL INSD, on a scanned PDF a property manager filed eleven months ago.

That page is an ACORD 25 certificate of insurance. A ticked box in that column means the association is named on the vendor's policy and can claim under it. Blank means it is not. The certificate is what a manager puts in front of a board, and if it ever matters, in front of an adjuster.

A machine reading that page gets three answers, not two: ticked, plainly blank, and unreadable.

The schema has to have somewhere to put "I could not tell"

If the field is declared as a plain boolean, the model has to pick one. It will pick one, and it will sound just as sure as it does on a clean scan. So the field is declared with room for the third answer:

additionalInsured: {
  type: ["boolean", "null"],
  description:
    "The ADDL INSD column. true if ticked, false if plainly blank, null if it cannot be read with confidence.",
}

The reader's instructions say why, in the sentence that governs the whole product: "Return true only when the box is clearly marked, false only when it is clearly blank, and null when the scan is ambiguous, cut off, or too degraded to call. A wrong true here means an association believes it has coverage it does not have."

CoverCheck interface showing insurance certificate requirements and approval workflow, Insurance coverage types organized by requirement with specific approval status for each.
CoverCheck interface showing insurance certificate requirements and approval workflow, Insurance coverage types organized by requirement with specific approval status for each.

Blank and unreadable are different findings

if (req.additionalInsuredRequired) {
  if (policy.additionalInsured === false) {
    findings.push({ code: "ADDITIONAL_INSURED_MISSING", severity: "blocker", ... });
    compliant = false;
  } else if (policy.additionalInsured === null) {
    findings.push({ code: "ADDITIONAL_INSURED_UNKNOWN", severity: "review", ... });
    compliant = false;
  }
}

Both branches set compliant = false. A blank box is the vendor's paperwork problem and it blocks. An unreadable box is our reading problem and it goes to a person. Neither one is a green tick, which is the rule the engine is built around: unknown is never a pass.

One requirement has no box anywhere on the form

Boards routinely ask that a vendor's liability cover be "primary and non-contributory", meaning the vendor's insurer pays first and the association's own policy is not dragged in alongside it. The ACORD 25 has no column for it. It appears, if it appears at all, as free text in the Description of Operations block.

That asymmetry decides the verdict. Finding the phrase confirms it. Not finding the phrase confirms nothing, because the form was never going to carry it. So the engine's worst possible answer here is "unconfirmed", never "missing", and it is always a review item.

Agents type that phrase a dozen ways, so the matcher flattens hyphens, slashes and commas, then collapses "non contributory" and "noncontributory" onto one spelling before comparing. A test feeds it "Coverage is primary and non-contributory.", "primary and noncontributory per written contract" and "PRIMARY AND NON CONTRIBUTORY", and expects the review item to stay off all three.

What the page showsStored valueFinding code and severityOverall verdict
ADDL INSD tickedtruenonecounts toward compliant
ADDL INSD plainly blankfalseADDITIONAL_INSURED_MISSING, blockernon_compliant
ADDL INSD too degraded to callnullADDITIONAL_INSURED_UNKNOWN, reviewneeds_review
No box exists (primary and non-contributory)free text, or nothingPRIMARY_NONCONTRIB_UNCONFIRMED, reviewneeds_review

Three verdicts, two emails

The distinction that matters to a board disappears at the point of action. The draft email to the vendor's insurance agent is built from the finding code, and ADDITIONAL_INSURED_MISSING and ADDITIONAL_INSURED_UNKNOWN fall through to the same sentence, word for word: name the association as additional insured by endorsement and attach the endorsement, because the ADDL INSD box alone is not evidence of it. Whether the box was blank or unreadable, the agent does the same afternoon's work.

One code produces no ask at all. EXTRACTION_UNCERTAIN, raised when the reader flagged a field it could not resolve, returns null from that switch, with a comment saying there is nothing to ask the agent for: it is our read that was uncertain, not their paper.

This is how we built CoverCheck: https://covercheck.thecompound.tech/?utm_source=compound-devto&utm_medium=social&utm_campaign=compound

---

One shipped product, taken apart, once a month. What it does, what it cost to build, what the pipeline behind it looks like, and what the numbers did, read off the repository and the live site, not written from memory. Join the list.

All writing