Operator manual

How to run it, and what every answer means.

Published in full. Written for the person who will use the software, not for the person who signs for it.

Version 0.2.0 · Revised 12 October 2026

01What this is

Two tools that read construction documents

The contract engine reads a subcontract you are already bound by. It compiles every clock, gate, threshold and forfeiture the contract imposes, then flags the clauses that will cost you money.

The tender intake reads a tender you have not bid yet. It pulls the dates, the requirements, the bill and the terms, and drafts a proposal with every gap marked.

Installed on your own machine, both run there entirely. Nothing is uploaded, nothing is sent anywhere, and neither tool needs a network connection once installed. The hosted console is the same software on a server in Riyadh: you sign in, the file goes to that server over an encrypted connection, and it is read there.

The principle behind it

The engine refuses rather than guesses. When it cannot read a value, it says so and gives you the candidates. When a document is not signed, it will not give you a settled verdict. A tool that quietly picks the wrong number is worse than no tool at all.

02Installing it

Two steps, about five minutes

1. Install Node

Node version 18 or newer. Download it from nodejs.org, take the LTS option, accept every default. Check it worked by opening a terminal and typing:

node --version

Anything from v18 upward is fine.

2. Unzip the package

Put the folder wherever you keep working files. There is nothing to install and no administrator rights are needed. The tool has no dependencies at all, so there is no npm install step and nothing is fetched from the internet.

Optional, for PDF files

Reading PDFs needs Poppler, which provides pdftotext and pdfinfo. Word, Excel, HTML and text files are read natively and need nothing.

PlatformCommand
Windowswinget install oschwartz10612.Poppler
macOSbrew install poppler
Linuxsudo apt install poppler-utils

03Starting it

Double click, and it opens

Double click Kontra+ in the folder. It checks that Node is present, finds a free port, starts the engine and opens the screen in your browser. The first time you run it, it also puts a Kontra+ shortcut on your desktop, so from then on it behaves like any other program.

Closing the black window stops it. Nothing keeps running in the background and nothing is installed.

Opening a job directly

The address bar takes a file, so a shortcut can point straight at a live job: http://127.0.0.1:7801/contract?file=C:\path\to\contract.pdf. Repeat &file= for the Appendix and each amendment.

Prove it works before you trust it with anything

Open a terminal in the folder and run these two commands.

npm test
npm run demo

npm test runs 527 checks: the contract engine and the tender intake against a contract that ships with the software, the knowledge base against the clause records and the statute library, and the register against published contracts the engine had never seen. It should finish with all green. If it does not, stop and read Troubleshooting rather than continuing.

npm run demo prints a full analysis of that same contract. It is a deliberately one sided fit-out subcontract written for this purpose, with every party and figure invented. Read the output once before you put a real contract through it, so you know what a complete result looks like.

04Reading a contract

One command, one or more files

node src/cli.js "conditions.pdf" "appendix.docx"
Pass every part of the contract together

The printed conditions and the Appendix are one contract, and the Appendix is where the money is. Reading only one of them produces a confident, incomplete answer, which is more dangerous than no answer. Include every amendment and every annex you were given.

To keep the result as data rather than text:

node src/cli.js "contract.pdf" --json --out profile.json

Accepted formats: .pdf, .docx, .xlsx, .html, .txt, .eml.

05Reading the report

Six blocks, in the order they matter

Provenance

Whether this is the signed contract. NOT_EXECUTED means blanks or signature lines remain, which is normal for a contract under review. The plan still compiles, but no clause verdict is presented as settled.

Document type

Whether it reads as a contract at all, with a confidence percentage. Below about 50 per cent, treat everything after it as unreliable.

Commercial terms

Retention, advance, performance security, mark up, caps and periods, each with a confidence marker.

MarkerMeaningWhat to do
HIGHRead cleanly from the AppendixUse it
COLLIDEDTwo figures printed on top of each other by the conversionBoth candidates are given. Confirm against the signed original
NOT_FOUNDNot located in the documents suppliedCheck you passed every part of the contract
Why a collision matters

A revised figure rendered over the one it replaced reads as 2412 months, which is not a real value. It is either 24 or 12, and the difference is a year of liability. The engine will not choose for you.

