From 4289a224621fffa4aeb63624c26441cc8c4bff78 Mon Sep 17 00:00:00 2001 From: sammiller Date: Wed, 28 Oct 2026 17:40:12 +0800 Subject: [PATCH 1/3] =?UTF-8?q?docs:=20record=20the=20owner's=20decision?= =?UTF-8?q?=20on=20hosted=20subscriptions=20and=20self-hosted=20mode=20(AD?= =?UTF-8?q?-0021=20=C2=A713a)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the official hosted center, center-mediated node connectivity, execution, monitoring and control, and MCP access are subscription services with no permanent free hosted-node allowance; essential sign-in, account, billing, security and recovery stay ungated; free use remains available through self-hosting, which needs no official subscription and gets a built-in default with optional operator limits. The mode is explicit and fails closed; availability never bypasses authentication, ownership, authorization, AGENT/HUMAN separation, audit or resource controls. Prices, trials, node limits and traffic allowances stay open (H-07). Adds R-CTR-017 and its traceability. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW --- docs/architecture/14-commercial-operations.md | 2 +- .../AD-0021-central-access-go-center.md | 13 ++++++++++--- docs/product/product-definition.md | 2 +- docs/product/requirements.md | 1 + docs/traceability/model.json | 16 ++++++++++++++++ 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/docs/architecture/14-commercial-operations.md b/docs/architecture/14-commercial-operations.md index c16eb64..09be8c2 100644 --- a/docs/architecture/14-commercial-operations.md +++ b/docs/architecture/14-commercial-operations.md @@ -2,7 +2,7 @@ Decisions: [AD-0009](../decisions/AD-0009-cloud-relay-and-cost-controls.md) (cost controls), [AD-0010](../decisions/AD-0010-commerce-and-entitlements.md) (commerce). Requirements: R-COM-001..004, R-OPS-001..006, R-CLOUD-006. -**Amended 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md) (target; AF-CTR-02, AF-PLAT-01, AF-OPS-01).** The center is a Go service on Neon/PostgreSQL: in §7.1 the D1 dimensions are replaced by the PostgreSQL (Neon) compute and storage dimensions of the official deployment, and the C# host and `FleetHub` rows are history; readiness checks PostgreSQL reachability instead of D1; backups are Neon's point-in-time history (retention per the project's plan) plus the restore drill of AF-CTR-02, instead of D1 Time Travel; the D1 runbooks become PostgreSQL runbooks (connection budget, pooler errors, failover). Node connections terminate in the Container (AD-0021 §9), so while any node is connected the Container instance runs and `sleepAfter` no longer bounds its time: the daily worst case of §7.4 includes one always-on instance per `max_instances` of the deployment's instance type, and AF-PLAT-01 meters the Neon dimensions. The plan table of §2 is the earlier launch configuration (Free: relay nodes 0 predates center access); plan contents are an open owner question (AD-0021, H-07), and "never affected: local execution and LAN" reads "never affected: node-local execution of accepted work". +**Amended 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md) (target; AF-CTR-02, AF-PLAT-01, AF-OPS-01).** The center is a Go service on Neon/PostgreSQL: in §7.1 the D1 dimensions are replaced by the PostgreSQL (Neon) compute and storage dimensions of the official deployment, and the C# host and `FleetHub` rows are history; readiness checks PostgreSQL reachability instead of D1; backups are Neon's point-in-time history (retention per the project's plan) plus the restore drill of AF-CTR-02, instead of D1 Time Travel; the D1 runbooks become PostgreSQL runbooks (connection budget, pooler errors, failover). Node connections terminate in the Container (AD-0021 §9), so while any node is connected the Container instance runs and `sleepAfter` no longer bounds its time: the daily worst case of §7.4 includes one always-on instance per `max_instances` of the deployment's instance type, and AF-PLAT-01 meters the Neon dimensions. The plan table of §2 is the earlier launch configuration (Free: relay nodes 0 predates center access); plan contents are decided in structure by AD-0021 §13a (center-mediated services of the official hosted center are subscription services; no permanent free hosted-node allowance; essential operations ungated; self-hosting free) while prices, trials, node limits and traffic allowances remain open (H-07), and "never affected: local execution and LAN" reads "never affected: node-local execution of accepted work". ## 1. Operating model diff --git a/docs/decisions/AD-0021-central-access-go-center.md b/docs/decisions/AD-0021-central-access-go-center.md index 5207374..9107388 100644 --- a/docs/decisions/AD-0021-central-access-go-center.md +++ b/docs/decisions/AD-0021-central-access-go-center.md @@ -1,6 +1,6 @@ # AD-0021 — Central access through a configured center; a Go center on Neon/PostgreSQL; LAN out of current delivery -- Status: Accepted (2026-10-28; the product owner's decisions of 2026-10-27 and 2026-10-28, and the design choices made under them, separated in §17) +- Status: Accepted (2026-10-28; the product owner's decisions of 2026-10-27 and 2026-10-28, and the design choices made under them, separated in §17; amended 2026-10-28 by the product owner's decision on hosted subscriptions and self-hosted mode, §13a) - Amends: [AD-0002](AD-0002-platform-scope.md) (the cloud store named in its scope), [AD-0003](AD-0003-architecture-and-runtimes.md) §3 (the cloud runtime), [AD-0004](AD-0004-contracts-and-state.md) (the center as a transport participant), [AD-0007](AD-0007-ai-integration.md) §1 (the MCP route), [AD-0009](AD-0009-cloud-relay-and-cost-controls.md) §1, §2, §5 and §8 (the center, the node channel, remote commands, storage), [AD-0010](AD-0010-commerce-and-entitlements.md) (implementation in the Go center; no price or limit decided), [AD-0011](AD-0011-identity-and-login.md) (the endpoints and a third credential kind, the agent grant), [AD-0015](AD-0015-direction-editions-roadmap.md) §2 and §4 (editions, LAN scope) - Supersedes for current delivery: [AD-0008](AD-0008-lan-trust-and-placement.md) (kept as history; LAN distribution becomes roadmap RM-19) - Evidence: Cloud [#109](https://github.com/ArcForges/Cloud/pull/109) (the C# Hello reading Neon through the deployed Worker and Container, artifact `0.1.0-ci.417.1`, deployment run 40550306117) and Cloud [#110](https://github.com/ArcForges/Cloud/pull/110) (the same Hello in Go, artifact `0.1.0-ci.424.1`, deployment run 40563267870), both called by the published C# gRPC-Web client on 2026-10-27; health of `arcforges.com/api/healthz` on 2026-10-28: revision `faaffeade06f633fd48b10d0f17ff10c9a12ac8f`, `runtime=go`, `nativeAot=false`, `helloBackend=neon-postgresql`. @@ -67,6 +67,13 @@ The product owner decided a different product architecture: user-owned C# execut 12. **LAN leaves current delivery.** LAN discovery, LAN pairing, automatic cross-machine scheduling, distributed input and output transfer, and inter-node compiler-cache sharing are not built. Tasks AF-LAN-01, AF-LAN-02 and AF-LAN-03 are superseded; requirements R-LAN-001 … R-LAN-011 are out of current delivery; [AD-0008](AD-0008-lan-trust-and-placement.md) and [09](../architecture/09-lan.md) are kept as history; LAN distribution is roadmap RM-19. Published contracts and fields stay compatible: `arcforges.peer.v1`, `PeerService`, `NodeEnrollmentService.IssueNodeCertificate`, `GetLanHints` and `ReportLanEndpoints` stay in `v1` and are refused as not served. Same-machine cache reuse stays, and no dedicated WSL integration returns ([AD-0018](AD-0018-native-platforms-without-wsl-integration.md)). 13. **Editions and hosting.** User-owned compute and the open-source software (the node, CLI, clients and center under their licences) are distinct from the official hosted center, which is a service. A self-hosted center needs no official service. The earlier promise of account-free, center-free normal operation ([AD-0015](AD-0015-direction-editions-roadmap.md) §2) is withdrawn: normal operation uses a center, official or self-hosted. This record decides no price, free allowance, device limit or package; existing limits in [10](../architecture/10-cloud.md) §5 are current settings to assess, and prices remain H-07. +13a. **Hosted subscriptions and self-hosted mode** (the product owner's decision of 2026-10-28, recorded after this record was first accepted). + - **Official hosted center.** Center-mediated node connectivity, execution, monitoring and control, and MCP access are subscription services. There is no permanent free allowance of hosted nodes at this stage. Essential sign-in, account, billing, security and recovery operations stay available without a subscription. + - **Free use** remains available through self-hosting. A self-hosted center never requires an official ArcForges subscription. + - **Self-hosted mode** is an explicitly configured center mode. In it, a built-in default enables the self-hostable capabilities that are available, with optional operator-configured feature and resource limits. External services (e-mail, push, payments, storage) still need the operator's own configuration and credentials. + - **Fail closed.** The center's mode is explicit configuration. Missing or invalid configuration in official-hosted mode never silently enables every feature: without a valid subscription entitlement, a gated feature stays unavailable. + - **No bypass.** Feature availability never bypasses authentication, device ownership, authorization, AGENT/HUMAN separation, audit or resource controls; it is one more check after them. + - **Values are configuration.** Exact prices, trials, node limits and traffic allowances remain separate owner decisions (Plan acceptance register H-07, still open for them). The plan catalogue is configuration: development fixtures (tests and the acceptance environment's attributable test identities) are distinct from production settings, and production sales are not activated by this decision. 14. **Retained business capabilities** move to the Go center unchanged in meaning: identity and login ([AD-0011](AD-0011-identity-and-login.md)), devices, entitlements and commerce (Paddle, Google Play; [AD-0010](AD-0010-commerce-and-entitlements.md)), notifications, support, audit, configuration and operating budgets. Their remaining planned tasks are re-targeted to the Go center. 15. **The C# center is retired after its replacement is proven.** The C# Cloud host stays in the image only as the Hello rollback path and the `proof` environment's foundation until AF-CTR-09's exit criteria hold: every active route served by Go on the deployed revision, the PostgreSQL recovery drill passed, and one release on Go without rollback. Released artifacts, images and historical evidence are kept; nothing is unpublished or deleted. 16. **Verification.** The Go center is verified on both native legs ([AD-0020](AD-0020-post-push-verification-and-required-checks.md)): format, vet, static analysis, unit tests, generation drift and native builds on Windows and Linux; real PostgreSQL integration tests, the race detector and the container image on Linux, where Docker and cgo are available. Cross-compilation is never counted as another platform's execution. The engineering controls of the C# projects are carried over with explicit dispositions (AF-CTR-02). @@ -77,8 +84,8 @@ The product owner decided a different product architecture: user-owned C# execut These are not decided by this record and block only what their entry names ([Plan acceptance register](https://github.com/ArcForges/Plan/blob/main/acceptance-register.md) H-07): -1. **Plan contents under center access.** Which center features are gated, and the limits per plan (for example the number of nodes or devices per account and the free configuration). The current table of [14](../architecture/14-commercial-operations.md) §2 (Free: relay nodes 0) predates center access, under which a node needs the center for ordinary use; until the owner decides, it is an existing setting to assess, and activation of the center surfaces in production (AF-PROD-01) waits for the decision. -2. **Entitlements on self-hosted centers.** Whether a self-hosted center applies a plan catalogue at all. The proposed default, for the owner to confirm, is that a self-hosted center's operator configures its own catalogue, and that an unconfigured self-hosted center grants every center feature to its accounts. +1. **Plan contents under center access.** *Partly decided 2026-10-28 (§13a):* the gated features of the official hosted center are its center-mediated services, there is no permanent free hosted-node allowance, and essential operations stay ungated. Still open: exact prices, trials, node limits and traffic allowances; activation of the center surfaces and of sales in production (AF-PROD-01) waits for them. +2. **Entitlements on self-hosted centers.** *Decided 2026-10-28 (§13a):* no official subscription is required; an explicitly configured self-hosted mode enables the available self-hostable capabilities by a built-in default, with optional operator-configured feature and resource limits. ## Delivery state diff --git a/docs/product/product-definition.md b/docs/product/product-definition.md index 8fe8fd2..3acd768 100644 --- a/docs/product/product-definition.md +++ b/docs/product/product-definition.md @@ -99,7 +99,7 @@ Journeys are specified in [experience/journeys.md](../experience/journeys.md). - **Plan definitions are data.** Plans are defined in the existing Entitlement module and can change without code changes. The table above is the launch configuration. - **Later cloud services.** Hosted history and team administration are accepted future work (roadmap RM-06, RM-07). -*Amended 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md) §2, §13.* The promise of account-free, center-free normal operation above is withdrawn: ordinary use goes through a configured center, official or self-hosted, while node-accepted work never depends on the center's availability. User-owned compute and the open-source software are distinct from the official hosted center, which is a service; a self-hosted center needs no official service. The LAN row and the "no cloud dependency for local or LAN work" bullet are out of current delivery (LAN is roadmap RM-19). No price, free allowance, device limit or package is decided by this amendment; the table is the earlier launch configuration, to be re-decided by the owner (H-07). +*Amended 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md) §2, §13.* The promise of account-free, center-free normal operation above is withdrawn: ordinary use goes through a configured center, official or self-hosted, while node-accepted work never depends on the center's availability. User-owned compute and the open-source software are distinct from the official hosted center, which is a service; a self-hosted center needs no official service. The LAN row and the "no cloud dependency for local or LAN work" bullet are out of current delivery (LAN is roadmap RM-19). No price, free allowance, device limit or package is decided by this amendment; the table is the earlier launch configuration, to be re-decided by the owner (H-07). *Owner decision of 2026-10-28 (AD-0021 §13a):* on the official hosted center, center-mediated node connectivity, execution, monitoring and control, and MCP access are subscription services, with no permanent free hosted-node allowance at this stage; sign-in, account, billing, security and recovery stay available without a subscription; free use remains available through self-hosting, which never requires an official subscription. Prices, trials, node limits and traffic allowances remain open (H-07). ## 6. Platform scope diff --git a/docs/product/requirements.md b/docs/product/requirements.md index 5b4be77..1abc201 100644 --- a/docs/product/requirements.md +++ b/docs/product/requirements.md @@ -200,6 +200,7 @@ Added 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md). | R-CTR-014 | The Go code carries the effective engineering controls of the C# projects with a recorded disposition for each (toolchain and dependency pinning, formatting and analysis, tests including race and real PostgreSQL, contract drift, hooks, Dependabot, supply-chain checks, sealed candidates), verified on both native legs. | The control mapping and host verification evidence. | | R-CTR-015 | The server migration is complete: every C#, D1 and Worker behaviour has a recorded Go and PostgreSQL implementation or disposition, implemented retained domain logic is ported with parity tests, and the C# center's active paths are retired after their replacement and recovery are proven, keeping released artifacts and history. | Migration inventory; parity tests; deployed image contents. | | R-CTR-016 | The delivered center architecture is accepted end to end on the real deployment with real Windows and Linux nodes, real clients and a real MCP session, and missing evidence is recorded, never reported as passed. | The AF-CTR-10 acceptance record. | +| R-CTR-017 | The center's mode is explicit configuration. In official-hosted mode, center-mediated node connectivity, execution, monitoring and control, and MCP access need an active subscription entitlement, with no permanent free hosted-node allowance, while sign-in, account, billing, security and recovery operations need none; missing or invalid configuration never enables a gated feature. In self-hosted mode no official subscription is required: a built-in default enables the available self-hostable capabilities, with optional operator-configured feature and resource limits. Feature availability is checked after, never instead of, authentication, device ownership, authorization, AGENT/HUMAN separation, audit and resource controls. Plan values are configuration, with development fixtures distinct from production settings. | Tests per mode: a subscription-less official-mode account keeps essential operations and is refused gated ones; missing or invalid official configuration enables nothing gated; self-hosted defaults and operator limits apply without any official subscription; gating never admits an unauthenticated, foreign-device, AGENT-for-HUMAN or unaudited call. | ## R-UX — User surfaces diff --git a/docs/traceability/model.json b/docs/traceability/model.json index 5506a66..8c2068e 100644 --- a/docs/traceability/model.json +++ b/docs/traceability/model.json @@ -2007,6 +2007,22 @@ "AF-CTR-10" ], "verification": "The AF-CTR-10 acceptance record." + }, + { + "id": "R-CTR-017", + "design": [ + "docs/decisions/AD-0021-central-access-go-center.md", + "docs/decisions/AD-0010-commerce-and-entitlements.md", + "docs/architecture/14-commercial-operations.md" + ], + "tasks": [ + "AF-CTR-02", + "AF-CTR-03", + "AF-CTR-05", + "AF-CTR-07", + "AF-CLD-03" + ], + "verification": "Tests per center mode and gate (official-hosted, self-hosted, invalid configuration)." } ] } From ffb9a15a8bf90a31b158d9fff04358d0650b1b35 Mon Sep 17 00:00:00 2001 From: sammiller Date: Wed, 28 Oct 2026 17:44:57 +0800 Subject: [PATCH 2/3] =?UTF-8?q?docs:=20signatures=20and=20digests=20cover?= =?UTF-8?q?=20the=20transmitted=20bytes=20(AD-0021=20=C2=A710)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Go and C# Protobuf encoders produce equivalent but not always identical bytes, so signed calls and request digests are verified over the bytes as sent, never over a re-encoding. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW --- docs/decisions/AD-0021-central-access-go-center.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/decisions/AD-0021-central-access-go-center.md b/docs/decisions/AD-0021-central-access-go-center.md index 9107388..8076ee8 100644 --- a/docs/decisions/AD-0021-central-access-go-center.md +++ b/docs/decisions/AD-0021-central-access-go-center.md @@ -51,7 +51,7 @@ The product owner decided a different product architecture: user-owned C# execut | Secrets (D3) | Never; redacted by the node | No | Minimization, redaction, permissions and audit of [11](../architecture/11-security-privacy.md) apply; the center logs no command line, environment, output or file content. - **Routed calls are signed end to end** (T-11 unchanged). The center signs every call it routes to a node with its ES256 command-signing key ([AD-0009](AD-0009-cloud-relay-and-cost-controls.md) §5, V-N05): the signed payload carries the key ID, the target node, the caller principal and origin, the command ID, the method, a digest of the request and an expiry of at most 5 minutes. The node verifies the signature against the center keys it received at enrollment and with credential refresh, the target, the expiry (±120 s skew) and its local policy before it acts, and signs its result with its node key (generated at sign-in, with its public key registered by `CompleteNodeSignIn`; the center's public keys reach the node with `CompleteNodeSignIn` and `RefreshNodeSession`, AF-CTR-04). A call that arrives after its expiry is never executed. Neither the Worker that passes the connection through nor anything else on the path can inject or alter a call. + **Routed calls are signed end to end** (T-11 unchanged). The center signs every call it routes to a node with its ES256 command-signing key ([AD-0009](AD-0009-cloud-relay-and-cost-controls.md) §5, V-N05): the signed payload carries the key ID, the target node, the caller principal and origin, the command ID, the method, a digest of the request and an expiry of at most 5 minutes. The node verifies the signature against the center keys it received at enrollment and with credential refresh, the target, the expiry (±120 s skew) and its local policy before it acts, and signs its result with its node key (generated at sign-in, with its public key registered by `CompleteNodeSignIn`; the center's public keys reach the node with `CompleteNodeSignIn` and `RefreshNodeSession`, AF-CTR-04). A call that arrives after its expiry is never executed. Neither the Worker that passes the connection through nor anything else on the path can inject or alter a call. Signatures and request digests cover the exact serialized bytes as transmitted: a verifier never re-encodes a decoded message to check a signature or a digest, because the Go and C# Protobuf encoders produce equivalent but not always identical bytes (for example the position of `oneof` fields; AF-CTR-01 exchange evidence). 11. **Failure behaviour.** | Event | Behaviour | From 4d871f275f98e0cf40d6ace79cca2504bd0062e1 Mon Sep 17 00:00:00 2001 From: sammiller Date: Wed, 28 Oct 2026 17:50:31 +0800 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20enrollment=20and=20lapse,=20feature?= =?UTF-8?q?=20keys=20and=20review=20follow-ups=20(AD-0021=20=C2=A713a)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Record the ungated enrollment and the closing of a lapsed subscription's node connection, the feature keys of the hosted services, the plan-structure reference in §13 and §17, the R-COM note pointing to §13a, and the Contracts #117 evidence of the byte-order rule. Traceability follows the Plan. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW --- docs/architecture/14-commercial-operations.md | 2 +- docs/decisions/AD-0021-central-access-go-center.md | 10 ++++++---- docs/product/requirements.md | 2 +- docs/traceability/model.json | 5 ++++- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/architecture/14-commercial-operations.md b/docs/architecture/14-commercial-operations.md index 09be8c2..71452a2 100644 --- a/docs/architecture/14-commercial-operations.md +++ b/docs/architecture/14-commercial-operations.md @@ -2,7 +2,7 @@ Decisions: [AD-0009](../decisions/AD-0009-cloud-relay-and-cost-controls.md) (cost controls), [AD-0010](../decisions/AD-0010-commerce-and-entitlements.md) (commerce). Requirements: R-COM-001..004, R-OPS-001..006, R-CLOUD-006. -**Amended 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md) (target; AF-CTR-02, AF-PLAT-01, AF-OPS-01).** The center is a Go service on Neon/PostgreSQL: in §7.1 the D1 dimensions are replaced by the PostgreSQL (Neon) compute and storage dimensions of the official deployment, and the C# host and `FleetHub` rows are history; readiness checks PostgreSQL reachability instead of D1; backups are Neon's point-in-time history (retention per the project's plan) plus the restore drill of AF-CTR-02, instead of D1 Time Travel; the D1 runbooks become PostgreSQL runbooks (connection budget, pooler errors, failover). Node connections terminate in the Container (AD-0021 §9), so while any node is connected the Container instance runs and `sleepAfter` no longer bounds its time: the daily worst case of §7.4 includes one always-on instance per `max_instances` of the deployment's instance type, and AF-PLAT-01 meters the Neon dimensions. The plan table of §2 is the earlier launch configuration (Free: relay nodes 0 predates center access); plan contents are decided in structure by AD-0021 §13a (center-mediated services of the official hosted center are subscription services; no permanent free hosted-node allowance; essential operations ungated; self-hosting free) while prices, trials, node limits and traffic allowances remain open (H-07), and "never affected: local execution and LAN" reads "never affected: node-local execution of accepted work". +**Amended 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md) (target; AF-CTR-02, AF-PLAT-01, AF-OPS-01).** The center is a Go service on Neon/PostgreSQL: in §7.1 the D1 dimensions are replaced by the PostgreSQL (Neon) compute and storage dimensions of the official deployment, and the C# host and `FleetHub` rows are history; readiness checks PostgreSQL reachability instead of D1; backups are Neon's point-in-time history (retention per the project's plan) plus the restore drill of AF-CTR-02, instead of D1 Time Travel; the D1 runbooks become PostgreSQL runbooks (connection budget, pooler errors, failover). Node connections terminate in the Container (AD-0021 §9), so while any node is connected the Container instance runs and `sleepAfter` no longer bounds its time: the daily worst case of §7.4 includes one always-on instance per `max_instances` of the deployment's instance type, and AF-PLAT-01 meters the Neon dimensions. The plan table of §2 is the earlier launch configuration (Free: relay nodes 0 predates center access); plan contents are decided in structure by AD-0021 §13a (center-mediated services of the official hosted center are subscription services; no permanent free hosted-node allowance; essential operations ungated; self-hosting free) while prices, trials, node limits and traffic allowances remain open (H-07); the feature keys are `center.nodes` (node connectivity), `center.execute` (center-routed execution and file and workspace operations), `remote.view` (monitoring), `remote.control` (control), `center.mcp` (MCP access) and `push` (notifications), and "never affected: local execution and LAN" reads "never affected: node-local execution of accepted work". ## 1. Operating model diff --git a/docs/decisions/AD-0021-central-access-go-center.md b/docs/decisions/AD-0021-central-access-go-center.md index 8076ee8..dc4873f 100644 --- a/docs/decisions/AD-0021-central-access-go-center.md +++ b/docs/decisions/AD-0021-central-access-go-center.md @@ -51,7 +51,7 @@ The product owner decided a different product architecture: user-owned C# execut | Secrets (D3) | Never; redacted by the node | No | Minimization, redaction, permissions and audit of [11](../architecture/11-security-privacy.md) apply; the center logs no command line, environment, output or file content. - **Routed calls are signed end to end** (T-11 unchanged). The center signs every call it routes to a node with its ES256 command-signing key ([AD-0009](AD-0009-cloud-relay-and-cost-controls.md) §5, V-N05): the signed payload carries the key ID, the target node, the caller principal and origin, the command ID, the method, a digest of the request and an expiry of at most 5 minutes. The node verifies the signature against the center keys it received at enrollment and with credential refresh, the target, the expiry (±120 s skew) and its local policy before it acts, and signs its result with its node key (generated at sign-in, with its public key registered by `CompleteNodeSignIn`; the center's public keys reach the node with `CompleteNodeSignIn` and `RefreshNodeSession`, AF-CTR-04). A call that arrives after its expiry is never executed. Neither the Worker that passes the connection through nor anything else on the path can inject or alter a call. Signatures and request digests cover the exact serialized bytes as transmitted: a verifier never re-encodes a decoded message to check a signature or a digest, because the Go and C# Protobuf encoders produce equivalent but not always identical bytes (for example the position of `oneof` fields; AF-CTR-01 exchange evidence). + **Routed calls are signed end to end** (T-11 unchanged). The center signs every call it routes to a node with its ES256 command-signing key ([AD-0009](AD-0009-cloud-relay-and-cost-controls.md) §5, V-N05): the signed payload carries the key ID, the target node, the caller principal and origin, the command ID, the method, a digest of the request and an expiry of at most 5 minutes. The node verifies the signature against the center keys it received at enrollment and with credential refresh, the target, the expiry (±120 s skew) and its local policy before it acts, and signs its result with its node key (generated at sign-in, with its public key registered by `CompleteNodeSignIn`; the center's public keys reach the node with `CompleteNodeSignIn` and `RefreshNodeSession`, AF-CTR-04). A call that arrives after its expiry is never executed. Neither the Worker that passes the connection through nor anything else on the path can inject or alter a call. Signatures and request digests cover the exact serialized bytes as transmitted: a verifier never re-encodes a decoded message to check a signature or a digest, because the Go and C# Protobuf encoders produce equivalent but not always identical bytes (for example the position of `oneof` fields; AF-CTR-01 exchange evidence, Contracts PR #117, `docs/engineering-controls.md`). 11. **Failure behaviour.** | Event | Behaviour | @@ -62,23 +62,25 @@ The product owner decided a different product architecture: user-owned C# execut | New command for an offline node | Refused with `UNAVAILABLE/node_offline`; the center does not queue task submissions, because it does not persist task specifications (the earlier per-node envelope buffer of [10](../architecture/10-cloud.md) §3.6 is not built) | | Database outage | Calls that need the database fail with `UNAVAILABLE` and retry advice; node-accepted work continues | | Revocation of a node credential, session or agent grant | The next call with it is refused; a revoked node's connection is closed; accepted tasks continue at the node, and only a still-authorized principal (or the node's local owner) can read or cancel them | - | Entitlement change | New center-routed calls are checked against the current entitlement; accepted tasks are not cancelled | + | Entitlement change | New center-routed calls are checked against the current entitlement; a lapsed subscription closes the node's connection at the next entitlement check (§13a); accepted tasks are not cancelled | | Timeouts | Every center-routed call carries a deadline (≤ 55 s for waits); expiry returns the current state, never a guess | 12. **LAN leaves current delivery.** LAN discovery, LAN pairing, automatic cross-machine scheduling, distributed input and output transfer, and inter-node compiler-cache sharing are not built. Tasks AF-LAN-01, AF-LAN-02 and AF-LAN-03 are superseded; requirements R-LAN-001 … R-LAN-011 are out of current delivery; [AD-0008](AD-0008-lan-trust-and-placement.md) and [09](../architecture/09-lan.md) are kept as history; LAN distribution is roadmap RM-19. Published contracts and fields stay compatible: `arcforges.peer.v1`, `PeerService`, `NodeEnrollmentService.IssueNodeCertificate`, `GetLanHints` and `ReportLanEndpoints` stay in `v1` and are refused as not served. Same-machine cache reuse stays, and no dedicated WSL integration returns ([AD-0018](AD-0018-native-platforms-without-wsl-integration.md)). -13. **Editions and hosting.** User-owned compute and the open-source software (the node, CLI, clients and center under their licences) are distinct from the official hosted center, which is a service. A self-hosted center needs no official service. The earlier promise of account-free, center-free normal operation ([AD-0015](AD-0015-direction-editions-roadmap.md) §2) is withdrawn: normal operation uses a center, official or self-hosted. This record decides no price, free allowance, device limit or package; existing limits in [10](../architecture/10-cloud.md) §5 are current settings to assess, and prices remain H-07. +13. **Editions and hosting.** User-owned compute and the open-source software (the node, CLI, clients and center under their licences) are distinct from the official hosted center, which is a service. A self-hosted center needs no official service. The earlier promise of account-free, center-free normal operation ([AD-0015](AD-0015-direction-editions-roadmap.md) §2) is withdrawn: normal operation uses a center, official or self-hosted. This record decides no price, free allowance, device limit or package (the structure of hosted plans is decided in §13a); existing limits in [10](../architecture/10-cloud.md) §5 are current settings to assess, and prices remain H-07. 13a. **Hosted subscriptions and self-hosted mode** (the product owner's decision of 2026-10-28, recorded after this record was first accepted). - **Official hosted center.** Center-mediated node connectivity, execution, monitoring and control, and MCP access are subscription services. There is no permanent free allowance of hosted nodes at this stage. Essential sign-in, account, billing, security and recovery operations stay available without a subscription. - **Free use** remains available through self-hosting. A self-hosted center never requires an official ArcForges subscription. - **Self-hosted mode** is an explicitly configured center mode. In it, a built-in default enables the self-hostable capabilities that are available, with optional operator-configured feature and resource limits. External services (e-mail, push, payments, storage) still need the operator's own configuration and credentials. - **Fail closed.** The center's mode is explicit configuration. Missing or invalid configuration in official-hosted mode never silently enables every feature: without a valid subscription entitlement, a gated feature stays unavailable. - **No bypass.** Feature availability never bypasses authentication, device ownership, authorization, AGENT/HUMAN separation, audit or resource controls; it is one more check after them. + - **Enrollment and lapse** (design choices under this decision). Node sign-in and device association are account and device operations and stay ungated; the node's connection to the center is the gated connectivity. When a subscription lapses, the center refuses new gated calls and closes the node's existing connection at its next entitlement check, no later than the node's next credential refresh; node-accepted work continues at the node (§11). + - **Feature keys.** The catalogue's feature keys for these services are `center.nodes` (node connectivity), `center.execute` (center-routed execution and file and workspace operations), `remote.view` (monitoring), `remote.control` (control), `center.mcp` (MCP access) and `push` (notifications); essential operations have no key and are never gated. - **Values are configuration.** Exact prices, trials, node limits and traffic allowances remain separate owner decisions (Plan acceptance register H-07, still open for them). The plan catalogue is configuration: development fixtures (tests and the acceptance environment's attributable test identities) are distinct from production settings, and production sales are not activated by this decision. 14. **Retained business capabilities** move to the Go center unchanged in meaning: identity and login ([AD-0011](AD-0011-identity-and-login.md)), devices, entitlements and commerce (Paddle, Google Play; [AD-0010](AD-0010-commerce-and-entitlements.md)), notifications, support, audit, configuration and operating budgets. Their remaining planned tasks are re-targeted to the Go center. 15. **The C# center is retired after its replacement is proven.** The C# Cloud host stays in the image only as the Hello rollback path and the `proof` environment's foundation until AF-CTR-09's exit criteria hold: every active route served by Go on the deployed revision, the PostgreSQL recovery drill passed, and one release on Go without rollback. Released artifacts, images and historical evidence are kept; nothing is unpublished or deleted. 16. **Verification.** The Go center is verified on both native legs ([AD-0020](AD-0020-post-push-verification-and-required-checks.md)): format, vet, static analysis, unit tests, generation drift and native builds on Windows and Linux; real PostgreSQL integration tests, the race detector and the container image on Linux, where Docker and cgo are available. Cross-compilation is never counted as another platform's execution. The engineering controls of the C# projects are carried over with explicit dispositions (AF-CTR-02). -17. **Owner decisions and design choices.** Items 1–4, 6 (separate entry points, MCP authorization, explicit device selection, identity and session rules), 7, 8 (Go, Neon/PostgreSQL, Go bindings from the single source), 10 (what may pass through or persist, as minimization rules), 12, 13 and 14 restate the product owner's decisions. The following are design choices made under them, recorded here so that a later change needs only a reviewed amendment: node connections terminating in the Go center instead of a per-account Durable Object hub (§9); the bounded diagnostic `arcforges run --local` (§5); signed routed calls (§10); the 90-day retention of routing records (§10); no store-and-forward of submissions by the center (§11); PostgreSQL schemas per module ([data/cloud-store.md](../data/cloud-store.md) §6). +17. **Owner decisions and design choices.** Items 1–4, 6 (separate entry points, MCP authorization, explicit device selection, identity and session rules), 7, 8 (Go, Neon/PostgreSQL, Go bindings from the single source), 10 (what may pass through or persist, as minimization rules), 12, 13, 13a (except its design choices on enrollment, lapse and feature keys) and 14 restate the product owner's decisions. The following are design choices made under them, recorded here so that a later change needs only a reviewed amendment: node connections terminating in the Go center instead of a per-account Durable Object hub (§9); the bounded diagnostic `arcforges run --local` (§5); signed routed calls (§10); the 90-day retention of routing records (§10); the ungated enrollment, the lapse behaviour and the feature keys (§13a); no store-and-forward of submissions by the center (§11); PostgreSQL schemas per module ([data/cloud-store.md](../data/cloud-store.md) §6). ## Open questions for the owner diff --git a/docs/product/requirements.md b/docs/product/requirements.md index 1abc201..02d21c7 100644 --- a/docs/product/requirements.md +++ b/docs/product/requirements.md @@ -225,7 +225,7 @@ Added 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md). ## R-COM — Commerce -*Amended 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md) (target).* In R-COM-003 entitlement changes reach connected nodes over the node channel of the Go center. In R-COM-004 tokens describe center features; expiry never stops node-local execution or running tasks. Which features are gated is an open owner question (AD-0021, Open questions). +*Amended 2026-10-28 by [AD-0021](../decisions/AD-0021-central-access-go-center.md) (target).* In R-COM-003 entitlement changes reach connected nodes over the node channel of the Go center. In R-COM-004 tokens describe center features; expiry never stops node-local execution or running tasks. Which features are gated is decided by AD-0021 §13a; their values (prices, trials, limits and allowances) remain open (H-07). | ID | Requirement | Acceptance | |---|---|---| diff --git a/docs/traceability/model.json b/docs/traceability/model.json index 8c2068e..92f8dca 100644 --- a/docs/traceability/model.json +++ b/docs/traceability/model.json @@ -2020,7 +2020,10 @@ "AF-CTR-03", "AF-CTR-05", "AF-CTR-07", - "AF-CLD-03" + "AF-ID-02", + "AF-CLD-03", + "AF-CLD-04", + "AF-COM-01" ], "verification": "Tests per center mode and gate (official-hosted, self-hosted, invalid configuration)." }