Commit Graph

142 Commits

Author SHA1 Message Date
Joseph Doherty 5da4ab3ebd docs(index): HistorianGateway UI-sweep branch merged to main (e42ff31) — Theme 0.4.1 + Health 0.3.0 + Secrets 0.6.2 + Auth 0.2.1 now on its default 2026-08-13 08:58:09 -04:00
Joseph Doherty 3d2f3f59b2 docs(index): Auth 0.2.1 adoption commits pushed on all four apps 2026-08-13 08:52:25 -04:00
Joseph Doherty 58c2e14c38 docs(index): Auth 0.2.1 adopted by all four apps; FallbackServers live-gated on HG + ScadaBridge rig 2026-08-13 08:49:25 -04:00
Joseph Doherty f42aa14033 docs(inventory): add the QA stack (vq03/vq04/sql-vq03) and correct vd03 DEV-vs-prod
deployment.md:
- §1/§2.1: add wonder-app-vq03, wonder-app-vq04 and wonder-sql-vq03 with IPs and
  per-host roles; new §7.1 QA port map + live active/standby state.
- QA is a real 2-node HA pair (ScadaBridge central+site pairs, OtOpcUa pair) where
  DEV is a single all-in-one box, so it is the only environment here that exercises
  failover and leader election. MxGateway/HistorianGateway/Overview run on vq03 only.
