Repository navigation
[AF-CTR-03] Admit the arcforges-node, arcforges-mobile and arcforges-web products and add the WebBrowserSession document - #121
Merged
Conversation
…as device and session products The Go center (Cloud AF-CTR-03) binds every account session and node credential to a device installation (ArcForges-Design AD-0021 section 7 at 3392d02): a node's credential to its arcforges-node installation, a phone's session to its arcforges-mobile installation and a browser's own cookie session to an arcforges-web installation. The contract validations allowed only the branded products arcscope and companion, so ListSessions, DeviceService.List and an installation claim could not carry these values. - public/proto/constraints/con-07-identity.json: the product enum of InstallationClaim, SessionSummary, InstalledProduct and DeviceServiceRegisterRequest gains the three values; arcscope and companion stay. The application product IDs (ApplicationScope, ApplicationTarget and the history records) are not device or session products and are unchanged. - Regenerated with python eng/contracts.py generate: the aggregate public/proto/constraints.json and the Validation package's ProtoValidation checks. No proto file, descriptor or Go binding changes. - The published closed HTTP documents public/http/v1/browser.schema.json and native-auth.schema.json are unchanged: the CON.17 later-services window freezes them (identical since 1.0.0-ci.287.1). The browser session of an arcforges-web installation gets its own document in the next commit. - fixtures/public/con-07-identity.json: an accepted case per new value for each of the four messages, next to the existing allowed-companion cases. - eng/policy/product-names.json and eng/check_naming.py: a closed installationProducts entry lists the three values with their own Design reference (ArcForges-Design 3392d02, AD-0021). They are wire values only, with no display name, namespace, application ID or file association, and never a branded or retired product ID. The P2-019 pin and the DesktopPlatform derived declaration bound to it are unchanged, because moving that pin would detach the declaration from its Design source. - tests/tooling/test_naming_policy.py: the installation products are closed, unbranded and pinned; the device and session product validations of the constraint shard and the aggregate use exactly the branded products plus these values, while the application product IDs and the two frozen HTTP documents keep the branded set. - README.md: the naming policy section describes the new list. Signed-off-by: sammiller <dekueon@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW
…ser sessions A browser's own cookie session on the Go center is bound to an arcforges-web installation (ArcForges-Design AD-0021 section 7), and the browser session begin requests require an installation claim. The published closed BrowserSession document (public/http/v1/browser.schema.json) cannot carry that product: the CON.17 later-services window freezes it, so no content or version change in place is possible. The browser session of an arcforges-web installation gets its own closed document beside it instead. - public/http/v1/web-browser.schema.json (title WebBrowserSession, x-arcforges-schema-version 1): the meaning of BrowserSession, derived from it textually, with its own definition names (WebBrowser*, because generated model and file names are unique per output root), route identities (webBrowser.*) and paths (/session/v1/web/*, because route paths are limited to /session/v1/ under contract major 1), and an installation claim whose product also admits arcforges-web (not arcforges-node or arcforges-mobile). The frozen document and native-auth.schema.json are unchanged. - eng/generate_shapes.py and eng/contract-packages.json: the document is generated into ArcForges.Contracts.PublicApi (namespace ArcForges.Contracts.PublicApi.Http.V1.WebBrowser) with its validators in ArcForges.Contracts.Validation, and owned by ArcForges.Contracts.PublicApi only (the retired @arcforges/api-client row is unchanged). - Generated: 14 models and the WebBrowserSessionRoutes catalogue in PublicApi, 14 validators in Validation. - fixtures/public/con-07-identity.json: every BrowserSession HTTP vector is mirrored on the new roots with the same bytes and outcome (109), plus the product vectors: arcforges-web accepted by the new begin authentication and begin recovery requests, arcforges-node and arcforges-mobile refused there, and arcforges-web refused by the frozen document. The WebBrowserSession route table is added. - tests/tooling/test_identity_http.py and tests/StructureTests/IdentityCases.cs: the new document is interpreted independently and through the generated C# codecs and route catalogue; a new test holds it to the frozen document's meaning, its own routes and names, the product domain and its single package owner. tests/tooling/test_naming_policy.py holds its product field to the branded products plus arcforges-web. - README.md: the naming policy section names the document. Signed-off-by: sammiller <dekueon@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW
…oduct domain and WebBrowserSession Records for the two previous commits (source commit 71badd3): - eng/policy/contract-access.json: the 29 generated sources of the WebBrowserSession document (15 in ArcForges.Contracts.PublicApi, 14 in ArcForges.Contracts.Validation) with their declared types, the refreshed ProtoValidation hash, the new build input public/http/v1/web-browser.schema.json and the refreshed build-input hashes of eng/contract-packages.json, the aggregate public constraints and the identity constraint shard; sourceCommit 71badd3, reviewedOn 2026-10-28. No schema, package or access row is removed or reclassified. - Provenance: the immutable successor contract-bindings-af-ctr-03-r1 supersedes contract-bindings-af-con-01-r1. It keeps all 383 predecessor targets, refreshes the hash of the regenerated ProtoValidation checks and binds the 29 generated outputs of the new document (412 targets). The generator pins and the licence boundary are unchanged; the first-party input and generator snapshot moves to 71badd3 with refreshed evidence digests and the new document among the inputs. eng/provenance/files.json rebinds the 383 targets, binds the 29 new ones and classifies the record, the receipt and the new document as first-party; NOTICE.txt is regenerated. - Dependency admission: receipt af-ctr-03-r1 (previousReceipt af-ctr-01-r1) and the policy bind the refreshed contract-access.json and contract-packages.json and the provenance successor. The closure, every coordinate, version, integrity value, licence and framework selection is unchanged. The receipt and the provenance record name the independent AF-CTR-03 reviewer of the pull request with decision approved on 2026-10-28; the exact-head review must confirm it. Signed-off-by: sammiller <dekueon@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW
…-ctr-03-r1 The pinned full-history gitleaks scan (v8.30.1, image c00b6bd0aeb3, --diff-filter=tuxdb; scratch clone of the branch on the Linux host, range 7205743..952acd9) reports 6 generic-api-key findings, all on the commit adding receipt af-ctr-03-r1: the public SHA-256 input digest of eng/policy/contract-access.json in dependency-policy.json (lines 15 and 1020) and four rows of the immutable receipt (lines 35, 103, 172, 240). The product domain and WebBrowserSession commits (e7d9fe8, 71badd3) produce no finding. .gitleaks.toml (supporting file outside the task write paths, scope note in the PR) appends two exact-row [[allowlists]] blocks in the CON.43 form (1 row for the policy, 4 for the receipt); no existing block changes. tests/tooling/test_dependency_admission.py moves the allowlist count pin from 99 to 101, appends [1, 4] to the per-block regex counts and adds test_af_ctr_03_r1_secret_scan_allowlists_bind_only_exact_public_digest_tuples, reading its rows from the receipt. Signed-off-by: sammiller <dekueon@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW
…erialization policy test The serialization gate (eng/check_serialization.py) counts the generated strict System.Text.Json contexts; the WebBrowserSession document of 71badd3 adds its 14 root contexts, so the exact pin in tests/tooling/test_serialization_policy.py moves from 97 to 111. The gate and its rules are unchanged. Signed-off-by: sammiller <dekueon@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW
Contributor
Author
Review record: Contracts #121Reviewer: the independent AF-CTR-03 reviewer, a delegated agent that did not author this PR. Verdict: approve at 640f072. The code was approved as it stands. The one process finding (F1, the task's write scope) is resolved by Plan #77, which widens AF-CTR-03's Contracts paths and scope. Checks
Residual risks
Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[AF-CTR-03] Device and session products and the arcforges-web browser session document
Contracts part of Plan task AF-CTR-03 (Accounts, sessions and devices on the center). ArcForges-Design AD-0021 §7
(Design #43, merge 3392d02) binds every account session and node credential to a device installation: a node's
credential to its
arcforges-nodeinstallation, a phone's session to itsarcforges-mobileinstallation and abrowser's own cookie session to an
arcforges-webinstallation. The Contracts validations admitted only the brandedproducts
arcscopeandcompanion.Commits
e7d9fe8Admit arcforges-node, arcforges-mobile and arcforges-web as device and session productspublic/proto/constraints/con-07-identity.json: product enum ofInstallationClaim,SessionSummary,InstalledProduct,DeviceServiceRegisterRequestgains the three values (arcscope and companion stay).Application product IDs (
ApplicationScope,ApplicationTarget, history records) unchanged.public/proto/constraints.jsonandProtoValidation.g.cs. No proto, descriptor or Gobinding change.
fixtures/public/con-07-identity.json: one accepted case per new value for each of the four messages.eng/policy/product-names.json+eng/check_naming.py: closedinstallationProductslist with its own Designreference (ArcForges-Design 3392d02, AD-0021); wire values only, never branded or retired IDs. The P2-019 pin is
unchanged (the DesktopPlatform derived declaration is bound to it).
tests/tooling/test_naming_policy.py,README.md.public/http/v1/browser.schema.jsonandnative-auth.schema.jsonare NOT changed(see "CON.17 window" below).
71badd3Add the WebBrowserSession document for arcforges-web browser sessionspublic/http/v1/web-browser.schema.json, titleWebBrowserSession,x-arcforges-schema-version"1": derivedtextually from the frozen BrowserSession document and held to its meaning by a test. Differences only:
definition names
WebBrowser*, route idswebBrowser.*, paths/session/v1/web/*, the description, andWebBrowserInstallationClaim.product=arcscope,companion,arcforges-web(not node/mobile).eng/generate_shapes.py(mapping, namespaceArcForges.Contracts.PublicApi.Http.V1.WebBrowser) andeng/contract-packages.json(owned byArcForges.Contracts.PublicApionly; the retired api-client row unchanged).WebBrowserSessionRoutes(PublicApi), 14 validators (Validation).vectors (arcforges-web accepted by the new begin authentication/recovery requests; arcforges-node and
arcforges-mobile refused there; arcforges-web refused by the frozen document), the WebBrowserSession route table.
tests/tooling/test_identity_http.py(independent interpreter over the new document, a mirror test,routes, single package owner),
tests/StructureTests/IdentityCases.cs(generated C# codecs and route catalogue),tests/tooling/test_naming_policy.py.952acd9Bind access, provenance and dependency recordseng/policy/contract-access.json: 29 new distribution rows with declared types, ProtoValidation hash, the newbuild input, refreshed build inputs (contract-packages.json, aggregate constraints, con-07 shard); sourceCommit
71badd3, reviewedOn 2026-10-28.
contract-bindings-af-ctr-03-r1(supersedescontract-bindings-af-con-01-r1): 383 targetskept, 1 hash refreshed, 29 added (412); input/generator snapshot moved to 71badd3 with refreshed evidence digests
and the new document among the inputs;
files.jsonandNOTICE.txt.af-ctr-03-r1(previousReceiptaf-ctr-01-r1); closure unchanged.700d825Allow the exact reviewed public digest rows of receipt af-ctr-03-r1.gitleaks.toml: two exact-row blocks (1 + 4 rows) for the 6 generic-api-key findings of the pinned scan;tests/tooling/test_dependency_admission.py: count pin 99 -> 101, per-block counts, new exact-tuple test.640f072Count the WebBrowserSession strict JSON contexts in the serialization policy testtests/tooling/test_serialization_policy.py: exact pin of strict System.Text.Json contexts 97 -> 111 (the 14root contexts of the new document); the gate is unchanged.
CON.17 window and the document choice
eng/compatibility/later-services-window.jsonpins the closed CON.07-CON.16 documents by hash and version; anycontent or version change in place fails
check_compatibility.py --window. Both frozen documents staybyte-identical; no check was changed.
native-auth.schema.json: unchanged. A version-1NativeTokenResponsemust never list anarcforges-*installation (Cloud A1 records whether it filters them or leaves native token documents unserved). The node and
mobile native flows bring their own versioned document with AF-CTR-04 and AF-CLD-02.
public/http/v1/with routes under/session/v1/web/, notpublic/http/v2/with/session/v2/*: the generator's route guard (eng/generate_shapes.pyroute_catalogue, pinned bytests/tooling/test_con07_generator_guards.py) admits only/session/v1/...paths, and the change is additive undercontract major 1 (a
v2name would announce a breaking major). Generated model and file names are unique per outputroot, so the definitions are renamed in any layout.
$id: no Contracts document declares one; a document's identity is its path, title, namespace andx-arcforges-schema-version, all distinct here.(
identicalSincemust be a recorded candidate with its publication run and retained archive, andtest_closed_schemas_are_pinned_with_their_first_publicationholds the per-task path sets). The new document isunpublished and belongs to AF-CTR-03; a later window opened at the candidate that publishes it can pin it.
webBrowser.*routes; the Design companion PR with A2 records the browser-session documentchoice.
Linux leg
python3 eng/verify.py run --rev HEADat640f0728f743d871882774feb08cec16df722a30(base 7205743, 51 changedpaths, profile full, 19 steps, 546 s): LEG PASS (logs
.git/arcforges-verify/logs/20261029-053022-640f0728f743-linux).pass clone-identity, secret-scan (5 commits, no leaks), restore, dependency-admission, naming, provenance,
contract-access-test, format-audit, pack (167 s, including
check_compatibility.py --window: both frozen documentsunchanged), go-generate-drift, go-static, go-test, go-exchange, go-vulncheck, tooling-tests (550 tests OK),
clean-tree, security-build, security-naming, architecture-gate (214 s).
Earlier runs on this branch: the first shape (both frozen HTTP documents widened in place) failed
packon theCON.17 window; it was replaced by the commits above (the branch was never pushed). The run at
700d825failed onlytests/tooling/test_serialization_policy.py(strict JSON context pin 97, now 111: commit 5).Local checks run in the worktree
python3 eng/contracts.py generate/generate --check(exit 0).dotnet build ArcForges.Contracts.slnx -c Release --no-restore -p:ArcForgesBuildId=local(0 warnings, 0 errors);StructureTests: "CON.07: 3 services, 49 operations, 1096 shape and 298 HTTP exception vectors passed."python3 eng/check_provenance.py --owner Contracts --base origin/main --write-notice: passed (1299 files, 606reused).
node eng/check_contract_access.mjs: passed (3311 distribution files).python3 eng/dependency_admission.py: passed (58 dependencies, 235 inputs).python3 -m unittestdependency_admission, identity_http, naming_policy, compatibility_matrix,con07_generator_guards, json_shape_unions: 170 tests OK.
(dependency-policy.json lines 15, 1020; af-ctr-03-r1.json lines 35, 103, 172, 240), allowlisted by commit 4.
Windows
Contracts has only a Linux leg. Nothing in this change is Windows-specific: data, generated C# models and validators,
C# and Python tests. The new C# types reach Windows consumers only when they bump ArcForges.Contracts.PublicApi and
.Validation.
Scope notes
.gitleaks.tomlis a supporting file outside the task write paths (allowlist rows for the new receipt only).auth.token_expiredandauth.credential_revokedtransport rows (listed in the Cloud A1 PR body).
🤖 Generated with Claude Code
https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW