Phase 13: High availability and Active Directory #15

Merged
cliu merged 4 commits from docs/phase-13-ha-ad into main 2026-10-01 19:52:27 +10:00
12 changed files with 585 additions and 9 deletions

View file

@ -5,14 +5,17 @@ description: >-
create, list or remove CI Server users or authorization groups, choose authorization actions create, list or remove CI Server users or authorization groups, choose authorization actions
(ITEM_READ, ITEM_MODIFY_VALUE, …), set process areas, logoff timeout or initial display for (ITEM_READ, ITEM_MODIFY_VALUE, …), set process areas, logoff timeout or initial display for
a user, change how users log in (dssana.sup login method: Automatic, Manual CI Server, a user, change how users log in (dssana.sup login method: Automatic, Manual CI Server,
Manual OS, No, SSO, Deny), or hide Engineering Module features with a scheme. Manual OS, No, SSO, Deny; no-login profile CI_NO_LOGIN), hide Engineering Module features
Sources IM 36K10C10-01EN §2; Active Directory and single sign-on follow in phase 13 (IM 36K10J40). with a scheme, or connect CI Server to Active Directory (AD, domain users, security group or
OU mapping, directory group, profile priority, AD_INT_ON) and single sign-on for CI View
(SSO, SPNEGO, Kerberos, keytab, setspn, ktpass, kinit, krb5.ini). Sources IM 36K10C10-01EN §2,
IM 36K10J40-01EN.
--- ---
# Authorization (R1.03) # Authorization (R1.03)
Background: `knowledge/manuals/IM36K10C10-01EN.md` §2 (login methods, actions, user tabs, Background: `knowledge/manuals/IM36K10C10-01EN.md` §2 (login methods, actions, user tabs,
schemes). Login settings are in `dssana.sup` on CI Core (skill `portal-setup` for reading schemes), `IM36K10J40-01EN.md` (Active Directory, SSO). Login settings are in `dssana.sup` on CI Core (skill `portal-setup` for reading
and changing setup files). and changing setup files).
Rules: Rules:
@ -24,6 +27,7 @@ Rules:
| Task | File | Status | | Task | File | Status |
|---|---|---| |---|---|---|
| Create, check and remove authorization groups and users (quick load) | `tasks/users-groups.md` | verified | | Create, check and remove authorization groups and users (quick load) | `tasks/users-groups.md` | verified |
| Login methods per client and user interface (`dssana.sup`, tab *Login control*) | C10 summary §2 | from docs (installed values read) | | Login methods per client and user interface (`dssana.sup`, tab *Login control*); *No* login = full authorization when the profile user is missing | `tasks/login-methods.md` | verified (read; changes from docs) |
| Schemes (hide Engineering Module features) | C10 summary §2 | from docs | | Schemes (hide Engineering Module features) | C10 summary §2 | from docs |
| Active Directory, single sign-on, password rules | phase 13 | not covered | | Active Directory integration and single sign-on (SPNEGO) | `tasks/active-directory.md` | from docs (no domain) |
| Password rules (`dssana.sup` *Password rules*: length, digits, punctuation, mixed case) | L50 summary §3 | from docs |

View file

@ -0,0 +1,67 @@
---
task: Active Directory integration and single sign-on (SPNEGO) for CI Server
version: R1.03
source: IM 36K10J40-01EN §1–§3, App. 1; dssana.sup AD/SSO keywords and auth\WEB-INF templates checked on the test system 2026-10-01
status: from docs (no domain on the test system)
---
# Active Directory and single sign-on
Needs a Windows domain, domain-joined CI Server machines and admin rights on the machines and
the domain controller. Not practiced; give the procedure and prepare the setup-file changes,
the user (and the domain administrator) applies them. Details: `knowledge/manuals/IM36K10J40-01EN.md`.
## 1. Decide the mapping mode
| | `Security_group` (recommended) | `Organizational_unit` (default in the file) |
|---|---|---|
| CI Server side | Each user profile gets a *Directory group* (Engineering Module user form, tab *Directory Services*; `USER_DF.DIRECTORY_GROUP`) and a *Profile priority* (`MERGE_PRIORITY`) | User profile names = OU names |
| AD side | One security group per profile, same name as the directory group; users in the groups | One OU per profile containing the users; all users also in the group named in `AD_SEC_GRP` (default: group named like the CI Server node) |
Profiles: reuse CI Server users as roles (e.g. `ADMIN`, `ENG`, `OPER`, `<Section>` operators);
they need no password for AD logins. A user in several groups gets the highest priority profile.
## 2. Enable AD integration (CI Core / CI Portal)
Prepared `dssana.sup` lines (tab *Active Directory*):
```
AD_INT_ON
AD_MAP_MODE = Security_group
AD_CHECK_THRESHOLD = 30
```
Optional (installed keywords, not in the manual): `AD_SERVER = "<dc host>[:port]"`,
`AD_SERVER_BACKUP`, `AD_SECURE` (LDAPS, port 636), `AD_ACCESS_USER`/`AD_ACCESS_PASSWORD` (blank =
the account that runs CI Server). For OU mode set `AD_MAP_MODE = Organizational_unit` and
`AD_SEC_GRP = "<group>"`.
Then: join the machine to the domain; run the CI Service as a domain account that is a local
administrator (*Services › CI Server Service › Log On*); restart CI Server. Users log in as
`<domain>\<user>` or `<user>@<domain>`; the Edit/Engineering Module login methods are then
ignored. If web access must not be open to every domain user, disable CI Portal (port 0 in
`jwuiisg.sup`, *Client communication*) — the manual's own warning.
## 3. Single sign-on for remote CI View (SPNEGO)
Checklist (order matters):
1. DNS forward and reverse records for CI Portal and CI View; CI Portal reached by host name;
CI Portal with a valid SSL certificate (skill `portal-setup`).
2. DC: service user (e.g. `sso`), `setspn -S http/<portal FQDN> sso`, `ktpass … -out
<file>.keytab -princ http/<portal FQDN>@<REALM> …` (realm upper case), delegation trust.
3. Keytab to `%TLS_ALLUSERS_PATH%\wap\webapps\auth\WEB-INF`; `kinit http/<portal
FQDN>@<REALM>` succeeds on CI Portal (`tls\jre\bin`) and CI View (Remote Connect JRE).
4. `dssana.sup` tab *Single Sign On*: `SSO_INT_ON`, `WEBHMI_SERVER_FQDN = "<portal FQDN>"`,
`DOMAIN_NAME = "<REALM>"`, `KRB5_FILE = "<path>\krb5.ini"` (set the realm mapping in that
file), `KEYTAB_FILE = "<file>.keytab"`, `SSO_TOKEN_DURATION` (s); restart USER Service.
5. Browsers on CI View: Firefox `network.negotiate-auth.trusted-uris` and `…delegation-uris`
= `https://<portal FQDN>`; Edge/IE: add the site to *Local intranet*, integrated Windows
authentication on.
6. Test: temporarily enable the `test` servlet in `web.xml`, open
`https://<portal FQDN>:8443/auth/test`, expect *Authorization scheme : SPNEGO*; restore
`web.xml`.
7. Start applications from the *Remote Connect* folder on CI View; the login methods `SSO` in
*Login control* (installed default for most UIs) then log the user in without a prompt.
Common failures (manual): "realm not found" → fix `krb5.ini`; access by IP address or from the
CI Portal machine itself → no SPNEGO; DNS reverse lookup missing → ticket errors.

View file

@ -0,0 +1,47 @@
---
task: Read and change login methods per client and user interface (dssana.sup Login control)
version: R1.03
source: IM 36K10C10-01EN §2.2; IM 36K10J40-01EN §1.1, §2.10.3; dssana.sup help and installed values checked on the test system 2026-10-01
status: verified (reading and the No-login behaviour; changing the file from docs — admin)
---
# Login methods (`dssana.sup`, tab *Login control*)
## 1. Read the current methods
`findstr /b LOGIN_METHOD %TLS_ROOT_PATH%\tls\sup\dssana.sup` (or the Setup File Editor).
```
LOGIN_METHOD = <client>, "<user interface>", <method>, <no login when no users>, "<no-login profile>"
```
- `<client>`: host name or IP (wildcards allowed), `"<local>"` (this machine) or `"<remote>"`
(any other); lines are evaluated top-down, `<local>`/`<remote>` always last.
- `<user interface>`: the full name from the *User Interfaces* tab (`USER_INTERFACE = …`), e.g.
`"Engineering Module"`, `"Edit Module"`, `"Operator Interface"`, `"Quickload Utility"`.
- `<method>`: `Automatic` (Windows name = CI Server user, no password), `Manual CI Server`,
`Manual OS`, `No`, `SSO`, `Deny`.
Installed (R1.03.00): local and remote Engineering Module, Edit Module, Operator Interface, Item
Search, Mobile Operator, Excel Add-in → `SSO` (falls back to *Manual CI Server* while SSO is not
set up); local Quickload / Display and Symbol Utility → `No`; remote Playback Viewer, Quickload,
Display/Symbol utilities → `Deny`; OPC UA server, ODBC, `dnetapi` → `Manual CI Server`;
anonymous OPC UA (local) → `No` with profile `CI_NO_LOGIN_OPCUAS`.
## 2. *No* login — check the profile
With `No` the user interface runs with the no-login profile (5th field). **If no CI Server user
with that name exists, the session gets full authorization** (`dssana.sup` help; verified
indirectly: `Quickload Utility` uses `No` with an empty profile and every `dssqld` change is
recorded in the audit trail as user `FULL AUTHORIZATION`). The installed lines name
`CI_NO_LOGIN`, which does not exist by default (only `CI_NO_LOGIN_OPCUAS` does).
Before setting `No` for an operator UI: create user `CI_NO_LOGIN` with a restricted
authorization group (`users-groups.md`) and a password, then change the method.
## 3. Change a method
Admin rights; hand to the user (skill `portal-setup`, `change-setup-file.md`). Add a specific
line above the `<local>`/`<remote>` lines (e.g. one HMI PC by host name), save, restart USER
Service (or CI Server) for it to take effect. With **AD integration on** (`AD_INT_ON = YES`) the
methods of the Edit and Engineering Modules are ignored: see `active-directory.md`.

View file

@ -0,0 +1,35 @@
---
name: high-availability
description: >-
CI Server R1.03 high availability with HAC (redundant servers). Use when the user asks about
redundant / dual / triple / quad servers, primary and secondary server, active and standby,
switchover (automatic or manual), the HAC HMI (hacw_hmi), watchdog, recovery (restart a
process or tool, hacrec, -wdg_off), mirror / synchronization of the standby, journaling and
key file repair (isfjrn, *.jrn), history merge after an island situation (hachmfcmd), hac.sup,
CI_PRIM, hacw_standby / hacw_stop scripts, HAC status items (SYSTEM.HAC1), hacitmval, HAC
firewall ports (UDP 16000-16006), hardware watchdog or custom health checks, or applying a
patch to a redundant system. Source IM 36K10J20-01EN.
---
# High availability — HAC (R1.03)
Background: `knowledge/manuals/IM36K10J20-01EN.md` (concepts, processes, set-up steps,
installed `hac.sup` and the differences from the manual).
Rules:
- Run `system-check` first; follow the user's chosen way of working.
- HAC needs its own licence and at least two servers with two separate networks between them.
Nothing here was practiced on a real redundant pair: say so when giving procedures.
- `hac.sup`, the `tls\com` scripts and system variables need admin rights and a restart; hand
them to the user (skill `portal-setup`, `change-setup-file.md`).
- Never switch over, reboot or change a server's mode on a running plant without the user's
explicit approval, and only when the mirror is consistent (see `redundant-setup.md` §3).
- Do not start `hacrec` with `-wdg_off` on a server without reviewing its process list first:
stand-alone Recovery acts (default action for most processes is `TOOL` = restart services).
| Task | File | Status |
|---|---|---|
| Check HAC on a system: licence, processes, `hac.sup`, scripts, HMI properties, logs | `tasks/hac-checks.md` | verified (read-only, single server) |
| Set up and operate a redundant server pair: steps, `hac.sup` tabs, manual switchover, patching | `tasks/redundant-setup.md` | from docs |
| Recovery, logger and journaling on a stand-alone node | `tasks/standalone-recovery.md` | from docs |
| Dual-redundant Platform for Computer | — | not covered (separate product) |

View file

@ -0,0 +1,50 @@
---
task: Check HAC on a system (licence, processes, hac.sup, scripts, HMI properties, logs)
version: R1.03
source: IM 36K10J20-01EN §1.3–§1.5, §2, §4.1.4, §6.1; checked read-only on the test system 2026-10-01
status: verified (read-only, single unlicensed server)
---
# HAC checks
All read-only.
## 1. Is HAC in use?
| Check | Command / file | HAC in use when … |
|---|---|---|
| Licence | `dir %TLS_ROOT_PATH%\tls\sup\hacini.sup` | the file exists (licence files are `<tool>ini.sup`) |
| Start script | `type %TLS_ROOT_PATH%\tls\com\ci_start.cmd` | it is a copy of `hacw_standby` (title *CI Server_in stand-by mode*, starts `haclog`, `lockmgr`, `isfjrn`) |
| Server number | `echo %CI_PRIM%` | 0 primary, 1 secondary, 2, 3 |
| Processes | `tasklist /FI "IMAGENAME eq hac*"` | `hacwdg`, `hacrec`, `haclog`, `hacmir`, `hacwagt`, `hacwitm` run |
Test system (R1.03.00): no `hacini.sup`, normal `ci_start.cmd`, `CI_PRIM` unset, no `hac*`
process — HAC not used.
## 2. Configuration
- `tls\sup\hac.sup`: read with the Setup File Editor or
`findstr /v /b "!" %TLS_ROOT_PATH%\tls\sup\hac.sup` (active lines only). Check `MODE`,
`HAC_HOSTS` (real host names, not `SERVER_A`…), `PRIMARY`/`SECONDARY` addresses, `IP_DEVICE`
(a real router/switch with priority 1; **no `localhost`** in production), `START_MANUAL`
(`NO` once commissioned), `RECOVERY_ON`, `JOURNAL_ON`, `HMF_DAYS`.
The installed file is a template (`SERVER_A`, `192.168.1.1`, `localhost`, `START_MANUAL =
YES`): if these are still present the pair was never configured.
- `hac.sup` must be identical on all servers (it is excluded from the mirror on purpose).
- HAC HMI: `%TLS_WAP_PATH%\cfg\jhacProperties\application.properties` — `primary=`,
`secondary=` (addresses of every network), `port1`/`port2` (16000), `logport` (16001).
- Firewall: UDP 16000–16006, TCP 34489 (history merge), ICMP between the servers.
## 3. State and logs (running pair)
- HAC HMI: `hacw_hmi` (not in the start menu). Per server: responsive, operational status
(Standby / Activating / Active / Deactivating), mode (Automatic / Manual), CI Server / custom /
IP health, mirror mode and status (consistent = black text), recovery table, IP devices, log.
- Status items if configured: `<section>.OPER_MODE` (87 manual, 88 automatic), `.OPER_STAT`
(95 active, 99 standby), `.CI_STAT`/`.IP_STAT` (90 healthy, 89 fault), `.DATA1_MODE`/
`.DATA1_STAT` (mirror) — read with `itmval -g`.
- Logs: `%TLS_LST_PATH%\hac_log_<n>.txt` (cyclic; `hac_log_0.txt` names the current
page), `hacmir.log`/`hacmir_old.log` (mirror), `%TLS_LOG_PATH%\hacw_standby.log`,
`hacw_activate.log`, and `umhlog.log` (`HAC*`, `ISFJRN` messages; ISFJRN names the journal
report `<DSSSDA>_jrn.lst` after an unclean shutdown).
- Watchdog start problems: `hacwdg -d` in a console shows initialization errors.

View file

@ -0,0 +1,90 @@
---
task: Set up and operate a redundant HAC server pair (steps, hac.sup tabs, switchover, patching)
version: R1.03
source: IM 36K10J20-01EN §1.2–§1.5, §2.4–§2.6, §3, §4.3–§4.11, §6.4, §7; hac.sup and scripts checked on the test system 2026-10-01
status: from docs (needs two licensed servers; not practiced)
---
# Redundant server pair (HAC)
Everything here needs admin rights on both servers and a planned outage. Prepare the files;
the user applies them.
## 1. Preparation
- Identical servers: same OS, CI Server version and patches, install path, TLS variables, node
number and licence (including HAC).
- ≥ 2 separate network interfaces/segments between the servers (≤ 4), separate from field
networks if possible. One link only = single point of failure and the risk that both servers
go active.
- Time sync on each server from an NTP/GPS source with jumps ≤ 1 s (not DUR time sync between
the pair: same node number).
- At least one real IP device per server for the network check (router/switch, priority 1).
- CI Service start type *Automatic* (HAC reboots servers).
- `TLS_BACKUP_PATH` on a partition at least as large as `TLS_HIS_PATH` (the standby zips its
runtime environment before each synchronization; without the variable the scripts use
`TLS_LST_PATH`).
## 2. Steps (on every server unless noted)
1. System variable `CI_PRIM` = 0 (primary), 1 (secondary), 2, 3.
2. Start CI Server once; create the optional status items per server (section, e.g.
`SYSTEM.HAC1`, items `OPER_MODE`, `OPER_STAT`, `CI_STAT`, `IP_STAT`, `DATA1_MODE`,
`DATA1_STAT`, …, all Integer); stop CI Server.
3. `tls\com`: rename `ci_start.cmd`/`ci_stop.cmd` to e.g. `ci_start_old.cmd`/`ci_stop_old.cmd`,
copy `hacw_standby.cmd` → `ci_start.cmd`, `hacw_stop.cmd` → `ci_stop.cmd`.
4. `hac.sup` on the primary (Setup File Editor), then copy to the others:
| Tab | Set |
|---|---|
| General | `MODE` (DUAL/TRIPLE/QUAD), `HAC_HOSTS` (host names in priority order), `HAC_UNIT` (status item sections), `HEARTBEAT` |
| Network | `PRIMARY`, `SECONDARY` … = the IP address of each network, same order on all servers |
| Watchdog | `IP_DEVICE = <ip>, <label>, <timeout>, <retries>, <interval>, <priority>` (≤ 20; priority 1 = loss makes the server unhealthy; **remove the template `localhost` entry**), `WDG_CONNECT = <alive check s>, <timeout s>, <retries>, <max time diff s>, <inhibit s>`, `HARDWARE_WDG`, `CUSTOM` (script in `tls\com`, exit 0 = healthy), `START_MANUAL` |
| Mirror (General) | `QUESIZE`, `MAXOPNDB`, timeouts, `MAX_ACTIONS`, `LOG_FILE_SIZE` — defaults normally fine |
| Mirror (Working set) | `INCLUDE_DIR`/`EXCLUDE_DIR`/`EXCLUDE_FILE`; keep the default excludes (node-private files such as `durm*.sup`, `*ini.sup`, `hac.sup`) |
| Recovery (General) | `RECOVERY_ON = YES` (required: it reports CI Server health to the Watchdog), `START_DELAY`, `TOOL` hierarchy, `PROCESS` list (remove unlicensed processes; add `HACMIR2`/`HACMIR3` for TRIPLE/QUAD), `NO_RUN`, `STANDBY` |
| Recovery (Monitoring) | `MAX_QUEUE`, `MAX_CPU`, `INACTIVE` (none set in the installed file) |
| Recovery (Custom actions) | `ACTION = <id>, <command>, <delay>, <params>` |
| History merge | `HMF_DAYS` (0 = off), `HMF_PATH` (outside the mirror, ~3 × period of history), `HMF_PORT` (34489) |
| Other | `JOURNAL_ON` (only small systems; needs write cache off), log size/pages/level, `PORTNUMS` (also change the `hacwsck` lines in the `hacw_*` scripts and the HMI properties) |
5. HAC HMI properties (`%TLS_WAP_PATH%\cfg\jhacProperties\application.properties`) on every
machine that runs the HMI: `primary=`, `secondary=` addresses.
6. Firewall: UDP 16000 (GUI/commands), 16003 (recovery), 16004 (watchdog↔watchdog), 16005 (item
setter), 16006 (file copy slave) between servers/HMI stations; 16001/16002 local; TCP 34489;
ICMP.
7. Start both servers; both come up STANDBY, the primary goes ACTIVE (if not in manual mode).
Test switchovers, then set `START_MANUAL = NO` so they start in AUTOMATIC.
## 3. Operating
- Manual switchover (HAC HMI): only when the mirror is consistent (active = master/active,
standby = slave/standby, black text) and at least one LAN is good. Set the ACTIVE server to
MANUAL and the STANDBY to AUTOMATIC, then change the ACTIVE server's status to STANDBY.
- Short maintenance on the active server: set all servers MANUAL (no automatic switchover),
restart what is needed, set back to AUTOMATIC. Status changes are refused in AUTOMATIC mode.
- No automatic switch-back to the primary after it recovers.
- Both servers active (HAC network lost): before reconnecting, put the server that should
become standby into standby by hand; then the active one synchronizes it. Use history merge
(`hachmfcmd` on the active server) to recover event history from the other server.
- Monitoring the standby from the active side: `hacitmval -c <active host> -n <section>.<item>
-v <int>` on the standby (the section must be one of the status item sections).
## 4. Patching a redundant pair (§6.4)
1. Full backup. 2. Stop the standby for maintenance (set it MANUAL, stop CI Server, set
`START_MANUAL = YES`). 3. Patch it. 4. Start it in manual; wait until the mirror shows master
active / slave standby. 5. Manual switchover to it. 6. Stop and patch the old active server.
7. Start it in manual (it becomes standby). 8. Set both to AUTOMATIC and `START_MANUAL = NO`.
Patches change files outside the mirror (`exe`, common files), so they are never copied
automatically.
## 5. Tips (§4.8, §6.5, §7)
- Large history: synchronization backups take long (ZIP of `TLS_HIS_PATH`); the manual's
options are to zip only the `*000000.*` administration files in `hacm_create_backup` /
`hacm_restore_backup` (history data then not protected) or use another archiver.
- Increase the Watchdog inhibit time on big systems so a fresh standby is synchronized before
another switchover is allowed; increase *Data to master* timeout if big key-file repairs on
the slave restart the synchronization.
- CI Server must start within 5 minutes, otherwise the servers keep switching.

View file

@ -0,0 +1,58 @@
---
task: Use HAC Recovery, logger and journaling on a stand-alone node
version: R1.03
source: IM 36K10J20-01EN §3.2, §3.3, §4.1, §4.9, §6.2; integration_start.cmd, database_start.cmd and hac.sup checked on the test system 2026-10-01
status: from docs (not started on the test system)
---
# HAC on a stand-alone node
Without a redundant pair, two HAC functions are still useful on any node: **Recovery** (restart
or report unhealthy CI Server processes) and **journaling** (repair after an unclean shutdown).
Admin rights and a restart are needed; hand the changes to the user.
## 1. Recovery and logger
1. In `tls\com\integration_start.cmd` uncomment the HAC block:
```
start /B /NORMAL %TLS_ROOT_PATH%\tls\exe\haclog.exe > nul
start /B /NORMAL %TLS_ROOT_PATH%\tls\exe\hacrec.exe -wdg_off > nul
start /B /NORMAL /WAIT %TLS_ROOT_PATH%\tls\exe\durwfp -p hacrec -t 10
```
and the matching stop lines in `integration_stop.cmd`. `-wdg_off` = no Watchdog: Recovery
acts itself.
2. **Review `hac.sup` first** (tab *Recovery (General)*): the installed list has ~70 `PROCESS`
lines, most with action `TOOL` (restart the tool and everything that depends on it), for
processes that may not run on your node (e.g. `HASEXE`, `ITHEEX`, `DSSSDA00`–`03`, PROCESS
executors). Remove what does not run there (an HMI node keeps only BUS, DATABASE and COLOUR
processes), list optional processes under `NO_RUN`, and prefer `ALERT` (message in
`umhlog.log`) until you are sure a restart is wanted. `REBOOT`/`SHUTDOWN` call
`tls\com\hac_reboot`/`hac_shutdown`, which are not shipped (copy `hacw_shutdown` if needed).
3. Optional checks (tab *Recovery (Monitoring)*): `MAX_QUEUE`/`MAX_CPU` (average % over a
period ≥ 10 s; the process must also be in `INACTIVE`) and `INACTIVE` (heartbeat-based
non-response, only processes that support it). None are set in the installed file.
4. `START_DELAY` (30 s) is also the pause after each recovery action; raise it to minutes with
`ALERT` to avoid repeated messages.
5. Read the result in `%TLS_LST_PATH%\hac_log_<n>.txt` (or the HAC HMI *Log* tab) and
`umhlog.log`.
Project processes: start them from `integration_start` (or a `<tool>_start`/`<tool>_stop` pair
plus a `TOOL` line), then add `PROCESS = <name>, <tool>, <action>`; a trailing `*` is the only
wildcard (`EQP*`).
## 2. Journaling
1. `hac.sup` tab *Other*: `JOURNAL_ON = YES` (heavy disk load — small systems only).
2. Disable the disk write cache for the `TLS_DAT_PATH`/`TLS_HIS_PATH` disks (Device Manager ›
disk › *Policies*) or use a UPS; optionally enable `ismflush <disk> <s>` in
`tls\com\database_start.cmd` (commented example `ismflush.exe \\.\C: 60`).
3. After an unclean shutdown: ISAM key files are repaired automatically at start (`ISFJRN`);
for datasets read the report named in `umhlog.log` (`tls\lst\<DSSSDA>_jrn.lst`) and run the
listed `dsschk -d <set>` / `dsschk -r <set>` (back up first; skill `system-management`,
`consistency-check.md`).
4. After restoring a backup, delete `%TLS_DAT_PATH%\*.jrn` so no false repairs run.
## 3. Related monitoring
For whole-system CPU, disk, TCP and DURM link checks use the INTEGRATION monitors (`intcpumon`,
`intdskmon`, `inttcpmon`, `intmon`): skill `system-management`, `monitoring-processes.md`.

View file

@ -37,7 +37,7 @@ development system (see "Test system" in `progress.md`); they do not exist on ot
| ISS-015 | 2026-09-30 | Setup File Editor | In `wfla_display.sup` the seven main keywords (`RELATION_LOCATION` … `TIMER_INTERVAL`) come before the only tab line `!TAB = Debug`. By IM 36K10R20 §3.1, keywords before the first `!TAB` are not shown, yet IM 36K10R10 §4.4.1 shows them on a *General* tab. What the editor really shows is unknown. | closed | Closed 2026-09-30 (checked in the Setup File Editor by the user; installed software is the reference). The editor shows keywords placed before the first `!TAB` on a **General** tab, followed by the defined tabs: `wfla_display.sup` shows *General* (all 7 fields, values as in the file) and *Debug*. The manual's statement that such keywords are ignored does not hold in R1.03. | `knowledge/manuals/IM36K10R20-01EN.md` §3; `knowledge/manuals/IM36K10R10-01EN.md` §4; `.claude/skills/portal-setup/tasks/change-setup-file.md` | | ISS-015 | 2026-09-30 | Setup File Editor | In `wfla_display.sup` the seven main keywords (`RELATION_LOCATION` … `TIMER_INTERVAL`) come before the only tab line `!TAB = Debug`. By IM 36K10R20 §3.1, keywords before the first `!TAB` are not shown, yet IM 36K10R10 §4.4.1 shows them on a *General* tab. What the editor really shows is unknown. | closed | Closed 2026-09-30 (checked in the Setup File Editor by the user; installed software is the reference). The editor shows keywords placed before the first `!TAB` on a **General** tab, followed by the defined tabs: `wfla_display.sup` shows *General* (all 7 fields, values as in the file) and *Debug*. The manual's statement that such keywords are ignored does not hold in R1.03. | `knowledge/manuals/IM36K10R20-01EN.md` §3; `knowledge/manuals/IM36K10R10-01EN.md` §4; `.claude/skills/portal-setup/tasks/change-setup-file.md` |
| ISS-016 | 2026-09-30 | Setup File Editor | The R1.03 editor has features IM 36K10R20 §2 does not describe: a *Templates* tab next to *Setup Files*; a *Status* column in the file list (e.g. "Default"); *Undo Field* and *Reset Field* buttons on the edit form besides OK/Cancel/Help; a status bar with the selected file's description and the time. | closed | Installed software is the reference (user decision). 2026-09-30, tested on `wfla_display.sup` (`DUR_QUEUE_SIZE` 1000 → 2000): clicking **OK writes the file immediately** (only the active line changed; the manual says OK keeps the change in memory until Exit). Status becomes **Changed** when an active value differs from the file's `!DEFAULT` block; the changed field's label turns **blue**. *Reset Field* is enabled when the cursor is in a changed field; *Reset Field* + *OK* put the value back to the `!DEFAULT` value (2000 → 1000) and wrote the file at once (16:22:28); the rest of the file was unchanged. Still to find: what *Templates* holds and what *Undo Field* does. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10R20-01EN.md` §2; `.claude/skills/portal-setup/tasks/change-setup-file.md` | | ISS-016 | 2026-09-30 | Setup File Editor | The R1.03 editor has features IM 36K10R20 §2 does not describe: a *Templates* tab next to *Setup Files*; a *Status* column in the file list (e.g. "Default"); *Undo Field* and *Reset Field* buttons on the edit form besides OK/Cancel/Help; a status bar with the selected file's description and the time. | closed | Installed software is the reference (user decision). 2026-09-30, tested on `wfla_display.sup` (`DUR_QUEUE_SIZE` 1000 → 2000): clicking **OK writes the file immediately** (only the active line changed; the manual says OK keeps the change in memory until Exit). Status becomes **Changed** when an active value differs from the file's `!DEFAULT` block; the changed field's label turns **blue**. *Reset Field* is enabled when the cursor is in a changed field; *Reset Field* + *OK* put the value back to the `!DEFAULT` value (2000 → 1000) and wrote the file at once (16:22:28); the rest of the file was unchanged. Still to find: what *Templates* holds and what *Undo Field* does. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10R20-01EN.md` §2; `.claude/skills/portal-setup/tasks/change-setup-file.md` |
| ISS-017 | 2026-09-30 | CI Portal setup files | IM 36K10R10 §4 says the logon method is the one user-interface setting normally changed, but the R1.03 `jwuiisg.sup` *Information* tab says the login method and login control settings have moved to `dssana.sup` (authentication and authorization). `dssana.sup` is not described in R10. | closed | Installed software is the reference. 2026-09-30: `dssana.sup` ("Authentication and authorization setup") has tabs General, User Interfaces, Clients System Trust, Login control (`LOGIN_METHOD = <client>, <user interface>, <method>, …`), Active Directory, Single Sign On, Password rules, Logging. Manuals mentioning it: IM 36K01A50 (5×), 36K10C10 (6×), 36K10J40 (13×), 36K10L45 (2×), 36K10L50 (3×). Cover it in phase 5 (C10) and phase 13 (J40). 2026-09-30: login methods (Automatic, Manual CI Server, Manual OS, No, SSO, Deny) now summarized from C10 §2.2 in `knowledge/manuals/IM36K10C10-01EN.md`; AD/SSO details remain for J40. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10R10-01EN.md` §4; `.claude/skills/portal-setup/SKILL.md` | | ISS-017 | 2026-09-30 | CI Portal setup files | IM 36K10R10 §4 says the logon method is the one user-interface setting normally changed, but the R1.03 `jwuiisg.sup` *Information* tab says the login method and login control settings have moved to `dssana.sup` (authentication and authorization). `dssana.sup` is not described in R10. | closed | Installed software is the reference. 2026-09-30: `dssana.sup` ("Authentication and authorization setup") has tabs General, User Interfaces, Clients System Trust, Login control (`LOGIN_METHOD = <client>, <user interface>, <method>, …`), Active Directory, Single Sign On, Password rules, Logging. Manuals mentioning it: IM 36K01A50 (5×), 36K10C10 (6×), 36K10J40 (13×), 36K10L45 (2×), 36K10L50 (3×). Cover it in phase 5 (C10) and phase 13 (J40). 2026-09-30: login methods (Automatic, Manual CI Server, Manual OS, No, SSO, Deny) now summarized from C10 §2.2 in `knowledge/manuals/IM36K10C10-01EN.md`; AD/SSO details remain for J40. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10R10-01EN.md` §4; `.claude/skills/portal-setup/SKILL.md` |
| ISS-018 | 2026-09-30 | Authorization (`dssana.sup`) | IM 36K10C10 §2.2 says the *No* login method applies the user profile `FT_NO_LOGIN`; the installed `dssana.sup` names `CI_NO_LOGIN` (and `CI_NO_LOGIN_OPCUAS` for anonymous OPC UA) as the no-login profile. `USER_DF` on the test system has `CI_NO_LOGIN_OPCUAS` but no `CI_NO_LOGIN`. | open | Installed software is the reference: use `CI_NO_LOGIN`. Still to check: behaviour of a *No* login when that user does not exist (manual: no profile applied). Covered again in phase 13 (IM 36K10J40). | `knowledge/manuals/IM36K10C10-01EN.md` §2 | | ISS-018 | 2026-09-30 | Authorization (`dssana.sup`) | IM 36K10C10 §2.2 says the *No* login method applies the user profile `FT_NO_LOGIN`; the installed `dssana.sup` names `CI_NO_LOGIN` (and `CI_NO_LOGIN_OPCUAS` for anonymous OPC UA) as the no-login profile. `USER_DF` on the test system has `CI_NO_LOGIN_OPCUAS` but no `CI_NO_LOGIN`. | closed | Installed software is the reference: use `CI_NO_LOGIN`. Answered in phase 13 (2026-10-01): the `dssana.sup` help says that when no user with the no-login profile name exists, **full authorization** is used (not "no profile" as IM 36K10C10 says). Verified indirectly: `Quickload Utility` has *No* login with an empty profile, and every `dssqld` change is recorded in the audit trail as user `FULL AUTHORIZATION`. Documented in `authorization/tasks/login-methods.md` (create a restricted `CI_NO_LOGIN` user before using *No* login). Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10C10-01EN.md` §2 |
| ISS-019 | 2026-09-30 | ITEM (string items) | Maximum string item length differs by source: IM 36K10C10 §3.3.4 says default 80, max 100; the Tutorial summary says up to 168 without audit; the data dictionary (`dssqld -f`) gives `ITEM_DF.STRING_LENGTH` range 1–200, default 80. | closed | Tested 2026-09-30 on CI-Eng-Sample (`dssqld -i`, `itmval -p/-g`, non-elevated): `STRING_LENGTH` 100, 168 and 200 load with or without `AUDIT_INFO`; 201 fails with `DSS-E-VAL_RANGE`. An item holds **length − 1** characters: a 99-character value in a length-100 item is stored with status 9 NORMAL; longer values are cut to length − 1 with status **12 OVERRANGED** (100 → 99, 200 → 199, 201 → 199). So the data dictionary (1–200) is right. Test items removed. Closed 2026-09-30 (confirmed by user). | `knowledge/manuals/IM36K10C10-01EN.md` §3; `knowledge/manuals/IM36K10G10-01EN.md` (items); `.claude/skills/item-engineering/SKILL.md` | | ISS-019 | 2026-09-30 | ITEM (string items) | Maximum string item length differs by source: IM 36K10C10 §3.3.4 says default 80, max 100; the Tutorial summary says up to 168 without audit; the data dictionary (`dssqld -f`) gives `ITEM_DF.STRING_LENGTH` range 1–200, default 80. | closed | Tested 2026-09-30 on CI-Eng-Sample (`dssqld -i`, `itmval -p/-g`, non-elevated): `STRING_LENGTH` 100, 168 and 200 load with or without `AUDIT_INFO`; 201 fails with `DSS-E-VAL_RANGE`. An item holds **length − 1** characters: a 99-character value in a length-100 item is stored with status 9 NORMAL; longer values are cut to length − 1 with status **12 OVERRANGED** (100 → 99, 200 → 199, 201 → 199). So the data dictionary (1–200) is right. Test items removed. Closed 2026-09-30 (confirmed by user). | `knowledge/manuals/IM36K10C10-01EN.md` §3; `knowledge/manuals/IM36K10G10-01EN.md` (items); `.claude/skills/item-engineering/SKILL.md` |
| ISS-020 | 2026-09-30 | DATABASE (`dssqld`) | `dssqld -i "<long absolute path>\user.qli"` failed with `CRL-E-ENOENT` / `DSSQ-E-QLD_FILOPN`: the path in the message was cut after 79 characters (`…\73b3559a-12.`). A relative file name from the same folder works. Similar to the `intspawn` path limit (ISS-007). | closed | Tested 2026-10-01: the limit is **79 characters** for the whole path. An input file of 80–81 characters gives `DSSQ-E-Q_QLIEXT` (the name is cut, e.g. `….ql`), 85+ gives `CRL-E-ENOENT`. An `-e` output path of 80+ characters gives **no error**, but no file appears under the given name. Documented: keep paths ≤ 79 characters, or `cd` to the folder and use relative names. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `.claude/skills/system-management/tasks/load-remove-records.md`; `.claude/skills/system-management/tasks/export-dataset.md` | | ISS-020 | 2026-09-30 | DATABASE (`dssqld`) | `dssqld -i "<long absolute path>\user.qli"` failed with `CRL-E-ENOENT` / `DSSQ-E-QLD_FILOPN`: the path in the message was cut after 79 characters (`…\73b3559a-12.`). A relative file name from the same folder works. Similar to the `intspawn` path limit (ISS-007). | closed | Tested 2026-10-01: the limit is **79 characters** for the whole path. An input file of 80–81 characters gives `DSSQ-E-Q_QLIEXT` (the name is cut, e.g. `….ql`), 85+ gives `CRL-E-ENOENT`. An `-e` output path of 80+ characters gives **no error**, but no file appears under the given name. Documented: keep paths ≤ 79 characters, or `cd` to the folder and use relative names. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `.claude/skills/system-management/tasks/load-remove-records.md`; `.claude/skills/system-management/tasks/export-dataset.md` |
| ISS-021 | 2026-09-30 | EQUIPMENT (`eqpiostat`) | IM 36K10L40 §2 says `eqpiostat` stores hourly I/O statistics per station line in "history group STATION_STAT". On the test system `eqpiostat` runs (started by `equipment_start.cmd` on the host node) and `STATION_STAT` is a dataset, but `dssqld -e` returned 0 records, also with filters on `TIME_STAMP` and `STATION` (AID Modbus stations, which send requests). | closed | Answered 2026-10-01: with `CIENG_PLC` communicating (Modbus slave mirror running), `STATION_STAT` holds one record per hour per station line (10 records since 30-09-2026 18:00; e.g. `TIMESPAN` 831 s, `SENDS`/`GOODANS` 1560/1560, no errors). The earlier empty export had no communicating station. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10L40-01EN.md` §2 | | ISS-021 | 2026-09-30 | EQUIPMENT (`eqpiostat`) | IM 36K10L40 §2 says `eqpiostat` stores hourly I/O statistics per station line in "history group STATION_STAT". On the test system `eqpiostat` runs (started by `equipment_start.cmd` on the host node) and `STATION_STAT` is a dataset, but `dssqld -e` returned 0 records, also with filters on `TIME_STAMP` and `STATION` (AID Modbus stations, which send requests). | closed | Answered 2026-10-01: with `CIENG_PLC` communicating (Modbus slave mirror running), `STATION_STAT` holds one record per hour per station line (10 records since 30-09-2026 18:00; e.g. `TIMESPAN` 831 s, `SENDS`/`GOODANS` 1560/1560, no errors). The earlier empty export had no communicating station. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10L40-01EN.md` §2 |
@ -72,3 +72,5 @@ development system (see "Test system" in `progress.md`); they do not exist on ot
| ISS-050 | 2026-10-01 | AUDIT (classifier `STORAGE`) | Setting `AUDIT_EVENT_CLAS_DF.STORAGE` = 0 for `DATASET.NULL-ATTR.MODIFY.ENT-ENG-MOD` at 17:01:12 did not stop the next `dssqld -m ITEM_VAL` change from being stored (17:01:12.573). IM 36K10L25 §3.2 explains a per-process cache refreshed every `ECL_REFRESH` s (default 1800); the notifier here is `DSSSDA`, so the change should apply within 30 minutes. | closed | Re-tested: at 17:32:18 (after the 30-minute refresh) the same change was **not** stored, so the flag works with a delay. Set back to 1 at 17:32; the next change was still not stored (the cache works in both directions). Documented: allow up to `ECL_REFRESH` (1800 s) or restart CI Server. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `.claude/skills/audit-trail/tasks/configure-audit.md` §1; `knowledge/manuals/IM36K10L25-01EN.md` §3 | | ISS-050 | 2026-10-01 | AUDIT (classifier `STORAGE`) | Setting `AUDIT_EVENT_CLAS_DF.STORAGE` = 0 for `DATASET.NULL-ATTR.MODIFY.ENT-ENG-MOD` at 17:01:12 did not stop the next `dssqld -m ITEM_VAL` change from being stored (17:01:12.573). IM 36K10L25 §3.2 explains a per-process cache refreshed every `ECL_REFRESH` s (default 1800); the notifier here is `DSSSDA`, so the change should apply within 30 minutes. | closed | Re-tested: at 17:32:18 (after the 30-minute refresh) the same change was **not** stored, so the flag works with a delay. Set back to 1 at 17:32; the next change was still not stored (the cache works in both directions). Documented: allow up to `ECL_REFRESH` (1800 s) or restart CI Server. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `.claude/skills/audit-trail/tasks/configure-audit.md` §1; `knowledge/manuals/IM36K10L25-01EN.md` §3 |
| ISS-051 | 2026-10-01 | AUDIT (manual vs installed) | Differences between IM 36K10L25 and R1.03.00: (1) App. 1 lists subject `F/T-SYSTEM`, the installed classifiers use `CI-SERVER` (logins) and also `EAL OPERATION` (subject and action) and source `VIA-OPC-UAS`, not in the manual; 463 classifiers installed. (2) App. 1 explanations of `SHELVE` and `UN-SHELVE` are swapped. (3) `QUESIZE`: manual default and maximum 200 kB, `adtsys.sup` help default 10 kB, minimum 10 (file sets 200). (4) `TIMEFMT` default: manual `DD/MM/YY hh:mm:ss.ppp`, `adtsys.sup` help without `.ppp`; `ADTLOG` output shows milliseconds (manual right). (5) `dssqld` changes are recorded with source `ENT-ENG-MOD`, not `QUICKLOAD`. (6) The selection expression language is not described in the manual; the compiler listing gives the words and operators (no `LIKE`). (7) `ADT` group lifetime 52 weeks on the test system vs 2 days default when `ADTSTO` creates it (§2.1.1). | closed | Documented in the L25 summary and the `audit-trail` skill. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10L25-01EN.md`; `.claude/skills/audit-trail/tasks/*.md` | | ISS-051 | 2026-10-01 | AUDIT (manual vs installed) | Differences between IM 36K10L25 and R1.03.00: (1) App. 1 lists subject `F/T-SYSTEM`, the installed classifiers use `CI-SERVER` (logins) and also `EAL OPERATION` (subject and action) and source `VIA-OPC-UAS`, not in the manual; 463 classifiers installed. (2) App. 1 explanations of `SHELVE` and `UN-SHELVE` are swapped. (3) `QUESIZE`: manual default and maximum 200 kB, `adtsys.sup` help default 10 kB, minimum 10 (file sets 200). (4) `TIMEFMT` default: manual `DD/MM/YY hh:mm:ss.ppp`, `adtsys.sup` help without `.ppp`; `ADTLOG` output shows milliseconds (manual right). (5) `dssqld` changes are recorded with source `ENT-ENG-MOD`, not `QUICKLOAD`. (6) The selection expression language is not described in the manual; the compiler listing gives the words and operators (no `LIKE`). (7) `ADT` group lifetime 52 weeks on the test system vs 2 days default when `ADTSTO` creates it (§2.1.1). | closed | Documented in the L25 summary and the `audit-trail` skill. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10L25-01EN.md`; `.claude/skills/audit-trail/tasks/*.md` |
| ISS-052 | 2026-10-01 | GRAPHICS (stale item id) | The HTML display `CIENG_Tank` showed **0** in its number field on `CI-Eng-Sample.TANK1.LEVEL` (live value 50) and the popup `ITM-E-NO_MAIN, No main item found`, in a fresh session after a CI Server restart. The display XML stores `<itemName>` **and** `<itemId>1.1.268.0.0.1.1.7</itemId>` from when it was built; after today's sample reloads the item has `ID_NUMBER` 357. Phase 10 had seen live values after a reload, so the id is not always used, but here it broke the field. | closed | Fixed in the sample: removed the `<itemId>` line from `displays/CIENG_Tank.xml`, redeployed; the field shows 50 and the popup is gone (binding by name). Documented in `create-display.md`. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `examples/CI-Eng-Sample/displays/CIENG_Tank.xml`; `.claude/skills/graphics/tasks/create-display.md`; `.claude/skills/graphics/tasks/deploy-displays.md` | | ISS-052 | 2026-10-01 | GRAPHICS (stale item id) | The HTML display `CIENG_Tank` showed **0** in its number field on `CI-Eng-Sample.TANK1.LEVEL` (live value 50) and the popup `ITM-E-NO_MAIN, No main item found`, in a fresh session after a CI Server restart. The display XML stores `<itemName>` **and** `<itemId>1.1.268.0.0.1.1.7</itemId>` from when it was built; after today's sample reloads the item has `ID_NUMBER` 357. Phase 10 had seen live values after a reload, so the id is not always used, but here it broke the field. | closed | Fixed in the sample: removed the `<itemId>` line from `displays/CIENG_Tank.xml`, redeployed; the field shows 50 and the popup is gone (binding by name). Documented in `create-display.md`. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `examples/CI-Eng-Sample/displays/CIENG_Tank.xml`; `.claude/skills/graphics/tasks/create-display.md`; `.claude/skills/graphics/tasks/deploy-displays.md` |
| ISS-053 | 2026-10-01 | HAC (manual vs installed) | IM 36K10J20 vs the installed `hac.sup`/scripts: (1) *Start in manual mode*: §1.3 says HAC starts in manual by default, §1.5 and the `hac.sup` help say automatic; the installed template sets `START_MANUAL = YES`. (2) `MAXOPNDB` default: help 500, manual 50 (§1.5) and 5 (§4.8). (3) `QUESIZE` default: help 100 K, manual 2000 K (file sets 2000). (4) §4.5 says `tls\com` and `tls\exe` cannot be mirrored, but the template mirrors `12 COM` (excluding `ci_command.cmd`). (5) §4.4 says the critical processes are already in the queue/CPU check lists; the installed file has no `MAX_QUEUE`/`MAX_CPU`/`INACTIVE` lines. (6) `hacw_standby` uses `TLS_LST_PATH` when `TLS_BACKUP_PATH` is unset (manual: `TLS_ALLUSERS_PATH`). (7) The template `IP_DEVICE` is `localhost` (priority 0), which §1.3 says to remove after testing. (8) HMI properties have `communicationInterval`/`Timeout`/`RetryCount`, not in the manual. | closed | Installed software is the reference (standing user decision); documented in the J20 summary §5 and the `high-availability` skill. Not testable on one server. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10J20-01EN.md`; `.claude/skills/high-availability/tasks/*.md` |
| ISS-054 | 2026-10-01 | AD (manual vs installed) | IM 36K10J40 vs the installed `dssana.sup`: the *Active Directory* tab has keywords the manual does not describe — `AD_SERVER`, `AD_SERVER_BACKUP` (host[:port], 389/636), `AD_SECURE` (LDAPS; installed `NO`, help says default yes), `AD_ACCESS_USER`/`AD_ACCESS_PASSWORD` (blank = the CI Server service account). The manual's *Profile priority* is `USER_DF.MERGE_PRIORITY`; *Directory group* is `DIRECTORY_GROUP` (68 characters). The SSO keytab path is given as `%TLS_WAP_PATH%\webapps\auth\WEB-INF` (§2.5.1) and `%TLS_ALLUSERS_PATH%\wap\webapps\auth\WEB-INF` (§3.4.3) — the same folder on the test system. | closed | Installed software is the reference; documented in the J40 summary §5 and `authorization/tasks/active-directory.md`. Not testable without a domain. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10J40-01EN.md`; `.claude/skills/authorization/tasks/active-directory.md` |

View file

@ -51,7 +51,11 @@ Test system (`dssana.sup` installed values): local Engineering/Edit Module, Oper
Interface etc. use **SSO**; remote Playback Viewer, Quickload and Display/Symbol utilities are Interface etc. use **SSO**; remote Playback Viewer, Quickload and Display/Symbol utilities are
**Deny**; OPC UA/ODBC use *Manual CI Server*. The no-login profile named there is **Deny**; OPC UA/ODBC use *Manual CI Server*. The no-login profile named there is
`CI_NO_LOGIN` (the manual says `FT_NO_LOGIN`, ISS-018); no user of that name exists on the `CI_NO_LOGIN` (the manual says `FT_NO_LOGIN`, ISS-018); no user of that name exists on the
test system. test system. The `dssana.sup` help says that when the no-login profile does not exist as a CI
Server user, **full authorization** is used (the manual says no profile is applied). Matches the
test system: `Quickload Utility` has *No* login with an empty profile, and `dssqld` runs appear
in the audit trail as user `FULL AUTHORIZATION`. Create a restricted `CI_NO_LOGIN` user before
using *No* login anywhere (`IM36K10J40-01EN.md` §5).
**Enterprise engineers (§2.3)** may maintain only their area: sections and everything in them, **Enterprise engineers (§2.3)** may maintain only their area: sections and everything in them,
definitions and deployments, authorization data, and equalization — and can deploy to a definitions and deployments, authorization data, and equalization — and can deploy to a

View file

@ -0,0 +1,112 @@
---
manual: IM 36K10J20-01EN
title: High Availability Computing
edition: 3rd Edition, Sep. 2023
version: R1.03
status: installed hac.sup, hacw_*/hacm_* scripts, HAC executables, HAC HMI properties and integration_start checked read-only on the test system 2026-10-01; redundancy, mirror, journaling, recovery and history merge from docs only (single unlicensed server, HAC not licensed)
---
# High Availability Computing — HAC (R1.03)
CI Server offers two high-availability options: **HAC** (active/standby servers, this manual)
and the Dual-redundant Platform for Computer (not covered). HAC is part of DATABASE Service,
installed on every node, but needs its own licence. Configuration is in `tls\sup\hac.sup`.
Section numbers refer to the manual; "installed" means checked on the R1.03.00 test system.
## 1. Concepts (§1.1, §3.1)
- **ACTIVE / STANDBY**: only one server runs CI Server completely; the standby runs a minimal
set (BUS, lock manager, HAC processes) and watches its partner. All servers start as
STANDBY; the highest-priority healthy one goes active.
- **PRIMARY … QUATERNARY**: physical machines, in priority order (DUAL, TRIPLE, QUAD). The
primary only matters at start-up: after a switchover the system does **not** switch back.
- **AUTOMATIC / MANUAL** per server: in MANUAL the server still checks health but takes no
action; no switchover to or from a MANUAL server. Use MANUAL for engineering and maintenance.
- Same CI Server node number on all servers, different IP addresses; clients do not see which
machine is active. Switchover takes some tens of seconds after a fault is detected.
- **Island**: a server with no partner and no IP device reachable shuts itself down;
otherwise the active server is shut down by its partner, not by itself.
## 2. Parts (§3)
| Function | Process | Job |
|---|---|---|
| Watchdog | `HACWDG` | Decides health from Recovery, partner link, IP devices (≤ 20, ping) and custom scripts; switches over; hardware-watchdog keep-alive script |
| Recovery | `HACREC` | Watches CI Server processes (running, DUR queue %, CPU %, non-responsive heartbeat). With a Watchdog it only reports; stand-alone (`-wdg_off`) it acts: ALERT, PROCESS, TOOL (restart tool and its dependants in hierarchy order), REBOOT, SHUTDOWN |
| Mirror | `HACMIR1` (+ `HACMIR2/3` for TRIPLE/QUAD), `HACMIRSLV`, `HACWAGT` | Keeps the standby in sync: zip backup of the standby first (`TLS_BACKUP_PATH`), then file comparison, then event-based ISAM record changes and file-change watching |
| Journaling | `ISFJRN` (start-up), DSS journal | Tracks open ISAM files (key file repaired automatically at start) and open datasets (report `<DSSSDA>_jrn.lst` in `tls\lst`, repair by hand with `dsschk -r`) |
| Logger | `HACLOG` | Cyclic text log `tls\lst\hac_log_<n>.txt`; `hac_log_0.txt` names the current page |
| Item setter | `HACWITM`, `hacitmval` | Standby server writes items on the active server (`hacitmval -c <host> -n <item> -v <int> [-s <status>]`; the section must be a status item location) |
| History merge | `hachmf*` | After an island period, copies event history of the secondary and merges it into the primary for OFFLINE periods (`HMF_DAYS` 0 = off; `hachmfcmd`) |
| HMI | `hacw_hmi` (Java) | Server states, LAN links, mode/status dialogs, recovery table, IP devices, log; reads `%TLS_WAP_PATH%\cfg\jhacProperties\application.properties` |
Status items (optional, created by the engineer, one section per server, e.g. `SYSTEM.HAC1`):
`OPER_MODE`, `OPER_STAT`, `CI_STAT`, `IP_STAT`, `DATA1–3_MODE`, `DATA1–3_STAT` with codes such as
87 manual, 88 automatic, 95 active, 99 standby, 89 fault, 90 healthy, 85/86 mirror master/slave.
## 3. Setting up a redundant pair (§1.2, §1.3)
1. Two (or more) identical servers, same install path and TLS variables, same node number and
licence; **at least two separate networks** between them (≤ 4); time sync with ≤ 1 s jumps
(DUR time sync cannot be used between the servers: same node number); CI Service start
type *Automatic* (HAC reboots servers).
2. System variable `CI_PRIM` = 0 primary, 1 secondary, 2, 3.
3. Start CI Server once, create the status items, stop.
4. In `tls\com`: rename `ci_start`/`ci_stop` (keep copies), copy `hacw_standby` → `ci_start`,
`hacw_stop` → `ci_stop`.
5. `hac.sup` on the primary, then copy to the others: mode, host names, status item sections
(*General*); IP addresses per network (*Network*); IP devices (at least one real device;
remove `localhost` after testing), partner alive check (*Watchdog*); mirror tabs; recovery
(remove unlicensed processes; add `HACMIR2/3` for TRIPLE/QUAD); journaling (*Other*).
6. HAC HMI properties: `primary=`/`secondary=` addresses, ports.
7. Firewall: UDP 16000–16006 as listed in §1.3, TCP 34489 (history merge), ICMP.
8. When tested: clear *Start in manual mode* so the servers start in AUTOMATIC.
Manual switchover (§2.6): set the active server MANUAL and the standby AUTOMATIC in the HAC HMI,
then set the active server's status to STANDBY. Only when the mirror is consistent (active =
master/active, standby = slave/standby, text black in the HMI) and at least one LAN is good.
Repair scenarios and patch installation (standby first, switch over, then the old active):
§6.4.
## 4. Stand-alone use (§4.1)
On any node HAC can run without a Watchdog: Recovery (`hacrec -wdg_off`) and the logger. The
lines are in `tls\com\integration_start.cmd`, commented out. Recovery then **acts** on
problems; review the process list (e.g. remove tools that do not run on an HMI node) and keep
actions at ALERT unless a restart is really wanted. Journaling also works stand-alone (needs
write cache off on the data/history disks, §4.9, and `ismflush` in `database_start.cmd`).
## 5. Installed (R1.03.00 test system)
- `hac.sup` template values: `MODE = DUAL`, hosts `SERVER_A`–`SERVER_D`, status sections
`SYSTEM.HAC1`–`4`, example IPs `192.168.1.x`/`192.168.2.x`, `IP_DEVICE = "localhost"` with
priority 0, `WDG_CONNECT = 1,2,5,30,120`, `START_MANUAL = YES`, `RECOVERY_ON = YES`,
`START_DELAY = 30`, the tool hierarchy BUS → HAC/DATABASE → HISTORY → AUDIT → ITEM → ALARM →
REPORT/PROCESS/ACCESS/INTEGRATION, ~70 `PROCESS` lines (mostly action `TOOL`), `NO_RUN =
FMFPRT`, `JOURNAL_ON = NO`, mirror include `SAV` (tree), `DAT`, `HIS`, `SUP`, **`COM`** with
node-private excludes (`durm*.sup`, `*ini.sup`, `hac.sup`, `ci_command.cmd`, journals,
SQLite `-wal`/`-shm` files). No `MAX_QUEUE`/`MAX_CPU`/`INACTIVE` lines and no history-merge
keywords are set.
- Keywords (`hac.sup` *KEYWORD* list): `MODE`, `HAC_HOSTS`, `HAC_UNIT`, `HEARTBEAT`,
`PRIMARY`…`QUATERNARY`, `IP_DEVICE`, `WDG_CONNECT`, `HARDWARE_WDG`, `CUSTOM`, `START_MANUAL`,
`QUESIZE`, `MAXOPNDB`, `REPLY_TIMEOUT`, `MASTER_TIMEOUT`, `SLAVE_TIMEOUT`, `ALIVE_TIMEOUT`,
`MAX_ACTIONS`, `LOG_FILE_SIZE`, `INCLUDE_DIR`, `EXCLUDE_DIR`, `EXCLUDE_FILE`, `RECOVERY_ON`,
`START_DELAY`, `TOOL`, `PROCESS`, `NO_RUN`, `STANDBY`, `MAX_QUEUE`, `MAX_CPU`, `INACTIVE`,
`ACTION`, `HMF_DAYS`, `HMF_PATH`, `HMF_PORT`, `JOURNAL_ON`, `LOG_SIZE`, `LOG_PAGES`,
`LOG_LEVEL`, `PORTNUMS`.
- Scripts in `tls\com`: `hacw_standby`, `hacw_activate`, `hacw_deactivate`, `hacw_stop`,
`hacw_shutdown`, `hacw_hmi`, `hacm_create/flush/restore_backup`, `hacm_mirror_start/stop`,
`hachmfcpy`. `ci_start.cmd` is the normal (non-HAC) one. `hacw_standby` falls back to
`TLS_LST_PATH` when `TLS_BACKUP_PATH` is not set. Executables: `hacwdg`, `hacrec`, `haclog`,
`hacmir`, `hacmirslv`, `hacwagt`, `hacwitm`, `hacitmval`, `hacwcmd`, `hacwsck`, `haccache`,
`hacldb`, `hachmf`, `hachmfclt`, `hachmfcmd`, `hachmfsrv`, `ismflush`.
- `CI_PRIM` and `TLS_BACKUP_PATH` are not set; no HAC process runs (single server).
- HMI properties add `communicationInterval` (2000 ms), `communicationTimeout` (3000 ms),
`communicationRetryCount` (1), not in the manual.
- Differences from the manual (ISS-053): `START_MANUAL` default; `MAXOPNDB` default (help 500,
manual 50 in §1.5 and 5 in §4.8); `QUESIZE` default (help 100 K, manual 2000 K; file sets
2000); `COM` folder **is** mirrored although §4.5 says `com`/`exe` cannot be; no queue/CPU
checks are pre-configured although §4.4 says the critical processes are listed; the backup
fallback path.
Task files: skill `high-availability`.

