Sign in to edit tickets from this page.

← all tickets · home

BENAC-C1-MATRIX-C2LITE-001 — Cross-Platform Station Acceptance and Minimal Replication Demonstration

resolved 210b6b27-0c50-4041-8f56-49e40ece4ecf

created_at
2026-05-02
updated_at
2026-05-03
priority
P1
ticket_type
feature
parent
618d387c
resolved_at
2026-05-03
resolution
accepted

Body

Ticket: BENAC-C1-MATRIX-C2LITE-001 — Cross-Platform Station Acceptance and Minimal Replication Demonstration

Status

Proposed follow-up to the C1 Hello World PWA ticket.

Owner intent

Move from a single-device/single-platform Hello World proof to a multi-Station demonstration with minimal architectural churn.

This ticket shall prove that the current Benac C1 Hello World Station can operate on:

This ticket shall also demonstrate a minimal replication path between Stations so the system can prove that replicated data moves, remains verifiable, and does not become local authority merely because it replicated.

This is intentionally a C2-lite replication demonstration, not full C2 completion. Full C2 remains larger: complete Couch/Pouch-compatible replication, encrypted private document replication, conflict UI, peer authentication depth, and all production-grade sync semantics are out of scope for this ticket unless explicitly listed below.

Background

The existing C1 Hello World PWA implementation has landed the core browser Station path: installable PWA shell, IndexedDB-backed stores, cryptographic Station principal, explicit local approval, trust/capability gating, declarative invocation, WASM invocation, invocation/evidence/effect/auth/audit records, trace export/import, and iOS acceptance evidence.

The next proof cannot be meaningfully completed inside one Station. Benac needs multiple Stations. The minimum useful move is to run the same package and same kernel semantics across Android, desktop browsers, and an Ubuntu shell Station, then replicate selected documents/blobs between them while preserving the core invariants:

Non-goals

Do not implement these in this ticket:

Architectural decisions

1. Reuse the existing PWA for Android and desktop browsers

The PWA shall remain the main browser Host. Android Chrome, Ubuntu Firefox, and Ubuntu Chrome/Chromium should run the same deployed static build as iOS.

Do not fork the PWA for Android or desktop unless an actual platform defect forces a narrow compatibility patch.

2. Add an Ubuntu shell Station as a Rust CLI

Create a small Rust CLI app rather than a native GUI.

Recommended package name:

apps/station-cli

Recommended binary name:

benac-station

The CLI shall reuse existing benac-core, benac-browser, benac-fixtures, and benac-conformance logic as much as possible. A broad refactor is not desired.

The current BrowserStationRuntime may be reused as the first CLI runtime despite the name. If a small rename/refactor to PortableStationRuntime is low-risk, it may be done, but this ticket does not require a naming cleanup.

3. Implement a minimal untrusted Relay Station for replication demonstration

Use a dev relay to move data between browser Stations and the CLI Station.

The relay is not a source of identity, trust, execution permission, or truth. It is a dumb transport/storage participant. All clients shall verify content IDs, signatures, schemas, and policy locally after pull.

Recommended implementation location:

tools/dev_sync_relay

or extend the existing operator sidecar only if the boundary stays explicit:

tools/gravitational_lens/src/sync_relay.rs

The relay shall be labeled as a Relay Station / dev sync relay, not Benac Core.

4. Use C2-lite document/blob replication semantics

This ticket shall replicate eligible public documents and public blobs.

Eligible documents:

package
schema
artifact_ref
blob_manifest
blob_availability
signed_claim
name_binding
station_profile
invocation
evidence
effect
audit_event
capsule_manifest
replication_run
sync_peer

Authority-bearing documents may replicate only as inspectable foreign records and shall not become active local authority:

trust_decision
capability_grant
auth_session
authenticated_approval
authentication_event
key_status

Forbidden from replication/export by default:

station_keypair
private_key_base64url
raw secret material
raw auth credentials
raw private data
unredacted sensitive evidence
browser local-storage internals

Blobs eligible for replication in this ticket:

public package artifact blobs
public fixture blobs
public trace/capsule blobs

Private blobs and encrypted private envelopes are out of scope.

5. Replication is a host action, not a package capability

Sync push/pull operations are initiated by the Station UI/CLI. The Hello World package does not gain network capability.

Every sync push/pull shall record effects/evidence, but package invocations remain no-network.

6. The owner is an acceptance/input device, not a gate

The developer may use the owner for physical device operations that the developer cannot perform directly. The developer should not ask the owner to approve ordinary implementation choices.

