Commit Graph

3261 Commits

Author SHA1 Message Date
Joseph Doherty 8ab520ef57 fix(scripts): gate the source dialog's existence on the held id, not the resolve
The modal's existence was a function of _rows (FindSourceScript() as the
visibility gate), so any render where the row is momentarily unresolvable —
a future reload nulling or replacing the list — unmounts the subtree and
disposes the Close handler's binding id mid-click (GetRequiredEventBindingEntry).
Latent here (_rows is written once, in OnInitializedAsync) but the identical
shape bit ScadaBridge live the moment a page refresh landed, and it presents
as an unattributable intermittent once one does.

ScadaBridge's shape, ported by the family sweep: intent (_sourceScriptId)
gates existence, the resolve drives only content; an unresolvable script
renders a notice with the frame and Close still mounted, and closing remains
the operator's action rather than a side effect of list state.
2026-08-11 06:06:49 -04:00
Joseph Doherty 29a202f5ee fix(logging): #561 — SelfLog to file+stderr and a startup file-sink growth self-check
v2-ci / build (push) Successful in 6m38s
v2-ci / unit-tests (push) Failing after 17m30s
Production ran six weeks with a healthy process and a 0-byte log because
Serilog isolates per-sink failures: a file sink whose every write fails is
invisible from anywhere but SelfLog, which was not enabled. Two instruments:

- LogPipelineDiagnostics.EnableSelfLog (before the first logger builds):
  SelfLog to logs/serilog-selflog.txt (rotated at 5 MB) + stderr — the only
  channel that carries the exception the sink swallows.
- CheckFileSinkGrowth (after the startup banner): verifies each configured,
  unbuffered file sink's rolled-file family physically grew across a marker
  event; a silent sink is reported at boot via SelfLog/stderr and the
  console sink instead of discovered months later. Growth-across-marker,
  not existence — a previous run's bytes must not mask a silent sink (the
  false pass an existence check would have given on wonder-app-vd03).

Never throws: both instruments swallow their own failures — a diagnostics
channel that can fail startup is worse than the defect it watches for.

The load-bearing test is the failure case (a sink that writes nothing IS
reported); a check that can only pass is indistinguishable from no check.
2026-08-11 05:52:54 -04:00
Joseph Doherty e82881c109 chore(theme): pin ZB.MOM.WW.Theme 0.4.1 (rail-btn-block width fix upstream; .btn rules identical to 0.4.0 — pin-only, no re-verify warranted)
v2-ci / build (push) Successful in 4m48s
v2-ci / unit-tests (push) Failing after 15m33s
2026-08-11 03:17:22 -04:00
Joseph Doherty 01c2c8a1b7 chore(theme): bump ZB.MOM.WW.Theme 0.3.1 → 0.4.0 — kit ships the .btn sizing block (local copy deleted); drop inert Accent param (kit-default value, inline --accent would beat a future dark override) 2026-08-11 02:56:14 -04:00
Joseph Doherty 7f7798cd8c merge: ui(density) Task 3 — EquipmentPage panel idiom + bounded RawPath 2026-08-10 18:01:39 -04:00
Joseph Doherty ac419cf2b7 merge: ui(density) Task 2 — Scripts inline expander → source dialog + stacked identity 2026-08-10 18:01:39 -04:00
Joseph Doherty 564f859215 merge: ui(density) Task 1 — truncation sweep (Abbreviate + title on unbounded text) 2026-08-10 18:01:39 -04:00
Joseph Doherty 88aaf1d947 ui(density): truncation sweep — Abbreviate + title on unbounded backend/free text (§1d Task 1) 2026-08-10 18:01:07 -04:00
Joseph Doherty 4cbd03bd21 ui(equipment): adopt panel idiom on tab bodies + bound RawPath column (§1d Task 3) 2026-08-10 18:00:20 -04:00
Joseph Doherty ac85a9acb5 ui(scripts): inline source expander → dialog + stacked row identity (§1d Task 2) 2026-08-10 17:59:11 -04:00
Joseph Doherty 9e337efa0a docs(plan): AdminUI density sweep — §1d scan findings + 3-task execution plan 2026-08-10 17:56:27 -04:00
Joseph Doherty 34d60c4125 ui(hosts): declutter — per-cluster panels, stacked driver identity, abbreviated Last error, Controls in a dialog
The page ran members, the driver-instances heading, and every cluster group
together inside one panel; driver name and id slammed inline; one long driver
exception blew the table out sideways (Controls scrolled out of reach); and the
inline #546 expander row dumped a full-width panel into the table.