Payment milestones

The schedule and whether it closes at 100 per cent. A schedule that does not sum to 100 means a stage is missing or misread.

Compliance plan

PartWhat it holds
HeartbeatsRecurring duties that must run without a gap while an event lasts
TriggersClocks that start when something happens on site
AnchorsOne off duties dated from the award
GatesWhat must be true before money moves
ForfeituresThe duties where missing the deadline destroys the entitlement

Read the forfeiture register first. It is the short list of ways to lose a claim on the calendar rather than on the facts.

Risk register

Each finding carries the sentence quoted from the contract, what it means in money, and the amendment to ask for. The verdict is set by how many critical findings there are.

VerdictTrigger
DO NOT SIGN WITHOUT NEGOTIATIONFour or more critical findings
NEGOTIATE THE CRITICAL ITEMS FIRSTOne to three critical
ORDINARY RISK, WORTH A READFindings, none critical
NOTHING FLAGGED, WHICH IS UNUSUALNothing matched. Read it yourself

The last one is not a pass. It usually means the document is not a construction subcontract, so the patterns do not apply.

06Tracking a live event

The part that saves the claim

A compliance plan is only worth having if something runs against it. Feed the plan an event and it returns every obligation that event opened, which are still live, which were missed, and which of the misses destroyed an entitlement.

node test/eot-scenario.js

That runs the worked example on the demo contract. It prints the same delay event twice, side by side.

What was doneResult
Nothing servedENTITLEMENT LOST
Notice served on day five, particulars kept runningSLIPPING, zero forfeited

Same event, same contract, same facts. The difference is a notice served on time.

When an obligation has been missed, the engine returns salvage routes rather than stopping: serve it late anyway, check when the clock actually started, check whether the same failure affects the main contractor upstream, and move the value to a route that has not expired.

To run it against your own contract, pass the file:

node test/eot-scenario.js "your-contract.pdf"

07Reading a tender

Before you commit to bidding

node src/rfp/cli.js "tender files..."

Pass the whole pack together: the instructions, the scope, the bill, the draft conditions and every addendum. They are one tender. Excel bills are read natively.

You get the submission clock with everything ambiguous flagged, the requirements with the disqualifying ones separated, the bill read back, the terms that will cost you, and a drafted proposal with every gap marked rather than invented.

TaskCommand
Draft the proposal and bid file--proposal proposal.md --bidfile bid-file.md
Compare two revisions for scope drift--diff "earlier.txt" "later.txt"
Create your bidder profile--init-bidder bidder.json
Scope drift

The diff exists because scope grows quietly between revisions. It reports what was added, removed or reworded, so a revised enquiry does not get priced against the original reading.

08The interface

For people who do not use a terminal

Double click Kontra+, or run it from a terminal:

npm start

The console has two screens, switched from the header.

ScreenFor
ContractA subcontract you are already bound by. Drop the files in and press Read the contract. On your own machine you can also open Browse this computer, which stays closed until you ask for it
TenderA tender you have not bid yet. Same file handling, different reader

Once a contract is read, the header carries the project name and the subcontract number, and the page opens on the project overview: the engine verdict, the traps by tier, the next notice deadline, the forfeiture clocks and the number of rules compiled. Below it sit six tabs.

TabWhat it holds
OverviewThe highest ranked traps, what was read from each file, the money terms and what to check before you rely on the reading. Read What was read first: a file that produced no text is a scan, and everything else was read from the remaining files only
Trap registerEvery finding, worst first, with its clause and what it does to you. Open a row for the clause as written and what to ask for
RedlinesEach flagged clause struck through beside the position to ask for instead. Copy the asks puts the whole list on the clipboard
ClocksEvery notice clock, grouped by the event that starts it, forfeitures first. Enter the date the event happened and each deadline is dated with the days left
TermsThe commercial figures with their confidence, collisions shown with both candidates, and the payment milestones
Full reportThe same output the command line prints. Copy report and Print sit beside the tabs

