SA Strategic Agent Grounded on your own records
The conversion layer

It never loses a file,
and it is never stopped by one

Trust is the product, and the conversion layer is where it is earned. Two promises, each with a mechanism behind it: nothing is dropped without a written reason, and no single bad file can halt the run. Both were learnt on real archives, the hard way, and the failures are published here rather than tidied away.

Never lost, never stopped

~2,250Unique files a minute after per-file isolation, up from ~3
0False quarantines at that rate
~578 → ~3.doc timeouts once the daemon was dropped for a single-shot reader
1,097,899Dead source paths repaired to zero

Every tool that reads documents works on the tidy majority. The difference is what happens on the rest: the file that hangs the reader, the listing that names a file the disk does not hold, the retry that looks like progress. This page is about the rest. The figures are from the engineering record; the approximate ones carry a tilde.

Two promises, stated exactly

what "never" means

Never loses a file means never silently. It does not mean every file is read: 787 legacy Office files have no reader, 962 are stuck in a cloud drive, photographs are media-only, and two Archive files hung the worker and are quarantined for a person. Each has a row in the manifest with a status and a reason. The promise is that the list of what did not come through is as complete as the list of what did.

Never stopped by one means the run finishes. A corrupt file, a missing one, a file that locks the reader inside C code — each costs one file's timeout and one row. None halts the pipeline, and none is reported as anything other than what it was.

A hang costs one file, not the run

the headline result

The first version read legacy .doc files through an office daemon. Two faults compounded: each file waited on the previous file's profile lock, and the timeout could never fire because a grandchild process held the output pipe open. Across the SIG tree that was ~578 stalls, the worst bottleneck. A native, single-shot converter that cannot hang took it to ~3, marked doc-needs-relo for a contained re-sweep. The lesson: prefer a single-shot tool, and assume any converter will hang.

Then a malformed PDF froze the extraction lane, and this was worse: the hang was inside the PDF library's C code, where no Python timeout can reach. The only defence is process isolation — run the risky parse in a short-lived child, give it no output pipe to deadlock on, put it in its own process group, and kill the group on a hard timeout. Every risky read now runs that way.

Before that, the backstop was an external watchdog that restarted the whole worker when the manifest stopped growing. It recovered, but every hang cost the full stall window plus a re-walk of the tree; on a hang-dense folder most of the wall-clock went to waiting. Unique throughput was ~3 files a minute. With each file in its own child and a short hard timeout it is ~2,250 a minute, with zero false quarantines — no good file marked bad because the worker was slow. Two trees of the same company's records differed enormously in hang density. The rule: you cannot predict the pathological few percent, so a hang has to be cheap, not merely survivable.

The storage layer will lie to you

before the file formats do

The most surprising failure was not a file format. A storage layer reported files it did not hold: offloaded to a cloud drive, still in the directory listing. The reader tried to open what was not there, failed or hung, and quarantined them — 87% of the files in one region, not one of them bad. The sentence that went into the record:

The storage layer will lie to you before the file formats do.

The rule now: a file the storage layer names but cannot deliver is reported as absent, with the error type in its status — never marked corrupt, never quietly passed over. The 962 cloud-stuck files in the proving corpus are reported that way today: a count a person can act on.

Progress that was not

three smaller lessons

A retry loop once made a manifest 3.6 times larger than the truth: 15,800 rows over about 4,400 real files, because every failed file was tried again on every restart. The rule now: a failed extraction is terminal, retried only in a bounded re-sweep a person starts, and progress is counted in unique files, never rows. The manifest page tells it in full.

A hard kill once landed mid-row and left a truncated line that crashed every restart at the same place; now it is one writer, every row committed whole, and a reader that skips a row with no path. And the OCR lane once built its entire worklist in memory before reading a page, ran out of memory and looped; it now takes its worklist from the manifest.

Originals are never touched

copies know their way home

Nothing on the source side is written to, renamed or moved; the readable copies go to a separate folder that can be deleted and rebuilt. Every copy carries the path of its original, the method that read it and its status, so a quoted line can always be traced to the file on your disk. A copy that has lost its original's address is a loss too, and is counted as one: when a move left 1,097,899 source paths pointing at nothing, they were repaired to zero.

What this page does not promise

It does not promise everything is readable — the gaps are counted above and on what it cannot read. The throughput and quarantine figures are the record's measurements of the proving run on the founder's archive, not a guarantee about yours; a different archive has its own pathological few percent. Nothing filed after 2026-07-22 is in any proving corpus. What is built, specified and never run is on the record.

Where to go next

three pages
Every file, one status

The manifest

The full status vocabulary, and the counting rule in detail.

Open ▸
Plain words

What it cannot read

The gaps, for someone who has never used a terminal.

Open ▸
Built · specified · never run

The record

Every unfinished item, with what would close it.

Open ▸