Files
felhom.eu/documentation/audits/SPIKE-facebook-page-api-2026-10-08.md
T
admin e9e6300cfc
gates / gates (push) Successful in 4m35s
Spike: Facebook Page reached after the operator's Page click; scheduled post + photo created, read back byte-equal, deleted
Read phase passes (Page 1360018983863273, CREATE_CONTENT/MODERATE/ANALYZE, page token PAGE expires_at 0, three insights
metrics alive on v26.0). Write test: removal check accepts Meta's code-10 'Object does not exist' (fixed without a row,
4 tests); run 1 evidence kept. R-914 READY, R-915 narrowed to Live mode.
2026-10-08 18:38:25 +02:00

7.5 KiB
Raw Blame History

SPIKE — can Claude Code run the Felhom.eu Facebook Page? (2026-10-08)

Verdict: yes. The system-user key is valid and never expires; it reaches the Felhom.eu Page with every task the skill needs; a scheduled text post and a scheduled photo were created, read back byte-equal (Hungarian accents) and deleted, each removal proven by a failed GET. Open: posts made while the app is in development mode are seen only by people with a role on the app (read, not measured) — public posting needs the app switched to Live (R-915).

Baseline felhom.eu @ fe0dc0d03f. Probe: scripts/facebook/fb_probe.py (stdlib; tests test_fb_probe.py). Evidence: facebook-page-api-2026-10-08/ — read run at the top level, write-test/ the passing write run, write-test-run1-strict-check/ the first write run (see „Removal proof"). Graph API v26.0 accepted, no fallback. Grades: measured = this run; read = Meta's documentation, not run.

Architecture: no document in documentation/architecture/ covers marketing or social media (checked 00–12). Correct — the Page is a business tool, not part of the product. Decision home: CONTEXT.md (2026-10-08, „Facebook Page"); rows R-914, R-915.

Timeline. First read (twice): /me/accounts empty — the app was assigned to the robot, the Page was not. The operator assigned the Page (Business settings → Pages → Felhom.eu → assign felhom-cc); the same key, not regenerated, then saw the Page. A system-user token is not pinned to a Page list (measured).

Findings

Question Answer Grade Evidence
Key valid? type? is_valid: true, SYSTEM_USER, app 2273465403490709 (felhom.eu) measured A1-debug-token.json
Does it expire? expires_at: 0, data_access_expires_at: 0 — never measured A1
Scopes read_insights, pages_show_list, business_management, pages_read_engagement, pages_read_user_content, pages_manage_posts, pages_manage_engagement, public_profile; granular scopes carry no target_ids measured A1
Robot id 122094150717513084 (app-scoped), name felhom-cc; Business Suite shows it as 61595392523486 (business-scoped) — the same robot measured B1-me.json
Page reached exactly one: Felhom.eu, Graph ID 1360018983863273 (the browser profile address shows 61595336666018) measured B2-me-accounts.json
Page tasks CREATE_CONTENT, MODERATE, MESSAGING, ADVERTISE, ANALYZE, MANAGE_LEADS, VIEW_MONETIZATION_INSIGHTS measured B2
Page token derived from /me/accounts?fields=…,access_token; type: PAGE, expires_at: 0; a fresh value on each derivation (199 / 201 chars) measured B3-debug-page-token.json
Page fields name, link, category Information Technology Company, about, website, followers_count 0, fan_count 0 measured C1-page.json
Feed 1 post (profile picture update) measured C2-feed.json
Insights (v26.0, period=day) page_post_engagements, page_follows, page_media_view all answer (values 0) — none deprecated measured C3-insights-*.json
Scheduled text post — D POST /{page}/feed message, published=false, scheduled_publish_time=now+7d → id {page}_{post}; read back is_published: false, scheduled_publish_time equal, message hex equal measured write-test/D1, D2, D9-verdict.json
Scheduled photo — E POST /{page}/photos multipart source (website/assets/logo.png), caption, published=false, scheduled_publish_time → only id (a photo id), no post_id; photo name read back hex equal; DELETE on the photo id measured write-test/E1, E3, E9-verdict.json
Is App Review / Live needed to post? No refusal in development mode: both writes answered HTTP 200 — no (#200), (#10) or (#3) measured D1, E1
Dev-mode posts visible to the public? No: „Any data generated while an app is in Development mode, such as test posts, can only be seen by role users"; visible to all once the app is Live read app modes
App Review for our own Page? Standard Access is automatic and covers users/assets with a role on the app; Advanced Access (review + business verification) is for others' assets read access levels
What does Live need? display name, contact e-mail, Terms of Service URL, app icon, category, app purpose (each „required to switch your app to Live mode"); Privacy Policy URL and data-deletion URL listed beside them read basic settings
Headers facebook-api-version: v26.0; x-business-use-case-usage keyed by business 4713349378884589, type business_integration_system_user_platform_endpoints; x-app-usage measured F1-headers.json

Removal proof — a deleted post answers code 10, not 100

Object DELETE GET after DELETE (quoted)
text post 1360018983863273_122096071749511222 (run 1) {"success": true} (#10) „Object does not exist, cannot be loaded due to missing permission or reviewable feature, or does not support this operation…" fbtrace_id AVitleYH5GQggv9QstbpU4Q
text post 1360018983863273_122096072277511222 (run 2) {"success": true} same (#10) text, fbtrace_id Aiogseplh0f5BKjQ8tqEzpR
photo 122096072325511222 (run 2) {"success": true} (#100, subcode 33) „Unsupported get request. Object with ID '122096072325511222' does not exist…" fbtrace_id AREMCG8p12jhITdpE8zqsPp

Run 1 stopped (exit 7) because the probe expected code 100. Code 10 also means a missing permission, so it is counted as removal only because the same Page token read the same post with HTTP 200 seconds before the DELETE (D2-readback.json). gone_error() now accepts code 100, or code 10 with „Object does not exist" (tests in test_fb_probe.py). A different-channel control — Meta Business Suite → Planner showing no scheduled post — is the operator's look, not run here.

Gaps (for the skill)

  • The photo's publish state was not read: the photo object has no is_published, and no post_id came back, so „scheduled, not public" is unproven for photos. Its created_time was the create time (16:36 UTC), while the text post's created_time was its scheduled time. The skill should read scheduled photos back through the Page's scheduled-post listing before trusting the photo path.
  • Is the system user a „role user" for the dev-mode visibility rule? Not stated in the docs read; measured only after Live.

What the skill needs

  • Base https://graph.facebook.com/v26.0/; token FACEBOOK_API via load_key() (R-453 strip + asserts), sent as Authorization: Bearer; never in a logged URL.
  • Page token: GET /me/accounts?fields=id,name,tasks,access_token, pick name == "Felhom.eu" (id 1360018983863273), memory only, re-derive per run.
  • Text: POST /{page}/feed form message, published=false, scheduled_publish_time=<unix> → id.
  • Photo: POST /{page}/photos multipart source, caption, published=false, scheduled_publish_time → id (photo).
  • Delete: DELETE /{id} → {"success": true}; prove with GET /{id} → error per gone_error().
  • Stats: GET /{page}/insights?metric=<m>&period=day for the three metrics above.
  • Every response through redact(); HTTP 200 with an error body counts as failure.