diff --git a/A2-galaxyrepository-adoption-handoff.md b/A2-galaxyrepository-adoption-handoff.md
new file mode 100644
index 0000000..2df7b77
--- /dev/null
+++ b/A2-galaxyrepository-adoption-handoff.md
@@ -0,0 +1,174 @@
+# A2 — Adopt the shared `ZB.MOM.WW.GalaxyRepository` library
+
+> Handoff note. Written 2026-06-25 from the HistorianGateway side, where the shared lib is
+> already consumed in production. This is the mxaccessgw half of the cross-repo
+> "Galaxy-browse normalization" follow-on (HistorianGateway `pending.md` A2 /
+> scadaproj component-normalization).
+
+## Goal
+
+Replace mxaccessgw's **inline** Galaxy-browse code (`src/ZB.MOM.WW.MxGateway.Server/Galaxy/**`
+plus `Grpc/GalaxyRepositoryGrpcService.cs` + `Grpc/GalaxyProtoMapper.cs`) with a
+`PackageReference` to the shared **`ZB.MOM.WW.GalaxyRepository`** library, so there is **one**
+Galaxy-browse implementation shared by both sidecars instead of two copies that can drift.
+
+The wire contract is **unchanged** — both repos already serve the same `galaxy_repository.v1`
+proto — so **no client change is required**. This is an internal refactor.
+
+## Why this is safe to do now
+
+The shared lib was **extracted from this very code**: the file names under
+`src/ZB.MOM.WW.MxGateway.Server/Galaxy/**` map ~1:1 onto
+`scadaproj/ZB.MOM.WW.GalaxyRepository/src/ZB.MOM.WW.GalaxyRepository/**`. HistorianGateway
+consumes it (`PackageReference @ 0.1.0`) and runs it live against `wonder-sql-vd03`. So the SQL
+provider, hierarchy cache, deploy notifier, snapshot store, background refresh service, projectors,
+glob matcher, tag lookup, and the gRPC service are **already proven** in the package — the work here
+is wiring + reconciling the mxaccessgw-only pieces, not reimplementing browse.
+
+## The clean part — 1:1 swap
+
+These inline files are superseded by the package (delete on adoption; rebind references to namespace
+`ZB.MOM.WW.GalaxyRepository`):
+
+| mxaccessgw inline (`…Server/Galaxy/`) | Shared lib equivalent |
+|---|---|
+| `GalaxyRepository.cs` / `IGalaxyRepository.cs` | same |
+| `GalaxyHierarchyCache.cs` / `IGalaxyHierarchyCache.cs` / `GalaxyHierarchyCacheEntry.cs` | same |
+| `GalaxyHierarchyRefreshService.cs` | same (registered as `HostedService` by the lib's DI ext) |
+| `GalaxyDeployNotifier.cs` / `IGalaxyDeployNotifier.cs` / `GalaxyDeployEventInfo.cs` | same |
+| `GalaxyHierarchySnapshot*.cs` / `IGalaxyHierarchySnapshotStore.cs` | same |
+| `GalaxyHierarchyProjector.cs` / `GalaxyBrowseProjector.cs` / `GalaxyHierarchyIndex.cs` | same |
+| `GalaxyObjectView.cs` / `GalaxyHierarchyRow.cs` / `GalaxyAttributeRow.cs` | same |
+| `GalaxyBrowseChildrenResult.cs` / `GalaxyHierarchyQueryResult.cs` | same |
+| `GalaxyTagLookup.cs` / `GalaxyGlobMatcher.cs` / `GalaxyCacheStatus.cs` | same |
+| `GalaxyRepositoryOptions.cs` | `GalaxyRepositoryOptions` (lib ships **no validator** — see below) |
+| `Grpc/GalaxyRepositoryGrpcService.cs` / `Grpc/GalaxyProtoMapper.cs` | lib bundles its own `Grpc/GalaxyRepositoryGrpcService.cs` + `GalaxyProtoMapper.cs`, mapped by `MapZbGalaxyRepository()` — **but verify authz parity first, see ⚠️ below** |
+| `Galaxy/GalaxyRepositoryServiceCollectionExtensions.cs` | replaced by the lib's `AddZbGalaxyRepository` / `MapZbGalaxyRepository` |
+
+## ⚠️ The hard part — mxaccessgw-only consumers the shared lib does NOT cover
+
+HistorianGateway was a greenfield consumer (browse + dashboard tree only). mxaccessgw has **extra
+consumers of the Galaxy cache/hierarchy that the shared lib was not extracted with.** These are the
+real work and the real risk:
+
+1. **Alarm watch-list / alarm-attribute discovery — capability GAP in the lib.**
+ - mxaccessgw has `Galaxy/GalaxyAlarmAttributeRow.cs` and `GalaxyRepository.GetAlarmAttributesAsync()`,
+ consumed by `Alarms/AlarmWatchListResolver.cs` (+ `IAlarmWatchListResolver`, `GatewayAlarmMonitor`).
+ - The shared lib has **`GalaxyAttributeRow` + `GetAttributesAsync()` only** — there is **no**
+ `GalaxyAlarmAttributeRow` / `GetAlarmAttributesAsync` in `0.1.0`.
+ - **Decision needed:** either (a) push the alarm-attributes SQL projection **upstream** into the
+ shared lib (a `0.2.0` additive feature — preferred, keeps it shared) and re-consume, or
+ (b) keep `AlarmWatchListResolver` + the alarm-attributes query **inline** in mxaccessgw, layered
+ **on top of** the shared `IGalaxyRepository`/`IGalaxyHierarchyCache`. (a) is the spirit of A2.
+
+2. **Dashboard consumers** — `Dashboard/DashboardGalaxyProjector.cs`, `DashboardBrowseService.cs`
+ (+ `IDashboardBrowseService`, `DashboardBrowseModel`), `DashboardSnapshotService.cs`,
+ `DashboardGalaxySummary.cs`, and the Razor pages `GalaxyPage.razor` / `DashboardHome.razor` all
+ `using ZB.MOM.WW.MxGateway.Server.Galaxy`. Mechanical rebind to `ZB.MOM.WW.GalaxyRepository`, but
+ confirm every type they touch is `public` in the lib (most are; double-check projector/snapshot
+ types).
+
+3. **Security / authorization** — `Security/Authorization/ConstraintEnforcer.cs` and
+ `GatewayGrpcScopeResolver.cs` consume Galaxy hierarchy to enforce per-key constraints. Rebind, and
+ see the gRPC-service question below.
+
+⚠️ **gRPC-service authz parity — VERIFIED 2026-06-25: NOT safe to swap wholesale.** The authorization
+is **split across two layers**, and the part that matters is **baked into the service body**:
+
+1. **Authentication + scope gating IS interceptor-based ✅ (safe).** `Security/Authorization/GatewayGrpcAuthorizationInterceptor.cs`
+ authenticates the API key and enforces the required scope; all five Galaxy RPCs map to the `metadata`
+ scope (`GatewayGrpcScopeResolver.cs:23-27` → `MetadataRead`). The interceptor also pushes the identity
+ into an ambient `IGatewayRequestIdentityAccessor` for the call. This mirrors HistorianGateway and is
+ shared-lib compatible.
+2. **Per-key browse-subtree CONSTRAINT FILTERING is baked into the service body ❌ (the blocker).**
+ mxaccessgw's `Grpc/GalaxyRepositoryGrpcService.cs` injects `IGatewayRequestIdentityAccessor` and
+ `ResolveBrowseSubtrees()` (`:287-291`) reads `identityAccessor.Current.EffectiveConstraints.BrowseSubtrees`,
+ threading those globs into the projectors for `DiscoverHierarchy` (`:78`), `BrowseChildren` (`:138`),
+ and the `WatchDeployEvents` count scoping (`:180,196,230-237`) — i.e. it restricts **which Galaxy
+ objects each API key can see**. The shared lib's service injects no identity accessor and passes
+ `browseSubtreeGlobs: null` everywhere; its own XML doc states it *"applies no per-identity
+ browse-subtree filtering … Authorization (including any subtree scoping) is the responsibility of the
+ hosting gateway's interceptor layer."*
+
+**Severity — silent per-key data exposure.** Glob semantics (`GalaxyHierarchyProjector.cs:225-227`):
+`null`/empty → match everything; non-empty → restrict. So keys with **no** browse constraint behave
+identically in both services (no regression), but a key **with** a `BrowseSubtrees` constraint would, on
+the shared service, receive the **entire** Galaxy hierarchy — a `metadata`-scoped key silently bypassing
+its restriction. The boundary is locked by tests that would fail against the shared service:
+`Tests/Gateway/Grpc/GalaxyRepositoryGrpcServiceTests.cs` → `BrowseChildren_BrowseSubtreesConstraint_FiltersChildren`
+(`:437`) and `DiscoverHierarchy_WithSubtreeRootAndDepth_FiltersDescendants` (`:90`).
+
+**Recommendation.** Do **not** call `MapZbGalaxyRepository()` directly. The shared projectors already
+accept a `browseSubtreeGlobs` param, so either fix is small plumbing:
+- **Preferred (spirit of A2 — push upstream):** give the shared `GalaxyRepositoryGrpcService` an optional
+ browse-subtree-constraint provider (e.g. `IBrowseSubtreeConstraintProvider`/delegate returning globs —
+ `null` in HistorianGateway, identity-derived in mxaccessgw). One shared service, both behaviors; bundle
+ with the same `0.2.0` bump as the alarm-attributes gap above.
+- **Fallback (isolate to mxaccessgw):** keep a thin mxaccessgw service that resolves subtrees from
+ identity and calls the shared (public) projectors, and map **that** instead of `MapZbGalaxyRepository()`.
+
+## Concrete wiring steps (template from the HistorianGateway side)
+
+1. **`nuget.config`** — mxaccessgw's `packageSourceMapping` for the `dohertj2-gitea` source currently
+ lists `ZB.MOM.WW.*` up to `Theme` but **NOT** GalaxyRepository. Add:
+ ```xml
+
+ ```
+ under the `dohertj2-gitea` ``. (Easy to miss — restore will fail without it.)
+
+2. **Server `.csproj`** — add:
+ ```xml
+
+ ```
+ (or whatever version ships the alarm-attributes add, if you go route 1(a) above.)
+
+3. **DI + endpoint wiring** (in mxaccessgw's host composition — `GatewayApplication.cs` / its
+ `Program`), mirroring HistorianGateway's `Program.cs`:
+ ```csharp
+ using ZB.MOM.WW.GalaxyRepository;
+ using ZB.MOM.WW.GalaxyRepository.DependencyInjection;
+
+ // service registration — bind from mxaccessgw's section path (NOT top-level "Galaxy"):
+ builder.Services.AddZbGalaxyRepository(builder.Configuration, "MxGateway:Galaxy"); // confirm the exact section path mxaccessgw uses today
+
+ // endpoint pipeline (after AddGrpc):
+ app.MapZbGalaxyRepository();
+ ```
+ Delete mxaccessgw's own `Galaxy/GalaxyRepositoryServiceCollectionExtensions.cs` registrations.
+
+4. **Option validation** — the shared lib **binds only, ships no validator** (deliberate). mxaccessgw
+ already validates Galaxy options via `Configuration/GatewayOptionsValidator.cs` — **keep that**; it
+ stays the owner of fail-fast validation, exactly as HistorianGateway's `ConfigPreflight` does.
+
+5. **Health check** — keep mxaccessgw's existing Galaxy-SQL readiness check; read the connection
+ string from the same `MxGateway:Galaxy` section the lib binds (HistorianGateway does this with a raw
+ `SELECT 1` `SqlConnectionHealthCheck` — see `Program.cs:196`).
+
+## Tests
+
+mxaccessgw has a large `Tests/Galaxy/**` suite that **duplicates the shared lib's own tests**
+(`GalaxyHierarchyCacheTests`, `GalaxyHierarchyProjectorTests`, `GalaxyHierarchySnapshotStoreTests`,
+`GalaxyProtoMapperTests`, `GalaxyHierarchyIndexTests`). On adoption these are covered upstream and can
+be **deleted**. **Keep** the mxaccessgw-specific ones that exercise behavior the lib doesn't own:
+`GalaxyAlarmAttributeMappingTests`, `GalaxyFilterInputSafetyTests`, `GalaxyRepositoryGrpcServiceTests`
+(unless their subjects move upstream too), and the live `IntegrationTests/Galaxy/**`.
+
+## Suggested order
+
+1. ~~Verify the **gRPC-service authz parity** question~~ **DONE (2026-06-25):** wholesale swap is unsafe —
+ per-key browse-subtree filtering is baked into the service body. The service must keep an mxaccessgw
+ subtree-scoping hook (push the provider upstream, or wrap). See the ⚠️ block above.
+2. Decide alarm-attributes: **upstream into the lib (`0.2.0`)** vs keep inline on top of shared interfaces.
+3. If upstreaming: do that in `scadaproj/ZB.MOM.WW.GalaxyRepository` first, publish, bump the version.
+4. `nuget.config` + `csproj` + DI/endpoint wiring; delete the superseded inline files; rebind namespaces
+ in dashboard/alarms/security consumers.
+5. Delete duplicated tests; build zero-warning; run the suite; live-validate browse + alarm watch-list.
+6. Propagate to the scadaproj umbrella index + HistorianGateway's `pending.md` A2 (mark adopted).
+
+## Reference pointers
+
+- **Working consumer (copy this):** `~/Desktop/HistorianGateway/src/ZB.MOM.WW.HistorianGateway.Server/Program.cs`
+ (`AddZbGalaxyRepository` @ ~line 174, `MapZbGalaxyRepository` @ ~line 314) + its `nuget.config` + Server `.csproj`.
+- **Shared lib source:** `~/Desktop/scadaproj/ZB.MOM.WW.GalaxyRepository/` (DI ext at
+ `src/ZB.MOM.WW.GalaxyRepository/DependencyInjection/GalaxyRepositoryServiceCollectionExtensions.cs`).
+- **Tracked in:** HistorianGateway `pending.md` §A2 + `CLAUDE.md` → Known Follow-Ons; scadaproj component normalization.
diff --git a/docs/plans/2026-06-25-galaxyrepository-upstream-gaps-design.md b/docs/plans/2026-06-25-galaxyrepository-upstream-gaps-design.md
new file mode 100644
index 0000000..f7b11bf
--- /dev/null
+++ b/docs/plans/2026-06-25-galaxyrepository-upstream-gaps-design.md
@@ -0,0 +1,103 @@
+# Galaxy Repository — Upstream Gaps + Full Adoption (Design)
+
+**Date:** 2026-06-25 · **Status:** Approved (design) · **Scope:** full adoption — close the upstream gaps in `ZB.MOM.WW.GalaxyRepository`, publish `0.2.0`, wire mxaccessgw to consume it, delete the inline Galaxy code.
+
+Supersedes the open question in `A2-galaxyrepository-adoption-handoff.md` and the `stillpending.md` §2 "Adopt the shared `ZB.MOM.WW.GalaxyRepository` library" item.
+
+## Goal
+
+mxaccessgw and HistorianGateway both browse the Galaxy Repository. The browse implementation was extracted from mxaccessgw into the shared `ZB.MOM.WW.GalaxyRepository` library, which HistorianGateway already consumes (`PackageReference @ 0.1.0`). mxaccessgw still runs its own **inline** copy under `src/ZB.MOM.WW.MxGateway.Server/Galaxy/**`. This work closes the small set of gaps that prevent mxaccessgw from dropping the inline copy, then swaps mxaccessgw to the package so there is **one** Galaxy-browse implementation. The `galaxy_repository.v1` wire contract is unchanged — no client change.
+
+## Gap analysis (evidence-backed)
+
+Two parallel diff audits compared every type/member in mxaccessgw's inline Galaxy surface against the lib. Result: the lib is a near-exact extraction. The divergences are:
+
+### Real upstream gaps (must be added to the lib)
+
+1. **Alarm-attribute discovery — capability gap.** Absent from the lib entirely; consumed by mxaccessgw `Alarms/AlarmWatchListResolver.cs`. Four pieces:
+ - `GalaxyAlarmAttributeRow` (public, 4 props: `FullTagReference`, `SourceObjectReference`, `Area`, `AckCommentSubtag`) — `Galaxy/GalaxyAlarmAttributeRow.cs`.
+ - `IGalaxyRepository.GetAlarmAttributesAsync(CancellationToken = default) → Task>` — `Galaxy/IGalaxyRepository.cs:37`.
+ - `GalaxyRepository.GetAlarmAttributesAsync` impl (`:124-142`), `internal static MapAlarmRow` (`:164-173`), private `AlarmAttributesSql` const (`:328-371`, a CTE selecting alarm-bearing attributes via the `AlarmExtension` primitive, projecting `full_tag_reference`, `source_object_reference`, `area_name`).
+
+2. **Per-identity browse-subtree scoping hook — service-wiring gap.** mxaccessgw's `Grpc/GalaxyRepositoryGrpcService.cs` injects `IGatewayRequestIdentityAccessor` and threads per-API-key browse-subtree globs (`EffectiveConstraints.BrowseSubtrees`) into `DiscoverHierarchy` (`:78-86`), `BrowseChildren` (`:126-143`), and `WatchDeployEvents`/`MapDeployEvent` scoped counts (`:180,196,224-253`). The lib's service hard-codes `browseSubtreeGlobs: null` and documents that subtree scoping is "the responsibility of the hosting gateway's interceptor layer." The projector overloads already accept the globs publicly — only the service wiring is missing. (Verified 2026-06-25; see the ⚠️ block in `A2-galaxyrepository-adoption-handoff.md`.)
+
+### Not a lib gap (resolved host-side)
+
+3. **Dashboard summary — coupling, stays host-side.** mxaccessgw's `GalaxyHierarchyCacheEntry` carries a `DashboardSummary` (`DashboardGalaxySummary` + status/template/category types); the lib deliberately shed it. **No lib change needed:** the lib's `GalaxyHierarchyCacheEntry` already exposes `Objects`, `Index`, all five counts, status, and timestamps — every `DashboardGalaxySummary` field (including `TopTemplates` / `ObjectCategories`) is derivable by grouping `Objects` host-side. Keeping it out of the lib matches the lib's intent and keeps HistorianGateway dashboard-free.
+
+### Not lib gaps (host config, intentional)
+
+- `GalaxyRepositoryOptions.SectionName` (`"MxGateway:Galaxy"` vs lib `"GalaxyRepository"`) — host passes its section path to `AddZbGalaxyRepository`.
+- `SnapshotCachePath` default (Windows path vs empty) — host must supply an explicit path or persistence no-ops.
+- Options **validator** — lib intentionally ships none; mxaccessgw keeps `GatewayOptionsValidator`.
+
+## Upstream design (`ZB.MOM.WW.GalaxyRepository` → 0.2.0)
+
+All changes are **additive and backward-compatible**. HistorianGateway @ 0.1.0 is unaffected; if it ever bumps to 0.2.0 the behavior is identical (default no-op scope provider). HistorianGateway is **not** modified by this work.
+
+### A. Alarm-attribute discovery
+
+Port the four pieces verbatim into the lib (namespace `ZB.MOM.WW.GalaxyRepository`):
+- New `GalaxyAlarmAttributeRow.cs` (public, XML-documented).
+- Add `GetAlarmAttributesAsync` to `IGalaxyRepository` and `GalaxyRepository`, with `MapAlarmRow` (internal) and `AlarmAttributesSql`.
+- Add `[assembly: InternalsVisibleTo("ZB.MOM.WW.GalaxyRepository.Tests")]` if not already present, so `MapAlarmRow` stays unit-testable.
+- Port `GalaxyAlarmAttributeMappingTests` into the lib test project.
+
+### B. Browse-subtree scoping hook — **Approach (A): injectable provider**
+
+- New public interface:
+ ```csharp
+ public interface IGalaxyBrowseScopeProvider
+ {
+ IReadOnlyList? ResolveBrowseSubtrees(ServerCallContext context);
+ }
+ ```
+- Default `NullGalaxyBrowseScopeProvider` returns `null` (no scoping). `AddZbGalaxyRepository` registers it via `TryAddSingleton` so the lib's current behavior is byte-identical and a consumer can override it.
+- Inject `IGalaxyBrowseScopeProvider` into `GalaxyRepositoryGrpcService`. Replace each hard-coded `null` with `scope.ResolveBrowseSubtrees(context)`:
+ - `DiscoverHierarchy` / `BrowseChildren`: pass globs to `ComputeFilterSignature` + `Project`/`ProjectChildren`.
+ - `WatchDeployEvents`: resolve once per stream; restore the scoped-count `MapDeployEvent` (re-projects the hierarchy when globs are present, as mxaccessgw does today).
+- Lib tests: (1) default provider → full hierarchy (current behavior); (2) provider returning a glob → filtered hierarchy + scoped deploy-event counts.
+
+Rejected alternatives: `protected virtual` + subclass (forces consumers to register a subclass instead of mapping the shared service); teaching the lib about API-key constraints (couples the lib to the gateway auth model).
+
+### Versioning
+
+Bump `Directory.Build.props` `` `0.1.0 → 0.2.0`. Adding a ctor dependency to `GalaxyRepositoryGrpcService` is source-breaking only for direct constructors; all consumers use DI / `MapZbGalaxyRepository()`, and the default registration covers it.
+
+### Publish
+
+`dotnet pack -c Release` then `dotnet nuget push` to the Gitea feed (`https://gitea.dohertylan.com/api/packages/dohertj2/nuget/index.json`) with `GITEA_TOKEN`. Verify the version is listed via the Gitea packages API. **Publish before** the mxaccessgw restore (mxaccessgw cannot `PackageReference 0.2.0` until it exists in the feed).
+
+## Host-side design (mxaccessgw adoption)
+
+1. **nuget.config** — add `` under the `dohertj2-gitea` `packageSourceMapping` source (restore fails silently otherwise).
+2. **Server `.csproj`** — ``; remove inline Galaxy compile items (delete the files).
+3. **DI / endpoints** — `services.AddZbGalaxyRepository(configuration, "MxGateway:Galaxy")`; `endpoints.MapZbGalaxyRepository()`; register `GatewayBrowseScopeProvider : IGalaxyBrowseScopeProvider` (reads `IGatewayRequestIdentityAccessor.Current?.EffectiveConstraints.BrowseSubtrees`). Delete `Galaxy/GalaxyRepositoryServiceCollectionExtensions.cs`.
+4. **Dashboard summary relocation** — move `BuildDashboardSummary` / `MapDashboardStatus` / `ResolveCategoryName` out of the (now-shared) cache into a host-side projector that computes `DashboardGalaxySummary` from `cache.Current` (`Objects` + counts + status + timestamps). `DashboardGalaxySummary` + supporting types remain in `Server/Dashboard/`.
+5. **Keep host-side** — `AlarmWatchListResolver` (now calls the lib's `GetAlarmAttributesAsync`), Galaxy options validation (`GatewayOptionsValidator`), the SQL readiness health check.
+6. **Namespace rebind** — `ZB.MOM.WW.MxGateway.Server.Galaxy` → `ZB.MOM.WW.GalaxyRepository` in dashboard (`DashboardGalaxyProjector`, `DashboardBrowseService`, `DashboardSnapshotService`), alarms (`AlarmWatchListResolver`), security (`ConstraintEnforcer`), sessions (`ArrayAddressNormalizer`). Confirm each consumed type is `public` in the lib (the audit confirms `GalaxyTagLookup`, `GalaxyHierarchyIndex.TagsByAddress`, `GalaxyGlobMatcher.IsMatch`, `IGalaxyHierarchyCache.Current`, projectors all are).
+7. **Config** — set an explicit `MxGateway:Galaxy:SnapshotCachePath` (lib default is empty → persistence no-ops). Keep the `MxGateway:Galaxy` section path.
+8. **Tests** — delete duplicated `Tests/Galaxy/**` now owned upstream (`GalaxyHierarchyCacheTests`, `GalaxyHierarchyProjectorTests`, `GalaxyHierarchySnapshotStoreTests`, `GalaxyProtoMapperTests`, `GalaxyHierarchyIndexTests`). Keep mxaccessgw-specific: `GalaxyFilterInputSafetyTests`, the wired `GalaxyRepositoryGrpcServiceTests` browse-subtree filtering test (now exercises the host scope provider end-to-end), the dashboard-summary projector test, and the live `IntegrationTests/Galaxy/**`.
+
+## Verification
+
+- **Lib:** `dotnet build` + `dotnet test` (net10.0) — runs on the Mac.
+- **mxaccessgw Server:** `dotnet build src/ZB.MOM.WW.MxGateway.Server` + targeted `dotnet test src/ZB.MOM.WW.MxGateway.Tests --filter` for Galaxy / Alarm / Constraint / Dashboard — runs on the Mac. The net48 x86 worker is untouched and not built here.
+- Live Galaxy SQL tests stay opt-in (`MXGATEWAY_RUN_LIVE_GALAXY_TESTS=1`).
+- Zero-warning build (both repos enforce analyzers; the lib has `GenerateDocumentationFile=true` → XML-doc all new public members).
+
+## Sequence & risks
+
+1. Lib A + B + lib tests → build/test green.
+2. Bump `0.2.0`, pack, publish to Gitea, verify in feed.
+3. mxaccessgw: nuget.config + csproj + DI + scope provider + dashboard relocation + namespace rebind + delete inline files + delete duplicated tests.
+4. Build Server + run targeted tests green.
+5. (Optional) live browse + alarm-watch-list validation; update `A2-galaxyrepository-adoption-handoff.md`, `stillpending.md` §2, HistorianGateway `pending.md` §A2, scadaproj normalization index.
+
+**Risks:** publish-ordering (must publish before mxaccessgw restore); the dashboard-summary relocation is the fiddliest host edit; namespace-rebind churn spans many files; lib `GenerateDocumentationFile=true` requires XML docs on new public members.
+
+## Out of scope
+
+- Modifying HistorianGateway (stays on 0.1.0; additive change is forward-compatible).
+- Changing the `galaxy_repository.v1` proto / any client.
+- The session-resilience epic and other `stillpending.md` items.
diff --git a/stillpending.md b/stillpending.md
index ad8307d..06a2d2d 100644
--- a/stillpending.md
+++ b/stillpending.md
@@ -63,6 +63,7 @@ These are documented, deliberate, and mostly enforced. Listed so the deferred su
- 🔵 **No server-side / streaming browse search** — `docs/plans/2026-05-28-lazy-browse-design.md:208`.
- 🔵 **Alarm command surface is ack + query only** — no Clear/Disable/Enable/Silence/Shelve/Inhibit; matches the MXAccess alarm-client set. `Worker/MxAccess/AlarmCommandHandler.cs`, shelve/suppress out of scope per `docs/AlarmClientDiscovery.md:60-66`.
- 🟡 **Dashboard EventsHub has no per-session ACL — still true on `main`, planned (epic Phase 4, not started).** Any authenticated dashboard user may still subscribe to any session group (`Dashboard/Hubs/EventsHub.cs` `TODO(per-session-acl)`). The enabling foundation (session `OwnerKeyId`) already merged in epic Phase 1; epic Phase 4 (Tasks 16–19) adds the gRPC session-owner gate, a session tag + group-to-tag config, and EventsHub per-session ACL with a hub-token tag claim. `docs/plans/2026-06-15-session-resilience.md` Phase 4. (See also §8.)
+- 🔵 **Adopt the shared `ZB.MOM.WW.GalaxyRepository` library (cross-repo normalization) — not started.** The inline Galaxy-browse code under `src/ZB.MOM.WW.MxGateway.Server/Galaxy/**` (+ `Grpc/GalaxyRepositoryGrpcService.cs`/`GalaxyProtoMapper.cs`) is the source the shared lib was extracted from; HistorianGateway already consumes it as a `PackageReference @ 0.1.0`. Swapping to the package gives one Galaxy-browse implementation across both sidecars (same `galaxy_repository.v1` wire contract — no client change). Non-trivial: mxaccessgw has extra consumers the lib doesn't cover (alarm watch-list / `GetAlarmAttributesAsync`, dashboard projectors, constraint-authz). The gRPC-service authz-parity gate is **verified (2026-06-25): a wholesale swap to `MapZbGalaxyRepository()` is unsafe** — per-key browse-subtree filtering is baked into mxaccessgw's service body (`Grpc/GalaxyRepositoryGrpcService.cs`), so the service must keep a subtree-scoping hook (push the provider upstream, or wrap), not just rely on the interceptor. Full handoff: **`A2-galaxyrepository-adoption-handoff.md`** (repo root). Tracked cross-repo in HistorianGateway `pending.md` §A2 + scadaproj component normalization.
---