Reading AFTEC Source — and Knowing What Actually Runs

Method notes for anyone doing AFTEC archaeology — ERP migration analysis, tracing a calculation, or answering “what does this screen actually do.” Verified 2026-08-07.

The one rule that matters: finding source in a directory tells you nothing about whether it runs. The UniData catalog decides, and the catalog can be older than the source on disk.


Where the source is

\\ad.ptihome.com\DFS\Data\LinuxShare\pro3prog\ (drive S: maps to \\ad.ptihome.com\DFS\Data). About 270 directories. Contents are current — items dated as recently as 2026-01.

DirectoryWhat it is
PBSBASEPSI’s PRO-III layer — the largest single source of running code
VBBASEPSI’s newer VB_* subroutine layer, called by the .NET/VB6 apps
CABASE, IBASE, SFBASE, SYBASE, POBASE, APBASE, …Base AFTEC modules — these run too
PBSUTILUtilities and one-off fixes
*PR (CAPR, IPR, MPR, …)Driver PROCs — always plain text
PBS.PARABatch paragraphs (DAILY.JOBS, WEEKLY.JOBS)
AFTECVendor source archive. Does not execute — see below
MENUFILEUniData hashed file; decodes to the whole green-screen menu tree

*.1287 in a program or file name marks a PSI-specific extension to base AFTEC.

Encrypted vs readable

PBSBASE is roughly half plain text (~948 of 1,885 items); PBSUTIL similar; PBS.PARA and the *PR PROC directories are entirely plain text. CABASE, PROBASE, UBASE and much of VBBASE are encrypted with the AFTEC stream cipher.

Don’t try to decrypt. Read the compiled companion instead: every source item X has an object item _X in the same directory, and the object keeps a null-separated literal table containing every OPEN’d file name, the "<FILE> FILE (<FILE>)" open-error text, screen headings and prompts. That is enough to build a program → table cross-reference for the whole system.

Two shortcuts worth trying first: an encrypted CABASE/X often has a plain-text twin at PBSBASE/X or AFTEC/ACT.X, and the plain-text driver PROC in CAPR usually reveals the batch sequence.


The catalog decides what runs

Cataloging is a deliberate, per-program act — someone ran CATALOG <file> <item>. There is no directory-precedence rule; no layer “supersedes” another.

A locally cataloged program leaves a type-C record in the account’s VOC, with the source file and item in attribute 3:

C  ⁞  /home/pro3/CTLG/CA1745.CA  ⁞  PBSBASE CA1745.CA

Most programs are globally cataloged instead, with the objects in $UDTHOME/sys/CTLG and no VOC entry. A copy of UniData home sits at S:\mrp1\DataBackup\ud.backup. Note the catalog directory is hashed into single-letter subdirectories — CTLG/e/END.OF.SHIFT — so recurse when you look.

How PSI catalogs a program (John Tymes)

Most AFTEC programs are cataloged straight out of the editor with fibegf:

LetterMeaning
fifile — save
bcompile binary
ccatalogue
gglobal
fforce

fib saves and compiles only — no catalog, which is how source gets ahead of production. PROCAT catalogs already-compiled code through a prompt sequence.

The prefix rule — get this wrong and nothing works

Many programs in AFTEC and PBSBASE are named as a letter-group, a period, then the name — I.1656, I.0001, MRP.6810P, PO.0150. The cataloged name drops the prefix. PBSBASE/I.1656 is cataloged as 1656; IPR/I.0005P as 0005P.

Verified across the catalog — every one of these resolved by hash:

Cataloged asSource item
1656PBSBASE/I.1656
0001PBSBASE/I.0001
0005PIPR/I.0005P
0007IBASE/I.0007

If someone compiles and catalogs one of these with the prefix, it will not work — not from the AFTEC menu, and not as a called program or subroutine, because every existing CALL and menu entry references the unprefixed name.

This also matters when reasoning about the catalog: a name-based comparison must try the prefix-stripped form, or prefixed programs look like orphans. Four did in the first pass here.

Resolving provenance by hash

CATALOG copies the object. So you can identify what a program name resolves to by hashing the catalog object against every _NAME object in pro3prog. Results as of 2026-08-07, over 3,318 catalog objects and 3,943 compiled source objects:

ResultCountMeaning
Exact byte match to a source object2,877Provenance proven
Same name, different bytes91Recompiled after cataloging — source on disk is not what runs
No matching source item in pro3prog350Source lives elsewhere, or was deleted

43 different source directories feed the catalog — PBSBASE 864, VBBASE 317, CABASE 193, SFBASE 115, IBASE 113, SYBASE 111, UBASE 94, APBASE 84, POBASE 83, and on down. The module directories all run.

AFTEC is the sole exception — 0 of its 2,202 items source any cataloged object. It holds no compiled objects at all, so there is nothing to catalog. Treat it as reference material only.


