arcane-cli 0.26.2 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/assets/.arcane/governance/compliance-standards.md +238 -0
- package/dist/assets/.arcane/governance/mobile-release-standards.md +239 -0
- package/dist/assets/.claude/commands/spell-compliance.md +13 -0
- package/dist/assets/.claude/commands/spell-eas-store-deploy.md +13 -0
- package/dist/assets/.github/prompts/spell-compliance.prompt.md +129 -0
- package/dist/assets/.github/prompts/spell-eas-store-deploy.prompt.md +253 -0
- package/dist/index.js +18 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -120,14 +120,14 @@ Arcane isn't a prompt snippet — it's a full framework. Everything installs int
|
|
|
120
120
|
|
|
121
121
|
<!-- arcane:start -->
|
|
122
122
|
<details>
|
|
123
|
-
<summary><b>📜 The full spell catalogue (
|
|
123
|
+
<summary><b>📜 The full spell catalogue (40)</b></summary>
|
|
124
124
|
|
|
125
125
|
**Session** — `open-session` · `close-session` · `commit-work` · `status` · `arcane-version`
|
|
126
126
|
**Capture** — `save-idea` · `todo` · `feedback` · `suggest-feature` · `document` · `brainstorm` · `explain-concept`
|
|
127
127
|
**Delivery** — `create-pull-request` · `sync-pull-request` · `address-review`
|
|
128
128
|
**Review** — `review` · `review-batch`
|
|
129
129
|
**Planning** — `plan` · `architect` · `scope` · `product-review`
|
|
130
|
-
**Build** — `implement` · `test` · `full-cycle` · `bug` · `bump` · `dotnet-expert` · `security-review` · `ship` · `enchant` · `generate-bot-icons` · `make-discoverable` · `scry`
|
|
130
|
+
**Build** — `implement` · `test` · `full-cycle` · `bug` · `bump` · `dotnet-expert` · `security-review` · `ship` · `enchant` · `generate-bot-icons` · `make-discoverable` · `scry` · `eas-store-deploy` · `compliance`
|
|
131
131
|
**Docs** — `adopt-docs`
|
|
132
132
|
**Venture** — `summon-venture` · `manifest`
|
|
133
133
|
**Meta** — `present-arcane` · `check-drift`
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Compliance Standards
|
|
3
|
+
audience: both
|
|
4
|
+
last_updated: YYYY-MM-DD
|
|
5
|
+
status: active
|
|
6
|
+
distributable: true
|
|
7
|
+
tags: [compliance, privacy, gdpr, ccpa, soc2, hipaa]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Compliance Standards
|
|
11
|
+
|
|
12
|
+
A starting reference for the regulatory and privacy obligations a typical SaaS product runs into —
|
|
13
|
+
GDPR, CCPA, SOC 2, and HIPAA — mapped to the concrete artifacts a product actually needs (data
|
|
14
|
+
inventory, consent, retention/deletion, breach notification, access controls, audit logs), plus a
|
|
15
|
+
tiered guide for which frameworks plausibly apply at which stage.
|
|
16
|
+
|
|
17
|
+
**This is not legal advice.** It is a governance reference and a self-assessment starting point,
|
|
18
|
+
written at the level of established, uncontroversial obligations — not a substitute for a qualified
|
|
19
|
+
lawyer's analysis of a specific business's specific facts. Applicability determinations, especially
|
|
20
|
+
close calls, should be confirmed with counsel before being treated as settled.
|
|
21
|
+
|
|
22
|
+
## Executive Summary
|
|
23
|
+
|
|
24
|
+
- GDPR and CCPA both apply based on **whose data you handle and how**, not where your business is
|
|
25
|
+
incorporated — a US-only company with EU visitors or California residents can still be in scope.
|
|
26
|
+
- Both frameworks converge on the same underlying artifacts regardless of which one applies: know what
|
|
27
|
+
personal data you hold and why (a data inventory), get real consent before non-essential processing,
|
|
28
|
+
define and enforce retention/deletion periods, and be able to act on a user's rights request within a
|
|
29
|
+
bounded time.
|
|
30
|
+
- SOC 2 is an operational-controls attestation, not a privacy law — it becomes relevant when a customer
|
|
31
|
+
(typically enterprise) requires it contractually, not from a regulatory trigger.
|
|
32
|
+
- HIPAA has a narrow trigger: it applies to covered entities and their business associates handling
|
|
33
|
+
protected health information specifically. Most consumer SaaS products never trigger it.
|
|
34
|
+
- Treat this doc as a checklist of what to go verify, not as verification itself — every rule below
|
|
35
|
+
names the artifact or evidence that would actually demonstrate compliance, not just the obligation in
|
|
36
|
+
the abstract.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Rule index
|
|
41
|
+
|
|
42
|
+
| ID | Rule (one line) |
|
|
43
|
+
|----|------|
|
|
44
|
+
| CS-01 | GDPR applies based on whose data is processed (EU residents) and what the processing does (offering goods/services, or monitoring behavior), regardless of where the business is based. |
|
|
45
|
+
| CS-02 | GDPR requires a documented lawful basis for every category of processing, and grants data subjects enforceable rights (access, rectification, erasure, portability, objection) with a response-time bound. |
|
|
46
|
+
| CS-03 | GDPR requires notifying the relevant supervisory authority of a qualifying personal-data breach within 72 hours of becoming aware of it. |
|
|
47
|
+
| CS-04 | CCPA/CPRA applies based on revenue/data-volume thresholds and California residency, and grants consumers rights to know, delete, correct, and opt out of sale/sharing of their personal information. |
|
|
48
|
+
| CS-05 | A CCPA-covered business must provide a clear opt-out mechanism for the sale/sharing of personal information, not just a general privacy policy. |
|
|
49
|
+
| CS-06 | Consent, where required by either framework, must be specific, informed, freely given, and distinguishable from other terms — pre-ticked boxes and bundled consent do not qualify. |
|
|
50
|
+
| CS-07 | A data inventory (what personal data exists, where, and why) is the prerequisite artifact every other obligation in this doc depends on — rights requests and retention policy are both unenforceable without it. |
|
|
51
|
+
| CS-08 | Data minimization requires a defined retention period per data category and actual deletion at the end of it — not merely marking a record inactive. |
|
|
52
|
+
| CS-09 | SOC 2 is a controls attestation against the Trust Services Criteria, not a privacy law — Security is mandatory, the other four criteria are opted into based on what a customer's contract or questionnaire actually requires; Type I attests to a point in time, Type II to operating effectiveness over a period. |
|
|
53
|
+
| CS-10 | SOC 2's Security criterion expects least-privilege access control, periodic access reviews, and audit logging of access to systems holding customer data. |
|
|
54
|
+
| CS-11 | HIPAA applies narrowly, to covered entities and their business associates handling protected health information — most consumer SaaS products never trigger it. |
|
|
55
|
+
| CS-12 | Which frameworks plausibly apply changes by product stage: a privacy policy and lawful-basis/consent groundwork are day-one MVP concerns if any EU or California user could sign up; a working data-subject-request process is a public-launch concern; SOC 2 readiness typically becomes an enterprise-sales-stage concern, not an earlier one. |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## GDPR
|
|
60
|
+
|
|
61
|
+
### CS-01: Applicability is about whose data and what processing, not where the business sits
|
|
62
|
+
|
|
63
|
+
The GDPR applies to any organization processing the personal data of individuals in the EU, when that
|
|
64
|
+
processing relates to offering goods or services to those individuals (paid or free) or to monitoring
|
|
65
|
+
their behavior — regardless of whether the organization itself has any EU presence. A US-only company
|
|
66
|
+
with EU visitors signing up for a free product is a plausible trigger; a company with zero EU users is
|
|
67
|
+
not, but "zero" needs to be an actual verified fact about the user base, not an assumption based on
|
|
68
|
+
where the company is headquartered.
|
|
69
|
+
|
|
70
|
+
**Rule (CS-01):** Determine GDPR applicability from the actual or intended user base's location and
|
|
71
|
+
what the processing does, never from the business's own location alone.
|
|
72
|
+
|
|
73
|
+
### CS-02: A lawful basis and enforceable data-subject rights
|
|
74
|
+
|
|
75
|
+
Every category of personal-data processing needs a documented lawful basis (consent, contract necessity,
|
|
76
|
+
legal obligation, legitimate interest, among others) — "we're processing it" is not itself a basis. Data
|
|
77
|
+
subjects additionally hold enforceable rights: access to their data, rectification of inaccuracies,
|
|
78
|
+
erasure ("right to be forgotten"), portability to another provider, and objection to certain processing.
|
|
79
|
+
Requests exercising these rights carry a response deadline (commonly one month, extendable in limited
|
|
80
|
+
cases) — a rights-request process that has no defined owner or turnaround time is itself a gap, even
|
|
81
|
+
before any request arrives.
|
|
82
|
+
|
|
83
|
+
**Rule (CS-02):** Document a lawful basis per processing category, and maintain a working process — with
|
|
84
|
+
a defined owner and turnaround time — for handling data-subject rights requests.
|
|
85
|
+
|
|
86
|
+
### CS-03: 72-hour breach notification
|
|
87
|
+
|
|
88
|
+
A personal-data breach that risks the rights and freedoms of data subjects must be reported to the
|
|
89
|
+
relevant supervisory authority within 72 hours of the organization becoming aware of it. This clock
|
|
90
|
+
starts at awareness, not at confirmation of scope — an incident-response process that only begins
|
|
91
|
+
drafting a notification after a full investigation completes risks missing the window entirely.
|
|
92
|
+
|
|
93
|
+
**Rule (CS-03):** Have a breach-notification process that can produce an initial report to the
|
|
94
|
+
supervisory authority within 72 hours of awareness, even before the full scope of an incident is known.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## CCPA / CPRA
|
|
99
|
+
|
|
100
|
+
### CS-04: Threshold-based applicability and consumer rights
|
|
101
|
+
|
|
102
|
+
CCPA (as amended by CPRA) applies to for-profit businesses collecting California residents' personal
|
|
103
|
+
information that meet at least one threshold — commonly framed around annual revenue, the volume of
|
|
104
|
+
consumers'/households' data processed, or revenue from selling/sharing personal information (exact
|
|
105
|
+
thresholds are set in statute and updated periodically; verify current figures rather than treating any
|
|
106
|
+
number here as current). Covered businesses must honor consumer rights to know what's collected, delete
|
|
107
|
+
it, correct inaccuracies, and opt out of the sale or sharing of their personal information, plus limit
|
|
108
|
+
use of sensitive personal information on request.
|
|
109
|
+
|
|
110
|
+
**Rule (CS-04):** Verify CCPA's current statutory thresholds against the business's actual revenue and
|
|
111
|
+
data volume, rather than assuming applicability (or non-applicability) from the business's category
|
|
112
|
+
alone.
|
|
113
|
+
|
|
114
|
+
### CS-05: A real opt-out mechanism, not just a policy statement
|
|
115
|
+
|
|
116
|
+
A covered business must provide a clear, functioning mechanism for a consumer to opt out of the sale or
|
|
117
|
+
sharing of their personal information — commonly a "Do Not Sell or Share My Personal Information" link
|
|
118
|
+
or an equivalent global-privacy-control-honoring mechanism. Stating an opt-out right exists in a privacy
|
|
119
|
+
policy's prose, without a working mechanism a consumer can actually use, does not satisfy the
|
|
120
|
+
requirement.
|
|
121
|
+
|
|
122
|
+
**Rule (CS-05):** Verify the opt-out mechanism itself functions end-to-end — a link that exists in the
|
|
123
|
+
footer but doesn't actually stop the described sharing is not compliant, regardless of what the privacy
|
|
124
|
+
policy says.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Shared obligations (both frameworks)
|
|
129
|
+
|
|
130
|
+
### CS-06: Consent must be real, not assumed
|
|
131
|
+
|
|
132
|
+
Where either framework requires consent, it must be specific to the processing purpose, informed (the
|
|
133
|
+
person understands what they're agreeing to), freely given (not a condition of using an unrelated
|
|
134
|
+
feature), and distinguishable from other terms — not buried in a general terms-of-service acceptance.
|
|
135
|
+
Pre-ticked checkboxes, and consent bundled with acceptance of unrelated terms, do not qualify as valid
|
|
136
|
+
consent under either framework.
|
|
137
|
+
|
|
138
|
+
**Rule (CS-06):** Any consent mechanism must be opt-in (not pre-ticked), specific to its actual purpose,
|
|
139
|
+
and separable from acceptance of unrelated terms.
|
|
140
|
+
|
|
141
|
+
### CS-07: A data inventory is the load-bearing prerequisite
|
|
142
|
+
|
|
143
|
+
Honoring an access, deletion, or portability request requires first knowing what personal data exists,
|
|
144
|
+
where it lives, and why it was collected. Without a maintained data inventory (sometimes called a
|
|
145
|
+
Records of Processing Activities under GDPR Article 30), every downstream rights-request and retention
|
|
146
|
+
obligation is unenforceable in practice, even if a policy document claims it's honored — there is no way
|
|
147
|
+
to actually locate everything that would need to be produced, corrected, or deleted.
|
|
148
|
+
|
|
149
|
+
**Rule (CS-07):** Maintain a data inventory naming what personal data is collected, where it's stored,
|
|
150
|
+
and why, before treating any rights-request or retention process as operational.
|
|
151
|
+
|
|
152
|
+
### CS-08: Retention periods must be defined and actually enforced
|
|
153
|
+
|
|
154
|
+
Data minimization requires defining how long each category of personal data is kept and why, then
|
|
155
|
+
actually deleting it at the end of that period — not simply flagging a record as inactive or archived
|
|
156
|
+
while the underlying data persists indefinitely. An undefined retention period is itself a gap, distinct
|
|
157
|
+
from and prior to the question of whether deletion is correctly implemented.
|
|
158
|
+
|
|
159
|
+
**Rule (CS-08):** Define a retention period per data category, and verify deletion is real (data is
|
|
160
|
+
actually removed, not merely deactivated) at the end of that period.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## SOC 2
|
|
165
|
+
|
|
166
|
+
### CS-09: A controls attestation, not a privacy law — and Type I vs. Type II matters
|
|
167
|
+
|
|
168
|
+
SOC 2 is an attestation against the AICPA's Trust Services Criteria, produced by an independent auditor
|
|
169
|
+
— it has no regulatory trigger of its own and becomes relevant when a customer's contract or security
|
|
170
|
+
questionnaire requires it, typically at the enterprise sales stage. The Security criterion is mandatory
|
|
171
|
+
for any SOC 2 report; Availability, Processing Integrity, Confidentiality, and Privacy are each opted
|
|
172
|
+
into based on what's actually being attested to. A **Type I** report attests that controls were
|
|
173
|
+
suitably designed at a single point in time; a **Type II** report attests that those controls actually
|
|
174
|
+
operated effectively over an observation period (commonly 3-12 months) — a Type I report does not
|
|
175
|
+
substitute for a Type II when a customer's requirement specifically calls for one.
|
|
176
|
+
|
|
177
|
+
**Rule (CS-09):** Confirm which Trust Services Criteria and which report type (I vs. II) a customer's
|
|
178
|
+
actual requirement calls for before scoping a SOC 2 engagement — do not assume Security-only Type I
|
|
179
|
+
satisfies a requirement that wasn't explicitly checked against what was asked for.
|
|
180
|
+
|
|
181
|
+
### CS-10: Access control and audit logging are the operational backbone
|
|
182
|
+
|
|
183
|
+
SOC 2's Security criterion expects least-privilege access to systems holding customer data, periodic
|
|
184
|
+
review of who has access to what (not just at onboarding), and audit logging of access to
|
|
185
|
+
sensitive systems sufficient to reconstruct who did what and when. These are the same operational
|
|
186
|
+
controls a real security program needs regardless of whether a SOC 2 report is ever pursued — building
|
|
187
|
+
them only when an audit is scheduled means starting the evidentiary trail late.
|
|
188
|
+
|
|
189
|
+
**Rule (CS-10):** Implement least-privilege access control, periodic access review, and audit logging of
|
|
190
|
+
access to customer-data-holding systems as an ongoing practice, not as audit-time preparation.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## HIPAA
|
|
195
|
+
|
|
196
|
+
### CS-11: A narrow trigger — covered entities and business associates handling PHI
|
|
197
|
+
|
|
198
|
+
HIPAA applies to covered entities (health plans, healthcare clearinghouses, healthcare providers that
|
|
199
|
+
transmit health information electronically) and their business associates — vendors that create,
|
|
200
|
+
receive, maintain, or transmit protected health information (PHI) on a covered entity's behalf. A
|
|
201
|
+
typical consumer SaaS product with no health-data handling does not trigger HIPAA merely by having
|
|
202
|
+
users who happen to be patients elsewhere; the trigger is the product's own handling of PHI, not its
|
|
203
|
+
users' medical status in general.
|
|
204
|
+
|
|
205
|
+
**Rule (CS-11):** Confirm HIPAA applicability specifically against whether the product creates,
|
|
206
|
+
receives, maintains, or transmits PHI as a covered entity or business associate — do not assume
|
|
207
|
+
applicability (or safety from it) based on the target market alone.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Tiered applicability guide
|
|
212
|
+
|
|
213
|
+
### CS-12: What plausibly applies at which stage
|
|
214
|
+
|
|
215
|
+
- **Early MVP:** if the product could realistically have any EU visitor or California resident sign up —
|
|
216
|
+
which is the default for anything reachable on the open internet — a privacy policy and a documented
|
|
217
|
+
lawful basis/consent approach are day-one concerns, not deferred ones. Waiting until "we have real
|
|
218
|
+
users" to start is waiting until the obligation is already live.
|
|
219
|
+
- **Public launch:** a working data-subject-request process (someone owns it, there's a defined
|
|
220
|
+
turnaround) and a real, functioning consent/opt-out mechanism move from "nice to have documented" to
|
|
221
|
+
"will actually be exercised by a real person" — this is the stage where CS-02, CS-05, CS-06, and CS-07
|
|
222
|
+
need to be operational, not just written down.
|
|
223
|
+
- **Enterprise sales stage:** SOC 2 readiness (CS-09, CS-10) typically becomes relevant when a customer's
|
|
224
|
+
procurement or security-questionnaire process asks for it — building the access-control and logging
|
|
225
|
+
practices in CS-10 well before an audit is scheduled makes the eventual Type II observation period
|
|
226
|
+
starts from real evidence rather than a scramble. HIPAA (CS-11) becomes relevant only if the business
|
|
227
|
+
is entering healthcare specifically, at whatever stage that happens.
|
|
228
|
+
|
|
229
|
+
**Rule (CS-12):** Use product stage as a prompt to re-check applicability, not as a substitute for
|
|
230
|
+
checking it — a pre-launch product with EU beta users is already in GDPR's scope regardless of stage.
|
|
231
|
+
|
|
232
|
+
## Related
|
|
233
|
+
|
|
234
|
+
- [[.arcane/governance/threat-model|Threat Model]] and
|
|
235
|
+
[[.arcane/governance/hardening-checklist|Hardening Checklist]] — the security-control side of SOC 2 and
|
|
236
|
+
breach-notification readiness overlaps with these existing docs; this doc doesn't restate their
|
|
237
|
+
content.
|
|
238
|
+
- `spell-compliance` — the runnable self-assessment that cites these rules by ID.
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Mobile Release Standards
|
|
3
|
+
audience: both
|
|
4
|
+
last_updated: YYYY-MM-DD
|
|
5
|
+
status: active
|
|
6
|
+
distributable: true
|
|
7
|
+
tags: [mobile, app-store, google-play, release, deployment]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Mobile Release Standards
|
|
11
|
+
|
|
12
|
+
Durable facts about how the Apple App Store and Google Play review consoles and release pipelines
|
|
13
|
+
actually behave — true regardless of which build tool produced the binary. These are platform
|
|
14
|
+
properties, not Expo/EAS-specific tooling behavior; the EAS-specific workflow that consumes these rules
|
|
15
|
+
lives in `spell-eas-store-deploy`. Sourced from two real dogfooding runs (a first-ever App Store
|
|
16
|
+
submission, then a from-zero Google Play listing to a live production release) — every rule here was hit
|
|
17
|
+
for real, not derived from documentation alone.
|
|
18
|
+
|
|
19
|
+
## Executive Summary
|
|
20
|
+
|
|
21
|
+
- A store's review/track model is not symmetric with the other store's, and approval on one track never
|
|
22
|
+
promotes a binary anywhere else — treat each track and each store as its own release, not a step in a
|
|
23
|
+
shared pipeline.
|
|
24
|
+
- Several consoles distinguish "saved" from "submitted," and several silently drop scripted input —
|
|
25
|
+
verify the console's own state readout before trusting that an action took effect (`EV-01`/`EV-03`).
|
|
26
|
+
- Identity and signing facts (the certificate an installed app actually presents, which `(package,
|
|
27
|
+
SHA-1)` pair an integration is keyed to, where a public developer address actually comes from) are
|
|
28
|
+
frequently not visible on the console page you'd naturally check — read them from the artifact or the
|
|
29
|
+
system that actually enforces them, not from a console summary.
|
|
30
|
+
- Two platform-specific binary/UI constraints (notification icon requirements, a native dialog's button
|
|
31
|
+
cap) have no equivalent on the other platform and are easy to carry over incorrectly from iOS-first
|
|
32
|
+
development.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Rule index
|
|
37
|
+
|
|
38
|
+
| ID | Rule (one line) |
|
|
39
|
+
|----|------|
|
|
40
|
+
| MR-01 | Google Play's tracks are independent: only *internal testing* skips review, and approval on any one track never promotes the binary to another. |
|
|
41
|
+
| MR-02 | A fresh Google Play production track starts with zero countries/regions, which surfaces as a generic, uninformative release error. |
|
|
42
|
+
| MR-03 | Google Play console edits are staged until an explicit "send for review" action; saving is not submitting. |
|
|
43
|
+
| MR-04 | Google Play's IARC content-rating questionnaire re-renders when the app category changes, shifting rows under answers already given. |
|
|
44
|
+
| MR-05 | "Data collected" means data that leaves the device — and both stores' privacy/data-safety declarations must agree with each other. |
|
|
45
|
+
| MR-06 | The two stores' supported locale catalogues differ; do not copy one store's locale list onto the other. |
|
|
46
|
+
| MR-07 | Reviewer/demo-account access is scoped per app, not per account type, and is length-capped. |
|
|
47
|
+
| MR-08 | Google Play's "no deobfuscation file" warning is benign and permanent until a mapping file is uploaded. |
|
|
48
|
+
| MR-09 | The signing certificate an installed Android app actually presents can differ from what any single console page shows — read it from the device, never infer it. |
|
|
49
|
+
| MR-10 | Android OAuth clients are keyed to one `(package name, SHA-1)` pair each, and ship with the custom-URI-scheme toggle off by default. |
|
|
50
|
+
| MR-11 | Google Play sources the public developer address from the D-U-N-S record; confirming it in-console locks in whatever address is currently on file. |
|
|
51
|
+
| MR-12 | Audit the permissions the built artifact actually declares, not what the source code appears to use. |
|
|
52
|
+
| MR-13 | Android push-notification icons need a dedicated monochrome asset shipped in a native build; there is no OTA path for this. |
|
|
53
|
+
| MR-14 | Android's native `AlertDialog` silently caps at three buttons; a menu built on `Alert.alert` past that cap loses the overflow, typically the dismiss action. |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Release tracks and console state
|
|
58
|
+
|
|
59
|
+
### MR-01: Google Play's tracks are independent — nothing promotes automatically
|
|
60
|
+
|
|
61
|
+
*Internal testing* publishes with no review. *Closed*, *open*, and *production* each trigger a real
|
|
62
|
+
review. Passing review on one track says nothing about any other track: production is a wholly separate
|
|
63
|
+
release, with its own binary assignment and its own country list. An operator who watches a closed-test
|
|
64
|
+
release turn green will reasonably conclude the app is live to the public — it is not, and nothing in
|
|
65
|
+
the console actively corrects that assumption.
|
|
66
|
+
|
|
67
|
+
**Rule (MR-01):** Treat each Google Play track as an independent release requiring its own review and
|
|
68
|
+
its own configuration; passing review on one track never promotes the binary to another.
|
|
69
|
+
|
|
70
|
+
### MR-02: A fresh production track starts with zero countries — and fails silently about why
|
|
71
|
+
|
|
72
|
+
Countries and regions are configured per track, not once per app. A brand-new production track therefore
|
|
73
|
+
starts with none selected. The release wizard responds to this with a generic "We found some problems
|
|
74
|
+
with your release / To save, fix errors" that never names the actual cause. The real signal is the track
|
|
75
|
+
summary reading `0 countries / regions` — set the country list on the track before attempting to build
|
|
76
|
+
the release, not after the generic error appears.
|
|
77
|
+
|
|
78
|
+
**Rule (MR-02):** Before building a release for any Google Play track, confirm its country/region list
|
|
79
|
+
is non-empty; a generic "fix errors" message with no named cause is this failure's signature.
|
|
80
|
+
|
|
81
|
+
### MR-03: Saving is not submitting
|
|
82
|
+
|
|
83
|
+
Google Play console edits land in the Publishing overview as staged changes. They reach Google only
|
|
84
|
+
through an explicit "Send changes for review" action, which itself carries a second confirmation dialog.
|
|
85
|
+
A workflow that stops at "Save" ships nothing. The listing pages carry the identical trap under a
|
|
86
|
+
differently-worded "Save and publish" action with its own second dialog.
|
|
87
|
+
|
|
88
|
+
**Rule (MR-03):** After any Google Play console edit, look for and complete the explicit send-for-review
|
|
89
|
+
(or save-and-publish) action and its confirmation dialog — "saved" is not a release state.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Console review quirks
|
|
94
|
+
|
|
95
|
+
### MR-04: The IARC questionnaire re-renders on category change
|
|
96
|
+
|
|
97
|
+
Changing an app's category in the Google Play console causes the IARC content-rating questionnaire to
|
|
98
|
+
re-render, shifting which question sits at which row. A batch of clicks issued against the prior layout
|
|
99
|
+
lands on the wrong questions and can silently set an unintended answer — including sensitive categories
|
|
100
|
+
like graphic violence or location sharing.
|
|
101
|
+
|
|
102
|
+
**Rule (MR-04):** Answer the IARC questionnaire one question at a time, and re-read the full form after
|
|
103
|
+
any change to the app's category, rather than assuming the row order is stable.
|
|
104
|
+
|
|
105
|
+
### MR-08: The "no deobfuscation file" warning is benign and permanent
|
|
106
|
+
|
|
107
|
+
Google Play shows a "no deobfuscation file" warning on every release once mapping-file upload isn't
|
|
108
|
+
wired up. This warning does not resolve itself and does not indicate a build defect — it will appear on
|
|
109
|
+
every future release until a mapping file is actually uploaded. State this explicitly wherever it
|
|
110
|
+
appears in documentation or in-flight guidance, since it reads as alarming on a first submission.
|
|
111
|
+
|
|
112
|
+
**Rule (MR-08):** Treat Google Play's "no deobfuscation file" warning as an expected, permanent state
|
|
113
|
+
absent mapping-file upload — not a signal of a broken release.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Cross-store consistency
|
|
118
|
+
|
|
119
|
+
### MR-05: "Collected" means leaves the device — and the two stores' answers must agree
|
|
120
|
+
|
|
121
|
+
Google Play's data-safety framework and Apple's App Privacy responses both hinge on the same underlying
|
|
122
|
+
definition: data is "collected" only if it leaves the device. Purely on-device processing is not
|
|
123
|
+
collection. Because both declarations are public, a reviewer or a user can compare them directly — the
|
|
124
|
+
two stores' answers for the same app must describe the same underlying behavior, not merely satisfy each
|
|
125
|
+
store's form independently.
|
|
126
|
+
|
|
127
|
+
**Rule (MR-05):** Data-safety and privacy declarations across both stores must agree with each other on
|
|
128
|
+
what is actually collected, using "leaves the device" as the collection test in both places.
|
|
129
|
+
|
|
130
|
+
### MR-06: The stores' locale catalogues differ
|
|
131
|
+
|
|
132
|
+
Release notes are supplied per-language, and the set of locales each store's catalogue supports is not
|
|
133
|
+
identical between Apple and Google. A locale available on one store may not exist on the other, so a
|
|
134
|
+
default-language or locale-coverage choice has to be made against each store's own list — never copied
|
|
135
|
+
across from the other store's configuration.
|
|
136
|
+
|
|
137
|
+
**Rule (MR-06):** Resolve locale/language coverage against each store's own supported-locale list
|
|
138
|
+
independently; do not assume the other store's locale set applies.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Access, identity, and signing
|
|
143
|
+
|
|
144
|
+
### MR-07: Reviewer access is scoped per app and length-capped
|
|
145
|
+
|
|
146
|
+
The demo-credentials/reviewer-access box is required per app, not per account type, and has a length
|
|
147
|
+
cap. An app with genuinely distinct account types (consumer vs. business, for example) needs one working
|
|
148
|
+
account supplied directly, with prose describing how a reviewer reaches the other flows — there is no
|
|
149
|
+
mechanism for supplying multiple credential sets natively.
|
|
150
|
+
|
|
151
|
+
**Rule (MR-07):** Provide one working reviewer account per app submission, with any additional
|
|
152
|
+
account-type flows described in prose rather than as separate credentials.
|
|
153
|
+
|
|
154
|
+
### MR-09: Read the actual signing certificate — never infer it
|
|
155
|
+
|
|
156
|
+
Google Play App Signing, combined with "automatic protection," can result in an installed app presenting
|
|
157
|
+
a signing certificate that does not appear on any console page an operator would naturally check.
|
|
158
|
+
Anything keyed to a `(package, SHA-1)` pair — Maps API keys, Google Sign-In, App Links / `assetlinks.json`
|
|
159
|
+
— then fails specifically on Play-delivered installs while working normally on sideloaded builds. Zero
|
|
160
|
+
traffic in a provider's own usage metrics is not evidence the app isn't calling it (an auth failure can
|
|
161
|
+
occur before any billable request is logged), and a working browser-based OAuth flow proves nothing
|
|
162
|
+
about certificate matching, since that flow never checks certificates. This is the same discipline
|
|
163
|
+
`EV-01` states in general form — re-read the actual persisted/served state, never trust the interface —
|
|
164
|
+
applied to a case where the "interface" is a console page that may not even show the value in question.
|
|
165
|
+
|
|
166
|
+
**Rule (MR-09):** Never infer an Android signing SHA-1 from a console page; read the certificate the
|
|
167
|
+
installed app actually presents, via `adb logcat` against a Play-delivered install (`EV-01`).
|
|
168
|
+
|
|
169
|
+
### MR-10: Android OAuth clients are scoped to one `(package, SHA-1)` pair, custom scheme off by default
|
|
170
|
+
|
|
171
|
+
Each Android OAuth client is keyed to exactly one `(package name, SHA-1)` combination — a Play-signed
|
|
172
|
+
install, an upload-signed sideload, and a separate `.dev` build variant each need their own client, not a
|
|
173
|
+
shared one. Separately, new Android OAuth clients ship with "Enable custom URI scheme" switched off by
|
|
174
|
+
default; leaving it off produces a visible `Error 400: invalid_request`, which is a console
|
|
175
|
+
configuration gap, not a code defect.
|
|
176
|
+
|
|
177
|
+
**Rule (MR-10):** Provision one Android OAuth client per distinct `(package, SHA-1)` pair, and confirm
|
|
178
|
+
"Enable custom URI scheme" is on for any client that needs a custom-scheme redirect.
|
|
179
|
+
|
|
180
|
+
### MR-11: The public developer address comes from D-U-N-S, and confirming it locks it in
|
|
181
|
+
|
|
182
|
+
Google Play publishes the developer's address on the public listing, and that address is not directly
|
|
183
|
+
editable inside Play — it is sourced from the developer's D-U-N-S record. The console offers only
|
|
184
|
+
"confirm" or "contact D&B." Clicking "confirm" first locks in whatever address is currently on file,
|
|
185
|
+
which for a solo operator is frequently a home address. The correct order is: fix the address at D&B
|
|
186
|
+
first, wait for propagation (days to weeks), let Google re-sync, and only then confirm. Android developer
|
|
187
|
+
verification carries its own hard deadline, so this correction needs to start early enough that the
|
|
188
|
+
D&B propagation window still fits before that deadline.
|
|
189
|
+
|
|
190
|
+
**Rule (MR-11):** Correct the address at the D-U-N-S source and allow it to propagate before confirming
|
|
191
|
+
it in the Google Play console — confirming first permanently publishes whatever address is on file at
|
|
192
|
+
that moment.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Binary and platform specifics
|
|
197
|
+
|
|
198
|
+
### MR-12: Audit what the binary actually declares, not what the code appears to use
|
|
199
|
+
|
|
200
|
+
A dependency that is installed but no longer called from application code still contributes its declared
|
|
201
|
+
permissions to the built artifact, and every declared permission is both review and data-safety surface.
|
|
202
|
+
The only reliable check is against the artifact itself (`aapt2 dump permissions`, or an equivalent raw
|
|
203
|
+
manifest inspection) — inspecting source code for call sites is not equivalent, since an unused
|
|
204
|
+
dependency's manifest entries survive independently of whether anything still calls it. Removing a
|
|
205
|
+
permission means removing the dependency that declares it, and the removal must be re-verified against a
|
|
206
|
+
newly built artifact, not assumed from the source diff.
|
|
207
|
+
|
|
208
|
+
**Rule (MR-12):** Verify declared permissions against the actually built artifact, not against source
|
|
209
|
+
code's apparent usage, both before submission and after removing a permission-declaring dependency.
|
|
210
|
+
|
|
211
|
+
### MR-13: Android notification icons need a dedicated asset, shipped natively
|
|
212
|
+
|
|
213
|
+
Android requires a dedicated monochrome, white-on-transparent small icon for notifications; without one,
|
|
214
|
+
the system falls back to a generic glyph in the notification shade. This is a native configuration
|
|
215
|
+
change and therefore ships only in a build — there is no OTA path for it. When diagnosing a "broken"
|
|
216
|
+
notification icon, check the notification shade specifically rather than the heads-up banner, since some
|
|
217
|
+
OEM skins legitimately omit the small icon from the banner view while still rendering it correctly in the
|
|
218
|
+
shade. The branded, full-color icon slot is `largeIcon`, a separate asset from the required small icon.
|
|
219
|
+
|
|
220
|
+
**Rule (MR-13):** Ship a dedicated monochrome small-icon asset for Android notifications in a native
|
|
221
|
+
build (never an OTA), and diagnose icon issues via the notification shade, not the heads-up banner.
|
|
222
|
+
|
|
223
|
+
### MR-14: Android's native `AlertDialog` caps at three buttons
|
|
224
|
+
|
|
225
|
+
Android's native `AlertDialog` silently drops any button past a hard cap of three. A menu built on
|
|
226
|
+
`Alert.alert` with more than three options loses whatever falls past the cap — in practice, typically
|
|
227
|
+
the *Cancel* row, leaving a dialog with no way to dismiss it. iOS has no equivalent limit
|
|
228
|
+
(`ActionSheetIOS` supports an arbitrary option count).
|
|
229
|
+
|
|
230
|
+
**Rule (MR-14):** For any Android menu that could exceed three options, use a real bottom sheet
|
|
231
|
+
dismissible at least three ways (an explicit cancel row, a scrim tap, and the hardware back gesture)
|
|
232
|
+
instead of `Alert.alert`.
|
|
233
|
+
|
|
234
|
+
## Related
|
|
235
|
+
|
|
236
|
+
- [[.arcane/governance/external-verification-standards|External Verification Standards]] — `EV-01`
|
|
237
|
+
(re-read persisted state) and `EV-03` (trust the readout, escalate rather than retry) are the general
|
|
238
|
+
principles `MR-09` applies to Android's signing-certificate opacity specifically.
|
|
239
|
+
- `spell-eas-store-deploy` — the runnable EAS Build + EAS Submit workflow that cites these rules by ID.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Use PROACTIVELY before a launch, an enterprise sales cycle, or a security questionnaire that raises GDPR/CCPA/SOC 2/HIPAA questions.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Compliance
|
|
6
|
+
|
|
7
|
+
Invoke the Arcane `spell-compliance` spell workflow.
|
|
8
|
+
|
|
9
|
+
See the full prompt at `.github/prompts/spell-compliance.prompt.md` for the complete workflow definition.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
@.github/prompts/spell-compliance.prompt.md
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Use PROACTIVELY when deploying an Expo app to the App Store or Google Play via EAS.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# EAS Store Deploy
|
|
6
|
+
|
|
7
|
+
Invoke the Arcane `spell-eas-store-deploy` spell workflow.
|
|
8
|
+
|
|
9
|
+
See the full prompt at `.github/prompts/spell-eas-store-deploy.prompt.md` for the complete workflow definition.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
@.github/prompts/spell-eas-store-deploy.prompt.md
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Spell — Compliance
|
|
3
|
+
description: Run a regulatory compliance self-assessment against this repo (GDPR, CCPA, SOC 2, HIPAA) and produce a prioritized remediation checklist. Read-only — never drafts policies or fixes gaps automatically.
|
|
4
|
+
argument-hint: Optional focus (e.g., "GDPR only", "pre-launch check", "SOC 2 readiness")
|
|
5
|
+
agent: agent
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Executive Summary
|
|
9
|
+
|
|
10
|
+
- This spell self-assesses a repo's compliance posture against GDPR, CCPA, SOC 2, and HIPAA, and
|
|
11
|
+
produces a prioritized remediation checklist.
|
|
12
|
+
- **It is read-only.** It never drafts a privacy policy, invents a retention period, or fixes a gap on
|
|
13
|
+
its own — every finding is a checklist item for a human (often with legal input) to act on.
|
|
14
|
+
- **This is not legal advice**, and the report says so explicitly. It is a starting self-assessment
|
|
15
|
+
against established, uncontroversial obligations — not a substitute for a qualified lawyer's analysis
|
|
16
|
+
of this specific business's specific facts.
|
|
17
|
+
- Findings cite `CS-nn` rule IDs from
|
|
18
|
+
[`compliance-standards.md`](../../.arcane/governance/compliance-standards.md) — the rationale for each
|
|
19
|
+
obligation lives there, not restated here.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Context files
|
|
24
|
+
|
|
25
|
+
- [governance/compliance-standards.md](../../.arcane/governance/compliance-standards.md) — every
|
|
26
|
+
`CS-nn` rule this spell checks against. Rules are **cited by ID only** in this spell, never restated.
|
|
27
|
+
**If the file is not installed**, this spell still runs in full — findings just cite each check as
|
|
28
|
+
`CS-nn (rationale unavailable — install the standards doc)` instead of linking to it.
|
|
29
|
+
- `threat-model.md` and `hardening-checklist.md`, if present — the security-control evidence for `CS-10`
|
|
30
|
+
(access control, audit logging) frequently already exists in these docs rather than needing to be
|
|
31
|
+
assessed fresh.
|
|
32
|
+
- `project.md` / `.arcane.json` — for the business context (target users, whether the product could
|
|
33
|
+
plausibly reach EU or California residents, whether it handles health data) that Phase 1 needs.
|
|
34
|
+
|
|
35
|
+
## Phase 1 — Determine applicability (ask, don't assume)
|
|
36
|
+
|
|
37
|
+
Applicability determinations have real consequences, so resolve each of the following by checking the
|
|
38
|
+
repo's own context first (`project.md`, `.arcane.json`, existing docs); **ask the operator directly**
|
|
39
|
+
for anything not resolvable from those sources — never assume:
|
|
40
|
+
|
|
41
|
+
- Could the product realistically reach EU residents (any public-internet-reachable consumer product
|
|
42
|
+
defaults to yes) — GDPR relevance (`CS-01`).
|
|
43
|
+
- Does the business meet, or plausibly approach, CCPA/CPRA's revenue or data-volume thresholds, and
|
|
44
|
+
could it reach California residents — CCPA relevance (`CS-04`). State plainly that exact thresholds
|
|
45
|
+
should be verified against current statute, not assumed from this spell's own knowledge.
|
|
46
|
+
- Is a customer, prospect, or procurement process currently asking for a SOC 2 report, or is one
|
|
47
|
+
expected within a near-term sales cycle — SOC 2 relevance (`CS-09`).
|
|
48
|
+
- Does the product create, receive, maintain, or transmit protected health information as a covered
|
|
49
|
+
entity or business associate — HIPAA relevance (`CS-11`). State plainly that this is a narrow trigger,
|
|
50
|
+
not a default.
|
|
51
|
+
|
|
52
|
+
Record which frameworks are in scope for this run and why, before proceeding — a framework judged
|
|
53
|
+
out of scope is reported as such in Phase 4, not silently skipped without explanation.
|
|
54
|
+
|
|
55
|
+
## Phase 2 — Inventory (read-only)
|
|
56
|
+
|
|
57
|
+
Enumerate what compliance-relevant artifacts already exist, without judging sufficiency yet:
|
|
58
|
+
|
|
59
|
+
- A privacy policy — does one exist, and where.
|
|
60
|
+
- A data inventory / Records of Processing Activities doc — does one exist and does it name what
|
|
61
|
+
personal data is collected, where it's stored, and why.
|
|
62
|
+
- A retention/deletion policy — does one exist, and does it define a period per data category.
|
|
63
|
+
- Consent mechanism indicators — a cookie/consent banner, a consent-management SDK, an opt-in flow in
|
|
64
|
+
the signup path; and separately, a "Do Not Sell or Share" link or equivalent opt-out mechanism.
|
|
65
|
+
- Existing security documentation this repo may already ship (`threat-model.md`,
|
|
66
|
+
`hardening-checklist.md`, `authentication-strategy.md`) — relevant evidence for `CS-10` without
|
|
67
|
+
needing to reassess it from scratch.
|
|
68
|
+
- Breach-notification process — is there a documented incident-response process with a named owner and
|
|
69
|
+
a notification path.
|
|
70
|
+
|
|
71
|
+
Report anything not found as absent, not as failed — Phase 3 is where absence becomes a finding against
|
|
72
|
+
a specific applicable rule.
|
|
73
|
+
|
|
74
|
+
## Phase 3 — Audit
|
|
75
|
+
|
|
76
|
+
For each framework marked in-scope in Phase 1, check its rules from `compliance-standards.md` against
|
|
77
|
+
what Phase 2 found. Mark each `PASS` / `FAIL` / `PARTIAL`, citing the rule ID only:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
CS-07 FAIL — no data inventory found; a data inventory is the prerequisite artifact CS-02/CS-04's
|
|
81
|
+
rights-request obligations depend on.
|
|
82
|
+
CS-06 PARTIAL — a consent banner exists, but the "accept all" and "reject non-essential" options are
|
|
83
|
+
not visually equivalent, which is a common consent-validity gap.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Do not restate why a rule matters — that reasoning lives in `compliance-standards.md`; cite the ID and
|
|
87
|
+
state the evidence.
|
|
88
|
+
|
|
89
|
+
## Phase 4 — Report
|
|
90
|
+
|
|
91
|
+
Produce a prioritized remediation checklist: mandatory-baseline gaps (GDPR/CCPA, if in scope) before
|
|
92
|
+
optional-tier gaps (SOC 2, HIPAA), and structural prerequisites (a missing data inventory) before the
|
|
93
|
+
rights-request/consent mechanisms that depend on them.
|
|
94
|
+
|
|
95
|
+
```markdown
|
|
96
|
+
## Compliance Self-Assessment — [repo name]
|
|
97
|
+
|
|
98
|
+
**Frameworks assessed:** [list, with in-scope/out-of-scope reasoning from Phase 1]
|
|
99
|
+
**Date:** [timestamp]
|
|
100
|
+
|
|
101
|
+
> This is a self-assessment against established compliance obligations, not legal advice. Confirm any
|
|
102
|
+
> finding below with qualified counsel before treating it as a compliance determination.
|
|
103
|
+
|
|
104
|
+
### Findings, by priority
|
|
105
|
+
|
|
106
|
+
#### Mandatory baseline (GDPR / CCPA)
|
|
107
|
+
- [ ] CS-07 — [gap + what artifact would close it]
|
|
108
|
+
|
|
109
|
+
#### Optional tier (SOC 2 / HIPAA), if in scope
|
|
110
|
+
- [ ] CS-10 — [gap + what artifact would close it]
|
|
111
|
+
|
|
112
|
+
### Out of scope this run
|
|
113
|
+
- [Framework] — [why, per Phase 1's determination]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Rules
|
|
117
|
+
|
|
118
|
+
This spell defers entirely to
|
|
119
|
+
[governance/compliance-standards.md](../../.arcane/governance/compliance-standards.md) for what each
|
|
120
|
+
obligation means and why. Findings in this spell cite rule IDs; they do not re-explain them. This spell
|
|
121
|
+
never drafts a policy document, never invents a retention period or lawful basis on the operator's
|
|
122
|
+
behalf, and never claims to produce a legal compliance determination — every output is a checklist item
|
|
123
|
+
for a human to act on, with legal input where the finding calls for it.
|
|
124
|
+
|
|
125
|
+
## Related
|
|
126
|
+
|
|
127
|
+
- [Compliance Standards](../../.arcane/governance/compliance-standards.md)
|
|
128
|
+
- **Feeds into:** the operator's own remediation work — this spell does not fix gaps, it enumerates
|
|
129
|
+
them.
|