Commit Graph

111 Commits

Author SHA1 Message Date
Joseph Doherty bc9843d2bd docs(plan): mark T17-T24 inbound-ack complete + merged-to-master
v2-ci / build (push) Failing after 7m11s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
2026-06-11 08:08:37 -04:00
Joseph Doherty 2b890fa716 docs(plan): re-scope script-log Layer 2 inbound-ack into T17-T24
The original single T17 (inbound method dispatch + ack plumbing) proved on a
2026-06-11 deep dive to be four hard problems: roles on the session identity
(T17), node-manager command router + AlarmAck veto + alarm-commands DPS topic
(T18), host-actor inbound handler (T19), and delta-gate double-emit (T20). Old
T18->T21 (AdminUI), old T19 split into T22 (Client.CLI feature) + T23 (verify),
old T20->T24. Adds the Layer 2 design-decisions preamble.
2026-06-11 05:37:54 -04:00
Joseph Doherty 74e1abdf32 docs(plan): record disable-login feature merged to master (2ad1dbc8) 2026-06-11 05:37:54 -04:00
Joseph Doherty bc31b6a4de docs(adminui): implementation plan for Security:Auth:DisableLogin dev flag
6-task plan (T0 branch -> T1 options/roles -> T2 handler -> T3 wiring -> T5 verify;
T4 config+docker-dev parallel). AutoLoginAuthenticationHandler registered under the
cookie scheme name so existing policies keep working; enabled in docker-dev.
2026-06-11 04:24:00 -04:00
Joseph Doherty 789176738f docs(adminui): design for Security:Auth:DisableLogin dev flag
Approved brainstorming design: a config flag that disables AdminUI login,
auto-authenticating every request as 'multi-role-test' with all roles via an
always-succeeding AuthenticationHandler registered under the cookie scheme name.
Default off; enabled in docker-dev (central-1/central-2). AdminUI cookie surface
only; OPC UA LDAP + deploy API key untouched.
2026-06-11 04:19:43 -04:00
Joseph Doherty 43e8a37ded chore(plan): mark T0-T16 complete; T17-T20 deferred (Layer 2 partial) 2026-06-11 01:25:17 -04:00
Joseph Doherty c42a056537 chore(plan): Layer 0 complete (T0-T3) — tracking update 2026-06-10 12:09:56 -04:00
Joseph Doherty 12423899aa docs(plan): script-log emit + scripted-alarm runtime implementation plan + tasks 2026-06-10 11:34:01 -04:00
Joseph Doherty df4c265753 docs(design): script-log engine emit + scripted-alarm runtime (3-layer) 2026-06-10 11:28:13 -04:00
Joseph Doherty 084c8a28e7 docs(scripting): implementation plan for equipment-relative tag paths ({{equip}}) 2026-06-10 07:36:59 -04:00
Joseph Doherty 5044664379 docs(scripting): design for equipment-relative tag paths ({{equip}})
Approved brainstorm: a reserved {{equip}} token in ctx.GetTag/SetVirtualTag
path literals is substituted at the compose seams with the owning equipment's
tag base prefix (derived from child-tag FullNames). Lets one virtual-tag script
be reused across machines. No schema migration, runtime untouched.
2026-06-10 07:27:44 -04:00
Joseph Doherty 8aec438cc5 chore(plan): mark Monaco script-editor plan complete (all 14 tasks) 2026-06-09 15:52:57 -04:00
Joseph Doherty 93aa6c2f81 docs(scripting): implementation plan for Roslyn-backed Monaco script editor
14-task plan: vendor Monaco + reusable MonacoEditor.razor, ScriptAnalysis
backend re-seated on the real evaluator wrapper (ScriptSandbox +
ForbiddenTypeAnalyzer + DependencyExtractor diagnostics), IScriptTagCatalog
path completion, six Monaco providers, ScriptEdit + virtual-tag-modal wire-in,
live docker-dev verification. Co-located .tasks.json for resume.
2026-06-09 13:56:59 -04:00
Joseph Doherty 7a03d01613 docs(scripting): design for Roslyn-backed Monaco script editor
Full IntelliSense parity with scadabridge (completions, hover, signature
help, live diagnostics, formatting, inlay hints, global tag-path
completion), re-seated on OtOpcUa's real script compile context
(ScriptSandbox + VirtualTagContext wrapper + ForbiddenTypeAnalyzer +
DependencyExtractor). Reusable MonacoEditor.razor wired into the
ScriptEdit page and the virtual-tag modal; Monaco vendored locally.
2026-06-09 13:44:20 -04:00
Joseph Doherty cc53fc8feb docs(plan): implementation plan for driver-typed tag editors (F-uns-1 / #135)
10-task plan: (1) surface DriverType to the TagModal driver dropdown,
(2) shared TagConfigJson util + empty TagConfigEditorMap + DynamicComponent
dispatch scaffold, (3) Modbus editor as the worked example, (4-8) S7/AbCip/
AbLegacy/TwinCAT/Focas editors (parallelizable, disjoint files), (9) register
the five in the map, (10) docker-dev live verify (needs a non-Galaxy driver in
the rig). Each editor = pure FromJson/ToJson/Validate model (unit-tested) + thin
razor shell; preserves unknown JSON keys; driver pages untouched. Co-located
.tasks.json for resume.
2026-06-09 09:11:02 -04:00
Joseph Doherty 913fea7a3c docs(plan): design for driver-typed tag editors in the UNS TagModal (F-uns-1 / #135)
Approved design: 6 new per-driver TagConfig editor components
(Modbus/S7/AbCip/AbLegacy/TwinCAT/Focas) dispatched by the selected driver's
DriverType via a TagConfigEditorMap + DynamicComponent; the 3 unmapped drivers
keep the generic raw-JSON editor; no raw-JSON toggle on typed drivers. Editors
reuse the drivers' enums + JSON property names (not razor markup); driver pages
untouched. Pure FromJson/ToJson/Validate helpers are unit-tested (no bUnit);
live verify needs a non-Galaxy driver added to docker-dev. AdminUI-only, no
data-model change.
2026-06-09 09:03:22 -04:00
Joseph Doherty 944732e500 docs(uns): implementation plan + task graph for global UNS management 2026-06-08 12:11:40 -04:00
Joseph Doherty 3361eac6d8 docs(uns): design for global UNS management tree-table 2026-06-08 12:02:18 -04:00
Joseph Doherty b962b041f3 docs(plan): driver-less equipment — all tasks complete + live-verified 2026-06-08 07:10:14 -04:00
Joseph Doherty d2dbf7b0d7 feat(config): make Equipment.DriverInstanceId nullable + driver-less AdminUI support + migration 2026-06-08 06:49:28 -04:00
Joseph Doherty a94d03a194 docs(plan): driver-less equipment namespace implementation plan (#143-147) 2026-06-08 06:40:14 -04:00
Joseph Doherty 064adb0bd0 docs(design): driver-less equipment namespace (nullable Equipment.DriverInstanceId, drop Modbus placeholder) 2026-06-08 06:36:40 -04:00
Joseph Doherty 446a45686f docs(plan): mark all VirtualTag/script-memory Phase-1 tasks complete
v2-ci / build (push) Failing after 37s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
2026-06-07 15:57:43 -04:00
Joseph Doherty cfbf0b2a17 feat(deploy): warn-only script-compile-cost advisory on deploy 2026-06-07 15:36:09 -04:00
Joseph Doherty 08d7477860 feat(vtag): passthrough fast-path skips Roslyn for mirror scripts (A) 2026-06-07 15:26:20 -04:00
Joseph Doherty df772dd09a docs(plan): VirtualTag/script memory Phase-1 implementation plan (A0+A+guardrail) 2026-06-07 15:00:11 -04:00
Joseph Doherty 321d57938f docs(design): VirtualTag/script memory scalability (A0+A+guardrail; C2 deferred) + measurement harness 2026-06-07 14:55:28 -04:00
Joseph Doherty fc52fbce49 docs: follow-ons tasks all complete
v2-ci / build (push) Failing after 43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
2026-06-07 10:56:27 -04:00
Joseph Doherty ce8c0811eb docs(plan): OtOpcUa follow-ons implementation plan (subscribe race, collision gate, docker-dev) 2026-06-07 10:20:52 -04:00
Joseph Doherty 4cb488c53e docs(design): OtOpcUa follow-ons — subscribe race, signal-name collision validation, docker-dev resources 2026-06-07 10:06:08 -04:00
Joseph Doherty 7e23ca8453 docs: tasks all complete 2026-06-07 06:09:23 -04:00
Joseph Doherty 2e4e100733 docs: mark WS-3a (Equipment live values) done; finalize task tracker 2026-06-07 06:08:36 -04:00
Joseph Doherty d5fb8f9142 docs(plan): equipment-namespace live values (VirtualTag route) implementation plan 2026-06-07 04:49:27 -04:00
Joseph Doherty 7bec2fd4db docs(plan): per-ClusterId scoping implementation plan + task graph
10 tasks: runtime scoping (ResolveClusterScope + scoped ParseDriverInstances/
ParseComposition, DriverHostActor + OpcUaPublishActor wiring, multi-cluster
E2E) then docker-dev compose/traefik/seed rewrite, live verification, docs.
2026-06-07 02:59:46 -04:00
Joseph Doherty ab8900eee5 docs(design): per-ClusterId scoping for hub-and-spoke single mesh
Central cluster (2 fused admin+driver nodes) hosts the only UI + deploy
singleton; site clusters (2 driver-only nodes each) join the central mesh
and are logically separated by ClusterId. Each node applies only its own
cluster's drivers + address space on a global deploy. Approved design;
next step is the implementation plan.
2026-06-07 02:50:49 -04:00
Joseph Doherty a79ed5fff1 test(opcua): full equipment-namespace structure pipeline against a real SDK node manager
v2-ci / build (push) Failing after 35s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Entities -> Phase7Composer.Compose -> MaterialiseHierarchy + MaterialiseEquipmentTags ->
real OtOpcUaNodeManager, asserting the Area/Line/Equipment folders + the equipment-signal
Variable land in a live OPC UA address space (structure-only). Also covers compose-side
EquipmentTags extraction. The cluster-level deploy + network-browse E2E + scadaproj loader
need the docker-dev fixture (not runnable on this dev box) and are tracked as a follow-up.
2026-06-06 15:07:45 -04:00
Joseph Doherty aaf869145a fix(opcua): equipment-tag planner diff + folder-scoped NodeIds (review findings)
Two bundle-review fixes + idempotency coverage:
- CRITICAL: the planner ignored EquipmentTags, so an incremental deploy changing only
  equipment tags produced an empty plan and HandleRebuild short-circuited before
  materialising them. Add TagId to EquipmentTagPlan + Added/Removed/ChangedEquipmentTags
  to Phase7Plan (diffed by TagId, in IsEmpty, driving Apply's needsRebuild) — mirroring
  the GalaxyTags treatment.
- IMPORTANT: equipment variable NodeId was the raw driver FullName, which collides across
  identical machines (e.g. two PLCs both exposing register 40001) — the second variable
  was silently dropped. NodeId is now folder-scoped (parent/Name); FullName stays on
  EquipmentTagPlan for the later values-routing milestone.
- Task 4: SDK-backed idempotency test (double-apply -> single variable); restart-safety
  confirmed (RestoreApplied reuses the same RebuildAddressSpace -> HandleRebuild path).
- Minor: align composer equipment-tag sort with the artifact decoder (coalesce FolderPath).
2026-06-06 15:02:50 -04:00
Joseph Doherty 08cddfe128 fix(opcua): UNS equipment folders browse by friendly Name, NodeId stays the logical Id
Equipment folder DisplayName was the colloquial MachineCode; the live rebuild (artifact
ReadEquipmentNode) + composer now use the UNS level-5 Name segment, matching Area/Line
folders + EquipmentNodeWalker. NodeId stays the logical EquipmentId so browse-path
resolution + ACLs are unaffected.
2026-06-06 14:51:12 -04:00
Joseph Doherty df0dc516c3 feat(opcua): materialise Equipment-namespace tags in the live rebuild
Add Phase7Applier.MaterialiseEquipmentTags — a sink-based pass (Task-0 decision A) that
ensures each EquipmentTagPlan's Variable (NodeId = FullName) under its existing equipment
folder, nesting any FolderPath as a sub-folder. Wire it into OpcUaPublishActor.HandleRebuild
after the Galaxy pass. Variables start BadWaitingForInitialData; never re-creates equipment
folders (decision #4).
2026-06-06 14:46:38 -04:00
Joseph Doherty febe462750 feat(opcua): carry Equipment-namespace tags through the deployment composition
Add EquipmentTagPlan + an init-only EquipmentTags member on Phase7CompositionResult
(mirror of GalaxyTags). Populate it compose-side (Tag.EquipmentId != null AND owning
namespace Kind == Equipment) and artifact-decode-side via BuildEquipmentTagPlans, with
FullName extracted from Tag.TagConfig. Init-only member (not a 7th positional param) so
existing convenience constructors + call sites are untouched.
2026-06-06 14:42:38 -04:00
Joseph Doherty c18943f6e1 docs: task-by-task plan for the Equipment-namespace structure milestone
v2-ci / build (push) Failing after 33s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Implements WS-1/WS-2/WS-4 (+ tests) of the materialization scope: carry
Equipment-namespace tags through the composition/artifact, add a sink-based
MaterialiseEquipmentTags pass to the live rebuild, browse folders by friendly
Name (NodeId stays the logical Id). 6 tasks with dependencies; structure-only
(BadWaitingForInitialData leaves) — live values are the next milestone. Resume
via /executing-plans docs/plans/2026-06-06-equipment-namespace-structure-milestone.md
2026-06-06 14:20:36 -04:00
Joseph Doherty 0b8cad1870 docs: scope Equipment-namespace materialization in the live deploy path
v2-ci / build (push) Failing after 38s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Equipment-kind namespaces materialise only their Area/Line/Equipment folder
skeleton on deploy, not the signals under them: EquipmentNodeWalker is fully
built + unit-tested but has no production call site, the composition/artifact
drops EquipmentId-bound tags, and no value source is wired (OpcUaClient driver
factory missing; VirtualTag ITagUpstreamSource unregistered). Documents the
gaps, workstreams, value-path options, and a structure-only-first sequencing.
2026-06-06 14:14:01 -04:00
Joseph Doherty 4893f7288d docs(plan): documentation audit implementation plan (27 tasks, Phase 0/1/2) 2026-06-03 14:06:24 -04:00
Joseph Doherty 47acdde78d docs(plan): documentation audit design (live-reference corpus, 4 dimensions, fill-every-gap) 2026-06-03 13:59:02 -04:00
Joseph Doherty 5e87f7e16f docs(alarms): record 2026-05-31 live re-confirmation of native alarm feed
v2-ci / build (push) Failing after 41s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Independently re-ran the D.1 alarm-source smoke against the live gateway
(10.100.0.48:5120) to back the native MxAccess alarm-event claim with a
fresh empirical run, not just the original 2026-05-29 capture.
2026-05-31 10:12:47 -04:00
Joseph Doherty 695fa6408b docs(alarms): record native alarms verified working; add D.1 smoke
v2-ci / build (push) Failing after 47s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
The 2026-04-30 alarm plan banners claimed worker-side native alarm
subscription was blocked on a COM-bitness finding. That's stale: the
mxaccessgw .NET client now has true MxAccess alarm-event support, and a
live StreamAlarms check (+ new Skip-gated GatewayGalaxyAlarmFeedLiveTests
through the lmxopcua consumer) confirms native alarms — operator comment,
category, severity, timestamps — flow end-to-end. Reconcile both plan docs
to reality and add docs/plans/alarms-d1-smoke-artifact.md as the D.1
alarm-source deliverable. Historian-write live smoke + full server->A&C
round-trip remain (Windows parity rig only).
2026-05-31 09:59:01 -04:00
Joseph Doherty b76561a780 docs(adminui): implementation plan + task persistence for deferred follow-ups
19 tasks across WS1 (driver collection editors), WS2 (typed resilience
form), WS3 (editable DB-backed LDAP role map, global), WS4 (cleanup).
2026-05-29 08:59:55 -04:00
Joseph Doherty c49fccbe0c docs(adminui): design for completing deferred follow-ups
Driver collection editors (modal-per-row shared shell), resilience typed
form, editable DB-backed LDAP->role map (global roles, live on next
sign-in), and stale-comment/note cleanup. Roles intentionally global —
no per-cluster permissions.
2026-05-29 08:45:50 -04:00
Joseph Doherty af691f3291 fix(security): correct challenge tests to match framework reality
ASP.NET Core's cookie-handler IsAjaxRequest heuristic only checks
X-Requested-With (not Accept). Drop the third test (Accept: application/json
was assumed to → 401 but actually → 302) and the Location.ShouldBeNull
assertion on the XHR test (framework still writes Location alongside 401;
clients ignore it). Renamed _ajax_ → _xhr_ for accuracy. Design doc
updated to match.
2026-05-29 07:58:18 -04:00
Joseph Doherty ee8add4416 docs: implementation plan for auth/login alignment with ScadaBridge
5 tasks following Section 6 of the approved design (bc4fce5). Tasks 3 and 4
parallelizable. Each task carries Classification + Estimated implement time
+ Parallelizable-with metadata for subagent dispatch.
2026-05-29 07:43:11 -04:00