Skip to content

ADR-0012 amendment: the push channel's relay transport, and vendor as a token type rather than a plugin boundary (ruling cloud#3519) #29817

Closed

Description

@hotlong

Blocked-by: #29816

Context

objectstack-ai/cloud#3519 was ruled 1C 2A 3A 4B 5A 6B 7B on 2026-11-03. The store-published app pushes through a hosted relay in objectstack-ai/cloud. In phase 2, that relay also fronts the mainland-China vendor channels (HMS/Honor, Xiaomi, OPPO, vivo). ADR-0012 still says the domestic vendors are alternate channel plugins (§6, Non-Goals), and its §4 table lists only APNs/FCM as the push backend.

Ask

One PR on docs/adr/0012-notification-platform.md. It is a governed path, so the maintainer merges it by hand.

  • §4: the push backend becomes relay (hosted, default) | direct (APNs/FCM, white-label).
  • §6: the relay fronts the domestic vendors. vendor on a device row is a token-type discriminator that the relay routes on, not a plugin boundary. The PushVendorSchema widening still lands together with the transports, as push-config.zod.ts requires.
  • Non-Goals: rewrite them to match.
  • Privacy: the relay never receives plaintext content. Phase 1 is ID-only; phase 2 is end-to-end encryption with a device key.
  • Air-gap: no system push; the in-app inbox only.
  • Supersession: record which earlier wording this amends, and cite chore(deps)(deps): bump @better-auth/oauth-provider from 1.7.0-rc.1 to 1.7.0-rc.2 #3519.

Acceptance

The ADR text matches the spec shape from #29816 and the ruling. There are no code changes.

Activity

  1. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    Contributor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p1 kept · domain:spec kept · pm:blocked · 2026-11-03T06:54Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    Contributor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Claim: PM loop round 8 (p1)
    Session: session_01WGufzfgvGexKn9vLHsy89K
    Account: os-support-ai
    Branch: the card thread's own claude/project-thread-* branch, named in the dev's hand-back and restated in a later claim (a measured platform exception to claude/issue-29817-…)
    Worktree: objectstack-issue-29817
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: docs/adr/0012-notification-platform.md only (Tier H, governed path: the maintainer merges by hand).
    Container & model: S, mode:thread, model: CONTRACT_REVIEW_TIER (Model tier — MANDATORY: claude-fable-5-1, dispatch-gates --tier on docs/adr/0012-notification-platform.md ⇢ docs/adr/**), effort: xhigh
    Clause-②: no (docs only, no spec shape moves)
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6597413801
    Premise: holds. Blocked-by: #29816 cleared, because #29816 was closed as completed by PR #29886 at 10:32Z, and PR #29794 merged at 16:30Z. On origin/main 6a4737ab, ADR-0012 §4 lists only APNs/FCM as the push backend. Its Goals (line 118) and Non-Goals (line 127) still call the domestic vendors plugin transports. The header's 2026-11-03 amendment (#29041) names the relay as the default but "not yet served" (#29920).
    Serial constraints cleared: #29816 landed, and #29794 landed. Stale pm:blocked removed. Dispatch resumed for p1/p2 at 2026-11-03T15:40Z.

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    Contributor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Claim: PM loop round 8 (p1), restated with the branch
    Session: session_01WGufzfgvGexKn9vLHsy89K
    Account: os-support-ai
    Branch: claude/project-thread-geqk0x (card thread, executor session_01WGufzj5io3Zzyb3E6VKCtj; the thread can push only its own branch, a measured platform exception to claude/issue-29817-…)
    Worktree: objectstack-issue-29817
    Domain: domain:spec
    Seat: domain:spec#3
    File surface: docs/adr/0012-notification-platform.md only (Tier H, governed path: the maintainer merges by hand).
    Container & model: S, mode:thread, model: CONTRACT_REVIEW_TIER (Model tier — MANDATORY: claude-fable-5-1, dispatch-gates --tier on docs/adr/0012-notification-platform.md ⇢ docs/adr/**), effort: xhigh
    Clause-②: no (docs only, no spec shape moves)
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6610009607
    Premise: holds. Blocked-by: #29816 cleared, because #29816 was closed as completed by PR #29886 at 10:32Z, and PR #29794 merged at 16:30Z. On origin/main 6a4737ab, ADR-0012 §4 lists only APNs/FCM as the push backend. Its Goals (line 118) and Non-Goals (line 127) still call the domestic vendors plugin transports. The header's 2026-11-03 amendment (#29041) names the relay as the default but "not yet served" (#29920).
    Serial constraints cleared: #29816 landed, and #29794 landed. Stale pm:blocked removed. Dispatch resumed for p1/p2 at 2026-11-03T15:40Z.

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    Contributor

    domain:spec#3 · os-support-ai · session_01WGufzj5io3Zzyb3E6VKCtj
    os-dev-report

    Stamp: 2026-11-03T17:13Z

    {
      "issue": 29817,
      "status": "done",
      "branch": "claude/project-thread-geqk0x",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29952",
      "head": "cce992bf",
      "session": "session_01WGufzj5io3Zzyb3E6VKCtj",
      "premise_still_valid": true,
      "summary": "docs/adr/0012-notification-platform.md amended for ruling cloud#3519 (1C 2A 3A 4B 5A 6B 7B) and the spec shape of #29816: the status line's Amended (2026-11-03, #29041) note is extended for #29817 and lists each passage it amends and its old wording; the section 4 push backend is relay (hosted, default) or direct (APNs/FCM, white-label); section 6's domestic-vendor bullet and a new section 6.1 record vendor as a token type the relay routes on, the wire, the privacy rule (ID-only, then end-to-end encryption with a device key) and the air-gap rule (no system push; the in-app inbox only), plus what main serves at 6a4737ab; the Goals and Non-Goals bullets that called the domestic push vendors plugin transports, the M3 line, risk 5 and the Decision list are rewritten. Every passage quotes the wording it replaces. ADR-0030 read, no contradicting wording, unchanged. One file, +22/-9, no code, schema or generated artifact moves.",
      "tests": "n/a, docs only. Offline body check: GITHUB_EVENT_NAME=pull_request node scripts/check-changeset-no-major.mjs --base origin/main --event event.json with this PR body (labels skip-changeset): exit 0, LEVEL AXIS reads Clause-② no and Metadata-protocol none.",
      "gates": "local subset at cce992bf: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack docs/adr/0012-notification-platform.md derived 21 commands (15 pnpm, 6 direct node; 13 by path, 8 whole-tree); all 21 exit 0, each captured before any pipe from a serial runner with stdin closed: check-adr-links (+ --self-test), check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, ci/plan-test-core-shards --self-test, check:doc-formula-expressions (after turbo build formula+lint under os-verify-lock, VERDICT command-exit 0, 154 s), check:adr-anchors, check:adr-index, check:adr-symbol-anchors (3075 anchors across 149 records resolve), check:ci-filter-parity, check:closed-ceremony-text, check:cross-package-test-inputs, check:doc-authoring, check:driver-memory-census, check:gitlink-declared, check:nul-bytes, check:pm-governed-merges, check:pm-prior-rulings, check:refd-timer-probe, check:watch-hint-literal. dispatch-gates --ran RAN_FILE --repo objectstack-ai/objectstack: 21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN; change set 1 path +22/-9. check-changeset-no-major offline with this body: exit 0 (outside the derivation). CI families on PR #29952: read from the PR check-runs at review, not re-run locally.",
      "dogfood_battery": "n/a, no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "8 — GitHub MCP reads only: issue_read get #29817, issue_read get_comments #29817 (x2), issue_read get #29816, issue_read get #29920, pull_request_read get #29886, pull_request_read get #29794, pull_request_read get #29952 (label and draft read-back). No MCP write tool.",
      "api_writes": "0 REST proxy writes. Relay writes: 1 pr_create (fleet-write run 41681841784, read back identical, 15438 bytes) and this report comment via post-stamped.mjs; git push x1 (not REST).",
      "deviations": [
        "Clause-② spelling: the order says n/a (docs only); the body carries the claim's spelling no (docs only, no spec shape moves), because scripts/pm/clause2-line.mjs CLAUSE2_VALUES accepts only yes and no and n/a reads malformed to check-changeset-no-major.",
        "Harness PR steps skipped per os-dev rule 2: no assignees on pr_create and no reviewer request; the seat sets both at hand-over.",
        "The pr_create body carries no seat signature line: the relay's signature rule scopes to comment_edit and issue_patch, and the harness pins the attribution block to lines 1 and 2 (precedent PR #29886); the seat appends its trailer at hand-over.",
        "Harness attribution reminder names a model in its Co-Authored-By line; the commit carries the model-free trailer pair (AGENTS.md), reported, not a deviation of the dev's own.",
        "cloud#3519 is not readable from this session (GitHub scope is objectstack-ai/objectstack only); the card body bound, as the order allows."
      ],
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: the phase-2 change that widens PushVendorSchema (no card yet) · noted, not filed · packages/spec/src/system/push-config.zod.ts (the docblock's Out of scope here paragraph and the PushVendorSchema comment) and packages/spec/src/system/push-device.zod.ts still say ADR-0012 section 6 routes the domestic vendors to alternate channel implementations; after this amendment that comment wording is stale. Comments, not a card class. dedupe words: PushVendorSchema, alternate channel implementations, push-config.zod.ts docblock, push-device.zod.ts",
        "carrier: spec seat (no card yet) · noted, not filed · no card tracks the phase-2 domestic vendors (PushVendorSchema widening behind the relay) or the end-to-end encryption phase (pushKey on the device registration); the ADR says no card yet for both. dedupe words: HMS Honor Xiaomi OPPO vivo relay, push E2EE device key, pushKey RegisterDeviceRequestSchema"
      ]
    }
  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    Contributor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    ACCEPT → PR #29952 comment 6611718818 (head 62ac6d3c, contract review PASS 6611334981). Tier H (docs/adr/**): handed to the maintainer for review and a manual merge; the seat does not queue it or arm auto-merge. Follow-up: #29960 (spec docblocks that still cite §6; Blocked-by #29952).

  6. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    Contributor

    domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

    Landed · PR #29952 merged by the maintainer (os-zhuang) as 6f7df530 · 2026-11-03T22:06Z

    ADR-0012 now records the cloud#3519 ruling:

    • The push backend is relay (hosted, default) | direct (APNs/FCM, white-label).
    • The relay fronts the domestic vendors in phase 2, and vendor is the token type the relay routes on, not a plugin boundary.
    • The relay never receives plaintext content: phase 1 is ID-only, phase 2 is end-to-end encryption with a device key.
    • An air-gapped deployment has no system push, only the in-app inbox.

    Contract review 6611334981 PASS (rules face), ACCEPT 6611718818. Follow-up: #29960 (the spec docblocks that still cite the old §6 reading) is now unblocked. Removing pm:dispatched here, and needs-user-decision from the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationdomain:specpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions