ci-server-engineer/.claude/skills/audit-trail/tasks/read-audit-trail.md
cliu bf7d88a027 R1.05 re-check batch 3: alarms, audit, authorization, classes, HAC, reporting, pyTOOLS
Full manual diffs (L15, C20, E30, L25, J40, C10 §2, L10, P10, P11, J20,
C30, P20, R40, E10) and read-only checks on the shared R1.05 test server.
Skills and summaries moved to R1.05; new skill pytools (IM 36K10P40) from
docs (no Python on the test server). Issues ISS-132..181; corrections to
version-differences (E10, E30, P11, dss_ath_grp_u0104); C10 summary lists
the 3 new authorization actions; r105-verification V10-V17.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:21:36 +11:00

8.4 KiB
Raw Blame History

task version source status
Read the audit trail (export, RQL query, audit report) and know what each tool records R1.05 (first written for R1.03) IM 36K10L25-01EN §1.1, §2.1.2, §3.1, App. 1 (4th ed., Feb. 2026); IM 36K10C50-01EN §2.22, §4.12 (Feb. 2026); IM 36K10G10-01EN ch. 9; R1.05 `tls\src\audit_trail.dss`; practiced on CI-Eng-Sample 2026-10-01 verified on R1.03 (2026-10-01); on the R1.05 test server 2026-10-09 (read-only) the dataset definition, an RQL read of the whole trail and the approval fields were checked; sample report CIENG_AUDIT loaded with 0 errors on 2026-10-08 (load check only, not generated)

Read the audit trail

Read-only. Dataset AUDIT_TRAIL (storage group ADT); every field is read-only except APPLICATION_SUB (the "modifiable ASCII application info") and PROFILE.

1. Fields

Field Content
NAME <ACTION_TIME>/<ACTION_STAMP>, e.g. 01-OCT-26 17:05:00.181/84
ACTION_TIME, NOTIFICATION_TIME, MODIFICATION_TIME When it happened / reached AUDIT Service / APPLICATION_SUB was last changed
SUBJECT_GROUP Subject: the dataset name for configuration and DSS value changes (ITEM_DF, ITEM_VAL, SECTION_DF, REPORT_DF, AUDIT_EVENT_CLAS_DF …) or a classifier subject (CI-SERVER for logins, ITEM, SUB-ITEM …)
SUBJECT_ATTRIBUTE Changed field (HIGH_LIMIT, ITEM_VALUE, DESCRIPTION …); empty for insert/delete/login
SUBJECT_ACTION INSERT, MODIFY, DELETE, LOGIN, LOGOUT, LOGIN-ATTEMPT, ACKNOWLEDGE, SHELVE, UN-SHELVE
SUBJECT_SOURCE Tool that made the change (table in §2)
SUBJECT_IDENT Record name: item, section, object (<object>:<attribute> for attribute values) …
USER_NAME, PROFILE, TERMINAL CI Server user and profile; terminal often empty
ACTION_NODE/ACTION_PROCESS, NOTIFICATION_NODE/NOTIFICATION_PROCESS Node and process (DSSSDA00, JHMISET1086, DSSQLD00875 …)
OLD_VALUE, NEW_VALUE Text, max 64 characters (longer values are cut)
REASON, APPLICATION_INFO, APPLICATION_SUB Free text from the notifying program (empty in the tests)
APPROVAL_REASON (256), APPROVER (128) R1.05 (R1.04 and later): reason and approver name given with the change (see §1a); read-only, select only

1a. Approval reason and approver (R1.04 and later)

Added for FDA 21 CFR Part 11 (the definition calls them CPP approval fields, a change to a critical process parameter). IM 36K10L25 does not mention them (ISS-140); IM 36K10C50 does:

  • An Update item/parameter action on a display (§4.12) can carry a Reason (≤ 256 characters) and an Approver (≤ 128 characters), typed in or taken from display parameters.
  • Alarm acknowledgement with reason and approver (§2.22): either through an item parameter (attribute Acknowledged = 1, item alarms only) or through the alarm overview's External Acknowledgement properties (Alarm Key, Approver, Reason, Trigger). Building the display: skill graphics, create-display.md.

Verified on the R1.05 test server (2026-10-09, read-only RQL): the fields exist in AUDIT_TRAIL; 3 records out of about 15 500 had both filled, all ITEM VALUE MODIFY from OPER-INTERFACE (an operator write), with REASON empty — so the reason goes to APPROVAL_REASON, not to REASON. An alarm acknowledgement with reason / approver was not tested (no such display; displays must not be changed on the shared server). Read them with:

column r as 'A40' heading 'Reason';
column p as 'A20' heading 'Approver';
select action_time, subject_group, subject_ident, subject_action, user_name, approver p,
       approval_reason r
  from audit_trail
 where approver > ' ' or approval_reason > ' '
 order by action_time;

(> ' ' finds non-empty text; this where clause was run on R1.05 with a shorter column list.) On R1.03 these fields do not exist and the query fails.

2. What is recorded (verified on R1.03.00)

