You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b008b15
Browse filesBrowse the repository at this point in the historyBrowse files
Improve cross-border data gate and consent improvements
Refactor SECTL data transmission to require dual consent:
- Introduced `IsServicesPolicyAccepted` and updated `IsEgressAllowed`
to enforce both SECTL policy and cross-border notice acceptance.
- Enhanced `EnsureTransferAcceptedAsync` to sequentially collect
user consent for SECTL services and cross-border data transfer.
Updated UI logic to reflect new consent requirements:
- Added `IsSectlEgressConsented` in `FirstRunOobeViewModel` to bind
UI state to dual consent status.
- Adjusted `FirstRunOobeWindow.axaml` and `VerificationSettingsPage`
to enable controls only when both consents are granted.
Improved default behavior for attestation uploads:
- Treated `AttestationUploadMode.Unset` as "do not upload" until
explicit user choice is made.
Clarified SECTL traffic gating:
- Ensured `OnlineStatusMode` does not control SECTL access.
- Excluded NIST Beacon from SECTL gating.
Added mandatory reading periods and checkboxes to consent dialogs.
Copy file name to clipboardExpand all lines: AGENTS.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -153,7 +153,7 @@ Keep this map short and stable. When code moves, AI agents should re-read the mo
153
153
- Point-call students and lottery prizes use `RecordId` as the internal stable identity for history/fairness. The visible `Id` field is optional display metadata only and must not be required by import, draw, or history logic.
154
154
- A roll-call student or lottery prize candidate must be enabled and have a nonblank `Id` or `Name`. Import may map either column and excludes rows where both are blank.
155
155
- Picking `ClearRecord` controls temporary draw records only; do not clear persistent profile histories from that setting. RollCall and QuickDraw share the same student temporary record store, while Lottery uses prize temporary records.
156
-
- Privacy settings split Sentry upload from online status reporting: `SentryTelemetryEnabled` only controls `SecRandom/Services/Telemetry/`, while `OnlineStatusMode` only controls `SecRandom/Services/OnlineStatusService.cs`. In this fork both channels default to off (`SentryTelemetryEnabled = false`, `OnlineStatusMode = Off`, which also disables `PlatformUsageReportService`), because their data still goes to the upstream SecRandom/SECTL infrastructure — the Sentry DSN and the SECTL endpoints are unchanged. Any surface that exposes these toggles must state that enabling them sends data to SecRandom and SECTL rather than to this fork; the OOBE privacy step and the privacy settings page both carry that notice, and the OOBE privacy policy repeats it per section. The OOBE legal page also carries a separate SECTL disclosure (`C_SecRandomServicesClause`: online features require a separate agreement with SECTL, an independent entity, which gains access to uploaded data; `C_SecRandomServicesDisclaimer`: using the online features accepts SecRandom's terms and privacy policy and forms a direct service relationship with SECTL to which VeriRandom is not a party) with the copied `SecRandomPrivacyPolicy` text (the fork's policy with the product name changed back to SecRandom) and its own checkbox. That acknowledgement is **optional** during first-run setup (the page says so in bold) and does NOT gate `IsPrivacyPolicyOnlyRequired()`: `SecRandomServicesConsent` demands it, through the same second-level confirmation dialog, the first time an action would actually send data to SecRandom/SECTL — switching to formal notarization or enabling Sentry telemetry / online status — and declining reverts that action. The formal-notarization confirmation dialog carries the upstream description plus a bold "note" and warning, and appends the SECTL disclosure with a required checkbox whenever the consent version is below current. Every deliberate-consent dialog in this flow (the notarization mode switch and the online-services acknowledgement) must arm `ConfirmDialogGate`, so its confirm button stays disabled for a five-second minimum reading period in addition to the required checkboxes.
156
+
- Privacy settings split Sentry upload from online status reporting: `SentryTelemetryEnabled` only controls `SecRandom/Services/Telemetry/`, while `OnlineStatusMode` only controls `SecRandom/Services/OnlineStatusService.cs`. In this fork both channels default to off (`SentryTelemetryEnabled = false`, `OnlineStatusMode = Off`, which also disables `PlatformUsageReportService`), because their data still goes to the upstream SecRandom/SECTL infrastructure — the Sentry DSN and the SECTL endpoints are unchanged. Any surface that exposes these toggles must state that enabling them sends data to SecRandom and SECTL rather than to this fork; the OOBE privacy step and the privacy settings page both carry that notice, and the OOBE privacy policy repeats it per section. The OOBE legal page also carries a separate SECTL disclosure (`C_SecRandomServicesClause`: online features require a separate agreement with SECTL, an independent entity, which gains access to uploaded data; `C_SecRandomServicesDisclaimer`: using the online features accepts SecRandom's terms and privacy policy and forms a direct service relationship with SECTL to which VeriRandom is not a party) with the copied `SecRandomPrivacyPolicy` text (the fork's policy with the product name changed back to SecRandom) and its own checkbox. That acknowledgement is **optional** during first-run setup (the page says so in bold) and does NOT gate `IsPrivacyPolicyOnlyRequired()`: `SecRandomServicesConsent` demands it, through the same second-level confirmation dialog, the first time an action would actually send data to SecRandom/SECTL — switching to formal notarization or enabling Sentry telemetry / online status — and declining reverts that action. `SectlTrafficPolicy` (app-layer) is the one gate every path that could send data to SECTL must pass, and it requires **both** acknowledgements: upstream's SECTL online-services policy (`AcceptedSecRandomServicesVersion`) and the fork's cross-border data transfer notice (`AcceptedCrossBorderTransferVersion`). Declining either one closes sign-in, heartbeat, cloud backup, online status, usage counters, the version report, and proof attestation. Never gate SECTL traffic on `OnlineStatusMode` alone — `PlatformVersionReportService` is deliberately not privacy-gated, so it must consult this policy explicitly. Ordinary-draw attestation additionally requires `VerificationSettingsConfig.AttestationUpload == Enabled`, and `Unset` (never asked) must never upload. The formal-notarization confirmation dialog carries the upstream description plus a bold "note" and warning, and appends the SECTL disclosure with a required checkbox whenever the consent version is below current. Every deliberate-consent dialog in this flow (the notarization mode switch and the online-services acknowledgement) must arm `ConfirmDialogGate`, so its confirm button stays disabled for a five-second minimum reading period in addition to the required checkboxes.
157
157
-`OnlineStatusMode` gates the SECTL online-status and usage-counter channels (`SecRandom/Services/OnlineStatusService.cs`, `PlatformUsageReportService`) but deliberately not `PlatformVersionReportService`; a version figure is not a privacy-gated channel, so a fork-level "no SECTL traffic" consent must gate it explicitly instead of relying on `OnlineStatusMode`.
158
158
- Usage statistics are a third, separate channel: `PlatformUsageReportService` counts roll-call, lottery, and app-launch events through the platform-neutral `UsageMetricCounter` and posts `platform_id`/`field_key`/`delta` daily increments to `https://appwrite.sectl.cn/api/stats/usage/increment`. The payload deliberately carries **no** time field: the service side stamps each increment with its own receive time and owns the weekly/monthly/lifetime figures, so the client's clock and timezone can never move an event into another bucket and no client-generated period string (`period`) is sent at all. The client therefore reports only the `daily_*` field keys (`daily_roll_call_count`, `daily_lottery_count`, `daily_app_launch_count`) and keeps just the current local day's counts plus the unsent increment queue in `data/config/usage-stats.json`. It is gated by `PrivacySettingsConfig.OnlineStatusMode == Off`, counts a draw only after the transactional commit succeeded, persists counters by atomic replace, restores a failed increment for the next attempt (so a partial batch is never replayed wholesale), and must stay best-effort — no statistics failure may reach a draw. The service-side counters are shared with the v2 client, which still reports its own period strings, so a server that starts deriving the coarser periods from daily rows must not do so for v2 traffic as well.
159
159
- Version usage is the fourth statistics figure: `PlatformVersionReportService` posts `platform_id`/`version`/`device_uuid` to `https://appwrite.sectl.cn/api/stats/version`, where the service dedups by identity and keeps one current version per identity (the sum over versions is the platform's deduplicated user count, which `/api/fields/values` and `/api/stats/usage/increment` cannot produce). The account identity the API also accepts (`user_id`) is deliberately **never** sent: a version figure must not be tied to a SECTL account, so the lowercase `DeviceUuidStore` device UUID is the only identity and the payload carries nothing else. It is deliberately **not** gated by `OnlineStatusMode` either — the version mix is the project's own release baseline — and its payload stays minimal for that reason: the version plus that one device UUID, never an address, region, or account. It reports exactly once per process (the API asks for one report per start; no polling, no retry storm, no state), so nothing has to be re-reported when a user signs in or out. The reported version is `GlobalConstants.Version` **including its `v` prefix**, because the service groups people by that exact string (do not switch it to `Tag` or strip the prefix). The report must stay on the thread pool (`Task.Run` from `ExecuteAsync`): `Host.StartAsync` runs a hosted service synchronously up to its first incomplete await, so the device-UUID file access and the HTTP send must neither run on nor delay the startup thread; a rejected or unreachable endpoint only costs statistics.
0 commit comments