Why this is a separate decision and not an amendment
rank: decision outranks: [] doc_id: PTV-DEC-0020 title: A credential shipped to every client install is disclosed, not stored date: 2026-08-17 status: closed owner: petrova-codes scaffold: PTV-SCF-0001 phase: P4 supersedes: none depends_on: docs/decisions/2026-08-17-what-counts-as-a-credential-store.md
Section titled “rank: decision outranks: [] doc_id: PTV-DEC-0020 title: A credential shipped to every client install is disclosed, not stored date: 2026-08-17 status: closed owner: petrova-codes scaffold: PTV-SCF-0001 phase: P4 supersedes: none depends_on: docs/decisions/2026-08-17-what-counts-as-a-credential-store.md”Why this is a separate decision and not an amendment
Section titled “Why this is a separate decision and not an amendment”PTV-DEC-0018 defines a credential store as any location, reachable by a
running deployment, from which that deployment obtains a secret it did not
receive through its platform environment variables. Nothing in that sentence
distinguishes a server process reading a key from a client binary that carries
the key to every install, and PTV-DEC-0018 §“Where the definition turns out
to be wrong” requires the repair to arrive as a new decision doc rather than as
an edit.
The case is not hypothetical. sparki-tools/mobile-ios is DEPLOYED via
Firebase App Distribution and TestFlight and carries 26 runtime-fetch
candidate hits — 26 of the 98 that survive PTV-FND-0052’s triage. Counting
them under the existing definition, or dropping them, both misreport, and
leaving them unadjudicated is a hole in PTV-DEC-0019 clause 4 whichever way it
is counted.
The distinction
Section titled “The distinction”A store and a shipped credential differ in the only property the sweep exists to measure — who can reach the secret.
| credential store | disclosed credential | |
|---|---|---|
| Reachable by | one running deployment under our control | every install, on hardware we do not control |
| Rotation | change the store, done | requires a client release, and old builds keep the old value indefinitely |
| Revocation | effective immediately | effective only after adoption; unrotatable in the installed base |
| Enumerable | yes, by reading the deployment | yes, by anyone with the binary |
| Blast radius | the deployment | every user, plus anyone who unpacks the app |
A disclosed credential is strictly worse than a store, not a variant of one. Treating it as a store understates it, because every mitigation a store affords — rotate, revoke, restrict — is either unavailable or delayed by a release cycle.
The decision
Section titled “The decision”- A credential embedded in, or fetched into, an artefact distributed to end users is not a credential store. It is a disclosed credential, a separate and more severe category.
N8N-27does not adjudicate disclosed credentials. The 26sparki-tools/mobile-ioshits leave the store candidate set, reducing it to 72 hits across 8 repos, and are handed to a new item rather than dropped.- The exclusion is recorded as a limit in
PTV-DEC-0019’s residual, in the form that makes the negative mean something: N8N-27’s store list excludes client-distributed artefacts by decision, and one repo with 26 candidate hits is known to be in that class. - The store definition in
PTV-DEC-0018is unchanged. This document narrows what N8N-27 adjudicates; it does not rewrite what a store is.
What this does not decide
Section titled “What this does not decide”- Whether the 26 hits are real credentials. They are unadjudicated
candidates in
runtime-fetch, one of the four classes whose only control is synthetic at 4/10 recall. The new item inherits both the candidates and the recall bound. - Whether other repos in the estate ship client artefacts. Exactly one was found among 29 candidate repos, by reading two workflows. No enumeration of client-distributed artefacts across the estate has been run, and this document must not be read as implying one has.
- Anything about
runtime-fetchon the server side. The class keeps its 50 remaining server-side hits insideN8N-27.
Amendment — 2026-08-18, before countersign (PTV-FND-0047)
Section titled “Amendment — 2026-08-18, before countersign (PTV-FND-0047)”Appended, not edited (MR-7).
The instance this document was written for does not exist.
sparki-tools/mobile-ios has never shipped a binary: zero Actions secrets at
repo scope and in both environments, six consecutive iOS Deploy failures, the
latest run’s jobs Deploy to Testing → failure and Deploy to Development → skipped, nothing since 2026-03-15. Its verdict is corrected to UNBUILT and
its 26 hits are code copies. No repo in N8N-27’s candidate set ships a
client-distributed artefact.
What survives. The distinction itself — that a credential shipped to every
install is disclosed rather than stored, and strictly worse because rotation
requires a release while the installed base keeps the old value — does not depend
on the instance and is not withdrawn. This document becomes pre-registration
for a case that has not yet occurred, which is the same posture PTV-DEC-0018
was written in and a sound one.
What changes. Clause 2’s arithmetic is void: the store candidate set is 72 hits across 8 repos because 26 hits were found unreachable, not because they were moved out of scope. The two routes reach the same figure and the coincidence must not be read as corroboration.
This decision no longer gates PTV-DEC-0019. It was blocking on the ground
that 26 unadjudicable hits left a hole in clause 4. There are no such hits.
Countersign it on the merits of the distinction, whenever, or leave it open — it
holds nothing up.
Countersign
Section titled “Countersign”- Human countersign — a shipped credential is disclosed rather than stored,
and
N8N-27closes its store list without adjudicating the 26 hits insparki-tools/mobile-ios
Countersigned by human:alex@devarno.com on 2026-08-18 — restated here from
this document’s own prior status: line (countersigned 2026-08-18 — alex@devarno.com), mapped to the recognized open|closed|superseded
vocabulary 2026-09-05. No fact about who signed or when is changed.
Unchecked, this decision is open, the 26 hits remain formally inside
N8N-27’s candidate set, and clause 4 cannot close.