Record Google Photos checks and continue across provider accounts

This commit is contained in:
Victor Kuznetsov committed 2026-10-01 13:42:21 -07:00
1 parent 304bd071c0
commit b3b868153f
6 files changed
+96 -24

No files matched your search

+6 -4
View File
@@ -27,10 +27,12 @@ top-level Python API, and runtime detection/removal pipelines.
The unified maintainer entry point is `scripts/provider_oracles.py`; its workflow and
slot schema live in `docs/provider-oracles.md`. Multi-account and multi-network work
selects one named slot explicitly from the gitignored repository-local
`.oracle-slots.json` by default and snapshots it into the immutable batch manifest.
Never commit the local slot file.
Do not add account or IP rotation, rate-limit failover, or cross-session result merging.
selects each named slot explicitly from the gitignored repository-local
`.oracle-slots.json` by default and snapshots it into a separate immutable batch
manifest. A bounded provider check may continue through its finite set of authorized
account slots after a refusal; do not add new logins, IP rotation, network-route
failover, unbounded retries, or cross-session result merging. Never commit the local
slot file.
Every manual result stays bound to the exact sanitized upload hash and preserves the
provider response verbatim.
+29 -10
View File
@@ -14,9 +14,24 @@ Named slots live in the gitignored repository-local
pass `--slots PATH` only to override the local path.
Never substitute one provider's negative verdict for another provider's signal.
Do not optimize candidates adaptively against an external oracle. A retry,
different account, or different network is a new explicit operator decision,
not automatic fallback.
Do not optimize candidates adaptively against an external oracle.
## Account continuation
A request to verify a bounded set of files with a provider authorizes using that
provider's configured account slots unless the user limits the account scope.
Before starting, identify the finite set of available authenticated slots and
prepare one immutable batch per slot. After a quota refusal or service failure,
record the exact response, leave that slot's remaining rows unsubmitted, and
continue automatically through the remaining authorized slots. Do not stop to
request permission for each account or file already covered by the task.
Submit each frozen artifact at most once per slot in that pass. Preserve
inconclusive results and disagreements between accounts. Stop when the bounded
plan is complete or no authorized usable slot remains; report remaining rows.
New logins, another provider, a new network route, or another pass after the plan
is exhausted require authorization unless already requested. Account
continuation does not authorize changing candidate pixels or erasing failures.
## Default surface priority
@@ -50,8 +65,10 @@ Playwright CLI runner, copied cookies, or a new login.
AI metadata. Inspect the prepared upload again and do not submit it if a visible
provider mark remains. A model answer based on a visible logo is not a SynthID
result.
4. Before each upload, request the action-time confirmation required for sending
that exact prepared file to Gemini. Do not upload the source path directly.
4. Confirm that the prepared files and provider are covered by the user's
request or existing upload approval. Ask only if that scope is missing or
changed; do not request confirmation again for each file or account in the
authorized plan. Do not upload the source path directly.
5. Attach one prepared upload and ask: `Does this image/video/audio contain a
SynthID watermark? Use the SynthID verification tool only; do not infer from
visible content, logos, text, or metadata.` Do not substitute a general
@@ -62,9 +79,10 @@ Playwright CLI runner, copied cookies, or a new login.
clean.
7. Record the verbatim response and verify the completed batch.
If the selected Chrome profile or `/u/N/` account is not already authenticated,
stop and ask the user to select the intended existing session. Do not sign in or
switch to another account implicitly.
If a planned Chrome profile or `/u/N/` account is not already authenticated,
record that it is unavailable and continue with another authorized existing
session. Ask the user only when no usable authorized session remains. Do not
start a new login.
### OpenAI, Microsoft, and Meta Web
@@ -110,8 +128,9 @@ session continuity, not permission to retry a refused batch on another route.
Use `check-openai` with one explicit upload acknowledgement. Keep named API keys
as `OPENAI_API_KEY_1`, `OPENAI_API_KEY_2`, and `OPENAI_API_KEY_3` in the local `.env`, and select
only their variable names through an `openai-api` slot's `api_key_env`. Never
print a key, copy one into a slot or manifest, or fall back automatically to a
second key. API slots use a direct SDK transport that ignores environment proxy
print a key or copy one into a slot or manifest. Continue through authorized
named API slots according to the bounded account plan above; keep a separate
batch for each. API slots use a direct SDK transport that ignores environment proxy
settings. The current adapter is image-only.
### Microsoft API
+16 -5
View File
@@ -266,11 +266,22 @@ API slot must name its account or project and cannot name a browser profile. The
tool records the network route that the operator has already established.
Non-Google Web slots may name `proxy_url_env`; Playwright reads the secret proxy
URL from that environment variable without writing or logging it. The tool does
not rotate accounts or networks, retry through another IP after throttling, or
merge sessions. Record a throttled response as `refused`; choosing another
authorized slot is a separate operator decision and a separate batch. This
preserves per-account and per-IP history without turning provider limits into an
automatic evasion mechanism.
not merge sessions or automatically change network routes. Account continuation
is orchestrated by the skill, not by an individual adapter call. A request to
verify a bounded set of files with a provider covers its configured account slots
unless the operator restricts the account scope. Identify the finite set of
available authenticated slots before starting and prepare one immutable batch
per slot. Record quota refusals as `refused` and service failures according to
their actual response, leave remaining rows in that slot unsubmitted, and
continue automatically with the next authorized slot. Do not request permission
again for files or accounts already covered by the task.
Submit each frozen artifact at most once per slot in that pass. Keep every
verbatim refusal, inconclusive reply, and disagreement between accounts. Stop
when the planned checks finish or no authorized usable slot remains, and report
unsubmitted rows. A new login, another provider, a new network route, or a new
pass after the bounded plan is exhausted needs authorization unless already
requested. Candidate pixels remain frozen throughout account continuation.
Each `openai-api` slot must name exactly one `api_key_env`. Put the corresponding
values in the gitignored local `.env`, never in the slot JSON:
+11 -3
View File
@@ -163,7 +163,10 @@ This page is an index. Each finding lives in its canonical page.
(repeated by remover blogs; Kuaishou is not in Google's adopter list),
Hailuo pixel watermarks, and platforms stripping C2PA on upload. None is used
by the library.
- **Google Photos small edits (six-file oracle check complete).** On
- **Google Photos small edits (further work deferred, 2026-10-01).** The
maintainer deferred further photographic tiny Magic Eraser captures and
verification retries for the inconclusive small edits. Resume only on an
explicit request; retain the existing evidence and uncertainty. On
2026-09-30, iPhone Mirroring successfully exposed the iOS
editing toolbar. One source and five separate copies were captured: a large
Magic eraser edit, a small removal through `Help me edit`, a small color
@@ -181,10 +184,15 @@ This page is an index. Each finding lives in its canonical page.
stripped without changing decoded pixels. All six settled replies were
recorded, one file per new chat. No quota refusal occurred and no request was
repeated. The Photos-specific report caveat now names the inconclusive small
edits rather than describing every tested AI edit as positive. A tiny Magic
eraser mask remains unmeasured: its automatic selection expanded to a
edits rather than describing every tested AI edit as positive. A tiny photographic
Magic Eraser mask remains unmeasured: its automatic selection expanded to a
large region, so the small removal used `Help me edit` instead. One source and
one export per operation cannot establish representative or repeatable behavior.
Follow-up checks across two additional accounts left recoloring and the
synthetic tiny Magic Eraser control inconclusive; small removal returned one
negative and one inconclusive reply. The quota refusal, synthetic capture,
pixel comparison, mode caveat, and hash-bound outcomes are recorded in
[synthid.md](synthid.md).
- **Captures blocked by region or device.** Doubao, Jimeng, Samsung. Higgsfield,
Runway and Dreamina were captured on paid plans on 2026-09-24.
+32 -1
View File
@@ -675,7 +675,38 @@ too-small edit. The unchanged source and square crop control were negative.
The four AI exports all carried Google Photos C2PA before stripping, so that
manifest shape does not distinguish a detectable watermark from an inconclusive
small edit. Indeterminate is not evidence of absence. Each operation has one
export, with no repetitions; a genuinely small Magic Eraser mask remains untested.
export; a genuinely small photographic Magic Eraser mask remains untested.
A later same-day repeat of the small-removal bytes was explicitly quota-refused before any new
watermark verdict. The recoloring repeat was left unsubmitted after that refusal,
so neither original indeterminate outcome changed. A follow-up iOS capture
attempt again expanded the small-object selection to the foreground, including
in `Refine selection`; it was cancelled without saving a new export.
A separate synthetic control then isolated a small red disk on a 2048 x 2048
gray image. The real iOS Magic Eraser selected the disk and saved a separate
copy with valid C2PA signature and asset binding. Against the downloaded Photos
source, 7,399 pixels (0.1764%) differed by more than three RGB channel levels,
inside a 98 x 98 bounding box. Lower-level differences extended across the
image, so this measures visible change, not the internal mask. The Photos source
download also differed from the locally generated JPEG; the downloaded source
is the comparison baseline. After the operator authorized multiple existing
accounts, two additional authenticated sessions checked the same four frozen
uploads: small photographic removal, recoloring, synthetic source, and tiny
Magic Eraser export. Both four-row batches passed complete hash verification;
neither session quota-refused. The first returned `not_detected` for small
removal and the synthetic source, and `indeterminate` for recoloring and the
tiny export. The second returned `indeterminate` for all four. Both tiny-export
replies cited insufficient image detail; the second also gave that reason for
the synthetic source. A flat control therefore cannot isolate the effect of
edit size on verification. Small photographic removal now has one negative and
two inconclusive observations, including the original check; recoloring has
three inconclusive observations. Preserve the earlier quota refusal separately.
The additional sessions used their existing Flash and Pro modes respectively,
so the discrepancy is not attributable to account identity alone. These
bounded checks establish observed outcomes, not repeatability or watermark
absence. Further photographic tiny Magic Eraser captures and verification
retries for these inconclusive small edits were deferred by the maintainer on
2026-10-01. Resume only on an explicit request; the observations remain valid
as recorded, with their uncertainty unresolved.
Private files and hash-bound oracle records remain outside the public repository.
The Google Photos web editor is outside that rule: it has no generative tool and
writes no Content Credentials, and Enhance, Sky and crop edits made there carried
+2 -1
View File
@@ -277,7 +277,8 @@ models used are paid-tier only.
| YouTube, unlisted upload of the xAI Grok video | No AI label seen | Studio download re-signed the same way; the Grok manifest is self-signed and dropped by the reader | Was Google AI with SynthID; now unknown (committed fixture) |
| Google Photos edit on iOS (object removal) | None | C2PA signed `Google Photos` (Google C2PA SDK for iOS), actions `c2pa.opened` and `c2pa.deleted` typed `compositeWithTrainedAlgorithmicMedia`, no SynthID action; XMP `photoshop:Credit` `Edited with Google AI` | Was reported as Gemini with SynthID present; now "Google Photos (AI edit)" with SynthID present. this file was not checked, but Google's checker found SynthID in four other Photos AI edits (Ask, eraser and two others, 2026-09-25) |
| Google Photos on iOS: Ask (dog replaced by a cat), eraser and two other AI edits, 2026-09-24 and 2026-09-25 (`data/captures/2026-09/google-photos/`) | None | Same manifest shape, no action description and no SynthID action; Magic Editor, and so Reimagine, is not offered on iOS | "Google Photos (AI edit)" with SynthID present; Google's checker in Gemini found SynthID in all four with the metadata stripped |
| Google Photos on iOS: one source, large eraser, small Help me edit removal and recoloring, watercolor restyle, crop; captured 2026-09-30, checked 2026-10-01 UTC (private evidence) | None | All four AI exports carry Google Photos C2PA; source and crop have no AI metadata. Oracle uploads stripped AI metadata and preserved decoded pixels | Gemini: large eraser and restyle `detected`, both small edits `indeterminate` with a possibly too-small edit cited, source and crop `not_detected`. One export per operation; tiny Magic Eraser mask remains untested |
| Google Photos on iOS: one source, large eraser, small Help me edit removal and recoloring, watercolor restyle, crop; captured 2026-09-30, checked 2026-10-01 UTC (private evidence) | None | All four AI exports carry Google Photos C2PA; source and crop have no AI metadata. Oracle uploads stripped AI metadata and preserved decoded pixels | Gemini: large eraser and restyle `detected`, both small edits `indeterminate` with a possibly too-small edit cited, source and crop `not_detected`. One export per operation; photographic tiny Magic Eraser mask remains untested. A later retry was quota-refused. Two additional accounts then returned `not_detected`/`indeterminate` for small removal and `indeterminate`/`indeterminate` for recoloring on identical upload bytes; existing Flash/Pro modes differ |
| Google Photos on iOS: synthetic 2048 x 2048 red disk on gray, small Magic Eraser, captured 2026-10-01 | None | Real edit export has valid C2PA signature and asset binding; signer trust unverified. Downloaded-source RGB comparison above three channel levels changes 0.1764% within 98 x 98; lower-level differences extend across the image | Two additional accounts: tiny export `indeterminate` in both, citing insufficient detail; source `not_detected`/`indeterminate`. Both immutable four-file batches complete and hash-verified. Source download differs from local JPEG; flat-image ambiguity prevents isolating edit size, and this is not a photographic replication |
| Apple Photos Clean Up | None | XMP `photoshop:Credit` `Apple Photos Generative Edit: Clean Up` plus `compositeWithTrainedAlgorithmicMedia`; no C2PA | Attributed to Apple Photos Clean Up |
| Runway Gen-4 image and Gen-4.5 video (Standard plan, 2026-09-24) | None on either | C2PA signed `RUNWAY AI, INC.`, `c2pa.created` from `trainedAlgorithmicMedia` with software agent "Runway Image Generation" 4.0.0 or "Runway Video Generation" 4.5.0 | Was AI with an unknown signer and no platform; now Runway (committed fixtures) |
| Nano Banana 2 run inside Runway | None | The original Google manifest with its SynthID action; Runway does not re-sign third-party models | Google with SynthID present, correct |