When owner action is needed, send a compact operator request with:

Build SHA / URL
Device/browser needed
Exact steps
Expected visible result
What to report back
Whether screenshots are useful

The developer remains responsible for interpreting results and deciding next technical actions.

Required deliverables

  1. Android Chrome installed-PWA acceptance run.
  2. Ubuntu KDE Firefox browser acceptance run.
  3. Ubuntu KDE Chrome/Chromium browser acceptance run.
  4. Ubuntu shell Station CLI.
  5. Cross-platform acceptance matrix recorded in repo docs.
  6. Minimal dev sync relay or equivalent C2-lite replication mechanism.
  7. Browser Sync UI for configuring relay, pushing, pulling, and inspecting replicated data.
  8. CLI sync commands for push, pull, inspect, and run.
  9. At least three cross-Station replication scenarios with receipts.
  10. New conformance or integration tests covering C2-lite replication invariants.
  11. Updated closeout comment for the original Hello World ticket.

Phase 0 — Baseline guardrail and release SHA discipline

Implementation

cargo test --workspace
cargo run -p xtask -- build-hello-world-fixtures
trunk build apps/pwa/index.html --release --dist dist
cargo run -p xtask -- finalize-pwa-dist dist
cargo run -p xtask -- validate-pwa-dist dist

Done means

Phase 1 — Android Chrome installed PWA acceptance

Implementation

Android may require no code changes. Start by deploying the current static PWA and testing it.

Required Android flow:

  1. Open deployed URL in Android Chrome.
  2. Confirm build SHA.
  3. Install/Add to Home Screen.
  4. Launch from Home Screen.
  5. Confirm standalone or installed-app display where Chrome exposes it.
  6. Confirm service worker registration.
  7. Confirm Station ready with cryptographic Station principal.
  8. Import bundled Hello World capsule.
  9. Verify capsule/package/blob/claim inspection reports.
  10. Approve no-risk local execution by explicit gesture.
  11. Run declarative Hello World.
  12. Run WASM Hello World.
  13. Inspect latest trace.
  14. Export trace capsule.
  15. Disable network.
  16. Reload/reopen installed PWA.
  17. Run already-imported declarative Hello World offline.
  18. Run already-imported WASM Hello World offline.
  19. Re-enable network.
  20. Record acceptance evidence.

Acceptance instrumentation

Extend existing acceptance events as needed. Required Android event kinds:

page_loaded
service_worker_registered
station_ready
capsule_imported
trust_approved
invocation_declarative_succeeded
invocation_wasm_succeeded
trace_exported
offline_observed
offline_invocation_declarative_succeeded
offline_invocation_wasm_succeeded

Each event shall include:

{
  "build_sha": "...",
  "station_principal": "benac-principal:v0:ed25519:...",
  "platform_guess": "android_chrome",
  "pwa_standalone": true,
  "online": true,
  "client_at": "...",
  "user_agent": "..."
}

Owner-assisted step

The developer may ask the owner to perform the physical Android flow. Use the operator-request format. Do not ask the owner to approve implementation decisions.

Done means

Phase 2 — Ubuntu KDE desktop browser acceptance: Firefox and Chrome/Chromium

Implementation

Run the same deployed PWA on Ubuntu KDE 5.x in:

Firefox
Chrome or Chromium

Firefox is not required to prove desktop PWA installation if the browser does not expose an equivalent install flow. It is required to prove browser Station operation.

Chrome/Chromium should test the installable PWA path if available on the development machine.

Required browser flow for both Firefox and Chrome/Chromium:

  1. Open deployed URL.
  2. Confirm build SHA.
  3. Confirm service worker registration where supported.
  4. Confirm Station ready with cryptographic Station principal.
  5. Import bundled Hello World capsule.
  6. Approve no-risk local execution.
  7. Run declarative Hello World.
  8. Run WASM Hello World.
  9. Inspect latest trace.
  10. Export trace capsule.
  11. Reload page.
  12. Confirm imported package/trust state rehydrates.
  13. Run declarative and WASM again.
  14. Disable network or use browser offline mode where practical.
  15. Confirm app shell/offline behavior where service-worker support permits.

Playwright

Add or extend Playwright coverage for:

chromium
firefox

Use Playwright for repeatable browser automation, but keep manual real-browser acceptance on KDE as the final proof.

Required Playwright checks:

status page shows build SHA
station_ready appears
import bundled capsule succeeds
approve no-risk succeeds
declarative invocation succeeds
WASM invocation succeeds
trace page shows package hash, descriptor hash, implementation hash, Station principal
reload preserves station/package/approval state
untrusted fresh Station denial still leaves receipt

