SENTINEL/i — Personal Auto & Property Insurance Core

SteelFrame X application operation manual  ·  ← back to Operation Manuals  ·  Sign On

SENTINEL/i is a personal-lines (auto + property) insurance core system: party/producer masters, policy administration across the full lifecycle (issue → endorse → renew → cancel), risk/coverage items with rating-driven underwriting, installment billing and oldest-due-first cash application, a claims workflow (FNOL → adjudication → payment), agent commissions, and a balanced GL posting feed cross-checked debits=credits. It is a classic AS/400-native application: column-exact DDS physical/logical/display/printer files, RPG (fixed-form C-spec and /free), one ILE COBOL program, CL build and night-batch drivers, DB2 for i (one RUNSQLSTM table + embedded SQL), 5250 WORKSTN screens (plain and SFL/SFLCTL subfile), PRTF spool, and journaling. Business rules live in the RPG/COBOL programs themselves; there is no SQL-PL layer. This manual is the reference for the operator who runs the screens and the night batch, and for the developer maintaining the application. It is grounded entirely in the committed source (insurance2-app/src/sources.mjs, src/seed.mjs, PLAN.md, and the test/sentinel_*.mjs drivers). Everything runs in library SENTINEL.

Contents

A. Overview & Architecture ↑ top

A.1 What it does

SENTINEL/i administers one coherent line of business — personal auto and property insurance — end to end:

A.2 Classic-RPG architecture: programs own the logic

Unlike a SQL-PL-centric design, SENTINEL/i keeps its business rules in the RPG and COBOL programs themselves. There is no stored-procedure layer: rating math is in UWCHK, the payment waterfall/aging/pro-rata math is in the RPG programs, and DB2 for i appears only as (1) one RUNSQLSTM-created table, GLPOST2, the GL posting feed, and (2) embedded EXEC SQL INSERT/SELECT/COMMIT/ROLLBACK in the three GL-touching programs (COMMRUN, CLMPAYP, GLRUN) and the COBOL cross-check (POLSUM2). All other I/O is native record-level access (CHAIN / READ / WRITE / UPDATE) over DDS files.

The system is deliberately built as a broad platform-stress workload: it exercises DDS PFs/LFs, keyed and arrival I/O, fixed-form and free-form RPG, program-to-program CALL (POLBINDUWCHK), an ILE COBOL + DB2 bridge, CL build and night-batch drivers, three DSPF screens (plain + subfile + menu), a PRTF spool, journaling with a receiver roll, and commitment-controlled posting with a balanced control total. All objects live in one library, SENTINEL.

A.3 Component & flow

  SETUP / ISSUANCE          ONLINE (5250)            NIGHT BATCH (SNNIGHT, SBMJOB)
  ----------------          -------------            -----------------------------
  SNSETUP  (build+jrnl)     MAINMENU (menu)          STRCMTCTL LCKLVL(*CHG)
  REFLD    (seed rates,       opt 1 -> POLVIEW         BILLRUN   (installments)
            parties, prod)      (POLSCRN, plain)       CASHAPP   (apply receipts)
  POLBIND  --CALL--> UWCHK    opt 2 -> CLMVIEW         COMMRUN   (commission + GL)
    (issue, journal 'I')        (CLMSCRN, SFL/SFLCTL)  CLMPAYP   (claim pay + GL)
  POLENDT/POLRENEW/POLCANCL                            GLRUN     (premium GL, balance
    (endorse/renew/cancel,   \                    /              gate: COMMIT/ROLLBACK)
     journal E/R/C)           \                  /     ENDCMTCTL
  CLMOPEN -> CLMADJ            v                v
    (FNOL, adjudicate)   POLICYMS / RISKMS / CLAIMMS / INSTMS ...   SNJRN (journals POLLOG)
                                |
  REPORTING                     +--> POLLOG  (journaled txn/audit log: I/E/R/C)
  AGERUN  (PRTF spool)          +--> GLPOST2 (DB2 GL feed: batch 10 prem, 20 claim, 30 comm)
  POLSUM2 (COBOL+SQL x-check)

A single business event — say, issuing a policy — flows: REFLD seeds and closes the rate/party/producer reference data → POLBIND CALLs UWCHK for the rated premium → writes the POLICYMS header, its RISKMS coverage rows, and a journaled POLLOG ‘I’ row → the SNJRN journal captures the POLLOG write. Downstream, the night SNNIGHT chain bills, applies cash, commissions, pays claims and posts a balanced GL under commitment control.

A.4 Object inventory

ObjectTypeRole
PARTYMSPFParty/insured master.
PRODMSPFProducer (agency) master with commission rate.
POLICYMSPFPolicy header (the heart of the app).
POLLOGPF (journaled)Immutable policy transaction/audit log.
RISKMSPFCoverage/risk items (N per policy).
RATETBPFUnderwriting rating-factor table.
INSTMSPFBilling installment schedule.
RCPTMSPF (arrival)Cash receipts.
CLAIMMSPFClaim header.
CLMLINEPF (arrival)Claim reserve/adjudication/payment lines.
COMMMSPFCommission line per bound transaction.
POLLOGLV / RISKLV / AGEDLV / CLMLINLVLF (4)Logical views (history / risks / aging / claim lines).
GLPOST2DB2 tableGL posting feed (RUNSQLSTM, not an objfs *FILE).
POLSCRN / CLMSCRN / MAINMNUDSPF (3)Policy inquiry / claim inquiry (subfile) / menu.
POLREGP2PRTFAged-receivables printer file.
UWCHKRPGLECallable underwriting/rating subprogram.
REFLDRPGLEReference/master seed loader.
POLBIND / POLENDT / POLRENEW / POLCANCLRPGLE (4)Policy lifecycle drivers.
PARTYMNTRPGLEParty master maintenance.
BILLRUN / CASHAPP / AGERUNRPGLE (3)Billing / cash / aging.
CLMOPEN / CLMADJRPGLE (2)FNOL / adjudication.
CLMPAYP / COMMRUN / GLRUNSQLRPGLE (3)GL-posting programs (embedded SQL).
POLVIEW / CLMVIEW / MAINMENURPGLE (3)Interactive 5250 programs.
POLSUM2CBLLEILE COBOL portfolio summary + DB2 cross-check.
SNSETUP / SNNIGHTCLP (2)Build+journal / night-batch chain drivers.
SNJRN / SNJRNR*JRN / *JRNRCVJournal + receiver for POLLOG.

The catalogue is 11 PFs + 4 LFs + 1 DB2 table, 3 DSPF + 1 PRTF, 19 RPG/COBOL programs, 2 CL programs, and 1 journal/receiver pair. Sections D and F expand each.

B. Online Transactions & Screens ↑ top

B.1 The command/entry line

SENTINEL/i has no CICS transaction identifiers and no transid switch. On IBM i, each program is reached by name from a 5250 command-entry line (or a JOBQ/scheduler for the batch jobs). The operator equivalent of “type a transid and Enter” is “type a CALL command and Enter”. Before invoking anything, the job's library list must include SENTINEL — the tested jobs run with LIBL = QSYS QGPL SENTINEL QTEMP and CURLIB = SENTINEL.

To do thisType on the command line
Open the operator menu (routes to the inquiries)CALL SENTINEL/MAINMENU
Open the policy inquiry directlyCALL SENTINEL/POLVIEW
Open the claim inquiry (subfile) directlyCALL SENTINEL/CLMVIEW
Build/compile everything + arm journalingCALL SENTINEL/SNSETUP (once, at install)
Seed reference/master dataCALL SENTINEL/REFLD
Issue the day's policies (calls UWCHK)CALL SENTINEL/POLBIND
Party master maintenance (add/change/inquire)CALL SENTINEL/PARTYMNT PARM('A' 'IN0009' 'name')
Run the night batch chainSBMJOB CMD(CALL SENTINEL/SNNIGHT) JOBQ(SENTINEL/NITEQ)
Honest note on parameters and dates. The lifecycle and batch programs are self-contained drivers with hard-coded work data, not parameter-driven services: POLBIND issues two specific policies (AUTO0001, PROP0001) with literal DOBs, premiums and dates; POLENDT/POLCANCL act on literal policy numbers; POLRENEW's renewal window is the literal EXPDT ≤ 20270101; billing/claim dates are literals in the source. There is no run-date control table (contrast the LOANSVC/i LNCTL model). Only PARTYMNT takes CALL parameters (a 1-char action code + party number + name). This is a demonstration/stress workload; a production build would parameterise these.

B.2 The menu & the two inquiry screens

Three DSPF programs are interactive. MAINMENU (format MENUFMT over MAINMNU) is the entry point: it prompts for a 1-char option and routes via a classic, indicator-conditioned dynamic CALL — option 1 CALLs POLVIEW, option 2 CALLs CLMVIEW. Any other value redisplays with Invalid option. F3 exits.

SENTINEL/i Main Menu 1. Policy Inquiry 2. Claim Inquiry Option . . . . : _ F3=Exit Enter=Select

POLVIEW — policy inquiry (POLSCRN, plain WORKSTN)

A non-subfile screen: key a policy number, Enter, and it CHAINs POLICYMS and displays the header (insured party, line of business, status, annual premium, balance) plus up to four risk/coverage lines read from the RISKLV logical (the program loads at most 4 fixed slots, DRISK1DRISK4). A not-found key shows Policy not found:. The loop re-displays until F3.

Policy Inquiry - SENTINEL/i Policy number: AUTO0001 Insured . . . : IN0001 Line of bus. . : A Status . . . . : I Ann. premium . : 1200.00 Balance . . . : 900.00 Risk Limit Deduct Premium BI 100000.00 0.00 600.00 PD 75000.00 500.00 750.00 Policy found. F3=Exit Enter=Inquire

CLMVIEW — claim inquiry (CLMSCRN, SFL/SFLCTL subfile)

The one subfile screen. Key a claim number, Enter: it CHAINs CLAIMMS for the header (policy, loss date, cause, status, total reserved/paid), then loads a subfile (DDS record CLMSFL under control record CLMCTL, SFLPAG(0010), SFLSIZ(0020)) from the CLMLINLV logical — one row per claim line (reserve R, adjudication A, payment P) with its date, type and amount. The screen uses the standard indicator set *IN31=SFLDSP, *IN32=SFLDSPCTL, *IN33=SFLCLR, *IN34=SFLEND(*MORE).

Claim Inquiry - SENTINEL/i Claim number: CLM00001 Policy . . . . : AUTO0001 Loss date . . : 20260215 Cause . . . . : REAR-END COLLISION Status . . . . : A Date Type Amount 20260215 R 5000.00 20260218 A 5000.00 20260220 P 3000.00 5000.00 reserved 3000.00 paid Claim found. F3=Exit Enter=Inquire
Known DDS rendering artifact (app-authoring, not a platform defect). In CLMSCRN, the CLMCTL column-header literals Date/Type/Amount are placed at row 7 cols 4/14/18 — the identical coordinates as the CLMSFL subfile record's first displayed row (SLINEDT/SLINETYP/SLINEAMT). On a real 5250 the header line and the first subfile row overlap (e.g. the “Type” header and a row's “R” collapse to Rype). Authentic IBM i hardware reproduces this identically given this DDS; the fix would be to move the headers to row 6 or start the SFL at row 8. Documented in PLAN.md §6 (SIM-2026-D5). Operationally the data is correct; only the header row renders overlapped.

Actions & keys (all three screens)

B.3 Controls & audit workflow (no four-eyes maker–checker)

Honest statement: SENTINEL/i does not model a true four-eyes maker–checker / separate-authorization workflow. There is no “one user enters, a second approves” gate: a policy issued by POLBIND is inforce immediately; a claim adjudicated by CLMADJ moves O→A in one program; a payment posted by CLMPAYP is applied at once. Even the two 5250 screens (POLVIEW, CLMVIEW) are inquiry-only — they read and display, they do not update. All state change happens in the batch/driver programs. The control model the application does have:

In sum, the control posture is immutable journaled audit + business-rule/limit gating + a balanced GL control total, rather than a segregation-of-duties approval workflow.

C. Batch Jobs & the Periodic Cycle ↑ top

SENTINEL/i's batch work centres on one night chain, SNNIGHT, submitted as a single SBMJOB onto a job queue and run under commitment control. Around it sit the on-demand lifecycle drivers (issue/endorse/renew/cancel) and the two reporting programs. Because the programs carry hard-coded work data (see B.1), a run is a bare CALL/SBMJOB with no run-date parameter.

-- install once: build all objects + arm journaling on POLLOG
CRTCLPGM PGM(SENTINEL/SNSETUP) SRCFILE(SENTINEL/QCLSRC) SRCMBR(SNSETUP)
CALL PGM(SENTINEL/SNSETUP)

-- seed reference/master data, then issue the day's policies
CALL PGM(SENTINEL/REFLD)
CALL PGM(SENTINEL/POLBIND)

-- submit the night chain onto a job queue (runs BILLRUN..GLRUN under STRCMTCTL)
CRTJOBQ JOBQ(SENTINEL/NITEQ) TEXT('SENTINEL night batch queue')
SBMJOB CMD(CALL SENTINEL/SNNIGHT) JOB(SNNITE) JOBQ(SENTINEL/NITEQ) HOLD(*NO)

C.1 Full batch / driver program set

ProgramPurposeFiles / callsOutputsFrequency
REFLD Seed rate table, insured parties, producer; runs to completion so its rows are visible to UWCHK. RATETB / PARTYMS / PRODMS (all O-A). 3 rate bands (YNG 1.250, STD 1.000, SNR 0.900), 2 parties, 1 producer (AG01 @10%); DSPLY. Install / on demand.
POLBIND Issue the day's policies; CALLs UWCHK to rate the premium. POLICYMS/RISKMS/POLLOG (O-A); CALLP UWCHK. 2 inforce policies (AUTO0001 1200.00 std, PROP0001 1620.00 senior), 3 risk rows, 2 journaled 'I' POLLOG rows. Per issuance run.
POLENDT Mid-term endorsement: raise a coverage limit, re-rate the header by a delta. POLICYMS/RISKMS (UF); POLLOG (O-A). AUTO0001 PD limit +25000.00, ANNPREM +150.00 (1200→1350.00); journaled 'E' row (LOGAMT 150.00). On demand.
POLRENEW Renewal sweep: roll term +1yr, apply 5% load for inforce policies in the window. POLICYMS (UF-A); POLLOG (O-A). EXPDT +10000, ANNPREM ×1.05; journaled 'R' row per policy; DSPLY POLRENEW RENEWED=n. Renewal cycle.
POLCANCL Cancellation: pro-rata unearned credit, POLSTAT→C. POLICYMS (UF); POLLOG (O-A). PROP0001 → STAT C, POLBAL=earned half; journaled 'C' row with NEGATIVE unearned credit. On demand.
PARTYMNT Party master maintenance (add/change/inquire) by 1-char action code. PARTYMS (UF-A). ADDED / CHANGED / INQ / NOTFOUND / DUP / BADACT DSPLY per action. On demand.
BILLRUN Idempotent quarterly installment generation (4 per inforce policy). POLICYMS (IF); INSTMS (UF-A); dup-check CHAIN. 8 installments (ANNPREM/4, remainder on inst 4); rerun skips (dup-key); DSPLY GENERATED=/SKIPPED=. Night chain (step 1).
CASHAPP Apply RCPTMS receipts oldest-due-first, partial-pay aware; decrement POLBAL. RCPTMS (IF arrival); INSTMS/POLICYMS (UF). Inst ISTAT O→D (partial) / →P (full); POLBAL reduced by applied cash; DSPLY FULL=/PART=/NONE=. Night chain (step 2).
COMMRUN Commission per bound 'I' POLLOG row; write COMMMS + balanced GL pair. POLLOG/POLICYMS/PRODMS (IF); COMMMS (O-A); EXEC SQL GLPOST2. Commission = LOGAMT×COMMPCT/100 (120.00 + 162.00 = 282.00); GL batch 30 DR/CR pair. Night chain (step 3).
CLMPAYP Post a claim payment within remaining limit; update TOTPAY; GL pair. CLAIMMS (UF); RISKMS (IF); CLMLINE (O-A); EXEC SQL GLPOST2. 'P' line 3000.00, TOTPAY→3000.00; GL batch 20 claim-expense DR / cash CR pair. Night chain (step 4).
GLRUN Post premium DR/CR per 'I' POLLOG row, then balance-gate the whole feed. POLLOG (IF); EXEC SQL GLPOST2 + SUM + COMMIT/ROLLBACK. GL batch 10 (premrec DR / written-prem CR, 2820.00); DSPLY IN BALANCE/OUT OF BALANCE. Night chain (step 5).
CLMOPEN / CLMADJ FNOL intake / adjudication (approve+cap reserve vs coverage limit). CLAIMMS (O-A/UF); RISKMS (IF); CLMLINE (O-A). CLM00001 opened (reserve 5000.00, 'R' line); CLSTAT O→A, 'A' memo line. Intraday / on demand.
AGERUN Aging pass over AGEDLV (by due date); spooled aged-receivables report. AGEDLV (IF); POLREGP2 (PRINTER). PRTF spool (banner + detail + total); bucket PAID/PARTIAL/OPEN; DSPLY LINES=/OPEN=. Reporting / on demand.
POLSUM2 ILE COBOL portfolio summary + DB2 cross-check. POLICYMS (indexed FD, COMP-3); EXEC SQL GLPOST2. Inforce count + premium; SUM of written-premium GL credits; IN BALANCE/OUT OF BALANCE. Reporting / on demand.

C.2 The SNNIGHT night chain

SNNIGHT is a CL program that runs the five posting programs in one commitment boundary:

SNNIGHT (CL):
  STRCMTCTL LCKLVL(*CHG)
  MONMSG    MSGID(SFF0000)
  CALL PGM(SENTINEL/BILLRUN)    generate installments
  CALL PGM(SENTINEL/CASHAPP)    apply receipts, reduce POLBAL
  CALL PGM(SENTINEL/COMMRUN)    commission + GL batch 30
  CALL PGM(SENTINEL/CLMPAYP)    claim payment + GL batch 20
  CALL PGM(SENTINEL/GLRUN)      premium GL batch 10 + balance gate
  ENDCMTCTL

The three GL-touching programs' EXEC SQL INSERTs are staged inside the commit boundary; GLRUN makes the final decision — COMMIT if the whole feed balances, ROLLBACK otherwise. In the reference day the feed balances at DR = CR = 6102.00 (premium 2820.00 + claim 3000.00 + commission 282.00, each posted as a balanced pair), and the premium batch (10) credit total persists at exactly 2820.00 post-COMMIT.

Expected DSPLY highlights across the chain:
  BILLRUN GENERATED=2 SKIPPED=0
  CASHAPP FULL=1 PART=1 NONE=0
  COMMRUN ROWS=2 TOTAL=282.00
  CLMPAYP PAID 3000.00
  GLRUN IN BALANCE DR=6102.00 CR=6102.00

C.3 Ordering & dependencies

D. Data Files (data dictionary) ↑ top

All files are in library SENTINEL, defined by column-exact DDS in sources.mjs. Dates are stored as signed zoned 8S 0 in YYYYMMDD form; money is packed 9P 2 (or wider for GL); rating factors are packed 5P 3. UNIQUE-keyed PFs are the masters; three PFs (POLLOG, RCPTMS, CLMLINE) are effectively arrival logs keyed by a generated sequence.

Status-code legend: POLSTAT I=inforce C=cancelled X=expired; LOGTYPE I=issue E=endorse R=renew C=cancel; ISTAT O=open D=part-paid P=paid; CLSTAT O=open A=adjudicated/approved C=closed D=denied; LINETYP R=reserve A=adjudication P=payment; DRCR D=debit C=credit.

PARTYMS — Party/insured master (UNIQUE, K PARTNO)

FieldTypeMeaning
PARTNO6AParty number (key), e.g. IN0001.
PNAME25AParty name.
PADDR / PCITY / PST / PZIP20A / 12A / 2A / 5AAddress, city, state, ZIP.
PDOB8S 0Date of birth (YYYYMMDD) — drives UWCHK's age band.

PRODMS — Producer/agency master (UNIQUE, K PRODNO)

FieldTypeMeaning
PRODNO4AProducer number (key), e.g. AG01.
PRODNAME20AProducer name.
COMMPCT5P 2Commission percent (10.00 = 10%), used by COMMRUN.
PRSTAT1AProducer status (A active).

POLICYMS — Policy header (UNIQUE, K POLICYNO)

FieldTypeMeaning
POLICYNO8APolicy number (key), e.g. AUTO0001.
PARTNO6AInsured party.
PRODNO4AProducer/agency.
LOB1ALine of business (A auto, P property).
EFFDT / EXPDT8S 0Effective / expiry dates (YYYYMMDD).
POLSTAT1APolicy status (I inforce, C cancelled, X expired).
ANNPREM9P 2Annual premium (set by UWCHK, adjusted by endorse/renew).
POLBAL9P 2Outstanding policy balance (reduced by CASHAPP).

POLLOG — Policy transaction/audit log (UNIQUE, K LOGID; journaled)

FieldTypeMeaning
LOGID8S 0Log sequence number (key).
POLICYNO8APolicy the transaction is for.
LOGTYPE1AI issue / E endorse / R renew / C cancel.
LOGDT8S 0Transaction date (YYYYMMDD).
LOGAMT9P 2Amount or delta (endorsement delta; cancel carries a NEGATIVE unearned credit).

RISKMS — Coverage/risk items (UNIQUE, K POLICYNO+RISKCD)

FieldTypeMeaning
POLICYNO / RISKCD8A / 3APolicy + coverage code (composite key), e.g. BI/PD/DWL.
RLIMIT9P 2Coverage limit (the adjudication/payment ceiling).
RDEDUCT7P 2Deductible.
RPREM9P 2Coverage premium.

RATETB — Underwriting rating factors (UNIQUE, K BANDCD)

FieldTypeMeaning
BANDCD3AAge band (YNG / STD / SNR).
RFACTOR5P 3Multiplier on base premium (1.250 / 1.000 / 0.900).
BANDDESC20ABand description.

INSTMS — Billing installments (UNIQUE, K POLICYNO+INSTNO)

FieldTypeMeaning
POLICYNO / INSTNO8A / 2S 0Policy + installment number 1–4 (composite key).
DUEDT8S 0Installment due date.
DUEAMT9P 2Amount due (ANNPREM/4; remainder on installment 4).
PAIDAMT9P 2Amount paid so far.
ISTAT1AO open / D part-paid / P paid.

RCPTMS — Cash receipts (arrival, UNIQUE K RCPTNO)

FieldTypeMeaning
RCPTNO8S 0Receipt number (key).
POLICYNO8APolicy the receipt is for.
RCPTDT / RCPTAMT8S 0 / 9P 2Receipt date / amount (applied oldest-due-first by CASHAPP).

CLAIMMS — Claim header (UNIQUE, K CLAIMNO)

FieldTypeMeaning
CLAIMNO8AClaim number (key), e.g. CLM00001.
POLICYNO8APolicy the claim is against.
LOSSDT / CAUSE8S 0 / 20ALoss date / cause description.
CLSTAT1AO open / A adjudicated / C closed / D denied.
TOTRSV / TOTPAY9P 2 / 9P 2Total reserved / total paid.
RISKCD3ACovering coverage code (the limit CLMADJ/CLMPAYP check against).

CLMLINE — Claim lines (arrival, UNIQUE K LINEID)

FieldTypeMeaning
LINEID8S 0Line sequence number (key).
CLAIMNO8AClaim the line belongs to.
LINEDT / LINEAMT8S 0 / 9P 2Line date / amount.
LINETYP1AR reserve / A adjudication / P payment.

COMMMS — Commission lines (K COMMR; keyed to avoid dup-write)

FieldTypeMeaning
PRODNO4AProducer earning the commission.
POLICYNO8APolicy the commission is for.
LOGID8S 0Source POLLOG transaction (10001 / 10002).
COMMAMT9P 2Commission amount (LOGAMT × COMMPCT/100).

GLPOST2 — GL posting feed (DB2 table, RUNSQLSTM)

ColumnTypeMeaning
BATCHNOINTEGERPosting batch: 10 premium (GLRUN), 20 claim (CLMPAYP), 30 commission (COMMRUN).
ACCTNOCHAR(10)GL account (e.g. 1200-PREMREC, 4000-WRTNPRM, 4100-CLMEXP, 1000-CASH, 5200-COMMEXP, 2100-COMMPAY).
DRCRCHAR(1)D debit / C credit.
GLAMTDECIMAL(9,2)Posting amount.
SRCPGMCHAR(10)Posting program (GLRUN / CLMPAYP / COMMRUN).
Platform note: GLPOST2 is created by RUNSQLSTM and lives in the DB2/SQL catalogue, not the object filesystem — objExists('SENTINEL','GLPOST2','*FILE') returns false even though INSERT/SELECT work. Verify it with a real SELECT COUNT(*), not an object-existence check (PLAN.md §6).

Logical files (4)

LFOverKeyUse
POLLOGLVPOLLOGPOLICYNO+LOGIDPer-policy transaction history.
RISKLVRISKMSPOLICYNOA policy's coverage lines (POLVIEW).
AGEDLVINSTMSDUEDTAging pass by due date (AGERUN).
CLMLINLVCLMLINECLAIMNO+LINEIDA claim's line history (CLMVIEW subfile source).

Relationships

E. Operations Runbook ↑ top

E.1 Day-in-the-life

  1. One-time install: CRTLIB SENTINEL, seed the source members, compile the two CL programs, then CALL SENTINEL/SNSETUP — this creates all PF/LF/DSPF/PRTF objects, the GLPOST2 DB2 table (RUNSQLSTM), compiles every RPG/COBOL program, and arms journaling on POLLOG (CRTJRNRCV SNJRNR / CRTJRN SNJRN / STRJRNPF POLLOG IMAGES(*BOTH)).
  2. Seed & issue: CALL SENTINEL/REFLD (rates/parties/producer, runs to completion), then CALL SENTINEL/POLBIND to issue the day's policies (rates via UWCHK, journals 'I').
  3. Intraday lifecycle / claims as they arrive: endorse (POLENDT), party maintenance (PARTYMNT), open+adjudicate a claim (CLMOPENCLMADJ), and record cash receipts into RCPTMS.
  4. Night batch: create the queue (CRTJOBQ SENTINEL/NITEQ) and SBMJOB CMD(CALL SENTINEL/SNNIGHT) JOBQ(SENTINEL/NITEQ). Wait for the job to reach OUTQ.
  5. Inquiries: handle policy/claim look-ups through CALL SENTINEL/MAINMENU (option 1 → POLVIEW, option 2 → CLMVIEW). These are read-only.

Pre-checks: confirm the job's library list includes SENTINEL; confirm REFLD ran and closed before POLBIND (otherwise premiums come out at the default 1.000 factor).

Post-checks after the night chain:

E.2 Period close & reporting (reconciling figures)

  1. Run the aged-receivables report: CALL SENTINEL/AGERUN, then read the POLREGP2 spooled file. It shows a SENTINEL/i -- Aged Receivables banner, one detail line per installment with a PAID/PARTIAL/OPEN bucket, and a total line.
  2. Run the COBOL cross-check: CALL SENTINEL/POLSUM2. It totals inforce annual premium from POLICYMS and compares to SUM(GLAMT) of the written-premium GL credits (BATCHNO=10, DRCR='C'), printing IN BALANCE or OUT OF BALANCE.

Reconciling figures (the same ones the focused test suites assert against):

Honest cross-period caveat (COMMRUN / GLRUN scope). COMMRUN and GLRUN read only POLLOG rows with LOGTYPE='I' (original issuance). Endorsement ('E') and renewal ('R') premium increases earn no commission and post no written-premium GL, and commission is computed from the historical LOGAMT, never from the current ANNPREM. Over a period with endorsements/renewals the GL written-premium stays frozen at the issue total while true inforce premium grows — and POLSUM2 then correctly reports OUT OF BALANCE (e.g. INFORCE 3118.50 vs GLWRITTEN 2820.00). That is the cross-check doing its job, not a defect (PLAN.md §6, SIM-2026-W2/M3/Y4).

E.3 Failure & re-run rules

SituationBehaviourAction
UWCHK rated at 1.000 unexpectedlyRATETB CHAIN found nothing — REFLD did not run/close before POLBIND.Run REFLD to completion first, then re-issue. See F.4.
Re-run BILLRUNDup-key CHAIN on INSTMS skips already-billed policies.Idempotent — still exactly 8 installments, no double-billing.
Re-run POLRENEW same windowPolicies whose EXPDT is now past the cutoff no longer match.Idempotent — a same-window rerun renews 0 (EXPDT-driven guard).
GLRUN finds the feed out of balanceIt EXEC SQL ROLLBACKs the whole commit unit and DSPLYs OUT OF BALANCE.Correct the posting programs' pairs, then re-run under STRCMTCTL. Nothing is left half-posted.
CLMPAYP over the coverage limitPayment exceeds RLIMIT − TOTPAY; rejected with REJECT OVER LIMIT.No P line, no GL, no TOTPAY change. Re-adjudicate or pay within the remaining limit.
SNNIGHT job fails partwayNative file changes (BILLRUN/CASHAPP) persist; the staged GL INSERTs are inside the commit boundary and un-committed until GLRUN.Re-submit SNNIGHT; BILLRUN is idempotent, and the GL only commits when it balances.
PARTYMNT add of an existing partyCHAIN finds it; program DSPLYs DUP and does not overwrite.Use action C to change, or a new party number.
Because every policy event is journaled to POLLOG (with before/after images under IMAGES(*BOTH)) and every claim movement is an immutable CLMLINE row, any run's effect is fully reconstructable after the fact via DSPJRN and the logicals.

F. Developer Reference ↑ top

The complete program surface, from sources.mjs. All objects are in library SENTINEL; source members live in QDDSSRC, QRPGLESRC, QCBLLESRC, QCLSRC, QSQLSRC.

F.1 Programs (19 RPG/COBOL + 2 CL)

UWCHK (RPGLE) — PI: pDob(8:0), pClaims(3:0), pBasePrem(9:2) in; pOutPrem(9:2), pOutStat(1) out
Callable rating subprogram. Hard-declines when pClaims > 3 (pOutStat 'D', premium 0). Otherwise derives an age band from (today − pDob)/10000 (<25 YNG, ≥65 SNR, else STD), CHAINs RATETB for the factor, and returns pBasePrem × RFACTOR with pOutStat 'A'. Uses nested if/else (not free-form elseif) — see F.4.
REFLD (RPGLE)
Reference/master seed loader (RATETB bands, two parties, one producer). Runs to completion so the rows are visible to UWCHK's CHAIN. Opens RATETB/PARTYMS/PRODMS output-add.
POLBIND (RPGLE)
Issues AUTO0001 (std) and PROP0001 (senior): callp uwsub(...) to rate, writes the POLICYMS header, RISKMS coverage rows, and a journaled 'I' POLLOG row per policy.
POLENDT (RPGLE)
Endorsement: full-key CHAIN/UPDATE on RISKMS (raise PD limit +25000, +150 delta) and POLICYMS (re-rate header), writes a journaled 'E' POLLOG row carrying the delta only.
POLRENEW (RPGLE)
Renewal sweep: sequential READ over POLICYMS; for inforce policies with EXPDT ≤ 20270101 rolls EFFDT/EXPDT +1yr (+10000 packed add), applies a 5% load, writes a journaled 'R' row. Its EXPDT-past-cutoff test makes a same-window rerun renew 0.
POLCANCL (RPGLE)
Cancellation: computes a pro-rata unearned credit (ANNPREM × 0.500 for a half-term remaining), sets POLBAL to the earned half, flips POLSTAT 'C', writes a journaled 'C' POLLOG row with the negative unearned credit.
PARTYMNT (RPGLE) — PI: pAct(1), pPartno(6), pPnam(25)
Master maintenance over PARTYMS via a SELECT on the action code: 'A' add (if not found), 'C' change name (if found), 'I' inquire (CHAIN + DSPLY), else BADACT.
BILLRUN (RPGLE, fixed-form + /free)
One pass over inforce POLICYMS; per policy a dup-check CHAIN(E) on INSTMS (skip if installment 1 exists), else generate 4 installments (ANNPREM DIV 4, remainder via MVR on installment 4). Idempotent.
CASHAPP (RPGLE, fixed-form + /free)
Arrival pass over RCPTMS; per receipt a bounded full-key chain (policyno:instno) retry 1..4 for the oldest open/partial installment; full pay → ISTAT 'P', partial → ISTAT 'D'; then decrements POLICYMS.POLBAL by the applied amount.
AGERUN (RPGLE)
Forward READ over the AGEDLV (by DUEDT) logical; buckets each installment PAID/PARTIAL/OPEN and writes the POLREGP2 PRTF (header, detail, total) to spool. Uses nested if/else for the bucket (see F.4).
CLMOPEN (RPGLE)
FNOL: writes the CLAIMMS header (CLM00001 on AUTO0001, reserve 5000.00, CLSTAT 'O', covering RISKCD 'PD') and the initial 'R' reserve CLMLINE.
CLMADJ (RPGLE)
Adjudication: CHAINs CLAIMMS, then the covering RISKMS line (full composite key POLICYNO+RISKCD) for RLIMIT; caps the reserve at the limit if over, flips CLSTAT 'O'→'A', writes an 'A' memo line.
CLMPAYP (SQLRPGLE)
Claim payment: remaining limit = RLIMIT − TOTPAY; if the 3000.00 payment fits, writes a 'P' CLMLINE, bumps CLAIMMS.TOTPAY, and posts a balanced GL pair (batch 20: 4100-CLMEXP DR / 1000-CASH CR) via embedded SQL.
COMMRUN (SQLRPGLE)
Per POLLOG 'I' row: CHAIN POLICYMS then PRODMS, commission = LOGAMT × COMMPCT/100, write COMMMS + a balanced GL pair (batch 30: 5200-COMMEXP DR / 2100-COMMPAY CR).
GLRUN (SQLRPGLE)
Per POLLOG 'I' row: premium GL pair (batch 10: 1200-PREMREC DR / 4000-WRTNPRM CR). Then SELECTs SUM(DR)/SUM(CR) over the whole feed and COMMITs if equal, else ROLLBACK — the balance gate for the commit unit-of-work.
POLVIEW / CLMVIEW / MAINMENU (RPGLE, WORKSTN)
The three interactive programs (B.2). POLVIEW: plain EXFMT over POLSCRN, header + up to 4 RISKLV lines. CLMVIEW: SFL/SFLCTL over CLMSCRN, header + CLMLINLV subfile load. MAINMENU: menu + indicator-conditioned dynamic CALL 'POLVIEW'/'CLMVIEW'.
POLSUM2 (CBLLE, ILE COBOL + EXEC SQL)
Indexed sequential READ over POLICYMS (COMP-3 FD matching the packed layout byte-for-byte), totals inforce ANNPREM, then EXEC SQL SELECT SUM(GLAMT) ... WHERE BATCHNO=10 AND DRCR='C' and prints IN/OUT OF BALANCE.
SNSETUP (CLP)
Install driver: DLTF/CRTPF/CRTLF/CRTDSPF/CRTPRTF, RUNSQLSTM GLPOST2, CRTBNDRPG/CRTBNDCBL every program, and CRTJRNRCV/CRTJRN/STRJRNPF POLLOG IMAGES(*BOTH).
SNNIGHT (CLP)
Night chain under STRCMTCTL LCKLVL(*CHG): BILLRUN → CASHAPP → COMMRUN → CLMPAYP → GLRUN → ENDCMTCTL.

