Cascorp's BATCH table: every STATUS 4 row has an end time and no exception
code (finished), STATUS 1 rows have no end time and starts long passed
(waiting). So AX 3.0 uses the same order as AX 4.0+: 0 Tilbageholdt,
1 Venter, 2 Udfører, 3 Fejl, 4 Afsluttet. The old assumption (0 Venter ...
4 Tilbageholdt) treated finished jobs as held and waiting ones as running.
SQLI-AX-003 skips waiting jobs planned more than BatchAbandonedDays (30)
ago: the customer has 25 such rows from 2007-2018 that no batch server
serves; they are dead rows, not a live alarm.
Adds docs/dynamics-ax/verificer-ax30-batchstatus.sql (read-only) to repeat
the check at other AX 3.0 customers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- "Ikke målbar" texts, notes and detection problems carry the GRANT text with
the agent's login and database user. API v1 (batch-jobs, number-sequences,
recids, databases, rule-states) returned them as they were, although logins
are redacted everywhere else. AxReadAccess.WithoutPrincipals replaces them
with the placeholder unless sensitive values are allowed; the grant script
also hides a database user that differs from the login.
- SQLI-AX-010 put the host and program name (in 2-tier AX 3.0 the user's own
PC) in the finding's explanation, which reaches the hub unredacted for an
opted-in database. They are only in the sensitive evidence now, with the raw
CONTEXT_INFO; the CONTEXT_INFO parsing says it is not verified against
customer data.
- A database named e.g. "AX · test" was read from a subject as "AX", whose
hub opt-in then applied. Middle dots in the database are doubled in AX
subjects, and the AX community rules' subjects are built the same way.
- API v1 now also has the detection problems (/detection-problems), what each
raw batch STATUS means, and the thresholds behind the number sequence and
RecId pages; the blocking explanation is no longer redacted (it holds
nothing sensitive now).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Axapta 3.0 and AX 4.0 store batch and cleanup times as a local date plus
seconds. They were turned into UTC with the SQL Server's offset at collection
time, so every time from the other side of a DST change was an hour off (a job
planned 01:50 CET on the spring night looked 70 minutes late at 03:00 CEST),
and a SQL Server running UTC behind a CET AOS shifted every time.
AxLocalTime converts with the rules of the AX time zone on that date:
SQLInsight:DynamicsAx:LocalTimeZone (Windows or IANA id), else the agent's own
zone when its offset matches the SQL Server's, else the server's offset (to the
nearest quarter hour) with a Danish data note. The skipped spring hour and the
repeated autumn hour get standard time (deterministic, never throws, never a
false "late"); seconds outside 0..86400 are unknown and 86400 is midnight. The
AX 3.0 cleanup time is local by version, also when LATESTCLEANTIME is missing.
AX 2009+ UTC times are untouched. Also: remaining numbers cannot overflow for
HIGHEST = Int64.MaxValue, and run keys use the invariant culture.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
After the first read, BATCHJOBHISTORY was read from the watermark minus an
overlap of 2000 RecIds with TOP (1000), oldest first. From AX 4.0 RecIds are
handed out per table and are dense, so once 1000 rows existed in the overlap
every read returned the same old rows: the watermark never moved and new runs
were never read again (every AX 2009/2012 installation with more than ~1000
history rows). The read after the watermark now takes the overlap plus 1000
rows (TOP (3000)), so at least 1000 new runs are read each time. Test with
20,000 dense RecIds.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
One place recognises AX (version 3.0/4.0/2009/2012/2012 R2/F&O, schema owner,
model store) from metadata only. Per-version adapters hold all table/column
knowledge, check every column in sys.columns before use and degrade to
'ikke målbar' with the exact column or the exact GRANT text. Only AX 3.0 is
verified against a real customer schema; 2009/2012 are written from
Microsoft's documented schema (docs/dynamics-ax/*.documented.tsv, replaced
by a real export when one is dropped in). grant-dynamics-ax-read.sql is
version- and schema-aware (bmssa) and covers exactly the adapters' tables.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>