Two things on the screen are yours, not the engine's. Type the contract value into the money terms and the console works out what retention, security and the delay damages cap come to in riyals. Enter an event date in Clocks and it dates the deadlines that event opened, in calendar days, so check the contract's own definition of a day. Both are kept in your browser only and come back when you reopen the same subcontract.

It is bound to this machine on purpose

The interface listens on 127.0.0.1 only, and it reads and writes files anywhere on the machine, which is what a tender tool has to do. Do not expose it to a network or forward its port. It has no authentication because it is not meant to be reachable by anyone but the person sitting at the keyboard. The hosted console puts a sign in and a web server in front of it, and that server refuses folder browsing and file saving outright.

09When it refuses

A refusal is a result, not a failure

What you seeWhat it meansWhat to do
UNREADABLEA scan with no text layerRun it through optical character recognition first, or get the original file
NOT_A_CONTRACTReads as something else entirelyCheck you passed the right document. An empty result here means the wrong file, not no obligations
CONTRACT_OUTSIDE_SCOPEA real contract, but not a construction subcontract or tender, such as a services agreement, or an employment contract (including a Qiwa contract), which it names as oneNothing was reviewed and no findings is not a clean result. Have it read by someone who reviews that kind of agreement. For an employment contract the Labour pack is coming
NOT_EXECUTEDA draft, comparison or unsigned copyUse the plan, but get the signed original before relying on a clause verdict
TEMPLATEAn unfilled formThe numbers have not been written yet. An empty plan is correct
PARTIALSome contract signals, not enough to be sureRead the output with care and verify anything you act on

10What it cannot do

Stated plainly, so nothing surprises you

  • Scans need the opt in reader. A scanned signed contract with no text layer is refused. On the command line, --ocr=local reads it on this computer with a vision model running in LM Studio, so nothing leaves the machine; it takes about a minute and a half a page. --ocr instead sends the page images to an outside transcription service, so it is off unless you ask for it. The console uses neither. Numerals inside stamps and handwriting are the weak points of both.
  • Party and appendix extraction is narrow. It reads specific subcontract conventions. On documents written to other conventions those fields come back empty rather than wrong.
  • It is one machine, one operator. There are no accounts, no roles and no shared history.
  • It does not store anything. Output is files and terminal, or the page in your browser. There is no record of who ran what.
  • It is not legal advice. It reads what the document says and tells you what it will do to you. Whether to sign is a commercial and legal decision.
What generalises well

The risk register and the refusal behaviour hold up on documents the engine has never seen. On an unfamiliar subcontract it found 17 findings, each quoted from the text. That is the part you can rely on from day one.

11Troubleshooting

The five things that actually go wrong

SymptomCause and fix
node: command not foundNode is not installed or not on your path. Reinstall from nodejs.org and open a new terminal
Everything is empty and the verdict is UNREADABLEA scanned PDF, or Poppler is missing. Check with pdftotext -v
Terms are NOT_FOUND on a real contractThe Appendix was not included. Pass every part of the contract in one command
Milestones do not sum to 100A stage was missed in conversion. Check the schedule by eye against the document
The interface will not openPort 7801 is in use. Run node src/rfp/server.js 7802 and use that port

If npm test does not finish green on a clean copy, do not use the output for anything. Report it with the failing test names.

12Command reference

Everything, on one page

CommandWhat it does
npm test527 checks. Must finish green
npm run demoFull report on the contract that ships with the software
Double click Kontra+Starts it and opens the screen. The normal way in
npm startThe same thing from a terminal, on port 7801
node src/cli.js "files..."Read a contract
node src/cli.js "files..." --json --out p.jsonSame, as data
node src/rfp/cli.js "files..."Read a tender
node src/rfp/cli.js "files..." --proposal p.md --bidfile b.mdDraft the proposal and bid file
node src/rfp/cli.js --diff "a.txt" "b.txt"Scope drift between two revisions
node src/rfp/cli.js --init-bidder bidder.jsonCreate a bidder profile
node test/eot-scenario.js ["file"]The delay scenario, end to end
node test/hr-scenario.jsThe workforce scenario, Saudi Labour Law

Put Kontra+ on your own computers.

The NDA is signed before anything is sent. We reply the same working day.