F.2 The rating & GL model

Rating. Premium = base × age-band factor (RATETB): YNG (<25) 1.250, STD 1.000, SNR (≥65) 0.900. Endorsement adds a flat delta; renewal applies a 5% load; cancellation credits a pro-rata unearned fraction. A prior-claim count > 3 hard-declines.

GL feed. Three balanced DR/CR batches, all cross-checked SUM(DR)=SUM(CR):

BatchSourceDebitCredit
10GLRUN (per 'I')1200-PREMREC4000-WRTNPRM
20CLMPAYP4100-CLMEXP1000-CASH
30COMMRUN (per 'I')5200-COMMEXP2100-COMMPAY

F.3 Journaling

POLLOG is journaled to SNJRN (receiver SNJRNR) with IMAGES(*BOTH), armed in SNSETUP. Effects verified by sentinel_journal.mjs: WRITE puts appear as PT record-put images; a native UPDATE captures a UB before-image and a UP after-image (UB seq < UP seq); DSPJRN JRN(SENTINEL/SNJRN) FILE(SENTINEL/POLLOG) renders those lines; and a receiver roll (CRTJRNRCV SNJRNR2 + CHGJRN) detaches SNJRNR (*ONLINE), attaches SNJRNR2 (*ATTACHED), and a traversal spans both receivers with seq still increasing.

F.4 Embedded-SQL & platform-quirk adaptations

The three SQLRPGLE programs and the COBOL program use these embedded-SQL idioms; the app also carries several documented adaptations to the emulator (from PLAN.md §6 — the app is adapted AS-IS, the engine is never modified):

G. Glossary ↑ top

Adjudication
The middle claim step (CLMADJ): approve the reserve against the covering coverage limit (cap it if over-limit), move CLSTAT O→A, write an 'A' memo line.
Age band / rating factor
A date-of-birth band (YNG/STD/SNR in RATETB) whose factor multiplies the base premium at underwriting (UWCHK).
Arrival file
A PF read/written in arrival (physical) sequence rather than by key — here RCPTMS, POLLOG and CLMLINE (each keyed by a generated sequence number).
Commitment control
STRCMTCTL/ENDCMTCTL bracket a unit-of-work; SQL INSERTs stage until COMMIT (or discard on ROLLBACK). SNNIGHT wraps the whole GL posting chain; GLRUN decides.
Endorsement
A mid-term policy change (POLENDT): raise a coverage limit and re-rate the header by a delta; journaled 'E'.
FNOL — First Notice of Loss
Opening a claim (CLMOPEN): the CLAIMMS header + an initial 'R' reserve line.
GL feed (GLPOST2)
The DB2 table of balanced debit/credit posting rows (batches 10 premium, 20 claim, 30 commission), cross-checked SUM(DR)=SUM(CR).
Idempotent
Safe to run again with the same result. BILLRUN (dup-key skip) and POLRENEW (EXPDT-past-cutoff guard) are idempotent.
Inforce
An active policy (POLSTAT='I'); the set BILLRUN bills and POLSUM2 totals.
Journaling / DSPJRN
Recording each POLLOG change to SNJRN with before/after images (IMAGES(*BOTH)); DSPJRN renders the entries (PT/UB/UP).
Line of business (LOB)
The coverage family on a policy: A auto, P property.
POLLOG
The immutable, journaled policy transaction/audit log — one row per lifecycle event (I/E/R/C) with its amount or delta.
Pro-rata unearned premium
On cancellation (POLCANCL), the fraction of premium for the unexpired term, refunded as a negative 'C' POLLOG credit; the earned half stays as POLBAL.
Reserve
The estimated claim liability set at FNOL (TOTRSV / 'R' line), reviewed/capped at adjudication.
SBMJOB / *JOBQ
Submit a program to run as a batch job on a job queue — here SBMJOB CMD(CALL SENTINEL/SNNIGHT) JOBQ(SENTINEL/NITEQ).
Subfile (SFL/SFLCTL)
A 5250 construct listing many rows on one screen; CLMVIEW's claim-line list (CLMSFL under CLMCTL).
UWCHK
The callable underwriting subprogram: age-band rating + prior-claim decline; the program-to-program CALL proof point.
Waterfall / oldest-due-first
CASHAPP applies each receipt to the oldest open/partial installment first (bounded 1..4 key retry), partial-pay aware.