Skip to content

feat(deployment): operator.customerGoverned — a record declares a customer-governed instance - #6374

Merged
rbuergi merged 5 commits into
mainfrom
feat/2604-customer-governance
Oct 10, 2026
Merged

rbuergi merged 5 commits into
mainfrom
feat/2604-customer-governance

Conversation

@rbuergi

@rbuergi rbuergi commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Maintainer decision (2026-10-09), quoted: "Plugins#2604 (+#2495/#2496): on a customer instance, approvals by the customer's own admins under the sole-maintainer rule declared in THEIR record; the instance may request only Restart, Recycle, Logs, Sample — rolls stay with control."

What this adds (core half; it lands FIRST)

  • HostingOperatorSpec.CustomerGoverned (operator.customerGoverned in a record, bool, default false). It is an additive init property, not a primary-constructor parameter, so the record-signature gate does not apply. It marks a CUSTOMER instance whose own global administrators approve the actions the instance requests. The sole maintainer for those approvals is the record's existing operator.maintainer, so "the sole-maintainer rule declared in THEIR record" needs no second field. The control plane reads the flag from the record and nothing renders it into portal config (a test pins that).
  • Two policy rows in the PolicyNotProse register: customer-instance-governance and customer-instance-requests. The date and author appear only there.

A record that does not name the flag (every Systemorph-managed instance) keeps today's control-side approval rule. The test's negative control pins that.

Paired change

Pairs-with: none — additive. The consumer is the Plugins half (Systemorph/MeshWeaver.Plugins PR for #2604, CustomerInstanceRequests + ApprovalGate). It resolves the newest SEALED platform set, so it needs this merged and sealed first.

Implementers: none — no interface member added.

Tests: FluentBuilderTest.ACustomerGovernedRecordSurvivesTheContractAndRendersNothingIntoThePortal checks the JSON round trip, the default-false negative control, and that no portal key is rendered. MeshWeaver.Deployment.Contract.Test: 55/55 passed locally. Release -warnaserror is clean for both touched projects.

Refs Systemorph/MeshWeaver.Plugins#2604 · Refs Systemorph/MeshWeaver.Plugins#2495 · Refs Systemorph/MeshWeaver.Plugins#2496

🤖 Generated with Claude Code

…rator.customerGoverned)

The control plane reads it to let a customer instance's own global administrators
approve the actions the instance requests, under the sole-maintainer rule with the
record's operator.maintainer. Default false keeps the control-side rule. Registers
policies customer-instance-governance and customer-instance-requests.

Refs Systemorph/MeshWeaver.Plugins#2604

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 9, 2026 19:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The policies prematurely claim enforcement, and the new declaration lacks its required German label entry.

2 open findings
What changed in this PR

Adds a deployment-contract flag for customer-governed instances and records its governance policies.

Changes:

  • Adds HostingOperatorSpec.CustomerGoverned.
  • Tests serialization, defaults, and portal-config exclusion.
  • Registers customer governance and request policies.
File Description
InstanceShape.cs Defines the governance flag.
FluentBuilderTest.cs Verifies contract behavior.
PolicyNotProse.md Records governance policies.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +204 to +205
| `customer-instance-governance` | On a CUSTOMER instance (its deployment record sets `operator.customerGoverned: true`), the governed actions the instance requests from its control instance are approved by the instance's OWN global administrators, attested by the instance over its signed per-deployment lane, under `sole-maintainer-approval` with the maintainer declared in THAT record (`operator.maintainer`): the approver is not the requester unless the requester is that declared maintainer. No administrator of the control instance is required, and a control-side approval does not stand in for the customer's. Records without the flag (every Systemorph-managed instance) keep the control-side rule unchanged. Mechanism: MeshWeaver.Plugins `CustomerInstanceRequests` + `ActionsExecutor.ApprovalGate`. **Owed:** the instance-side request and approval surface and the result return path for `Logs`/`Sample` (tracked on Systemorph/MeshWeaver.Plugins#2604). Refs Systemorph/MeshWeaver.Plugins#2495. | in force | 2026-10-09 | maintainer |
| `customer-instance-requests` | A customer instance may request exactly `Restart`, `Recycle`, `Logs` and `Sample` from its control instance; every other kind is refused by name. Rolls stay with the control instance: the self-update routed roll is governed there by the record's update policy, and a customer administrator cannot request an arbitrary roll. Refs Systemorph/MeshWeaver.Plugins#2496. | in force | 2026-10-09 | maintainer |

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.

Kept in force, deliberately: the maintainer DECIDED both rules on 2026-10-09 (quoted in the PR body), so the register states the rule in force, and the missing mechanism is carried as Owed: in the row. The register already uses that shape for a decided rule whose mechanism is still landing (module-live-update-default: in force, with an Owed clause). proposed is for a rule nobody has decided yet; using it here would read as "not decided", which is the opposite of the case.

Comment on lines +832 to +833
[Description("Customer-governed: the instance's own global administrators approve the actions it requests")]
public bool CustomerGoverned { get; init; }

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 094d54e: added the HostingOperatorSpec / CustomerGoverned English/German row to the labels appendix in ConfiguringAnInstanceFromAspire.md.

rbuergi and others added 2 commits October 9, 2026 21:45
…bels appendix

Refs Systemorph/MeshWeaver.Plugins#2604

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

   13 files     13 suites   33m 11s ⏱️
7 389 tests 7 389 ✅ 0 💤 0 ❌
7 401 runs  7 401 ✅ 0 💤 0 ❌

Results for commit b04cd6e.

♻️ This comment has been updated with latest results.

# Conflicts:
#	src/MeshWeaver.Documentation/Data/Architecture/PolicyNotProse.md
# Conflicts:
#	src/MeshWeaver.Documentation/Data/Architecture/PolicyNotProse.md
@rbuergi
rbuergi merged commit e67b712 into main Oct 10, 2026
@rbuergi
rbuergi deleted the feat/2604-customer-governance branch October 10, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants