# 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](https://developers.facebook.com/docs/development/build-and-test/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](https://developers.facebook.com/docs/graph-api/overview/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](https://developers.facebook.com/docs/development/create-an-app/app-dashboard/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=` → `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=&period=day` for the three metrics above. - Every response through `redact()`; HTTP 200 with an `error` body counts as failure.