Done means

Phase 3 — Ubuntu shell Station CLI

Implementation

Add apps/station-cli with a benac-station binary.

Recommended command shape:

benac-station --state ./stations/ubuntu init
benac-station --state ./stations/ubuntu profile --json
benac-station --state ./stations/ubuntu import hello-world.benac-capsule.json
benac-station --state ./stations/ubuntu inspect package
benac-station --state ./stations/ubuntu approve hello-world --no-risk
benac-station --state ./stations/ubuntu invoke hello-world --impl declarative --request '{"message":"hello"}'
benac-station --state ./stations/ubuntu invoke hello-world --impl wasm --request '{"message":"hello"}'
benac-station --state ./stations/ubuntu traces list
benac-station --state ./stations/ubuntu traces export --out ubuntu-trace.benac-capsule.json
benac-station --state ./stations/ubuntu reset

CLI state layout

Use a simple file-backed local state directory:

stations/ubuntu/
  station_keypair.json          # local only; never replicated/exported by default
  documents/
    <document-id>.json
  blobs/
    sha256/<content-id-safe-name>.blob
  meta/
    station_profile.json
    last_trace.json

The CLI shall preserve the same content IDs and trace semantics as the PWA.

Required CLI behavior

Done means

Phase 4 — C2-lite replication data model

Implementation

Add a minimal replication model to core/browser/CLI.

New or updated logical objects:

sync_peer
replication_run
replication_checkpoint
replication_effect
replication_evidence

Add explicit document eligibility classification:

pub enum ReplicationEligibility {
    EligiblePublic,
    EligibleForeignInactiveAuthorityRecord,
    LocalOnlySecretOrKeyMaterial,
    PrivateOutOfScope,
    Unsupported,
}

Add APIs:

list_replication_candidates(scope) -> Vec<LogicalDocument>
classify_replication_eligibility(doc) -> ReplicationEligibility
apply_replicated_document(doc, origin) -> ReplicationApplyResult
list_public_blob_candidates(scope) -> Vec<BlobRef>
apply_replicated_blob(content_id, bytes, origin) -> BlobApplyResult

Authority handling

Replicated authority-bearing records shall be inspectable but inactive.

For example, when Station B pulls Station A's trust decision:

Station B may display: "Foreign trust decision from Station A"
Station B shall not use it to authorize package execution
Station B shall deny invocation until Station B creates its own local trust decision/capability grant

Required tests

replicated_package_is_inspectable_but_untrusted
replicated_trust_record_is_foreign_inactive
replicated_capability_grant_is_foreign_inactive
replicated_missing_blob_denies_execution
replicated_public_blob_verifies_by_hash
replicated_tampered_blob_rejected
private_key_never_in_replication_candidates
auth_session_not_active_after_replication

Done means

Phase 5 — Dev sync relay

Implementation

Implement a minimal HTTPS-compatible dev relay with JSON APIs.

Recommended endpoints:

GET  /relay/v0/health
POST /relay/v0/workspaces/{workspace}/docs
GET  /relay/v0/workspaces/{workspace}/docs?since={checkpoint}
POST /relay/v0/workspaces/{workspace}/blobs/{content_id}
GET  /relay/v0/workspaces/{workspace}/blobs/{content_id}
GET  /relay/v0/workspaces/{workspace}/manifest

The relay stores and returns bytes. It does not validate trust. Clients validate everything.

Request/response constraints

Evidence/effects

A Station pushing to the relay shall record:

replication_push_attempted
replication_push_completed or replication_push_failed
data_egress_public_documents
public_blob_upload_attempted/completed/failed

A Station pulling from the relay shall record:

replication_pull_attempted
replication_pull_completed or replication_pull_failed
replicated_document_applied/rejected
replicated_blob_verified/rejected

Done means

Phase 6 — Browser Sync UI

Implementation

Add a new PWA route:

/#/sync

Required UI sections:

  1. Local Station identity:

    • Station principal
    • Station profile hash
    • platform guess
    • build SHA
  2. Sync peer configuration:

    • relay URL
    • workspace name
    • connect/test button
    • clear peer button
  3. Push:

    • candidate document count by object type
    • candidate public blob count
    • warning that this is public/demo replication only
    • push button
  4. Pull:

    • last checkpoint
    • pulled document count
    • applied/rejected count
    • pulled blob count
    • missing blob count
    • pull button
  5. Replicated authority status:

    • list foreign trust/capability/auth records
    • show inactive_on_this_station: true
    • provide local approve button only through the existing Trust flow, not by activating foreign trust
  6. Latest replication records:

    • replication runs
    • effects
    • evidence
    • errors

Done means

Phase 7 — CLI sync commands

Implementation

Add CLI commands:

benac-station --state ./stations/ubuntu sync configure --relay https://benac.benac.dev/relay/v0 --workspace demo-001
benac-station --state ./stations/ubuntu sync status --json
benac-station --state ./stations/ubuntu sync push --json
benac-station --state ./stations/ubuntu sync pull --json
benac-station --state ./stations/ubuntu sync inspect --json
benac-station --state ./stations/ubuntu sync reset-checkpoint

Required behavior:

Done means

Phase 8 — Cross-Station replication scenarios

Scenario A — Desktop Chrome to Android

  1. Desktop Chrome imports/approves/runs Hello World.
  2. Desktop Chrome pushes eligible docs and public blob to relay.
  3. Android pulls from relay.
  4. Android sees replicated package/trace/claim/blob.
  5. Android invocation before local approval is denied with receipt.
  6. Android approves locally.
  7. Android runs declarative and WASM.

Done means:

replicated data visible on Android
foreign trust inactive on Android
local Android trust required
Android invocation succeeds only after local approval

Scenario B — Android to Ubuntu CLI

  1. Android runs Hello World and pushes trace records.
  2. Ubuntu CLI pulls.
  3. CLI inspects Android invocation/evidence/effect records.
  4. CLI verifies content IDs and signed claim status.
  5. CLI does not treat Android trust as local trust.

Done means:

CLI can inspect Android-origin records
CLI does not activate Android authority
CLI can export an inspection report

Scenario C — Ubuntu CLI to Firefox

  1. CLI imports/approves/runs Hello World.
  2. CLI pushes eligible docs/blobs.
  3. Firefox pulls.
  4. Firefox displays CLI Station profile and invocation records.
  5. Firefox invocation before local approval is denied.
  6. Firefox local approval enables local invocation.

Done means:

Firefox can consume CLI-origin replicated data
replicated trust remains inactive
local Firefox trust enables execution

Scenario D — Missing blob behavior

  1. Relay contains package/schema docs but omits the WASM blob.
  2. A Station pulls docs only.
  3. Station reports missing required blob.
  4. WASM invocation fails closed with receipt.
  5. After blob pull, Station verifies hash and can execute only with local trust.

Done means:

metadata-only replication does not execute
missing blob is clearly reported
verified blob acquisition changes availability state

Scenario E — Tampered relay content

  1. Relay or test fixture returns wrong bytes for a known blob content ID.
  2. Station rejects blob.
  3. Denial/integrity failure is recorded.

Done means:

tampered relay blob never reaches execution
integrity failure appears in evidence/effect/audit records

Phase 9 — Acceptance campaign and owner operator flow

Developer responsibilities

The developer shall own the campaign. The owner is available as a physical-device operator.

The developer shall:

Owner request template

Use this exact shape when owner action is needed:

Operator request: Android Chrome installed-PWA acceptance

Build SHA:
URL:
Device/browser:
Estimated physical action: one pass through the numbered checklist

Steps:
1. Open <URL> in Android Chrome.
2. Confirm the Status page shows build <SHA>.
3. Tap Add to Home Screen / Install if offered.
4. Launch Benac from the Home Screen.
5. Go to Packages and import bundled Hello World.
6. Go to Trust and approve no-risk local execution.
7. Go to Invoke and run Declarative.
8. Run WASM.
9. Go offline.
10. Reopen and run both again.
11. Re-enable network and tap Sync Push.

Please report:
- Did the app install/open from Home Screen?
- Did Declarative show hello/world?
- Did WASM show hello/world?
- Did offline reload work?
- Any visible error text?
- Screenshot only if something looks wrong.

Do not ask the owner whether to proceed with implementation choices.

Done means

Phase 10 — Conformance and documentation

Implementation

Update or add:

crates/benac-conformance/src/replication_lite_suite.rs
docs/checklists/c1-cross-platform-c2lite-acceptance.md
docs/reports/c1-cross-platform-c2lite-closeout.md

The closeout shall include:

Done means

Requirement coverage

This ticket primarily advances:

BENAC-SYS-001  Host-neutral core
BENAC-SYS-002  Mobile browser PWA baseline, now including Android
BENAC-SYS-003  Desktop platform support, Ubuntu browser + CLI slice
BENAC-SYS-004  Station profile publication
BENAC-SYS-006  Server is not authority
BENAC-DOC-001  Couch/Pouch-compatible document model shape
BENAC-DOC-002  Local-first operation
BENAC-DOC-003  Optional replication, C2-lite only
BENAC-DOC-004  Replication does not grant trust
BENAC-DOC-005  Immutable document identity
BENAC-DOC-006  Append-only record preference
BENAC-DOC-007  Conflict/authority fail-closed behavior, minimal authority-import handling
BENAC-BLOB-001  Local CAS blob store
BENAC-BLOB-002  Document-to-blob separation
BENAC-BLOB-003  Blob verification before use
BENAC-BLOB-006  Blob availability records
BENAC-BLOB-009  Missing blob fail-closed behavior
BENAC-BLOB-010  No silent remote fetch
BENAC-AUTH-012  Replication authentication/content trust separation, semantic subset
BENAC-TRUST-001 Local trust required
BENAC-TRUST-004 Signatures/foreign trust are evidence, not authority
BENAC-CAP-004   Data egress as effect, for sync push/pull
BENAC-INV-001   Invocation record required, including denials
BENAC-EVD-001   Evidence ledger
BENAC-EFF-001   Effect ledger
BENAC-EFF-002   Denied effects recorded
BENAC-IO-003    Export capsules
BENAC-IO-004    Missing blob reporting
BENAC-IO-005    Capsule integrity
BENAC-INT-004   Conformance test suite
BENAC-INT-005   Same portable package behavior
BENAC-UX-003    Trace inspection
BENAC-AVL-001   Offline app shell
BENAC-AVL-002   Offline package invocation
BENAC-AVL-003   Clear network/resource failure
BENAC-PERF-001  Mobile practicality
BENAC-SAFE-004  Fail-closed default

Final acceptance criteria

This ticket is complete when all of the following are true:

  1. Android Chrome installed PWA imports, approves, invokes declarative, invokes WASM, exports trace, reloads offline, and invokes offline.
  2. Ubuntu KDE Firefox browser imports, approves, invokes declarative, invokes WASM, inspects trace, reloads, and preserves Station state.
  3. Ubuntu KDE Chrome/Chromium browser imports, approves, invokes declarative, invokes WASM, inspects trace, reloads, and preserves Station state.
  4. Ubuntu CLI Station imports, approves, invokes declarative, invokes WASM, exports trace, and denies untrusted execution with a receipt.
  5. At least three distinct Station principals participate in replication evidence.
  6. At least one browser Station pushes to the relay and another browser Station pulls from it.
  7. At least one browser Station and the CLI Station replicate through the relay.
  8. Replicated package/trace data is inspectable on the receiving Station.
  9. Replicated foreign trust/capability/auth records are visible but inactive.
  10. Receiving Station invocation before local approval is denied with a persisted receipt.
  11. Receiving Station invocation after local approval succeeds.
  12. Missing replicated blob causes fail-closed denial and clear missing-blob reporting.
  13. Tampered relay blob is rejected by hash verification.
  14. Sync push/pull records effects/evidence and identifies public data egress.
  15. Export/replication candidates exclude private key material and raw secrets.
  16. Existing C1 Hello World conformance suite still passes.
  17. New C2-lite replication tests pass.
  18. Closeout documents platform matrix, Station principals, invocation IDs, sync runs, and residual gaps.

Reviewer rejection triggers

Reject this ticket if any of these occur:

Proposed resolution

All eleven phases of BENAC-C1-MATRIX-C2LITE-001 are complete and live. Build sha adb0ff10fc8f238d874189e3de976f3522f5d29d. Cross-platform engine matrix exercised on real iOS Safari (WebKit), real Android Chrome (Chromium), real Ubuntu Firefox 150 (Gecko), Ubuntu shell Station CLI, and headless Playwright Chromium. Cross-Station replication demonstrated against the live production relay at https://benac.benac.dev/relay/v0 with 4 distinct cryptographic Stations contributing 974 documents and 1 verified blob across 5 push batches; Scenarios D (missing blob) and E (tampered relay) each landed concrete persisted denial receipts. Live audit against the relay storage: 0 station_keypair records, 0 private_key_base64url leakage, 0 authority records — proving the C2-lite ReplicationScope::default() filter holds across real browser-driven pushes. Conformance suite has 47 checks passing (27 hello-world + 20 replication-lite). Closeout: docs/reports/c1-cross-platform-c2lite-closeout.md. Evidence: docs/reports/phase8-evidence/.

History (10 events)

Sign in as a human to drive this ticket from the page, or use the MCP tools.

← all tickets · home