- Every QA fact is marked scan (port probe) or dash (read off the QA Overview
  dashboard's live polling). No QA config file was read; connection strings and
  service names stay unverified.
- Correct the tier: vd03 is DEV, not production (vd=dev, vq=qa, per
  mes-delmia-integration-api.md §1.1). Its ASPNETCORE_ENVIRONMENT really is
  "Production" -- a .NET overlay name, orthogonal to the tier, and the likely source
  of the original error. No production box has been identified.
- Record that QA requires Basic auth on /management where DEV does not, so DEV-only
  procedures relying on unauthenticated management calls will not work on QA.
- Record that inbound API keys never cross environments (per-stack peppered-HMAC,
  excluded from config bundles) plus the 401-vs-400 probe, with the caveat that auth
  runs before route resolution so a 401 needs a positive control.
- Withdraw the SSH-on-2222 claim made earlier in this same pass: all three wonder
  boxes accept TCP on 2222 and send no SSH banner, so servecli is not serving SSH and
  no shell access was available. Port scan cannot establish a service; banner grab can.

CLAUDE.md:
- Overview: record the second instance on wonder-app-vq03:5320, and that its real-FQDN
  registry is correct rather than a divergence -- the 127.0.0.1 rule is specific to
  vd03 co-locating every instance on one host.
- Add the DEV-vs-prod note pointing at deployment.md §2.1/§7.1.
2026-08-13 08:08:23 -04:00
Joseph Doherty 818775b311 docs(index): Auth 0.2.1 published -- AD referral fix + NAM group findings
CLAUDE.md: feed now carries 0.2.1; record the referral defect and that every
app is still exposed until it bumps off 0.1.5 (a functional fix, not
housekeeping), plus the new tools/LdapProbe.

ldap_setup.md: findings from probing the live NAM directory --

- LDAPS 636, StartTLS 389 and plain 389 all connect on both DCs. The only TLS
  chain error is UntrustedRoot, so installing zimmer-rootca is sufficient; the
  RSA 1024-bit key is rejected only by OpenSSL at SECLEVEL=2, i.e. Debian .NET
  containers, not by macOS or Windows hosts.
- The UG_WW_* Wonderware group convention, 39 groups enumerated directory-wide.
  This partly overturns this doc's earlier "no group->role convention exists"
  claim: that was true of Ignition, which was the only source audited, and
  false of the domain. Three shapes with a consistent role suffix (ADMIN, RO,
  OPERATOR, ENGINEER, SUPERVISOR, TESTER) across environment and site axes.
- A proposed mapping onto CANONICAL-ROLES, with the three gaps left open
  rather than guessed: SUPERVISOR/TESTER have no canonical equivalent, nothing
  maps to Deployer, and the DEV/QA/PROD axis is orthogonal to role so it must
  ride in the per-project scope payload or the role set triples.
- The referral defect and its fix.
2026-08-12 21:27:23 -04:00
Joseph Doherty 81e0005628 docs(index): OtOpcUa on 0.6.2; the NuGet partial cached-index trap recurs per publish 2026-08-11 09:09:05 -04:00
Joseph Doherty b850c3a47f docs(index): Secrets 0.6.2 — rejection message teaches the container case 2026-08-11 09:04:55 -04:00
Joseph Doherty 74066bbe27 docs(secrets): record the container over-rejection and the OtOpcUa 0.6.1 adoption 2026-08-11 09:01:04 -04:00
Joseph Doherty 90b7cc6c48 docs(index): Secrets 0.6.1 — the pin alone does not close the pre-host gap; mxgw 0.6.0 pushed and needs a follow-up 2026-08-11 08:46:13 -04:00
Joseph Doherty 9b6afe3efd docs(index): Secrets 0.6.1 — close the pre-host hole in the store-path guard 2026-08-11 08:39:21 -04:00
Joseph Doherty 105c230cb1 docs(index): Secrets 0.6.0 — fail-closed store-path validation, default moves outside the content root 2026-08-11 08:26:05 -04:00
Joseph Doherty f088cb81ba docs(index): ScadaBridge Central UI sweep merged + deployed to wonder (Theme 0.4.1 live) 2026-08-11 07:31:54 -04:00
Joseph Doherty 003783a593 docs(index): record ZB.MOM.WW.Overview — the hosted family dashboard, now deployed to wonder
This repo hosts one application besides its shared libraries, and the index did
not mention it at all. Adds what it is, that its registry ships empty by design,
and the two constraints that bit during the first real deployment: publish
self-contained (wonder has no .NET 10 runtime), and do not put co-located
instances on a shared host name, because leader-to-instance resolution matches on
host only and the first match wins the chip for every group.
2026-08-11 06:54:08 -04:00
Joseph Doherty 20e16c934c docs(index): Theme 0.4.1 — all five consumers pushed; two on branches, ScadaBridge's not deploy-ready 2026-08-11 05:52:30 -04:00
Joseph Doherty f9d4e2f514 docs(index): Theme 0.4.0/0.4.1 — .btn sizing upstreamed, rail-btn-block fixed, 5 consumers 2026-08-11 03:18:25 -04:00
Joseph Doherty 3b7dbfa082 docs: correct mxgw Bootstrap claim + fold five-app sweep findings into admin_ui_cleanup
CLAUDE.md (Secrets row):
- mxgw is NOT Bootstrap-free (libman.json pins bootstrap@5.3.3, App.razor:7
  links it ahead of ThemeHead). The scadaproj#2 modal gate had skipped mxgw on
  that false premise; gate since run and PASS 2026-08-11.
- scoped-CSS bundle claim scoped to its 2026-07-19 date; OtOpcUa links one now
  too, so it is two of four rather than one.

admin_ui_cleanup.md — five rounds now (adds mxgw, HistorianGateway, ScadaBridge):
- 1a-1: test sources are a fifth definition site, checked BEFORE the ghost list.
  A class matched only by a test is a selector, never a ghost. Extends to
  substring and visible-text assertions, so button labels are load-bearing.
- 1a-4: two inverted button-sizing instances (literal font-size neutering
  btn-sm app-wide; a chassis class standing in for the button system).
- 1a-5: determine dark scheme per app; where one exists the step inverts.
- 1a-6 (new): a token override emitted as an inline style on the shell root
  defeats every scheme-level :root override. OtOpcUa carries the inert-but-
  latent instance.
- 1c: reword nothing before checking test sources; the docs may be the wrong
  document, not the page.
- 2: btn-sm fold breaks button.btn-*.btn-sm locators; cell-clip is wrong for
  resizable columns; briefs carry the rubric, not just line numbers.
- verification: baseline pre-existing failures by measuring; a suspiciously
  fast green is a vacuous pass, not a pass.
- live gate: mandatory bUnit or not; hit-testability over visibility; measure
  behaviour where computed values mislead (-webkit-box serializes flow-root);
  record what could not be exercised.
- new: exemptions from a family-wide sweep must re-derive their premise.
2026-08-11 02:07:01 -04:00
Joseph Doherty 75648ea28b docs(index): Auth 0.2.0 — LDAP sticky backup-DC failover published 2026-08-10 16:43:04 -04:00
Joseph Doherty 95865f0e9b docs(index): OtOpcUa — tracker zeroed via #549–#559 authoring-parity arc (2 served-behaviour fixes: MQTT whitespace blobs, OpcUaClient legacy NodeId); R2-10 connect-path resilience; plan-task sweep; master pushed, origin back in sync at d06e92c6 2026-08-10 05:33:29 -04:00
Joseph Doherty 2f96709341 docs(index): ScadaBridge#34 FIXED — PID-1 crash wedge root-caused (SIGABRT ignored for PID 1); handler + init:true, live-verified
Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-08 05:24:20 -04:00
Joseph Doherty 46523db2bd docs(secrets): close scadaproj#4 — central shared SQL store + failover shipped
Program closeout: scadaproj#4 CLOSED (comment issuecomment-5751) — ScadaBridge's
central pair now runs ONE shared SQL-Server store in Grpc mode (0.5.0
FallbackEndpoints, 0.5.1 virgin-DB migrator race fix; ScadaBridge @ e697477c),
live-gated PASS 5/5 + re-drill. The pre-Serilog container-wedge defect the gate
reproduced twice is filed as ScadaBridge#34 (pre-existing, out of program scope).

- clustered-secrets.md: central pair = one shared SQL store (connstr literal/env,
  never ${secret:}); rewrap = ONE central run + both nodes of each site pair;
  FallbackEndpoints same-store-only rule; 0.5.1 minimum for central pairs
- components/secrets/GAPS.md: resolution section appended; stale wait-on-#4 struck
- CLAUDE.md Secrets row: #4 CLOSED, family 0.5.1, gate + residual recorded
- tasks.json: all 6 tasks completed

Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-07 11:43:53 -04:00
Joseph Doherty 5198d3dc7f docs(secrets): close out scadaproj#3 — gRPC hub shipped 0.4.1, both live gates PASS; residual filed as #4
Task 9 (closeout) of the Secrets gRPC-hub program. Bookkeeping only; no code.

- clustered-secrets.md, Production enablement: the gRPC hub is no longer
  pending. It is BUILT, SHIPPED (0.4.1) and LIVE-GATED PASS 4/4 (ScadaBridge
  main @ f6c3f7c5, docs/plans/2026-08-07-secrets-grpc-hub-live-gate.md), so the
  "until that ships, ScadaBridge replication stays off" line is replaced with
  the truth: the code path is merged and gated, and production enablement is a
  separate operator action behind a still-default-off flag. OtOpcUa's
  pair-local topology is recorded as live-gated (lmxopcua master @ 1bd79c8e)
  rather than pending re-gate. Rotation fan-out corrected: on ScadaBridge it is
  BOTH central nodes plus both nodes of every site pair, because each central
  node has its own independent store.

- components/secrets/GAPS.md: new "gRPC hub delivered" section recording the
  0.4.0/0.4.1 publish, both gates with SHAs and gate-doc paths, and the
  residual. Existing narrative left intact and amended, not rewritten.

- CLAUDE.md Secrets row: lib version 0.3.0 -> 0.4.1 and the app-pin claim
  corrected (ScadaBridge pins 0.4.1 for the Grpc replicator; the other three
  still pin 0.2.3); the "production topologies DECIDED" region now records
  delivery, both gates, default-off, and the residual.

- Plan ledger: task 9 completed.

Residual carried forward as scadaproj#4 — ScadaBridge's central pair does not
converge with itself (central-b served an authenticated but EMPTY manifest all
gate while central-a held every secret) and the site client dials a single
endpoint; these are one design question, since failover to an empty hub would
succeed and silently stop convergence. scadaproj#3 is closed.

Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-07 09:00:11 -04:00
Joseph Doherty 591307c13e docs(secrets): production replication topologies decided — OtOpcUa Akka pair-local, ScadaBridge central gRPC hub (pull-only); scadaproj#3
Design doc + runbook Production-enablement section + GAPS/index updates.
The previously-untracked production-KEK decision is now recorded: one
fleet-wide KEK via appsettings/env (never committed); ScadaBridge rejects
the SqlServer hub on topology grounds (sites talk to central, never the
DB) in favor of a new ZB.MOM.WW.Secrets.Replicator.Grpc package —
pull-only, updates originate at central only, by design.

Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-07 05:28:46 -04:00
Joseph Doherty 537a4f524d docs: truth sweep — index + component GAPS reconciled with shipped state (Health 0.3.0 merged both apps, OtOpcUa LocalDb Phase 2 executed, Auth 0.1.5, Secrets 0.2.3/0.3.0)
Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-07 02:00:58 -04:00
Joseph Doherty 1a7bff6a19 docs(index): OtOpcUa #548 FIXED — FOCAS duplicate sibling names disambiguate (AA_1/AA_2, merge 8b5c478c)
Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-06 21:09:30 -04:00
Joseph Doherty c8c4c2bcde docs(index): OtOpcUa #539 FIXED (AbCip browse honours the authored port); #540 CLOSED, axis residual now #548
Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-06 20:48:03 -04:00
Joseph Doherty 35f371ed74 docs(index): OtOpcUa ClusterClient→gRPC program CLOSED — Phase 4 terminal live gate PASS 8/8 (boundary proven, terminal suite 9,333/0)
Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-06 20:30:45 -04:00
Joseph Doherty 63cf4c6f0c docs(index): OtOpcUa Phase 3 ClusterClient deletion MERGED to master @ 2fa880b6; only the Phase 4 terminal gate remains
Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-06 16:58:16 -04:00
Joseph Doherty 0e416cac0a docs(index): OtOpcUa ClusterClient→gRPC migration — Phases 0-2 merged (rig default Grpc), Phase 3 deletion complete on branch pending merge
Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
2026-08-06 16:24:06 -04:00
Joseph Doherty 7ed2c29842 docs(index): OtOpcUa #541 FIXED — drivers now report the tags they skipped (twelve, not eight) 2026-08-06 02:18:42 -04:00
Joseph Doherty 2b45a59c5d docs(index): OtOpcUa #540 deployed to wonder — the 20 FOCAS fixed-tree tags read 20/20 Good 2026-08-05 18:54:49 -04:00
Joseph Doherty d30f54639f docs(index): FOCAS fixed tree is publishable (OtOpcUa #540); driver Healthy no longer implies tags are polled (#541) 2026-08-05 17:49:11 -04:00
Joseph Doherty 0bbe42eaa1 docs(index): OtOpcUa Sql driver now ships SqlServer + Postgres + Oracle providers 2026-08-05 08:00:14 -04:00
Joseph Doherty 6d222ea491 docs: correct the self-form watchdog record — rejected, not shipped
The InitJoin self-form watchdog (a timer calling Cluster.Join(SelfAddress) after a
window) was implemented and REJECTED after live testing: it sits outside Akka's join
handshake, so on a routine standby restart — peer alive, join stalled behind removal of
the node's own stale incarnation — it fires mid-join, abandons the in-flight join and
forms a permanent second cluster at the same address (measured: still split after 90s;
OtOpcUa hit it live in its manual-failover drill).

The safety argument 'a booting node only self-forms when no seed answers InitJoin' is
true of Akka's NATIVE first-seed rule (FirstSeedNodeProcess, inside the handshake) and
FALSE of the watchdog, which can fire while a seed is answering. That reasoning error is
now called out explicitly so no future plan re-derives the pattern.

- docs/plans/2026-07-22-initjoin-selfform-fallback.md: dated correction banner (history
  preserved) + the two surviving false claims struck in place (behavior-spec row and the
  Mechanism section's 'races are benign'); points at ScadaBridge
  Component-ClusterInfrastructure.md as the surviving design.
- akka_failover.md 6.1: shipped design stated as self-first seed ordering plus the
  opt-in, default-OFF simultaneous-cold-start bootstrap guard; added a
  never-re-derive-the-watchdog note. 6.2: two items my 6.1 edit contradicted are marked
  closed (OtOpcUa auto-down live gate, mesh election scope — both done 2026-07-24).
- CLAUDE.md: ScadaBridge issue #14 is CLOSED (2026-07-24), not open — v3 dual-namespace
  live gates all passed, ScadaBridge consumes OtOpcUa v3 end-to-end.
2026-08-01 11:09:45 -04:00
Joseph Doherty 7a6f997180 docs(index): OtOpcUa #520 complete — ACL grants authored from a scope picker (stage 7)
Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo
2026-08-01 10:54:19 -04:00
Joseph Doherty 555d1b4afc docs(index): OtOpcUa gates reads/browse/subscribe too — the previous entry said the opposite
#520 stage 6 (master 2026-08-01, live-gated). With Security:Acl:Enabled ON,
every data-plane operation needs a matching NodeAcl grant, not just writes /
alarm acks / HistoryRead. The stage-5 entry told ScadaBridge that a read-only
consumer was 'unaffected either way' — that now holds only while the flag is
off, which is the default.

Also records the two stage-6 behaviours a consumer would otherwise discover the
hard way: a deep Browse grant makes its ancestor folders browsable (so it
exposes their names), and revoking a grant stops a live subscription — one
BadUserAccessDenied then silence, resuming by itself if the grant returns, with
no reconnect needed.
2026-08-01 10:00:55 -04:00
Joseph Doherty 883601a72b docs(index): OtOpcUa node ACLs are now enforced behind Security:Acl:Enabled (#520 stage 5)
Default is off, so a read-only address-space consumer is unaffected. With it on,
writes / alarm acks / HistoryRead need a matching grant for the principal the
session authenticates as — anonymous unless ScadaBridge is issued a key.
Reads, browses and subscriptions stay ungated in both modes.

Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo
2026-08-01 05:01:07 -04:00
Joseph Doherty 6b12a7b75e docs(index): OtOpcUa AB CIP/Legacy now honour the authored EtherNet/IP port (#534) 2026-08-01 02:39:06 -04:00
Joseph Doherty 0121f55f1e docs(index): OtOpcUa's OPC UA data plane authenticates with API keys, not LDAP
Gitea #520 (OtOpcUa master, merge fbe7403c) replaced LdapOpcUaUserAuthenticator
with an API-key authenticator on the OPC UA data plane. The index still told a
consumer that enforcement was "LDAP roles plus a write gate", which is now the
wrong instruction for anyone wiring a client.

Records what a consumer actually needs: the UserName/`apikey`/`otua_...` token
shape, that LDAP survives for AdminUI login only, that anonymous still defaults
to admitted (so ScadaBridge is not broken today), and that revocation is
asymmetric because keys reach driver-only nodes inside the deployment artifact.
The "ACLs authored but not enforced" warning stands -- stages 3, 5 and 6 remove
it.

Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo
2026-08-01 00:29:17 -04:00
Joseph Doherty c07659c0e0 docs(index): OtOpcUa #527 fixed — comms-loss is detected and auto-recovers; withdraw the condition-Quality caveat 2026-07-31 10:59:50 -04:00
Joseph Doherty ded7cf0d6d docs(index): OtOpcUa — Sql browser layering (#526), IDriver dead-surface removal (#525), scripted-alarm comms-loss quality (#481) + the #527 caveat 2026-07-31 10:04:50 -04:00
Joseph Doherty f7f4554a36 docs(index): OtOpcUa MQTT driver — write-through (#508), Sparkplug primary-host STATE (#511), structured Template/DataSet flattening (#515)
All three live-gated and merged to OtOpcUa master. The index still said write-through was
deferred and every MQTT node read-only, which #508 changed on 2026-07-31; #511 and #515
landed in merge 857a10b4. Two of the three are consumer-visible to ScadaBridge: MQTT nodes
now materialize Operate rather than ViewOnly where a write destination is declared, and a
Sparkplug UDT surfaces as ordinary scalar nodes instead of being skipped.
2026-07-31 08:15:31 -04:00
Joseph Doherty 850e23646a docs(index): OtOpcUa — #521 host connectivity now consumed via telemetry; #522 tier machinery deleted
Both were recorded as open keep-or-delete decisions; both closed on OtOpcUa master abda6f9e.
Neither changes the OPC UA wire contract, so neither is consumer-facing to ScadaBridge — but
the index asserted them as current state, so it would have drifted.

Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo
2026-07-30 04:59:06 -04:00
Joseph Doherty ff073450dc docs(index): OtOpcUa — tag-set drift detection REMOVED (#523, merge 2a0461a1)
The entry claimed the periodic tag-set drift check had shipped. It was taken back
out two days later and is not in master. Corrected in place rather than deleted,
so the record shows both what landed and what became of it.

Carries forward the consequence a reader needs: AbCip and FOCAS browse a live
backend but implement no IRediscoverable, so they now have no tag-change signal
at all. Galaxy/TwinCAT/MTConnect/Mqtt raise natively and are unaffected. Still
not consumer-facing to ScadaBridge -- no OPC UA wire-contract change either way,
and the IRediscoverable operator prompt is untouched.

Also records the rest of that merge: 13 stale skipped tests retired, a reflection
guard over the deploy-time TagConfig gate, three silently-failing OpcUaClient
integration tests fixed, and the two missing driver guides written.

Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo
2026-07-30 03:42:45 -04:00
Joseph Doherty e96b5d49f9 docs(index): OtOpcUa — deferment remediation merged to master (914d70bf)
The index recorded this as unmerged on a feature branch; it landed on master
2026-07-28. Also records the two follow-ups the first pass had deliberately
left unbuilt and which have since shipped: Sql/FOCAS in-place config re-parse
(made atomic, so a config change cannot half-apply a new tag set against an
old connection or backend), and tag-set drift detection for the four
genuinely-browsable drivers.

Neither is consumer-facing to ScadaBridge — no OPC UA wire-contract change, and
the drift signal is advisory rather than an address-space rebuild. The
previously-noted operationally-visible item stands: a DriverConfig edit now
costs a driver reconnect.
2026-07-28 13:24:36 -04:00
Joseph Doherty b0b57f8d54 docs(index): OtOpcUa — rediscovery is now a prompt; deferment remediation underway
Corrects a fact this index recorded two days ago as consumer-relevant to
ScadaBridge. "IRediscoverable is inert fleet-wide" no longer holds: it is
consumed as an operator re-browse prompt on /hosts, carried on
DriverHealthChanged. The consumer-facing conclusion is unchanged and worth
keeping explicit — the served address space still only changes on a config
redeploy, because the prompt is advisory by design.

Gitea #507 (discovered-node injection) is closed as superseded and its code
deleted; it read two structures that are structurally empty in v3, so it could
never have injected anything. #521 tracks the still-unconsumed
IHostConnectivityProbe.

Adds the remediation status for the deferment register (branch
feat/deferment-remediation, tip 88ce8df0, unmerged). One item there is
operationally visible beyond OtOpcUa: #516 makes a changed DriverConfig
stop+respawn the driver rather than an in-place delta, so a config edit now
costs a driver reconnect — previously five drivers ignored the edit entirely
while the deployment still sealed green.
2026-07-27 20:04:32 -04:00
Joseph Doherty eedbf13712 docs(index): OtOpcUa — mesh program COMPLETE (Phase 7 + bootstrap guard), deferment register
Corrects four stale claims about OtOpcUa and adds two consumer-relevant facts,
all source-verified against the OtOpcUa repo (not its docs):

  * "Phases 0a..6 done, 7 not started" -> PROGRAM COMPLETE. Phase 7 merged
    c50ebcf7 (6/6 failover drills) + bootstrap guard d1dac87f, both on master
    and pushed 2026-07-24.
  * The auto-down 1-vs-1 crash-the-oldest live gate is no longer "still open" /
    "deferred to Phase 7" — Phase 7 drill D4 closed it; every survivor stayed
    Up without self-downing.
  * Phase 6's live gate was NOT "deferred by owner choice" — it ran and caught
    three fix-forward defects, including a boot-crash StackOverflow on every
    node (IClusterRoleInfo resolved inside the AddAkka configurator while the
    ActorSystem was still building).
  * Records the MAIN-only manual-failover constraint and the default-OFF
    bootstrap guard's founder-election shape.

Adds OtOpcUa/deferment.md (e08855fb) and its two ScadaBridge-relevant entries:
  * Node ACLs are authored, shipped in every artifact, and NOT ENFORCED — the
    evaluator subsystem has zero production consumers and OtOpcUaNodeManager
    never references it. Reads are ungated; authored deny rules have no effect.
    Do not assume OtOpcUa filters an address space per-user.
  * IRediscoverable is inert fleet-wide (#518/#507) — nine drivers raise it,
    nothing consumes it, so a Galaxy redeploy / PLC re-download / Agent restart
    does not change the served address space without a config redeploy.
2026-07-27 17:28:28 -04:00
Joseph Doherty 035c5feeb8 Merge branch 'feat/overview-dashboard'
# Conflicts:
#	CLAUDE.md
2026-07-27 15:26:37 -04:00
Joseph Doherty b02d7a92bb docs(index): record OtOpcUa's MTConnect Agent driver (merged to master, PR #506)
Keeps the umbrella index in step with the OtOpcUa driver set, per the
propagation rule in that repo's CLAUDE.md. Read-only Agent driver:
hand-rolled HTTP/XML client (probe/current + multipart /sample pump),
TrakHound dependency evaluated and dropped, browse free via the Wave-0
universal discovery browser, write-back deferred. Live-gated against a
real mtconnect/agent 2.7.0.12 fixture.
2026-07-27 14:03:15 -04:00
Joseph Doherty 75f267c4c9 docs(index): index edits go on main and get pushed
Sister projects are told to update their entry here whenever an indexed fact
changes, but that edit lands in this repo's own checkout — so a naive commit
writes it onto whatever branch scadaproj happens to be on. Observed 2026-07-27:
the OtOpcUa Sql driver's entry sat unpushed on feat/overview-dashboard for three
days, and the Mqtt entry was about to join it.

Records the procedure (stash, main, push, restore) and says to cherry-pick
stranded index commits rather than merge the branch they are stuck on.

Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
2026-07-27 13:36:18 -04:00
Joseph Doherty 7dcd93c326 docs(index): OtOpcUa's MQTT / Sparkplug B driver is merged to master
Merge c3a2b0f7, pushed to origin 2026-07-27. Supersedes the
"on branch feat/mqtt-sparkplug-driver, not yet merged" note in bf75e26.

Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
2026-07-27 13:34:10 -04:00