View file

@ -0,0 +1,103 @@
---
manual: IM 36K10J40-01EN
title: Active Directory Integration
edition: 3rd Edition, Sep. 2023
version: R1.03
status: installed dssana.sup (Active Directory, Single Sign On and Login control tabs), USER_DF fields and the auth WEB-INF templates checked read-only on the test system 2026-10-01; AD and SPNEGO set-up from docs only (no domain)
---
# Active Directory Integration (R1.03)
With AD integration CI Server takes users from a Windows domain (Kerberos/AD) instead of its own
user list; with single sign-on (SPNEGO) remote CI View users start CI Portal applications without
a login dialog. Windows only. Section numbers refer to the manual; "installed" means checked on
the R1.03.00 test system.
## 1. What it gives (§1)
Users and policies kept in one place (the domain), no second login after Windows, strong
password rules from Windows, still works when the domain controller is unreachable (cached
profiles), switchable per CI Server system. No *secondary login* (temporary elevation) with
AD/SSO. AD integration **overrides** the per-application login methods in `dssana.sup`.
Prerequisites (§2.1): CI Server machines in a valid AD domain, .NET 3.5+, domain users, and the
CI Service started by a domain user that is a local administrator (§2.12: add the AD user to
the local *Administrators* group, then *Services › CI Server Service › Log On* with that account).
## 2. Mapping AD users to CI Server user profiles (§2.4–§2.7)
The CI Server user records (`USER_DF`, Engineering Module user profile form) act as **profiles**;
AD users need no CI Server password. Two mapping modes (`AD_MAP_MODE`, one only):
| Mode | How a user gets a profile |
|---|---|
| `Organizational_unit` (default) | The user's AD **OU** name = CI Server user name; the user must also be in the AD security group named in `AD_SEC_GRP` (`"use_default_node_name"` = a group named like the CI Server node) |
| `Security_group` (**recommended**) | The CI Server user's *Directory group* (`USER_DF.DIRECTORY_GROUP`, tab *Directory Services*) = an AD security group name, e.g. `ADMIN` ↔ `FT-ADMIN-GR`, `ENG` ↔ `FT-ENG-GR`, `OPER` ↔ `FT-OPER-GR`. Several memberships: the highest *Profile priority* (`MERGE_PRIORITY`) wins; equal priority → first in alphabetical order. Nested groups count |
`ADMINE` is the enterprise profile (Enterprise Automation System only). When AD is enabled the
`ADMIN` profile is the default.
## 3. Setup steps (§2.8–§2.12)
1. IP addresses and DNS (AD server as preferred DNS) on the domain controller, CI Portal/Core
and CI View machines.
2. Domain controller: AD DS role, promote to DC (new forest), DNS forward **and reverse**
lookup zones with A and PTR records for CI Portal and CI View (`nslookup` to verify).
3. *Active Directory Users and Computers*: an OU for the CI Server objects (example
`SCADAGROUP`), then OUs + one security group (OU mode) or security groups (group mode), the
users, memberships.
4. `dssana.sup` tab *Active Directory* on CI Core/Portal: enable, mapping mode, security group
(OU mode only), check threshold. Restart USER Service.
5. Join CI Portal/Core to the domain; users log in as `<domain>\<user>` or `<user>@<domain>`.
6. When AD is on, the login methods of the Edit and Engineering Modules are ignored and no login
dialog appears; access depends on the mapped profile's rights. **Security note** in the
manual: anyone with a domain account can then use CI Portal; set the CI Portal port to 0 in
`jwuiisg.sup` (*Client communication*) if web access is not wanted.
## 4. Single sign-on for CI View (SPNEGO, §3)
Prerequisites: AD integration on, valid CI Server profile for the domain user, CI Portal with a
valid SSL certificate, CI View in the intranet zone, CI Portal addressed by host name with
forward and reverse DNS, browser integrated Windows authentication, CI View not on the CI
Portal machine.
1. DC: a dedicated AD user (e.g. `sso`, password never expires), `setspn -S
http/<portal FQDN> <user>`, `ktpass -out <file>.keytab -princ http/<portal FQDN>@<REALM>
-mapuser <user> -mapOp set -pass <password> -crypto All -ptype KRB5_NT_PRINCIPAL` (realm in
upper case; one SPN per CI Portal), *Trust this user for delegation* (Kerberos only).
2. Copy the keytab to `%TLS_ALLUSERS_PATH%\wap\webapps\auth\WEB-INF`; check with `setspn -L`.
3. `kinit http/<portal FQDN>@<REALM>` from `tls\jre\bin` on CI Portal and from the Remote
Connect JRE on CI View (must succeed).
4. `dssana.sup` tab *Single Sign On*: CI Portal FQDN, SPN domain, `krb5.ini` path (realm
mapping; template in `auth\WEB-INF`), keytab file name, token duration. Restart USER Service
(generates the `*.conf` files).
5. Browser: Firefox `network.negotiate-auth.trusted-uris`/`delegation-uris`; IE/Edge intranet
sites + integrated Windows authentication.
6. Test page: uncomment the `test` servlet in `web.xml`, restart, open
`https://<portal FQDN>:8443/auth/test` → *Authorization scheme : SPNEGO*; restore `web.xml`.
7. CI View: start applications from the *Remote Connect* start-menu folder; no login prompt,
the loaded profile shows in the status bar.
## 5. Installed (R1.03.00 test system)
- `dssana.sup` *Active Directory* tab keywords: `AD_INT_ON` (installed `NO`), `AD_SECURE`
(`NO`; help: "default is yes"), `AD_SERVER`, `AD_SERVER_BACKUP` (host or IP, optional
`:port`; 389 plain, 636 secure), `AD_ACCESS_USER`/`AD_ACCESS_PASSWORD` (blank = the account
that runs CI Server), `AD_MAP_MODE` (`Organizational_unit`), `AD_SEC_GRP`
(`"use_default_node_name"`), `AD_CHECK_THRESHOLD` (30 s). The server, secure and access-user
keywords are **not in the manual** (ISS-054).
- *Single Sign On* tab: `SSO_INT_ON` (`NO`), `SSO_TOKEN_DURATION` (20 s),
`WEBHMI_SERVER_FQDN` (`'my-host.some.domain'`), `DOMAIN_NAME` (`SOME.DOMAIN`), `KRB5_FILE`,
`KEYTAB_FILE` (`'keytab'`) — placeholders.
- `%TLS_WAP_PATH%\webapps\auth\WEB-INF` holds `krb5.ini`, `readme.txt` and the templates
`spnego.conf.tpl`, `spnego.properties.tpl`, `web.xml.tpl`, `webstartauth.conf.tpl`.
- `USER_DF` has `DIRECTORY_GROUP` (68 characters) and `MERGE_PRIORITY` (the manual's *Profile
priority*).
- *Login control*: the installed lines use **SSO** for local and remote Engineering Module, Edit
Module, Operator Interface and other UIs; without SSO set up this falls back to *Manual CI
Server* (help text). The *No* login profile is `CI_NO_LOGIN` (anonymous OPC UA:
`CI_NO_LOGIN_OPCUAS`); help: if no user with that name exists, **full authorization** is used.
Verified indirectly: `Quickload Utility` has *No* login with an empty profile and every
`dssqld` run is recorded as user `FULL AUTHORIZATION` in the audit trail (ISS-018).
Task files: skill `authorization` (`login-methods.md`, `active-directory.md`).