- One panel per cluster group, node chips in the panel head.
- Driver id renders on its own muted mono line under the name.
- Last error abbreviated to 60 chars (DisplayText.Abbreviate — #504 rule),
  full text on the tooltip and in the Controls dialog.
- DriverStatusPanel moved from an inline expander row to a modal (one at a
  time); the dialog re-resolves its row from the current groups each render so
  the 5 s rebuild can't strand it, and the Enabled-in-key recycle discipline
  carries over unchanged. HostsPanelWiringTests re-pinned to the dialog markup.

Live-verified on docker-dev: separated cards, in-viewport table, dialog opens
with live breaker/status data and grouped Reconnect|Restart, closes cleanly.
2026-08-10 17:34:37 -04:00
Joseph Doherty ef55ff3977 merge: AdminUI sweep — Shared/Drivers+Acls (DriverFormShell lever, CollectionEditor, tint swaps)
v2-ci / build (push) Successful in 4m56s
v2-ci / unit-tests (push) Failing after 15m23s
2026-08-10 16:33:24 -04:00
Joseph Doherty 47bf7a3186 merge: AdminUI sweep — Shared/Raw (modal feet, rebirth confirm pair, tree-twist) 2026-08-10 16:33:24 -04:00
Joseph Doherty 5b7fdb8911 merge: AdminUI sweep — UNS pages (modal feet, UnsTree action buttons, tree-twist) 2026-08-10 16:33:24 -04:00
Joseph Doherty 5c3b8cd8d1 merge: AdminUI sweep — ops pages (btn-groups, Security:Ldap key fix, prose deletions) 2026-08-10 16:33:24 -04:00
Joseph Doherty 9c04c0dcee merge: AdminUI sweep — Clusters pages (btn-groups, notice-alert, stale-prose deletions) 2026-08-10 16:33:24 -04:00
Joseph Doherty 8f8d8b300c merge: AdminUI sweep foundation — scoped-bundle link, btn sizing vars, notice-alert, tree-twist, doc relocations 2026-08-10 16:33:24 -04:00
Joseph Doherty ec652f6bde ui(adminui): group driver/acl shared button pairs, adopt notice-alert + tree-twist
Sweep task 5 (Shared/Drivers + Acls):
- btn-group the Save/Cancel pair in DriverFormShell (all 13 driver forms),
  CollectionEditor foot + per-row Edit/Delete, DriverConfigModal /
  DeviceModal / DriverTagPicker / AclScopePickerModal feet,
  DriverStatusPanel Reconnect+Restart and its inline restart confirm,
  and the Refresh+Close browse toolbars on the FOCAS/AbCip/TwinCAT pickers.
- Replace the no-op inline border-color:var(--alert) tint with .notice-alert
  in DriverFormShell, DriverConfigModal, DeviceModal, MqttDriverForm,
  MTConnectDriverForm, MqttDeviceForm.
- Replace inline style="width:18px" expander sizing with .tree-twist in
  DriverBrowseTree and AclScopeTree.

Markup only — every @onclick, binding, disabled and arm->confirm flow is
unchanged.
2026-08-10 16:32:47 -04:00
Joseph Doherty 3d6d28e5a2 style(adminui): btn-groups + prose trim on top-level ops pages
Group related action buttons into btn-group/btn-group-sm on Alerts, Certificates,
ApiKeys and ScriptEdit; promote the RoleGrants Delete from btn-link to
btn-outline-danger. Replace the two inline style="border-color:var(--alert)"
no-ops with the .notice-alert class, and the undefined --surface-2 token in
Scripts with the theme's shipped --zebra-bg.

Delete unconditional documentation prose now covered by docs/ (Redundancy,
Telemetry, AlarmTracking, security, Reservations, AlarmHistorian, ScriptEditor),
keeping state banners and live captions. Correct the LDAP config key on
RoleGrants to Security:Ldap:GroupToRole (LdapOptions.SectionName) and drop the
same wrong key from Account with its deleted block; reword the stale
"Engine emit (F8/F9) is pending" script-log empty state.
2026-08-10 16:32:29 -04:00
Joseph Doherty 30345c2941 style(adminui): group UNS page + modal buttons into btn-groups
Task 3 of the AdminUI UI sweep. Behavior-preserving markup only:

- GlobalUns: Expand/Collapse pair -> btn-group btn-group-sm (Import stays
  separate); delete-confirm footer Cancel+Delete -> btn-group.
- Area/Line/ScriptedAlarm/VirtualTag/AddReference/ImportEquipment modal
  footers: Cancel + primary -> btn-group.
- EquipmentPage: the three text-end action cells (Save name/Remove,
  Edit/Delete x2) -> btn-group btn-group-sm, me-1 spacers dropped.
- UnsTree: per-node actions become real small buttons (outline-secondary,
  outline-danger for destructive) and adjacent runs of >=2 group into
  btn-group btn-group-sm; the genuine navigation links (cluster settings,
  equipment Open) stay links. Expander/leaf placeholder adopt .tree-twist
  in place of the inline width:18px.
2026-08-10 16:31:55 -04:00
Joseph Doherty d2ad58be0e style(adminui): group Raw modal button pairs, drop py-0 hack, use tree-twist
UI sweep task 4 (Shared/Raw). Markup-only; no behavior change.

- Wrap the Cancel+primary modal-footer pairs in a Bootstrap btn-group across
  RawNameDialog, RawDriverTypeDialog, RawConfirmDialog, RawTagModal,
  RawManualTagEntryModal, RawCsvImportModal, RawBrowseModal and
  RawCsvExportModal (the last mixes a <button> with the download <a>, which
  is valid btn-group membership; the download attribute is unchanged).
- RawBrowseModal: the rebirth confirm pair (Publish rebirth request + Cancel)
  becomes a btn-group btn-group-sm in place of the d-flex gap-2 wrapper.
- RawCsvImportModal: drop the py-0 padding hack from the per-row remove
  button; .btn-sm sizing covers it.
- RawTree: replace the expander's inline style="width:18px" (and the matching
  leaf placeholder) with the shared .tree-twist class.

