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 counterpart650of 2,200 vendor items
Identical to the vendor original42
Comment-only — a dated note added, no behaviour change211
Code changed397+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

ProgramSourceAddedRemovedVendor → PSI
I.0001PBSBASE+1,028−748922 → 1,223
E0052PBSBASE+1,060−516 → 1,461 — see the warning below
CA1740PBSBASE+592−273774 → 1,104
W2PBSBASE+529−192261 → 747
VIMPBSBASE+419−214619 → 848
W.7270PBSBASE+391−235883 → 1,108
PO.0150PBSBASE+320−246866 → 954
CA1716PBSBASE+326−230790 → 907
CA1745.CAPBSBASE+831*−651*730 → 910

E0052 is a false positive — and it shows how to read this table

The vendor’s E0052 is a 17-line dispatcher that chains to E0052.COMM (866 lines) or E0052.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 CHAIN dispatcher — mostly small driver PROCs that don’t move the totals. The two E0052 rows overstate the aggregate by roughly 8%. Detail on the Product Master & BOM page.

E0052 is 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.

EraVolumeWhat was happening
1990–1999~980Original implementation and the long tail of fitting the package to PSI
2000424 — the single biggest yearY2K 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~370Maintenance trough
2015–2026~1,000The current era: END.OF.SHIFT automation, the *.1287 extensions, Power BI extracts, web/API integration

Authorship — and the concentration risk

InitialsChangesShare
JPT1,81361%
CFS45816%
RMS44715%
DLT1696%
BMC, DJA, others572%

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.

ProgramChangesSpan
VBBASE/WIPBMF.REV6581999–2026
VBBASE/WIPBMF.REV8511999–2024
PBSBASE/MRPSHRTS.AUTO501990–2017
VBBASE/WIPBMF.REV7441999–2023
VBBASE/VB_PART_ALLOCATION_INQUIRY.REV5422000–2024
PBSBASE/END.OF.SHIFT342015–2024
VBBASE/VB_POMAINTWRITE.REV5322000–2025
PBSBASE/TS.UPD281998–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 repairedUtilities touching it
PRODUCT24
LOTHIST15
OPENWO13
ITEMMANF12
BMF10
INVHIST8
JOBLEDGER.SUM8
ITEMQTY, EMPLOYEE, JOBLEDGER.INV, ITEMCA7 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 STOP ending a top-level program is normal, a CLEARFILE inside a rebuild utility is the point. Treat this as a reading list. Each needs someone who knows the program.

PatternRunning programsWhy it might matter
Unchecked EXECUTE461Runs a SELECT but never tests @SYSTEM.RETURN.CODE. A query matching nothing yields a silent empty pass — the run “succeeds” having done nothing
Bare STOP234Ends the whole run. Normal at the end of a top-level program, dangerous mid-flow — the END.OF.SHIFT failure mode
CLEARFILE117Empties an entire file
READU with no RELEASE108Safe when it always reaches a WRITE; a stuck record lock when it can exit first
Unguarded DELETE81Deletes without a guarded read on that key
Hard-coded host path82Breaks silently if a box or share is renamed
Two-digit year handling19Explicit century arithmetic
Hard-coded fiscal period5Silently 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

PassSourceOutput
Vendor manuals68 files at S:\Dept\Computer\Documents\PTIS2\AFTEC — LibreOffice for WordPerfect/Office, Tesseract OCR for three scanned PDFs (160 pages)799 program narratives
Catalog provenance3,318 objects in $UDTHOME/sys/CTLG hashed against 3,943 compiled objects under pro3progwhat each program name actually resolves to
Vendor divergenceAFTEC/ vs the running copy, indentation normalised, comments separated397 code-changed programs
Change timelinedated modification comments across every plain-text program2,947 entries
Riskrepair utilities and their targets; defect-describing comments; pattern scan restricted to running programsthe 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