The drift hazard

Because CATALOG copies, recompiling without re-cataloging leaves the catalog copy running while the source moves on. 91 programs are in that state. For those, reading pro3prog source tells you what someone intended, not what production does.

The live example that proves it matters:

END.OF.SHIFT catalog copy (what runs)2024-09-11
PBSBASE/_END.OF.SHIFT object2025-02-24, 8 bytes larger, identical literal table

An identical literal table with a small size delta means a pure control-flow change — and it is: a bare STOP added early in the nightly, which would strand timesheets, WIP receipts, WIP close and the entire evening financial block. It was written, compiled, and never re-cataloged, so it never went live. Confirmed by behaviour: JOB.IP.1287 is written every night by a step that sits after the STOP.

If anyone recompiles and catalogs END.OF.SHIFT from current source, the nightly silently stops doing most of its work. Same shape of risk applies to the other 90.

The 91

Four sit in the job-costing path — END.OF.SHIFT, PBS1803 (inventory valuation, writes the G/L side of JOB.IP.1287), VB_W.7285 (WIP receipts), VB_JOB.COST.REV1 (the SO Manager Job Cost tab) — along with GET.MAT, RPT.WIPLEDGER, TS.UPD and FIXJOBHRS.

The rest, by directory: PBSBASE 51, VBBASE 32, PBSUTIL 9, PROBASE 3, GLBASE / IBASE / UBASE / WBASE 2 each, and one apiece in APBASE, ARBASE, PAYBASE, PCNBASE, POBASE, SYBASE, TESTBASE. Notable names include MENU.PROCESSOR, MRP.DAILY, NOTIFY.REDBOOK, SEND.NOTIFICATIONS, PROCESS.NOTIFY, WIPBMF.REV6, VB_PORECEIPT.REV2, VB_POMAINTWRITE.REV5 and most of the RPT.* Power BI extract programs.

Two caveats before treating this as a to-do list. Drift means the bytes differ — not that the newer source is correct; some of it is parked work-in-progress. And the 350 catalog objects with no source item in pro3prog are a separate unknown: their source is either somewhere not searched or gone.


Reproducing the analysis

  1. Copy $UDTHOME/sys/CTLG (3,318 objects, ~seconds over SMB with robocopy /MT).
  2. Copy every _* item under pro3progrobocopy S:\LinuxShare\pro3prog <dst> "_*" /S /MT:32.
  3. SHA-256 both sides, recursing into the catalog’s letter subdirectories. Exact match proves provenance; same-name-different-bytes is drift; the catalog copy wins.
  4. For drifted or unmatched objects, extract the null-separated literal table and match on content.

A faster first pass, if you only need one program: sha256sum the catalog object on the host and grep the source tree for a match, rather than copying anything.

Two gotchas that will skew the numbers if you miss them: recurse into the catalog’s letter subdirectories, and try the prefix-stripped name when matching by name — four programs were mis-filed as orphans in the first pass here for exactly that reason.


The original AFTEC documentation

S:\Dept\Computer\Documents\PTIS2\AFTEC\ holds the vendor’s own manuals — 71 files, mostly WordPerfect, one per module, with screen layouts, field-by-field descriptions and per-program narratives. This is the authority on what a program was designed to do, which is often not what PSI actually uses it for.

FileCovers
CABASE.wpd (710 KB)Cost accounting — job/WIP ledgers, roll-ups, financial release/relief/close
IBASE, WBASE, SFBASE, POBASE, GLBASE, APBASE, ARBASE, MRPBASE, OBASE, PAYBASE, SYBASE, EBASE, FSBASE, PMBASE, PBBASE, MBASE (.wpd)The other modules; several have a …OVER.wpd overview companion
AftecPro3Master1–3.pdf (12 MB)The PRO-III master manuals
GENERAL.WPD, PRO3PROG.WPD, aftecdoc.wpd, Timesheets.wpd, JOBHRS.WPD, WORKFLOW.WPDCross-cutting notes

Convert with LibreOffice (installed locally, and on PS-PROXY):

& 'C:\Program Files\LibreOffice\program\soffice.exe' --headless --norestore `
  -env:UserInstallation=file:///C:/Temp/lo_profile `
  --convert-to txt:Text --outdir <out> <files>

Batch roughly 80 files per invocation — passing them all on one command line exceeds the Windows command-length limit.

The parsed result is published as the AFTEC Module Reference — 799 programs across 19 modules.

Reading source and narrative together is what separates “this program writes that file” from “this is what it was for, and PSI stopped using it.” The job-costing page has a worked example: the vendor narrative shows CA1777/CA1778 are the standard-cost roll-up gated on financial release, which explains why PSI — who never adopted financial release — posts actuals directly instead.