The CSV import all-or-nothing commit gating and RawTree's tree logic are
untouched.
2026-08-10 16:31:44 -04:00
Joseph Doherty 697a773340 fix(adminui): link the dead scoped-CSS bundle; add btn/notice-alert/tree-twist rules
Foundation task of the AdminUI UI sweep. CSS/link/doc only — no behavior change
beyond restoring styles that were built but never served.

- App.razor: link the RCL's scoped-CSS bundle
  (_content/ZB.MOM.WW.OtOpcUa.AdminUI/ZB.MOM.WW.OtOpcUa.AdminUI.bundle.scp.css).
  It is produced on every compile and served by the Host, but nothing referenced
  it, so ContextMenu.razor.css was dead at runtime and context menus rendered
  in-flow with no position:fixed.
- site.css: three additions.
  * .btn / .btn-sm sizing as Bootstrap CSS-VARIABLE overrides (never box
    properties — .btn-group depends on Bootstrap's own .btn rules for its seams
    and end-cap radii). Theme 0.3.1 ships no .btn rule, so Bootstrap's 1rem
    applied against the theme's 0.9rem body. Upstreaming candidate, same as the
    ignitionoee router's app.css.
  * .notice-alert — red variant of the kit's amber .notice, on the --bad/
    --bad-bg/--bad-border tokens. The 13 existing call sites hack this with
    style="border-color:var(--alert)", and no --alert token exists anywhere, so
    the tint silently no-ops today. Call-site migration is a separate task.
  * .tree-twist — shared 18px expander column for the tree components, replacing
    repeated inline style="width:18px". Rows are d-flex, so flex-basis is what
    actually holds the column. Adoption is a separate task.
- ContextMenu.razor.css: correct the header comment — the kit is light-only
  (no dark block in Theme 0.3.1, site.css, or this file). No rule changes.
- docs/Telemetry.md: record that driver-health is keyed per driver instance
  across the cluster, not per Akka member (the wire record carries no per-member
  identity). The fact previously lived only in Hosts.razor page copy.
- docs/Configuration.md: new audit-log subsection recording that EventId gives
  cross-restart dedup, enforced by the filtered unique index
  UX_ConfigAuditLog_EventId, so a retried apply inserts no duplicate row;
  CorrelationId joins a row to its originating workflow. Previously only in the
  historical v2 rebuild plan and ClusterAudit page copy.
2026-08-10 16:31:42 -04:00
Joseph Doherty 42924b6fb0 ui(adminui): clusters pages — button groups, notice-alert tint, prose trim
Task 1 of the AdminUI UI sweep. Behavior-preserving: only wrappers, classes
and prose change — every @onclick, disabled, href and arm->confirm flow is
untouched.

Buttons -> Bootstrap btn-group:
- ClusterOverview page-head Edit cluster + Deployments pair
- Edit-form feet (Save+Cancel grouped; ms-auto Delete stays outside):
  ClusterEdit, NodeEdit, NewCluster, AclEdit
- ClusterRedundancy confirm-failover Confirm+Cancel (ms-2 dropped)
- AclEdit permission-bundle presets: btn-link + middot separators become an
  outline-secondary btn-group

Inline style="border-color:var(--alert)" (a no-op — that token is defined
nowhere) replaced by the .notice-alert class: NodeEdit, AclEdit, ClusterEdit.

Prose (unconditional documentation deleted; state banners/legends kept):
- ClusterRedundancy: removed the stale RedundancyStateActor "on each admin
  node" block (cluster-scoped singleton on driver nodes since mesh Phase 6)
  which also hyperlinked an unserved repo path; trimmed the mesh-split
  explanation to its data-provenance first sentence
- ClusterAcls: removed the Security:Acl:Enabled mode walkthrough and the
  grant/principal explanation (both in docs/security.md); kept the
  unresolved-chip decoder and trimmed the empty state to one sentence
- AclEdit: removed its near-duplicate of that walkthrough
- ClusterAudit: dropped the stale (F3) label and the EventId/CorrelationId
  dedup sentence; kept the page-size + Details-JSON caption
- ClusterNamespaces / NamespaceEdit: retired-in-v3 placeholders reworded to
  past tense — Batches 2/3 shipped, /raw and /uns are live
2026-08-10 16:31:25 -04:00
Joseph Doherty 0355e83b31 docs(plans): AdminUI UI sweeps — discovery evidence + 6-task execution plan 2026-08-10 16:26:56 -04:00
Joseph Doherty 4d549571cc docs(deferment): eighth round — all 32 recorded-Open review findings resolved, fleet-wide 0 pending
v2-ci / build (push) Successful in 5m12s
v2-ci / unit-tests (push) Failing after 16m53s
2026-08-10 08:29:03 -04:00
Joseph Doherty 1882df4924 test(sql-browser): OracleFlavouredSqliteDialect implements the new ISqlDialect.MaxBindParameters (cross-branch composition) 2026-08-10 08:27:48 -04:00
Joseph Doherty aaccab9cdd docs(code-reviews): regenerate README — all 32 open findings resolved (0 pending fleet-wide) 2026-08-10 08:23:22 -04:00
Joseph Doherty acea65eb96 merge: MQTT browser+contracts review findings resolved (Driver.Mqtt.Browser-002..-005, Driver.Mqtt.Contracts-004..-007) 2026-08-10 08:23:16 -04:00
Joseph Doherty 2dc2075d05 docs(code-review): close all 8 open Mqtt.Browser + Mqtt.Contracts findings
Browser-002/-003/-004 fixed and -005 resolved as a documented constants change
(eddf5f57); Contracts-004/-005/-006/-007 fixed (93f70504). Both module headers
drop to 0 open findings. Each resolution records the disposition, the RED
evidence, and the deviations from the recommendation where one was taken.
2026-08-10 08:22:47 -04:00
Joseph Doherty 93f70504bd fix(mqtt-contracts): strict retainSeed, real bounds instead of dead [Range]s, DateTime edges, closed topic formatting
Driver.Mqtt.Contracts-004/-005/-006/-007.

-004: retainSeed was the last behavioural key read leniently, so "retainSeed":"false"
— what a CSV import produces — silently became the default TRUE, the INVERSE of the
authored intent. Both mappers now read it through TryReadBoolStrict (the qos
absent/valid/present-but-invalid split) and DescribeRejection names it. The authoring
side needed no hand-mirrored rule: MqttTagConfigModel.Validate already consults this
same parse through TagConfigParseGate, so the save is blocked with the inspector's
wording — pinned by a new AdminUI parity theory pair.

-005: the seven [Range] attributes on MqttDriverOptions/MqttPlainOptions never ran —
the options are bound by JsonSerializer, and nothing in the four MQTT projects calls
Validator.TryValidateObject. Two of them CONTRADICTED the real authority (KeepAlive's
[Range(1,…)] forbade the zero Normalize admits as legal MQTT; MaxPayloadBytes' forbade
the non-positive value its own remarks document as falling back to 1 MiB), so wiring
them up would have broken deliberate behaviour. Deleted, with each property naming
where its bound actually lives. The one escape they papered over is closed: an
out-of-range defaultQos rode into the SUBSCRIBE verbatim, and MqttSubscriptionManager's
constructor now clamps it exactly as the AdminUI driver form already persists.

-006: the DateTime write arm cast a negative long to ulong, so 1969-12-31 published a
timestamp ~584 million years in the future; it is now refused as ValueNotRepresentable.
An Unspecified kind was handed to ToUniversalTime(), which reads it as LOCAL — the same
authored instant encoded differently on the two nodes of a redundant pair; it is now
read as UTC.

-007: Format/FormatState enforced only null/empty, and nothing at all on deviceId, so
the type was not round-trip-closed. They now apply the parser's IsValidSegment (plus
'/', which only the format side can see). MqttWriteEncoder's own guards stay — TryEncode
returns an error rather than throwing, and that contract does not change.
2026-08-10 08:18:30 -04:00
Joseph Doherty a54661ded8 docs(code-reviews): reconcile Driver.Sql open-findings header after parallel branch merges (7 -> 0) 2026-08-10 08:11:56 -04:00
Joseph Doherty b8acabfa5f merge: SQL driver health review findings resolved (Driver.Sql-004/-005/-006/-008/-010)
# Conflicts:
#	docs/drivers/Sql.md
2026-08-10 08:11:40 -04:00
Joseph Doherty ead8a97511 merge: MTConnect review findings resolved (Driver.MTConnect-004 write-back authoring, -005/-006/-007)
# Conflicts:
#	code-reviews/Driver.MTConnect/findings.md
2026-08-10 08:11:03 -04:00
Joseph Doherty 38dee82e29 merge: SQL contracts review findings resolved (Driver.Sql.Contracts-001 scalar keyValue, -002 fleet-wide numeric-enum rejection) 2026-08-10 08:10:36 -04:00
Joseph Doherty bb83099300 docs(review): close Driver.Sql-004/005/006/008/010 with resolutions and RED evidence 2026-08-10 08:09:51 -04:00
Joseph Doherty 55f4354117 merge: Calculation review findings resolved (Driver.Calculation-005 pump split, Driver.Calculation.Contracts-001 single-parse Inspect) 2026-08-10 08:09:21 -04:00
Joseph Doherty 0edc3be13d docs(reviews): close Driver.MTConnect-004/-005/-006/-007
Resolutions record the red-first evidence and the two decisions a later reader would
otherwise re-litigate: why the write block is emitted in both states, and why -007's
race budget (8 racers x 3000 rounds) is part of the fix rather than incidental.

Open findings 5 -> 1. The remaining one is Driver.MTConnect-003 (High, browse-committed
MTConnect tags coerced to String by RawBrowseCommitMapper), which was not in this batch.
2026-08-10 08:08:42 -04:00
Joseph Doherty ad9ad00cd2 review(Driver.Sql.Contracts): both findings resolved — open count 2 → 0
001 aligned keyValue onto the same scalar read as whereValue (678aa3aa); 002 fixed the
numeric-enum-spelling accept in Core.Abstractions.TagConfigJson.ClassifyEnumText,
fleet-wide (8d4ca548).
2026-08-10 08:08:13 -04:00
Joseph Doherty 298ad04fba feat(adminui): author MTConnect write-back on the driver form (Driver.MTConnect-004)
IWritable shipped behind write.enabled and docs/drivers/MTConnect.md told the operator to
set it, but MTConnectDriverForm — the only editor DriverFormMaps maps for this type, with
no raw-JSON escape hatch and no driver-instance API — exposed no write section, so the
documented enablement path was a hand edit of DriverInstance.DriverConfig in the config DB.

- Write-back section: switch + form text stating it is observation injection, that the
  Agent's AllowPut is an independent second gate, and that it does not by itself make a
  node writable over OPC UA (Tag.AccessLevel still composes CurrentWrite).
- Write added to the mirrored MTConnectConfigDto and to the form model, written in BOTH
  states — an omitted block would leave a previously-authored true standing, so the switch
  could never turn writing off again.
- The false 'MTConnect is read-only' header comment is gone; the doc names the new section.

