Skip to content

[AF-CTR-03] Admit the arcforges-node, arcforges-mobile and arcforges-web products and add the WebBrowserSession document - #121

Merged
deku2026 merged 5 commits into
mainfrom
task/af-ctr-03-products
Oct 28, 2026
Merged

deku2026 merged 5 commits into
mainfrom
task/af-ctr-03-products

Conversation

@deku2026

Copy link
Copy Markdown
Contributor

[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-node installation, a phone's session to its arcforges-mobile installation and a
browser's own cookie session to an arcforges-web installation. The Contracts validations admitted only the branded
products arcscope and companion.

Commits

  1. e7d9fe8 Admit arcforges-node, arcforges-mobile and arcforges-web as device and session products
    • public/proto/constraints/con-07-identity.json: product enum of InstallationClaim, SessionSummary,
      InstalledProduct, DeviceServiceRegisterRequest gains the three values (arcscope and companion stay).
      Application product IDs (ApplicationScope, ApplicationTarget, history records) unchanged.
    • Regenerated: aggregate public/proto/constraints.json and ProtoValidation.g.cs. No proto, descriptor or Go
      binding 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: closed installationProducts list with its own Design
      reference (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.
    • The published closed documents public/http/v1/browser.schema.json and native-auth.schema.json are NOT changed
      (see "CON.17 window" below).
  2. 71badd3 Add the WebBrowserSession document for arcforges-web browser sessions
    • public/http/v1/web-browser.schema.json, title WebBrowserSession, x-arcforges-schema-version "1": derived
      textually from the frozen BrowserSession document and held to its meaning by a test. Differences only:
      definition names WebBrowser*, route ids webBrowser.*, paths /session/v1/web/*, the description, and
      WebBrowserInstallationClaim.product = arcscope, companion, arcforges-web (not node/mobile).
    • eng/generate_shapes.py (mapping, namespace ArcForges.Contracts.PublicApi.Http.V1.WebBrowser) and
      eng/contract-packages.json (owned by ArcForges.Contracts.PublicApi only; the retired api-client row unchanged).
    • Generated: 14 models + WebBrowserSessionRoutes (PublicApi), 14 validators (Validation).
    • Fixtures: all 109 BrowserSession HTTP vectors mirrored on the new roots (same bytes, same outcome), product
      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: 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.
  3. 952acd9 Bind access, provenance and dependency records
    • eng/policy/contract-access.json: 29 new distribution rows with declared types, ProtoValidation hash, the new
      build input, refreshed build inputs (contract-packages.json, aggregate constraints, con-07 shard); sourceCommit
      71badd3, reviewedOn 2026-10-28.
    • Provenance successor contract-bindings-af-ctr-03-r1 (supersedes contract-bindings-af-con-01-r1): 383 targets
      kept, 1 hash refreshed, 29 added (412); input/generator snapshot moved to 71badd3 with refreshed evidence digests
      and the new document among the inputs; files.json and NOTICE.txt.
    • Dependency receipt af-ctr-03-r1 (previousReceipt af-ctr-01-r1); closure unchanged.
  4. 700d825 Allow 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.
  5. 640f072 Count the WebBrowserSession strict JSON contexts in the serialization policy test
    • tests/tooling/test_serialization_policy.py: exact pin of strict System.Text.Json contexts 97 -> 111 (the 14
      root contexts of the new document); the gate is unchanged.

CON.17 window and the document choice

  • eng/compatibility/later-services-window.json pins the closed CON.07-CON.16 documents by hash and version; any
    content or version change in place fails check_compatibility.py --window. Both frozen documents stay
    byte-identical; no check was changed.
  • native-auth.schema.json: unchanged. A version-1 NativeTokenResponse must never list an arcforges-*
    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.
  • New document under public/http/v1/ with routes under /session/v1/web/, not public/http/v2/ with
    /session/v2/*: the generator's route guard (eng/generate_shapes.py route_catalogue, pinned by
    tests/tooling/test_con07_generator_guards.py) admits only /session/v1/... paths, and the change is additive under
    contract major 1 (a v2 name would announce a breaking major). Generated model and file names are unique per output
    root, so the definitions are renamed in any layout.
  • No $id: no Contracts document declares one; a document's identity is its path, title, namespace and
    x-arcforges-schema-version, all distinct here.
  • No new window row: the window pins documents of CON.07-CON.16 by the published candidate they first appeared in
    (identicalSince must be a recorded candidate with its publication run and retained archive, and
    test_closed_schemas_are_pinned_with_their_first_publication holds the per-task path sets). The new document is
    unpublished and belongs to AF-CTR-03; a later window opened at the candidate that publishes it can pin it.
  • Cloud A2 serves only the webBrowser.* routes; the Design companion PR with A2 records the browser-session document
    choice.

Linux leg

python3 eng/verify.py run --rev HEAD at 640f0728f743d871882774feb08cec16df722a30 (base 7205743, 51 changed
paths, 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 documents
unchanged), 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 pack on the
CON.17 window; it was replaced by the commits above (the branch was never pushed). The run at 700d825 failed only
tests/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, 606
    reused).
  • node eng/check_contract_access.mjs: passed (3311 distribution files).
  • python3 eng/dependency_admission.py: passed (58 dependencies, 235 inputs).
  • python3 -m unittest dependency_admission, identity_http, naming_policy, compatibility_matrix,
    con07_generator_guards, json_shape_unions: 170 tests OK.
  • Pinned gitleaks v8.30.1 (image c00b6bd0aeb3) on a scratch clone, range 7205743..952acd9: 6 generic-api-key findings
    (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.toml is a supporting file outside the task write paths (allowlist rows for the new receipt only).
  • Companion rows for the Design PR carried with Cloud A1 (DC-14): auth.token_expired and auth.credential_revoked
    transport rows (listed in the Cloud A1 PR body).

🤖 Generated with Claude Code

https://claude.ai/code/session_01H6Cf6pFe7uHMuN6zEgDLmW

deku2026 and others added 5 commits October 29, 2026 05:12
…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
@deku2026

Copy link
Copy Markdown
Contributor Author

Review record: Contracts #121

Reviewer: 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

  • Product domain. Exactly 4 device and session product fields are widened in con-07, and the aggregate and ProtoValidation match. Application product IDs (ApplicationScope and others) deliberately stay branded. installationProducts pins Design 3392d02, and check_naming is not weakened.
  • WebBrowserSession. An independent rename diff against the frozen BrowserSession document shows only the description, +arcforges-web, and the route ids and paths changed. The mirror test failed under 7 mutations. Vectors: 109 copies plus 7 product vectors. The generator guard is unchanged.
  • Frozen documents. browser.schema.json and native-auth.schema.json are byte-identical to main. check_compatibility.py --window passes, and an in-place widening still fails, as it should.
  • Records. contract-access, the provenance successor contract-bindings-af-ctr-03-r1 (412 targets), files.json, NOTICE and receipt af-ctr-03-r1 were recomputed, and all hashes match.
  • gitleaks. The pinned v8.30.1 scan finds 6 public-digest findings with main's configuration and 0 at the head. The new rows are exact-line and path-anchored.
  • Test pins. 101 allowlist rows and 111 strict JSON contexts; both checks are unchanged.
  • Generated code. Full regeneration leaves the tree clean.
  • Compatibility. The wire and the Go and npm contents are unchanged; the PublicApi and Validation additions are additive.
  • Leg. arcforges/linux succeeds at 640f072 (19 steps, 513 s).

Residual risks

  • Older Validation packages reject arcforges-* values. Consumers update to this cohort.
  • WebBrowserSession should be pinned in a later window at the candidate that first publishes it.
  • Cloud A2 must refuse any browser product it does not serve.

Generated by Claude Code

@deku2026
deku2026 merged commit 62ccef1 into main Oct 28, 2026
7 checks passed
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.

1 participant