Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/acr-retention/instances.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,9 @@
"",
"🚨 AN INSTALLATION'S IDENTITY IS `owner/name:id`, NOT `id` (MeshWeaver#3438, 2026-09-15).",
"`Hosting__Deployment` is unique inside ONE deployments repository and inside nothing larger.",
"`Systemorph/PartnerRe.Memex` was created at 2026-09-14T21:30Z and its control instance is",
"`memex` too — correctly: it is PartnerRe's memex, at partnerre.meshweaver.cloud — and the",
"`Systemorph/PartnerRe.Memex` was created at 2026-09-14T21:30Z and its instance was then",
"`memex` too (HISTORY — it has since been renamed `partnerre-test`, MeshWeaver#3848; see the",
"`repositories` entry below) — correctly: it was PartnerRe's memex, at partnerre.meshweaver.cloud — and the",
"collision took this lane down the same night with `installation 'memex' is declared by two",
"overlays … so which host answers for it is ambiguous`. NEITHER installation was then asked",
"anything, so `memex` — the one actually exposed to the ACR purge — got no locks either, and",
Expand Down Expand Up @@ -179,7 +180,7 @@
},
"Systemorph/PartnerRe.Memex": {
"role": "deployments",
"reason": "PartnerRe's deployments repository, created 2026-09-14T21:30:38Z (measured 2026-09-15: 2 overlay files). It declares its own control instance `memex` — partnerre.meshweaver.cloud, LIVE and answering /api/version with core 2592e228 — and `partnerre`, the hand-over template for PartnerRe's own estate, which still carries TODO placeholders including its ingress host. Its images are pinned in memexaksacr43rzd6faaix36.azurecr.io, an ACR in PartnerRe's OWN subscription and Entra tenant, which this lane's credential does not reach; the `registries` table below is where that is accounted for. 🚨 That host CHANGED on 2026-09-17, when the estate was torn down and rebuilt in PartnerRe's tenant, and the registry declaration did not follow it — which is the whole of the 2026-09-17 to 2026-09-21 red.",
"reason": "PartnerRe's deployments repository, created 2026-09-14T21:30:38Z (measured 2026-09-15: 2 overlay files). It declares its own instance — partnerre.meshweaver.cloud, LIVE and answering /api/version with core 2592e228 — which was `memex` until PartnerRe.Memex#85 renamed it `partnerre-test` (MeshWeaver#3848: `memex` is the fleet control instance's id, and the combo lane's credential maps are keyed by name; namespace and overlay directory stay `memex`), and `partnerre`, the hand-over template for PartnerRe's own estate, which still carries TODO placeholders including its ingress host. Its images are pinned in memexaksacr43rzd6faaix36.azurecr.io, an ACR in PartnerRe's OWN subscription and Entra tenant, which this lane's credential does not reach; the `registries` table below is where that is accounted for. 🚨 That host CHANGED on 2026-09-17, when the estate was torn down and rebuilt in PartnerRe's tenant, and the registry declaration did not follow it — which is the whole of the 2026-09-17 to 2026-09-21 red.",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(re-posted 2026-10-11; originally by Copilot on 2026-09-26)

This replacement leaves the earlier narrative strings in the same JSON (lines 150–160) saying ClientA's live control instance is still memex, while this reason now says it was renamed to client-a-test. Since the retention record emits both explanations, readers will see conflicting current identities. Update the earlier narrative or explicitly mark it historical.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(re-posted 2026-10-11; originally by @rbuergi on 2026-09-26)

Fixed in e0016b7. The header narrative now says ClientA's instance was memex, is marked HISTORY, and points to the repositories entry for the renamed client-a-test. The file no longer states two current identities. lock-pinned-digests.py --self-test still exits 0.

"declaredAt": "2026-09-15",
"issue": "MeshWeaver#3438"
},
Expand Down
14 changes: 10 additions & 4 deletions .github/scripts/derive-combo-instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ def derive(scans, roster) -> tuple[list[dict[str, str]], list[tuple[str, str, st
"one's verdict would land on the other's `Admin/UpdatePolicy`. TWO ways out exist "
"TODAY, and they do not carry the same cost. (1) Rename one installation — its "
"`Hosting__Deployment` is its inventory identity, so this moves whichever estate "
"owns the one that changes. (2) Key the maps by the qualified `repo:id` and say so "
"owns the one that changes; this is the answer taken the first time it happened "
"(#3848: PartnerRe's `memex` became `partnerre-test`, see "
"Doc/Architecture/ComboGateWiring). (2) Key the maps by the qualified `repo:id` and say so "
"here — this removes the collision and then demands a credential for every "
"installation named, including any in an estate this fleet holds none for. "
"🚨 A THIRD ANSWER IS THE RIGHT ONE IN PRINCIPLE AND IS NOT IMPLEMENTED: scoping "
Expand Down Expand Up @@ -366,14 +368,18 @@ def check(condition: bool, message: str) -> None:
"existing flag expresses it, and still flags it as the looser direction")

# …and two repositories declaring DIFFERENT names is the ordinary multi-repo fleet: no blocker.
# Spelled as the fleet resolved #3848: PartnerRe's installation keeps its `memex` NAMESPACE and
# overlay directory and changes only its `Hosting__Deployment`, which is all this lane keys on.
rows, _, blockers = derive([
_scan("Systemorph/Memex", [
("memex", "memex.systemorph.com", "deployments/aks/memex/values.memex.public.yaml")]),
_scan("Systemorph/PartnerRe.Memex", [
("partnerre", "partnerre.meshweaver.cloud", "deployments/aks/pr/values.pr.yaml")]),
("partnerre-test", "partnerre.meshweaver.cloud",
"deployments/aks/memex/values.memex.yaml")]),
], {})
check(blockers == [] and [r["name"] for r in rows] == ["memex", "partnerre"],
"two repositories declaring different names derive both, with no blocker")
check(blockers == [] and [r["name"] for r in rows] == ["memex", "partnerre-test"],
"two repositories declaring different names derive both, with no blocker — even from "
"overlays in same-named directories")

# Two ids, one host: the second would be verified with the first's credentials.
rows, _, blockers = derive([_scan("Systemorph/Memex", [
Expand Down
79 changes: 75 additions & 4 deletions src/MeshWeaver.Documentation/Data/Architecture/ComboGateWiring.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,13 @@ derived roster before it asks for credentials, and names the instance any map is
`memex-cloud` — and the fleet's overlays declared more than that on the day it was specified, which
is the failure mode a derivation removes rather than a tidiness argument.

🚨 **And what the derivation says TODAY is a refusal, which is the mechanism working.** Re-measured
> **RESOLVED — this paragraph and the next three record the state BEFORE the rename.** PartnerRe's
> installation now answers to `partnerre-test`, the derivation no longer refuses, and it prints five
> unique names: `build`, `memex`, `memex-cloud`, `partnerre-test`, `pearl`. See the
> section *DECIDED: the rename* below. The
> history is kept because the refusal still guards the next repository that declares a taken name.

🚨 **What the derivation said THEN was a refusal, which is the mechanism working.** Measured
2026-09-21 over all three deployments repositories, the fleet declares **five live** installations:
`build` (build.meshweaver.cloud), `memex-cloud` (memex.meshweaver.cloud), `memex`
(memex.systemorph.com) and `pearl` (pearl.meshweaver.cloud) in `Systemorph/Memex`, **and a second
Expand Down Expand Up @@ -530,7 +536,11 @@ assembler refuses by name, *"no repository is known for source 'X'"*, the verdic
worth doing and why it is not urgent — and it unblocks nothing on its own, because the refusal below
comes first.

### 🚨 MEASURED: the three inputs are necessary and NOT sufficient — the roster refuses first
### 🚨 MEASURED: the three inputs are necessary and NOT sufficient — the roster refused first

> **RESOLVED by the rename in the next section.** The roster derives now, so the three inputs are
> once again the whole of what is missing. The text below records why the decision had to come
> before any credential was issued.

This section used to open *"provisioning the three remaining `COMBO_*` inputs makes this lane green
today"* — **while the section above described the derivation refusing.** The page contradicted
Expand Down Expand Up @@ -568,6 +578,67 @@ maps do not exist:
Whichever is chosen, **it is not optional and it is not the operator's** — provisioning the three
inputs against today's tree buys a different red, not a verdict.

### ✅ DECIDED: the rename — PartnerRe's installation is `partnerre-test`

The first way out was taken (#3848). The control instance keeps `memex`; the installation at
partnerre.meshweaver.cloud answers to **`partnerre-test`**
([PartnerRe.Memex#85](https://github.com/Systemorph/PartnerRe.Memex/pull/85)). The id comes from that
record's own `purpose` ("PartnerRe test environment"); `partnerre` was not available (the hand-over
template `deployments/aks/partnerre/values.partnerre.yaml` declares it) and `partnerre-memex` is a
retired registry id.

**What moved is the identity and nothing else.** `Hosting__Deployment` (overlay and record
`extraPortalConfig`), the record's id and file (`mesh/Deployments/partnerre-test.json`) and that
repository's `envs.json` `deployment` changed. The namespace, the Helm release, the overlay
directory (`deployments/aks/memex/`), the database, the vault prefix `memex-`, the host and the
registry instance id (`pluginCatalog.instanceId: partnerre`) did not. The registry authenticates an
instance key by the instance it was registered for, never by `Hosting__Deployment`, so nothing is
re-registered. Because the record id no longer equals the namespace, PartnerRe.Memex's
`check-record-renders-overlay.py` now pairs a record with its overlay by the record's `configPath`.

What the rename changes on the running instance, which has no `Hosting:ReportTo` and lists
`Hosting/PlatformBuilds` itself (so it is its own control plane for both channels):

- its module inventory is filed at `Ops/Modules/partnerre-test` instead of `Ops/Modules/memex`;
- its self-update hand-over (the Local route) announces `deployment: partnerre-test`, and a
`Hosting/InstanceAction` filed on its own mesh must target that id (`RecycleRunner` refuses a
target that is not the instance's own `Hosting:Deployment`).

No mesh the fleet can read syncs that repository's `mesh/Deployments` — memex.systemorph.com's and
memex.meshweaver.cloud's `Deployments/_GitSync` both read `Systemorph/Memex` — so the file rename is
not a delete-and-create anywhere else.

The roster the derivation then prints is five names: `build`, `memex`, `memex-cloud`, `partnerre-test`
and `pearl`. The refusal and its self-test arm stay: they guard the mechanism, and the next
deployments repository to declare a taken name meets the same red.
Comment on lines +611 to +613

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e0016b7. Both earlier measured sections, the "derivation says TODAY" paragraph and "the three inputs are necessary and NOT sufficient", now open with a RESOLVED note. The note gives the five-name roster and says the text below is the pre-rename record. It is kept because the refusal still guards the next repository that declares a taken name. The "TODAY" wording became "THEN", and the remainder list item 0 is struck as done.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(re-posted 2026-10-11; originally by Copilot on 2026-09-26)

These new lines say the roster is now five names, but the earlier “what the derivation says TODAY” section at lines 306–324 still says the fleet contains two memex installations and that derivation refuses. That leaves the operator with contradictory instructions about whether to provision credentials. Update the earlier measured sections (including the text around lines 535–543) to record the resolved client-a-test roster instead of only appending the decision.


### Issuing the two credentials

Each is issued **on the instance it is for**, by a person, and neither can be read back afterwards.

- **`mwi_` key.** `/api/plugins/roll-target` and `/api/plugins/combo` authenticate through
`InstanceRegistryAuthenticator`, which resolves the key against the **called portal's own mesh**
(`MeshWeaverInstance` nodes and their hash index). So the key comes from that portal's
**Settings ▸ Security ▸ Instances** tab (`InstancesSettingsTab`, id `MeshWeaverInstances`):
register a NEW entry with its own id (for example `combo-verify`), which returns the raw key once.
That is additive and revocable on its own. **Never use Reissue on an existing entry**: `ReissueKey`
replaces that entry's key, and the old one stops authenticating the moment it completes. An
instance id is claimed mesh-wide, so on memex.meshweaver.cloud (the registry) pick an id no
installation uses. A registered entry is granted nothing to pull, and these two routes need no
grant.
- **`mw_` token.** **Settings ▸ Security ▸ API Tokens** (`/me/Settings/ApiTokens`), minted while
signed in as a **global admin** of that instance (the `Admin` role in `Admin/_Access`). The token
carries its minter's identity, and the lander's `POST /api/mesh/patch` of `Admin/UpdatePolicy`
needs that grant.

Both go in the **Actions** store of `Systemorph/MeshWeaver` only. `combo-verify.yml` triggers on
`workflow_run` and `workflow_dispatch`, and `check-pr-secret-preflight.py` finds no pull-request lane
that consumes either, so the Dependabot store is not involved. `vars.COMBO_VERIFY_SOURCES` is plain
data. Its value is the union of `pluginCatalog.sources` over every live installation's overlay,
plus the two registry mounts PartnerRe consumes from memex.meshweaver.cloud (`Plugins`,
`Reinsurance`, both already in that union). That gives `Plugins`, `Education`, `Reinsurance`, `Crm`,
`SocialMedia`, `FundReporting` and `PartnerRe`, each mapped to its `repoPath`.

### The three inputs are still the whole of the CREDENTIAL prerequisite — `verify:combo` is not one

The lander does not use the
Expand All @@ -582,8 +653,8 @@ prerequisite that does not exist and blocks the remediation that would actually

So the remainder, in the order it can be done:

0. **Resolve the duplicate `memex`** (the section above). Not the operator's, and not skippable:
until it is resolved the derivation refuses and no instance is verified whatever is provisioned.
0. ~~**Resolve the duplicate `memex`**~~: **decided and done** (the rename above). Until it landed,
the derivation refused and no instance was verified, whatever was provisioned.
1. **Provision the three inputs** (the table above). Nothing in this repository can substitute for
it: a credential is issued at the service that holds it, not derived. Two of the three cannot be
copied from anywhere — an `mwi_` key is hash-only and an `mw_` token is issued once — so they are
Expand Down
Loading