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 Permalink 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).