View file

@ -63,8 +63,8 @@ AID is not needed.
| 11 | IM 36K10C30 | Engineering Module - Reporting | done by quick load for report definitions (ad hoc + parameters, schedule, item trigger, HTML, logbook), generated reports and a file device/destination; Engineering Module forms, generate and view checked by the user; report component in displays and hardcopy printers from docs ([notes](manuals/IM36K10C30-01EN.md)) | | 11 | IM 36K10C30 | Engineering Module - Reporting | done by quick load for report definitions (ad hoc + parameters, schedule, item trigger, HTML, logbook), generated reports and a file device/destination; Engineering Module forms, generate and view checked by the user; report component in displays and hardcopy printers from docs ([notes](manuals/IM36K10C30-01EN.md)) |
| 11 | IM 36K10E10 | Excel Add-in | summarized, from docs (Excel not installed on the test system) ([notes](manuals/IM36K10E10-01EN.md)) | | 11 | IM 36K10E10 | Excel Add-in | summarized, from docs (Excel not installed on the test system) ([notes](manuals/IM36K10E10-01EN.md)) |
| 12 | IM 36K10L25 | Audit Trail Management | done for processes, classifiers, `AUDIT_TRAIL` reading/export, audit report, selection groups, `ADTLOG` (default and filtered); distributor, extra collectors, classifier extension in C and operator-side `ITEM.*` events from docs ([notes](manuals/IM36K10L25-01EN.md)); skill `audit-trail` | | 12 | IM 36K10L25 | Audit Trail Management | done for processes, classifiers, `AUDIT_TRAIL` reading/export, audit report, selection groups, `ADTLOG` (default and filtered); distributor, extra collectors, classifier extension in C and operator-side `ITEM.*` events from docs ([notes](manuals/IM36K10L25-01EN.md)); skill `audit-trail` |
| 13 | IM 36K10J20 | High Availability Computing | not started (needs two servers) | | 13 | IM 36K10J20 | High Availability Computing | summarized from docs; installed `hac.sup`, scripts, executables and HMI properties checked read-only (single unlicensed server, HAC not licensed) ([notes](manuals/IM36K10J20-01EN.md)); skill `high-availability` |
| 13 | IM 36K10J40 | Active Directory Integration | not started (needs a domain) | | 13 | IM 36K10J40 | Active Directory Integration | summarized from docs; installed `dssana.sup` AD/SSO/login settings, `USER_DF` fields and `auth\WEB-INF` templates checked read-only (no domain) ([notes](manuals/IM36K10J40-01EN.md)); skill `authorization` |
| — | IM 36K01A10 / A20 / A30 | Read Me First, License, OSS terms | skipped (no engineering content) | | — | IM 36K01A10 / A20 / A30 | Read Me First, License, OSS terms | skipped (no engineering content) |
Order change after reading IM 36K10J10: its migration procedure (§5.6) shows the dependency Order change after reading IM 36K10J10: its migration procedure (§5.6) shows the dependency
@ -142,6 +142,10 @@ now come before classes and objects (phase 6), and the other interfaces follow a
| L50/P30 | DSS tools: processes, `dss.sup`, quick load macro/include/memo file, `dssutl` read, DSS compiler syntax check ([task](../.claude/skills/system-management/tasks/dss-tools.md)) | passed | n/a | Memo from file: absolute path ≤ 82 characters only (ISS-046). Dictionary untouched. | | L50/P30 | DSS tools: processes, `dss.sup`, quick load macro/include/memo file, `dssutl` read, DSS compiler syntax check ([task](../.claude/skills/system-management/tasks/dss-tools.md)) | passed | n/a | Memo from file: absolute path ≤ 82 characters only (ISS-046). Dictionary untouched. |
| C30 | Report component on a display, hardcopy printer, extra report generators | not practiced | n/a | GUI / no printer / admin restart. | | C30 | Report component on a display, hardcopy printer, extra report generators | not practiced | n/a | GUI / no printer / admin restart. |
| E10 | Excel Add-in (DART) | not practiced | n/a | Excel not installed on the test system. | | E10 | Excel Add-in (DART) | not practiced | n/a | Excel not installed on the test system. |
| J20 | HAC checks: licence, processes, `hac.sup`, scripts, HMI properties, logs ([task](../.claude/skills/high-availability/tasks/hac-checks.md)) | passed (read-only) | n/a | No `hacini.sup`, normal `ci_start`, `CI_PRIM` unset: HAC not used; template `hac.sup` differs from the manual (ISS-053). |
| J20 | Redundant pair set-up, switchover, patching; stand-alone Recovery and journaling ([task](../.claude/skills/high-availability/tasks/redundant-setup.md), [task](../.claude/skills/high-availability/tasks/standalone-recovery.md)) | not practiced | n/a | Needs two licensed servers; stand-alone Recovery not started (default actions restart tools). |
| J40/C10 | Login methods and the *No*-login profile ([task](../.claude/skills/authorization/tasks/login-methods.md)) | passed (read) | n/a | *No* login without a matching user = full authorization (ISS-018). |
| J40 | Active Directory integration and SPNEGO single sign-on ([task](../.claude/skills/authorization/tasks/active-directory.md)) | not practiced | n/a | No domain on the test system; extra AD keywords installed (ISS-054). |
| L25 | AUDIT Service checks: processes, `ADT` group, classifiers, selection groups ([task](../.claude/skills/audit-trail/tasks/audit-checks.md)) | passed | n/a | `adtsto` + `adtcol`; 463 classifiers, 444 stored; `ADT` lifetime 52 weeks; manual differences ISS-051. | | L25 | AUDIT Service checks: processes, `ADT` group, classifiers, selection groups ([task](../.claude/skills/audit-trail/tasks/audit-checks.md)) | passed | n/a | `adtsto` + `adtcol`; 463 classifiers, 444 stored; `ADT` lifetime 52 weeks; manual differences ISS-051. |
| L25 | Read the audit trail: export, RQL, audit report, what each tool records ([task](../.claude/skills/audit-trail/tasks/read-audit-trail.md)) | passed | passed | Report `CIENG_AUDIT` (`19_audit_df.qli`); qli export needs `NAME` in `@FIELDS`; `dssqld` = `ENT-ENG-MOD`, Engineering Module = `LOC-ENG-MOD` (checked by the user); `itmval` not audited (ISS-049). | | L25 | Read the audit trail: export, RQL, audit report, what each tool records ([task](../.claude/skills/audit-trail/tasks/read-audit-trail.md)) | passed | passed | Report `CIENG_AUDIT` (`19_audit_df.qli`); qli export needs `NAME` in `@FIELDS`; `dssqld` = `ENT-ENG-MOD`, Engineering Module = `LOC-ENG-MOD` (checked by the user); `itmval` not audited (ISS-049). |
| L25 | Classifier `STORAGE`, selection groups, event logger `ADTLOG` ([task](../.claude/skills/audit-trail/tasks/configure-audit.md)) | passed | passed | Selection group `CIENG_ITEMS` compiles on load; `adtlog -n adtlogci` with sample setup file printed only CI-Eng-Sample events; storage flag cached (ISS-050); `AUDIT_INFO` effect not shown (ISS-049). Full sample remove/reload 0 errors. | | L25 | Classifier `STORAGE`, selection groups, event logger `ADTLOG` ([task](../.claude/skills/audit-trail/tasks/configure-audit.md)) | passed | passed | Selection group `CIENG_ITEMS` compiles on load; `adtlog -n adtlogci` with sample setup file printed only CI-Eng-Sample events; storage flag cached (ISS-050); `AUDIT_INFO` effect not shown (ISS-049). Full sample remove/reload 0 errors. |