Action Recorded as
dssqld load / modify / remove (any dataset) <DATASET>, field, INSERT/MODIFY/DELETE, source ENT-ENG-MOD, user FULL AUTHORIZATION, plus a CI-SERVER LOGIN/LOGOUT pair per dssqld run (not QUICKLOAD)
Writing a value through DSS (dssqld -m on ITEM_VAL) ITEM_VAL ITEM_VALUE MODIFY, old and new value — for every item, whatever its Audit trailing wanted (AUDIT_INFO)
Engineering Module: change an item field ITEM_DF <FIELD> MODIFY, source LOC-ENG-MOD, user ADMIN (the logged-in user)
Engineering Module: right-click item › Update value ITEM_VAL ITEM_VALUE_STR MODIFY (old/new) and ITEM_VAL STATUS MODIFY, source LOC-ENG-MOD
Engineering Module / Operator / OPC UA server login CI-SERVER LOGIN / LOGOUT, source LOC-ENG-MOD, OPER-INTERFACE, VIA-OPC-UAS
Operator display write (button / input) on an item with Audit trailing wanted (AUDIT_INFO 1) ITEM VALUE MODIFY OPER-INTERFACE (old/new) and ITEM STATUS MODIFY, user = operator; with AUDIT_INFO 0 nothing
itmval -p (ITEM Service API) nothing, even with AUDIT_INFO 1

So AUDIT_INFO matters only for operator (and PROCESS) writes; DSS changes are always audited. The SUBJECT_SOURCE of a user interface comes from its audit trail id in dssana.sup USER_INTERFACE (Engineering Module = LOC-ENG-MOD).

R1.05 additions (ISS-141; classifiers verified 2026-10-09, behaviour not re-tested):

  • Source REST-SERVER: the RESTful API (jrstsrv, skill data-access). The R1.05 test server's trail holds REST-SERVER LOGIN / LOGOUT pairs and MODIFY records.
  • Source PYTOOLS: the pyTOOLS Python module (IM 36K10P40). Not seen in the trail.
  • Source PASSWORD-CHECK: the Edit Module Password Check function (IM 36K10C50 §2.31). Not seen.
  • Action PENDING on ITEM VALUE / STATUS: per the R1.05 C header comments, for item writes with a Vnet on send / on receive update policy (CENTUM). Not seen; not tested (no Vnet).

Sources seen in the R1.05 test server's trail (2026-10-09, about 15 500 records): ENT-ENG-MOD (most: dssqld), LOC-ENG-MOD, OPER-INTERFACE, REST-SERVER, ENT-EDIT-MOD, LOC-EDIT-MOD, HMI, DSS-CLIENT, VIA-OPC-UAS.

3. Export

dssqld -e skips AUDIT_TRAIL in a full export (NO-EXPORT in dssqld.sup); name it:

dssqld -e audit.qlo -d AUDIT_TRAIL

or filter (dates as dd-mm-yyyy hh:mm:ss, local time):

@FIELDS
NAME,SUBJECT_GROUP,SUBJECT_ATTRIBUTE,SUBJECT_ACTION,SUBJECT_SOURCE,SUBJECT_IDENT,USER_NAME,OLD_VALUE,NEW_VALUE
@SELECT
'SUBJECT_IDENT = "<Section>.<Tag>" AND ACTION_TIME > "01-10-2026 17:00:00"'
@AUDIT_TRAIL

dssqld -e out.csv audit.qli -c (CSV). Keep NAME in @FIELDS: without the key field the export silently returns 0 records (verified). The whole trail can be large (5 000 records after a year of test work). Wildcards: SUBJECT_IDENT LIKE "<Section>.*" (*, not %; = with * matches nothing).

4. RQL query and audit report

column t as 'DD-MM-YYYY hh:mm:ss' heading 'Time';
select action_time t, subject_group, subject_attribute, subject_action, subject_source,
       subject_ident, user_name, old_value, new_value
  from audit_trail
 where action_time > @date - 3600 and subject_ident like '<Section>.%'
 order by action_time;

Use aliases with COLUMN … AS 'A12' to keep lines short (the fields are 16–256 characters wide). Try it in the interactive generator (skill reporting, rql-interactive.md): put the query in a file that starts with set @next 0; and set @page_size 0; and ends with exit;, then rptgen -s rptgen.rpt < q.rql > q.out in cmd (verified on R1.05 2026-10-09: one heading line, a ==== line, then one line per record; the echoed RPT> prompts appear in the output file). The sample report CIENG_AUDIT (examples/CI-Eng-Sample/19_audit_df.qli) lists the last hour of events on CI-Eng-Sample.*; generate it like any ad-hoc report (define-reports.md §2). On R1.05 it loaded with 0 errors (2026-10-08, reduced sample load); it was not generated there. Generated from dssqld it is stored but not printed (FSL-E-PRT_UNKUSER, ISS-045).

In the Engineering Module, Configuration › Reporting › Reports holds the system reports AUDIT_TRAIL and UA_SERVER_AUDIT (IM 36K10C30 App. 1). Generated there (as the logged-in user) CIENG_AUDIT printed to CIENG_FILE and showed in the report viewer (checked by the user).