No bUnit here, so the model/serialization seam is unit-tested both sides: the AdminUI test
pins the emitted bytes, and MTConnectFactoryTests parses that same document and asserts
MTConnectDriverOptions.Write.Enabled. Live page verification remains a rig step.
2026-08-10 08:07:36 -04:00
Joseph Doherty 5c8d6f6f98 test(calc): make the not-evaluated-inline assertion exact, not thread-id based
The first form compared the publish's managed thread id with the caller's, which flaked
(1 in 6): the evaluation pump may reuse the pooled thread the test released while awaiting
the drain, so an id match proves nothing. It now sets a ThreadLocal flag for exactly the
OnDependencyValue window, so 'published inline' is answered on the stack rather than by
thread identity. Re-falsified by making SchedulePump run the pump synchronously (red
immediately, reverted); 5 consecutive clean suite runs after.
2026-08-10 08:07:27 -04:00
Joseph Doherty 678aa3aa53 fix(sql): read keyValue with the same scalar read as whereValue (Driver.Sql.Contracts-001)
The two value-bearing fields were read asymmetrically and nothing said why.
whereValue went through ReadScalar (string/number/boolean — the design doc's own
wide-row example authors it as the number 7); keyValue went through the string-only
ReadString, so a numerically-authored key refused the tag outright. Nothing downstream
justified the split: both are BOUND as DbParameters and both are matched back as text —
SqlPollReader.IndexByKey stringifies the key cell precisely so an authored key can face
an INTEGER key column.

The refusal was also mis-explained. Inspect branched on ReadString(root, "keyValue") is
null, so a numerically-authored key drew "Sql KeyValue tag has no 'keyValue'" — telling
the operator the field is missing when it is right there in the blob, the #549 shape of
an authoring surface disagreeing with the runtime about WHY.

keyValue now uses ReadScalar; Inspect mirrors it with HasScalar and says what a usable
key is; SqlTagConfigModel loads it with the shared TagConfigJson.GetScalarText (which
also replaces SqlRowSelectorModel's private copy), so the editor is not left stricter
than the parser. An object/array/null key is still refused. docs/drivers/Sql.md updated.

RED first: 4 failing in Driver.Sql.Tests.
2026-08-10 08:07:15 -04:00
Joseph Doherty 9d4760fd2f docs(driver.sql): topByTimestamp is only defined when the ordering column is unique (Driver.Sql-008) 2026-08-10 08:06:27 -04:00
Joseph Doherty d7568ac342 merge: SQL dialect+chunking review findings resolved (Driver.Sql-002, Driver.Sql.Dialect-001/-002/-003) 2026-08-10 08:06:13 -04:00
Joseph Doherty 300abde4bb merge: SQL browser/probe review findings resolved (Driver.Sql-009, Driver.Sql.Browser-001/-002/-003) 2026-08-10 08:06:02 -04:00
Joseph Doherty 336e79ea9a fix(driver.sql): compare-and-swap the health field so a concurrent transition cannot be lost (Driver.Sql-010) 2026-08-10 08:05:23 -04:00
Joseph Doherty cb7096ddff docs(reviews): point the -003 Won't Fix at the commit that carries it 2026-08-10 08:05:21 -04:00
Joseph Doherty 3427370831 docs(reviews): close Driver.Sql-009 + Driver.Sql.Browser-001/002/003
-003 is a documented Won't Fix: the mitigating control is the ConfigEditor page
policy on the only two surfaces that reach a browse session (/raw and /uns),
there is no HTTP endpoint for browse, and PageAuthorizationGuardTests pins both
pages to that exact policy. Recorded in docs/security.md under Control-Plane
Authorization and pointed at from SqlDriverBrowser's class summary.
2026-08-10 08:05:12 -04:00
Joseph Doherty 1fe0017600 docs(code-review): close Driver.Sql-002 + Driver.Sql.Dialect-001/002/003
Dialect header 3 -> 0 open. The Driver.Sql header count is left alone for the
orchestrator to reconcile — sibling agents are editing that file in parallel.
2026-08-10 08:04:40 -04:00
Joseph Doherty 2637be8212 docs(code-review): close Driver.Calculation-005 + Driver.Calculation.Contracts-001
Both modules go to 0 open findings. -005 records the concurrency guarantee the fix rests
on (at most one evaluation at a time: single pump + _evalGate, lock order _evalGate ->
_lock), the RED evidence, why the dependency snapshot is taken at trigger time, why the
timer path was left on its own scheduler, and the unbounded-queue trade. -001 records that
the equivalence is exact (Inspect's pre-checks already establish TryReadTagConfig's) and
that its new pin was verified against the pre-refactor code.
2026-08-10 08:04:01 -04:00