AFTEC Change Audit
Open the interactive AFTEC Explorer → — browse all 799 programs by functional area, filter by what runs / what PSI changed / what has drifted, with the change timeline, the risk register and a UniBasic primer.
Everything on this page is derived from the system, not written by hand: five passes over the source, the catalog and the vendor manuals, joined on program name. Regenerating it takes minutes. Method and caveats are at the bottom.
What PSI changed from the vendor baseline
AFTEC/ holds the untouched vendor source and — with zero compiled objects — never executes. Diffing it
against the copy that does run is the modification history.
One trap first. The two trees indent differently: AFTEC/ indents statement lines two spaces,
PBSBASE/ does not. A naive diff therefore reports every line of every program as changed and yields a
meaningless ~71,000 changed lines. All figures below are whitespace-normalised, with comment-only changes
separated from real code.
| Count | ||
|---|---|---|
| Vendor programs with a running counterpart | 650 | of 2,200 vendor items |
| Identical to the vendor original | 42 | |
| Comment-only — a dated note added, no behaviour change | 211 | |
| Code changed | 397 | +22,357 / −15,793 real code lines |
Concentration is near-total: 367 of the 397 live in PBSBASE, the rest scattered one or two apiece
across PBSUTIL, PRIMEBASE, REVBASE and others.
Note the denominator. Only 650 of 2,200 vendor items have a same-named running counterpart, and roughly
half of PBSBASE plus most of CABASE is encrypted. This is the plain-text intersection, not the whole
system.
Most-rewritten programs
| Program | Source | Added | Removed | Vendor → PSI |
|---|---|---|---|---|
I.0001 | PBSBASE | +1,028 | −748 | 922 → 1,223 |
E0052 ⚠ | PBSBASE | +1,060 | −5 | 16 → 1,461 — see the warning below |
CA1740 | PBSBASE | +592 | −273 | 774 → 1,104 |
W2 | PBSBASE | +529 | −192 | 261 → 747 |
VIM | PBSBASE | +419 | −214 | 619 → 848 |
W.7270 | PBSBASE | +391 | −235 | 883 → 1,108 |
PO.0150 | PBSBASE | +320 | −246 | 866 → 954 |
CA1716 | PBSBASE | +326 | −230 | 790 → 907 |
CA1745.CA | PBSBASE | +831* | −651* | 730 → 910 |
E0052is a false positive — and it shows how to read this tableThe vendor’s
E0052is a 17-line dispatcher that chains toE0052.COMM(866 lines) orE0052.DOD(736). PSI’s tree kept the pre-refactor monolithic program and grew it to 1,461 lines, so comparing the two by name compares a dispatcher against a whole program.Matching is by name, so wherever the vendor later split or renamed something the delta is meaningless. Of the 397 code-changed programs, 59 have a suspicious size ratio and 20 have a vendor file that is a small
CHAINdispatcher — mostly small driver PROCs that don’t move the totals. The twoE0052rows overstate the aggregate by roughly 8%. Detail on the Product Master & BOM page.
E0052is still heavily customised — line similarity to either vendor variant is about 0.24 — just not 16 → 1,461.
*CA1745.CA figures are pre-normalisation and overstated; the point stands that the labor update is
heavily modified.
The change timeline
PSI’s convention is a dated, initialled comment at the top of every program it touches. Parsed across the whole plain-text tree that is a codebase-wide changelog: 2,947 dated entries, 1989 to 2026.
| Era | Volume | What was happening |
|---|---|---|
| 1990–1999 | ~980 | Original implementation and the long tail of fitting the package to PSI |
| 2000 | 424 — the single biggest year | Y2K and platform conversion. FPLOCATE — PSI’s fiscal-period locate helper — was retrofitted across the ledger programs, and it is the most common single modification in the tree |
| 2001–2014 | ~370 | Maintenance trough |
| 2015–2026 | ~1,000 | The current era: END.OF.SHIFT automation, the *.1287 extensions, Power BI extracts, web/API integration |
Authorship — and the concentration risk
| Initials | Changes | Share |
|---|---|---|
| JPT | 1,813 | 61% |
| CFS | 458 | 16% |
| RMS | 447 | 15% |
| DLT | 169 | 6% |
| BMC, DJA, others | 57 | 2% |
One person accounts for 61% of every recorded change to this system. That is the key-person risk on the ERP migration expressed as a number rather than an adjective.
Where the work concentrates
Change count per program, with backup and dated copies collapsed. Sustained churn over decades marks either the most business-critical code or the most fragile — here it is generally both.
| Program | Changes | Span |
|---|---|---|
VBBASE/WIPBMF.REV6 | 58 | 1999–2026 |
VBBASE/WIPBMF.REV8 | 51 | 1999–2024 |
PBSBASE/MRPSHRTS.AUTO | 50 | 1990–2017 |
VBBASE/WIPBMF.REV7 | 44 | 1999–2023 |
VBBASE/VB_PART_ALLOCATION_INQUIRY.REV5 | 42 | 2000–2024 |
PBSBASE/END.OF.SHIFT | 34 | 2015–2024 |
VBBASE/VB_POMAINTWRITE.REV5 | 32 | 2000–2025 |
PBSBASE/TS.UPD | 28 | 1998–2025 |
WIP bill of material (WIPBMF) is the hottest code in the system — three concurrent revisions, ~150
changes between them, still being edited in 2026. Anything touching WIPBMF in the migration deserves
disproportionate attention.
Risk
Confirmed — what the evidence shows
Catalog drift. 3,318 cataloged objects; 2,877 byte-match a source item; 91 do not — the source on
disk is ahead of what runs. END.OF.SHIFT is the worked example: the cataloged copy is 2024-09-11, the
PBSBASE object 2025-02-24 and 8 bytes larger with an identical string table — a bare STOP compiled but
never re-cataloged. Recompile and catalog that program from current source and the nightly silently stops
doing most of its work. Full list on the
Reading AFTEC Source page.
171 repair and verification utilities (FIX.*, REBUILD.*, RESET.*, CHECK.*) exist in the tree.
Each was written because something breaks, so what they repair is a map of what goes wrong:
| File repaired | Utilities touching it |
|---|---|
PRODUCT | 24 |
LOTHIST | 15 |
OPENWO | 13 |
ITEMMANF | 12 |
BMF | 10 |
INVHIST | 8 |
JOBLEDGER.SUM | 8 |
ITEMQTY, EMPLOYEE, JOBLEDGER.INV, ITEMCA | 7 each |
Part master, lot history and work orders need repairing more than anything else — and three of the top ten are job-costing files.
59 change comments explicitly describe a defect (fix / error / wrong / corrupt / out of balance). A weak
signal — only 2% of entries, and most fixes aren’t described that way — but each is a real historical bug in
the author’s own words. Example, CA1745.CA, 2000-02-14, JPT: “CORRECTED ERROR IN SUB 2550…FPLOCATE PASSED
LEDGREC INSTEAD OF HREC”.
Inferred — code patterns worth a look
Unverified by design
These are pattern-matched code smells, not confirmed defects, counted only across programs the catalog says actually run. Many will be correct as written — a
STOPending a top-level program is normal, aCLEARFILEinside a rebuild utility is the point. Treat this as a reading list. Each needs someone who knows the program.
| Pattern | Running programs | Why it might matter |
|---|---|---|
Unchecked EXECUTE | 461 | Runs a SELECT but never tests @SYSTEM.RETURN.CODE. A query matching nothing yields a silent empty pass — the run “succeeds” having done nothing |
Bare STOP | 234 | Ends the whole run. Normal at the end of a top-level program, dangerous mid-flow — the END.OF.SHIFT failure mode |
CLEARFILE | 117 | Empties an entire file |
READU with no RELEASE | 108 | Safe when it always reaches a WRITE; a stuck record lock when it can exit first |
Unguarded DELETE | 81 | Deletes without a guarded read on that key |
| Hard-coded host path | 82 | Breaks silently if a box or share is renamed |
| Two-digit year handling | 19 | Explicit century arithmetic |
| Hard-coded fiscal period | 5 | Silently wrong once the calendar passes it |
The highest-value one is the first. In UniBasic a SELECT that matches nothing doesn’t error — the next
READNEXT simply returns nothing and the program completes normally. 461 running programs never check.
Method
| Pass | Source | Output |
|---|---|---|
| Vendor manuals | 68 files at S:\Dept\Computer\Documents\PTIS2\AFTEC — LibreOffice for WordPerfect/Office, Tesseract OCR for three scanned PDFs (160 pages) | 799 program narratives |
| Catalog provenance | 3,318 objects in $UDTHOME/sys/CTLG hashed against 3,943 compiled objects under pro3prog | what each program name actually resolves to |
| Vendor divergence | AFTEC/ vs the running copy, indentation normalised, comments separated | 397 code-changed programs |
| Change timeline | dated modification comments across every plain-text program | 2,947 entries |
| Risk | repair utilities and their targets; defect-describing comments; pattern scan restricted to running programs | the tables above |
Two standing caveats. The vendor manuals describe designed behaviour and PSI does not use all of it — the cost-accounting standards path is documented in detail and completely dormant (see AFTEC Job Costing & WIP). And the divergence analysis covers only the plain-text intersection, because much of the tree is encrypted.
Related: AFTEC Module Reference · Product Master & BOM · Routing · Reading AFTEC Source