44 Commits

Author SHA1 Message Date
Oliver Kieselbach 4e73ba8900 Agent Host changes for agents/improve-changelog-promotion-ui (#152) 2026-09-08 14:57:11 +02:00
Oliver Kieselbach 8a259241b5 chore: operator scripts leave the public tree (versioned in the private infra submodule); scripts/ keeps only Bootstrap and CustomerSetup 2026-09-04 02:43:23 +02:00
Oliver Kieselbach db020789e1 chore: private submodule docs/ becomes internal/ (knowledge + decisions + work files + private instructions)
- .gitmodules: docs -> internal, repo renamed to Autopilot-Monitor-internal; the OKF bundle now lives at internal/docs/
- .claude/CLAUDE.md rewritten: where knowledge lives, working-file rules, hard rules; imports the private half from internal/CLAUDE.md (silently absent without submodule access)
- .claude/architecture-principles.md moved into the internal bundle (reconciled against the code)
- tasks/ (gitignored) retired; working files live in internal/work/
- doc path references docs/<bundle> -> internal/docs/<bundle> in code comments, skills gitlink, codeql paths, build script
- rule descriptions no longer cite an internal doc path (customer-visible text); rules/dist regenerated
- public tree no longer names private operator tooling
- .claude/commands gitlink: skill docs point at the new paths
2026-09-04 02:19:00 +02:00
Oliver Kieselbach a5c42de28c chore: move infra/ into a private submodule
The two Bicep templates — and the deployment scripts still to come — do not
belong in a public repository. They now live in okieselbach/Autopilot-Monitor-infra
(full history via git-filter-repo) and are mounted back at infra/, so the code
comments pointing at infra/mcp-server.bicep stay valid. No workflow reads
infra/, so CI is unaffected. The *.parameters.json ignore rule moved into the
submodule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 00:06:38 +02:00
Oliver Kieselbach 4d3d3c56f4 gitignore: restore ime-files/ - local binaries scratch of /ime-decompile
Still needed: the skill extracts each MSI here (msiexec /a payload for grepping
in binaries); only decompilates go to the ime-decompiles repo and MSIs to the
ime-archive blob container.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 01:51:26 +02:00
Oliver Kieselbach 32d8151185 updated .gitignore 2026-08-18 00:28:29 +02:00
Oliver Kieselbach ae85dc325c gitignore: exclude local ime-files/ working directory
Machine-local reference files, kept out of version control.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 23:51:08 +02:00
Oliver Kieselbach c4280e823c fragility audit P5.x + P7: drift guards across SignalR names, RowKeys, config sections, scoped routing
P5.x-A: Constants.SignalRMessages catalog (13 names) + SignalRGroupHelper.HubName;
all backend send sites and web subscriptions typed against the shared-manifest
union (SignalRContext.on/off) — unknown names are tsc errors. Dead eventStream
session-payload handling removed from diagnosis page.

P5.x-B: RowKeyCodec as the single inverted-tick encoder (persisted widths pinned,
UserActivity D20 legacy); DeletionRowDump.Table on tombstone rows with
DeletionTombstoneTables.Resolve replacing the duplicated Contains('_') heuristic
(legacy fallback retained for pre-field manifests).

P7.1: PATCH config/{tenantId}/fields flipped to TenantAdminOrGA (phase 2);
Settings sections save via per-section diff PATCH from sectionFieldMap.ts —
the ~39-field stale round-trip vector is gone; legacy webhook clearing now only
on the notifications save; agent-settings reset no longer discards contact edits.

P7.2/7.3: useGlobalAdminScope is a projection over useAggregatedAdminScope
(resolveConcreteScopeView, test-pinned); scopedApi builders own the tenant/global
endpoint-pair routing for all 11 former hand-rolled call sites; scopedFetch adds
the shared JSON fetch layer.

P7.4: navVisibility extraction + roles x nav-config matrix and nav<->route-guard
consistency test with a ratchet for the two known pre-existing mismatches
(Operator and GlobalReader vs /settings — user decision pending).

P7.5: web build stamp public/version.json (prebuild, GITHUB_SHA), SWA no-store
route, deploy-web verify poll + versions/web.json manifest, Portal Build card.

P7.6: OkAsyncBaselineGuardTests freezes the 44 anonymous-response sites
(shrink-only ratchet).

Verified: dotnet build 0W/0E, Functions.Tests 4123, DecisionCore 519, V2.Core
2206, SummaryDialog 44; tsc 0, ESLint 0, vitest 762/762; mutation proofs for all
new drift nets. Docs: docs/drift-guards.md + versioning.md web row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 23:17:48 +02:00
Oliver Kieselbach cf45911b69 Web upgrade: Next 16 + React 19 + MSAL v4 (#114)
* chore(web): bump to next 16, react 19, msal-browser 4, msal-react 3

react 19.2 aligns the declared dependency with the React the app router
has been running all along (Next-vendored 19 canary). msal-react 3.0.29
is the React-19-compatible bridge that only needs msal-browser 4 —
deliberately NOT msal v5, whose COOP redirect bridge requires new
bridge pages per origin plus app-registration changes (separate
project). The react-leaflet peer overrides are gone: react 19
satisfies react-leaflet 5 natively.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(web): react 19 / msal v4 / next 16 code adaptations

- msalConfig: allowNativeBroker -> allowPlatformBroker (v4 rename);
  storeAuthStateInCookie stays (deprecated in v4, removed only in v5)
- zero-arg useRef() removed in @types/react 19: GlobalSearch (2x),
  dashboard autoLoadTimerRef
- React.MutableRefObject -> React.RefObject in 5 session/progress hooks
  (all refs are mutable in 19 types)
- layout: data-scroll-behavior="smooth" opt-in so route changes keep
  jumping instead of animating (Next 16 stopped suppressing CSS
  smooth-scroll during navigation)
- next.config: analyzer comment - Turbopack default build skips the
  webpack-only analyzer, use --webpack for ANALYZE runs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(web): untrack Next-managed next-env.d.ts, generate types in CI

Next 16 rewrites next-env.d.ts on every dev/build run and the routes
import inside flips between .next/types and .next/dev/types (vercel/
next.js#86001) - official guidance is to gitignore it. CI now runs
`next typegen` before tsc so the type stubs exist on a fresh checkout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(web): migrate lint script to eslint CLI (next lint removed in 16)

Minimal flat config from eslint-config-next@16 (core-web-vitals +
typescript) with build-output ignores. Lint stays out of CI as before;
the 264 pre-existing findings are untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 23:54:12 +02:00
Oliver Kieselbach 5191751ed2 perf(web): lazy admin context + instant shell for software mapping
AdminConfigProvider no longer eagerly fetches global/config, config/all
(46 KB) and preview/whitelist on every /admin/* entry. Sections that
consume adminConfig/tenants trigger the idempotent ensureAdminConfigLoaded/
ensureTenantsLoaded on mount; fetchTenants stays as the explicit post-save
refresh. Pages that only need the token (Software Mapping, Backups, ...)
now pay nothing.

/admin/software gets a route-level loading.tsx and all three software tabs
render a TableSkeleton instead of a centered spinner on initial load. The
Mapped/Ignored mount guards ("!loaded && !loading") could refetch endlessly
after a failed fetch; now fetch only on !loaded.

Also gitignore .playwright-mcp/ (Playwright MCP browser artifacts).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 17:21:51 +02:00
Oliver Kieselbach 63ea2e3cee feat(mcp): search_docs — customer documentation as a third search corpus
The MCP server could answer telemetry questions ("why did this session fail")
but not product ones ("how do I deploy the agent", "where is my data stored").
Those answers already exist in the autopilotmonitor-docs bundle; search_docs
makes them semantically searchable.

Deliberately a separate index from search_knowledge: rules and prose answer
different questions, and sharing one topK would dilute both. Registered for
every role — published documentation carries no tenant data — and skipped
entirely when no corpus was baked in, so a doc-less build advertises no
broken tool.

Corpus handling:
- Chunked at h2/h3 and <details>/<summary>, each chunk prefixed with a
  "Page > Section > Subsection" breadcrumb so a mid-page hit is self-describing.
- Newlines are normalized before any parsing. This is a correctness
  precondition, not cosmetics: the bundle ships CRLF and JS `.` does not match
  \r, so /^(#{2,3})\s+(.*)$/ matched zero headings — silently, degrading every
  page to unlabelled paragraph splits.
- Two size exceptions: tables are never split (a split table leaves `| --- |`
  rows with no header), and unbroken changelog lists split at line level (left
  whole, their tails fall outside the model window and become unsearchable).
- Short sections are kept — a one-line answer is often the best hit, and the
  breadcrumb supplies the context a short body lacks.

Build and delivery:
- Docs are embedded at image build time into an optional third
  PrecomputedSection. Optional so a checkout without the docs repo does not
  invalidate the rules and event-type vectors; the reverse (server has docs,
  file does not) is staleness and is rejected.
- The deploy workflow checks the public docs repo into the build context and
  passes its SHA as DOCS_COMMIT, which /health reports alongside the chunk
  count — editing the docs does not update a running server, so staleness is
  made checkable rather than memorable.
- Embeddings are rounded to 6 decimals on serialize: 55% smaller index (2.63
  vs 5.88 MB) for a ~1e-5 norm error against a 1e-3 tolerance. indexPrecomputed
  now asserts unit norm, since the hydrate path never checked it.

Infra: the Bicep template was two changes behind the live deployment (EU
cutover and ACR hardening, both applied directly in Azure). Reconciled against
the running resources — managed-identity image pull replaces the admin
credentials and the acr-password secret — and infra/ is no longer gitignored so
it stops drifting. Container raised to 0.5 vCPU / 1.0 GiB for the cold-start
query-embedder load. The template does not model the mcp.autopilotmonitor.com
custom domain, so a full deployment would remove it; the header warns about it.

Verified: 428 tests pass; 45 pages produce 324 chunks; sample queries hit the
right page top-1/2; all 8 derived URLs return 200 live; the precompute output
is accepted by the boot validator and a mutated corpus is rejected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:48:28 +02:00
Oliver Kieselbach 6d7783566f feat(ci): shared build-counter blob, CI build parity, ZIP provenance attestation
Build numbers now come from a public counter blob (buildcounter-v2.txt,
reserve-before-build with ETag-CAS) shared by local build.ps1 and CI, so the
two paths can never mint the same number. The CI step that committed
buildcounter.txt bumps to main is gone; the repo file is now a gitignored
offline fallback for -SkipUpload smoke builds only.

CI parity fixes vs the local build:
- ship SummaryDialog.exe.config in the ZIP (WPF AppContextSwitchOverrides;
  without it the dialog dies with 0x8007045A when spawned from SYSTEM)
- verify EXE version == manifest == reserved build number before zipping
- update the AdminConfiguration hash-oracle only on publish_as_stable

CI-built release ZIPs now carry a GitHub Artifact Attestation (Sigstore
keyless provenance, actions/attest-build-provenance@v4).

Doc: docs/agent/build-counter-blob.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 10:49:18 +02:00
Oliver Kieselbach b18846a698 updated gitignore 2026-07-13 18:08:23 +02:00
Oliver Kieselbach 5775c7c176 fix(web+backend): Progress Portal live updates for end users + sidebar Dashboard gate
Two related fixes for the end-user Progress Portal experience:

Live updates / permissions: realtime/groups/join+leave were elevated to
MemberRead (regression c4dabeee), which 403'd roleless end users tracking
their own device - the page loaded initial status but never received live
eventStream pushes (looked frozen). Introduce a new EndpointPolicy tier
AuthenticatedUserWithRole that admits any authenticated caller but still
resolves IsGlobalAdmin/IsTenantAdmin/UserRole onto RequestContext, so the
SignalR functions can do per-group authorization. Real gating now lives in
SignalRAddToGroup/RemoveFromGroupFunction: tenant match, global-admins group
on GA, admin-tier notify group on TenantAdmin, member-tier notify group on
tenant membership. Plain AuthenticatedUser was rejected - it would leave the
role flags always-false and break GA/admin group joins.

Sidebar: hide the global Dashboard nav item for regular users (no
admin/operator access); they only see the Progress Portal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:21:59 +02:00
Oliver Kieselbach d973f457c4 chore: untrack scripts/Backup/setup-backup-container.ps1 (operator-local)
The script applies a lifecycle policy + container creation against a live
storage account using operator-specific parameters (StorageAccountName,
ResourceGroupName). It is not portable across environments and each
operator keeps their own copy, so it does not belong in the repo.

The file is preserved on disk (git rm --cached, not -f) so the local
operator setup keeps working — only the Git tracking is dropped, plus
the matching .gitignore entry so a future `git add scripts/Backup` is
silently ignored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 17:38:46 +02:00
Oliver Kieselbach 8dd80d7232 update gitignore 2026-05-15 09:39:37 +02:00
Oliver Kieselbach 594b3906ce feat(agent/v2,web): capture full health-script lifecycle with phase-aware semantics + live indicator
Replaces the line-by-line HS-COMPLIANCE / HS-EXITCODE / HS-STDOUT / HS-STDERR /
HS-RUN-CONTEXT pattern set (only ever captured the pre-detection phase, reset state
mid-cycle) with a single atomic source: HS-NEW-RESULT matches IME's "[HS] new result =
{JSON}" line and emits up to three script_completed events per policy run (pre-detection
/ remediation / post-detection). HS-SCRIPT-START now also fires a live script_started
event so the UI shows a "running" indicator immediately, before the consolidated final
result lands ~30s-3min later.

Phase-aware failure semantics: detection / post-detection scripts use exit code as a
compliance verdict (not a crash signal), so a non-compliant detection that gets
remediated no longer counts as a "failed" event in metrics — the row renders with
amber styling via isNonCompliantReport(). Only the remediation phase + platform
scripts route non-zero exit to script_failed.

Defensive against wire-format drift: regex uses [\s\S]* with end-anchor, JSON parsed
with try/catch + counter, frontend toNumber() accepts both numeric and string fields
(backend serializes ints as strings via Dictionary<string,string>). Reducer dedupes
with timestamp included so repeated runs of the same policy in long sessions don't
collapse into one row.

V2 only — V1 (Agent.Core) phasing out.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 22:36:49 +02:00
Oliver Kieselbach d1c5b78acf chore counter 2026-04-29 09:00:52 +02:00
Oliver Kieselbach 96dc1482c7 chore: drop local-only tooling + fixtures from repo
- tests/fixtures/enrollment-sessions-local/ is raw/pre-anonymization session
  fixture staging — keep untracked; remove .gitkeep + README.md from the index
  and simplify the gitignore to ignore the whole folder.
- tools/export-session-fixture.mjs is a local conversion helper; add to
  gitignore next to the existing tools/orphan-analysis.py entry.

Files remain on disk locally; only the Git index is pruned.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 17:22:01 +02:00
Oliver Kieselbach 23aa51a3f2 fix warnings and fix v2 agent hash compare 2026-04-22 20:09:42 +02:00
Oliver Kieselbach 37fff23943 chore: gitignore entire tasks/ folder, untrack per-session notes
Replaces the targeted `tasks/todo.md` ignore with a blanket `tasks/`
so the whole folder stays local-only. Content there is per-session
planning + lesson notes (todo.md, lessons.md, m2-copy-list.md); it
doesn't belong in version control alongside the shipped code — it's
operator workspace, not repo state.

Untracks the two files that were still being versioned
(tasks/lessons.md, tasks/m2-copy-list.md) via `git rm --cached` so
they stay on disk but leave the index. Historical versions remain
in git history for reference; new edits won't be tracked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:43:01 +02:00
Oliver Kieselbach 3f64b2809b chore: CLAUDE.md codex-review note, .gitignore additions, legacy buildcounter
Three small maintenance items accumulated during the M1/M2 session:

- .claude/CLAUDE.md: add "Codex will review your output once you are
  done!" note so the Codex review step is front-of-mind for agent work.
- .gitignore:
    * scripts/Deployment/build_and_upload_debug_agent_build_dev.ps1 —
      fill the gap next to the other two Legacy deployment scripts
      (already ignored).
    * plans/REFACTOR_AGENT_V2.md — the refactor plan stays local-only
      during active planning.
- src/Agent/AutopilotMonitor.Agent/buildcounter.txt: auto-incremented by
  MSBuild during the full-solution builds run for the M1/M2 gates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 13:36:48 +02:00
Oliver Kieselbach 710504549b refactor(agent): V2-Agent-Split skeleton + infrastructure copy (M2)
Three new projects as a clean-slate V2 fork of the Legacy Agent:

  AutopilotMonitor.Agent.V2         — net48 exe, minimal Program.cs,
                                      buildcounter 2.0.N, version-v2.json
  AutopilotMonitor.Agent.V2.Core    — net48 library, 94 files copied from
                                      Agent.Core via bulk sed namespace
                                      rewrite; same folder layout
  AutopilotMonitor.DecisionCore.Tests — xUnit net8.0 with ReplayHarness
                                        + 13 smoke/harness tests

V2 isolation is build-time-enforced via V2Isolation.targets imported from
both V2 csproj files — any Legacy ProjectReference fails the build with a
clear error. Grep-verified at commit time: zero `using
AutopilotMonitor.Agent.Core` statements and zero Legacy ProjectReferences
in the V2 tree.

Per plan §2.11, kernel items (CompletionStateMachine, CompletionGuards,
EnrollmentTracker*, Flows/*, WhiteGloveClassifier, WhiteGloveSignals,
EnrollmentStatePersistence) are transitionally retained so the V2 tree
compiles; M4 removes them when SignalAdapters + V2Orchestrator take over.

Per user direction (feedback_v2_kernel_only_refactor): the V2 refactor
replaces only the decision kernel. All peripheral capabilities — gather
rules, analyzers, diagnostics upload, timezone, server-driven actions,
summary dialog launch, env-var resolution, version checks, registry
watchers, network/DO/performance telemetry, self-update, bootstrap→cert
handover, self-destruct — are preserved verbatim via the bulk copy.

Supporting M3 bring-up platform:
 - ReplayHarness (empty-stream deterministic, SHA256 hash over terminal
   state fields) in DecisionCore.Tests/Harness/
 - Fixture scaffold under tests/fixtures/: committed anonymized directory
   with commit-policy README, plus gitignored enrollment-sessions-local/
   for raw exports
 - tools/export-session-fixture.mjs with --help / --dry-run / --validate
   modes; real MCP wiring marked TODO(v2-m3)

V2 bootstrap scripts scripts/Bootstrap/Install-AutopilotMonitor-v2(.|-dev).ps1
(committed, pure ASCII verified per feedback_ps1_ascii_only). V2 deployment
scripts under scripts/Deployment/V2/ are gitignored (analog to Legacy).

Test totals at M2 gate: 13 DecisionCore + 507 Agent.Core (unchanged) +
557 Functions (unchanged) = 1077 green.

Plan: plans/REFACTOR_AGENT_V2.md §4 M2 + §2.16 V2-Agent-Split.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 13:31:30 +02:00
Oliver Kieselbach 6f758ea0f1 late-aadj fix 2026-04-17 14:47:16 +02:00
Oliver Kieselbach 6efae2c709 feat(agent): WhiteGlove Detection Classifier and late-AADJ support 2026-04-17 12:35:25 +02:00
Oliver Kieselbach 4b3db3a1cd whiteglove completion logic and orphan events handling 2026-04-16 20:06:28 +02:00
Oliver Kieselbach 21716c7d5b more tests 2026-04-08 13:40:02 +02:00
Oliver Kieselbach 53e6692cad enhanced progress portal 2026-04-01 04:33:45 +02:00
Oliver Kieselbach 405916d582 progress portal bugfix 2026-04-01 04:27:17 +02:00
Oliver Kieselbach f181205694 update gitignore 2026-03-31 05:02:13 +02:00
Oliver Kieselbach d825e80ebd Move Claude Code skills and scripts to private submodule
- Replace public rule-builder.md and gitignored commands/scripts
  with a private submodule at .claude/commands/
- Submodule: okieselbach/Autopilot-Monitor-dotclaude (private)
- Script paths updated: .claude/scripts/ → .claude/commands/scripts/
- Clone with: git clone --recurse-submodules

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 07:02:02 +01:00
Oliver Kieselbach 6f24bf0c75 CPE Mappings simplified 2026-03-20 23:51:12 +01:00
Oliver Kieselbach 26e5925672 feat: Software Inventory Analyzer with Vulnerability Correlation 2026-03-20 14:43:58 +01:00
Oliver Kieselbach 66733209ec added agent emit event explicit flag for immediate upload 2026-03-20 00:31:48 +01:00
Oliver Kieselbach dc2aa913f6 added app insights 2026-03-19 22:04:59 +01:00
Oliver Kieselbach 9cd6669811 update gitignore 2026-03-19 19:52:58 +01:00
Oliver Kieselbach 1f7ac9374f update gitignore 2026-03-19 16:44:41 +01:00
Oliver Kieselbach e6662e1a0d fixes for Summary Dialog 2026-03-08 13:01:08 +01:00
Oliver Kieselbach 64a9a0aa99 chore: unignore rules/dist/ and add initial combined rule files
rules/dist/ was excluded by the global dist/ .gitignore pattern.
Added !rules/dist/ exception so the combine-rules workflow can
commit the generated files. Also adds the initial dist files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 13:24:15 +01:00
Oliver Kieselbach 000b7499bd updated .gitignore 2026-02-16 20:49:43 +01:00
Oliver Kieselbach 4154257c31 added build counter for agent 2026-02-13 11:22:15 +01:00
Oliver Kieselbach 3e3cc904f7 Agent re-architectured
- new IME log parser
- IME log replay option
- revised timeline and enrollment tracker
UI
- removed flight tracker
- fixed download tracker
- nice progress portal page
2026-02-10 02:37:31 +01:00
Oliver Kieselbach 557dd22c53 Authentication & Galactic Admin: Implement JWT-based multi-tenant access control with cross-tenant support
Backend Changes:
- Fix user identification to use UPN (User Principal Name) claim as primary identifier instead of display name
- Add JWT authentication validation to all API endpoints with Authorization header support
- Implement Galactic Admin role with cross-tenant access permissions for sessions, events, and SignalR groups
- Add cross-tenant validation in GetSessionEventsFunction, SignalRAddToGroupFunction, and SignalRRemoveFromGroupFunction
- Enhance AuthenticationMiddleware to log actual user identifier (UPN) instead of display name

Admin Configuration:
- Add GetAdminConfigurationFunction and UpdateAdminConfigurationFunction for global settings
- Create AdminConfigurationService for managing platform-wide configuration
- Add AdminConfiguration model with global rate limiting and maintenance settings
- Restrict admin configuration access to Galactic Admins only

SignalR Real-time Updates:
- Implement "galactic-admins" SignalR group for cross-tenant session visibility
- RegisterSessionFunction now sends "newSession" events to both tenant-specific and galactic-admins groups
- IngestEventsFunction sends "newevents" only to tenant-specific groups (prevents flooding)
- Frontend listens to both "newSession" and "newevents" for real-time updates
- Galactic Admins see new sessions from all tenants without being flooded with event updates

Frontend Changes:
- Add Authorization headers with JWT tokens to all API fetch calls (sessions, events, metrics, configuration)
- Implement automatic joining/leaving of "galactic-admins" SignalR group based on Galactic Admin mode
- Handle both "newSession" and "newevents" SignalR events for complete session list updates
- Add authentication error handling with user notifications for token failures

Security Improvements:
- Validate tenant access for all cross-tenant operations
- Ensure users can only access their own tenant data unless they're Galactic Admins
- Log all cross-tenant access attempts with user identifiers for audit trail
2026-02-05 20:49:36 +01:00
Oliver Kieselbach 5690620058 Initial commit 2026-02-05 06:14:41 +01:00