# Facebook — the Page's first post, drafted and scheduled 2026-10-09 · Page `1360018983863273` · evidence `documentation/audits/facebook-first-post-2026-10-09/` Own file on purpose: the shared `REPORT.md` belongs to whoever else is in this clone. --- ## In plain words The Page's first post is **written, approved by the operator, and scheduled for Monday 2026-10-12 at 19:00** Budapest time. It is **not public yet** — it sits in Meta Business Suite → Tervező (Planner), where it can still be changed or deleted. The robot cannot publish anything immediately; that is enforced in the code, not left to care. One thing the operator should know: the post repeats the website's "56 alkalmazás" figure, and I nearly changed it. The apps page carries **57** cards while saying 56 — which looks like an off-by-one until you read the category line, *„6 alkalmazás + 1 beépített"*. The 57th card is FileBrowser, built into every box and deliberately not counted. **56 is correct.** **The operator's one remaining click:** after the post goes out on Monday evening, pin it — „…" → „Kiemelés". --- ## 1. Baselines and commits | | | |---|---| | baseline | task named `fe80548144`; `main` was already at `96f68f1b44` when pulled (other sessions) | | drafts + `schedule-post` | **`3a77ed73aa`** | | records (this report) | see §9 | No architecture document covers marketing, and none should — it is a business tool, not part of the product. The decision home is `CONTEXT.md` (2026-10-08 Facebook entry). ## 2. Scenario A — the dry check A throwaway scheduled post, created **with the link**, read back, listed, deleted, listed again: | step | result | |---|---| | create with `link=https://felhom.eu/` | **accepted** — the open question in §3 of the brief is answered: `link` is not refused on a scheduled post | | read-back | `is_published=False`, `scheduled_publish_time` equal to what was sent, message **hex-equal** | | which list call answered | **`GET /{page}/scheduled_posts`** — the documented edge; the `feed?is_published=false` fallback was not needed | | present before delete | **True** | | after delete | **absent: True** | The removal proof comes from the **list**, not from an error after `DELETE` — which is what R-914 asks for, and the reason `list_scheduled()` returns `None` rather than a guess when both routes are refused. `documentation/audits/facebook-first-post-2026-10-09/probe/S*.json`. ## 3. The post | | | |---|---| | version | **6.2 Közepes** (operator's choice at the STOP) | | length | **638 Unicode characters** | | language | Hungarian only (operator declined an English paragraph) | | emoji / hashtags | **0 / 0** — see below | | link | `https://felhom.eu/` | | scheduled | **2026-10-12 19:00 Europe/Budapest** = epoch `1791824400` = 17:00 UTC | | post id | `1360018983863273_122096547315511222` | | permalink (after it publishes) | `https://www.facebook.com/122096546283511222/posts/122096547315511222` | Zero emoji and zero hashtags although the brief allowed two of each: the Felhom design system uses no emoji (the website gate holds it at 0), and two hashtags would have served no real search. The operator chose Monday over today on the reasoning offered: it was Friday 15:08, and a Friday evening is the weakest slot of the week for a first post — three days in Planner is also review time. ## 4. Read-back | check | result | |---|---| | `is_published` | **False** | | `scheduled_publish_time` sent vs read | **equal** (`1791824400`) | | message hex-equal to `COPY.md` §6.2 | **True** | | sha256, recomputed **outside** the probe | COPY.md `887514383eff997c` = posted `887514383eff997c` | | epoch → wall clock, checked with the tz database | `2026-10-12 19:00 CEST (Monday)` | | in `scheduled_posts` | **True** | | Planner, a different channel from the API | the card sits on **H 12 at 19:00** with the link preview attached (`A1-planner-monday-19-00.jpg`) | ## 5. Published yet? **No — the time has not come.** Monday 19:00 Budapest is in the future at the time of writing. The next session (or this one, if still open then) reads it back: `is_published` must become `true` and the permalink must resolve. **If it did not publish, report it — do not post again.** ## 6. The operator's next click After it goes out on Monday evening: open the post on the Page, „**…**" → „**Kiemelés**" to pin it to the top. Not done by API: the pin endpoint is unproven and one click is enough. ## 7. `schedule-post` — what it is and what it refuses A third sub-command on `fb_probe.py`, reusing its token loader (R-453), redaction, Bearer call and evidence writer. The guards, each with a test: - **It cannot publish immediately.** `published` is always `"false"` and **no argument can change it** — the test enumerates every keyword `schedule_form()` accepts and asserts none of them flips it. The operator's review in Planner is the safety net, so an immediate post has to be *unreachable*, not merely not-the-default. - **The body is read from `COPY.md` by section name**, never passed through a shell or an argv string (brief §9.6). The caller names `6.2`; the Hungarian stays in the file. - **`check_when()` refuses** a time under Meta's 10-minute floor or over its 6-month ceiling, *before* the call, so a bad time is a readable local refusal rather than a Graph error. - **`budapest_to_epoch()` uses the real tz database** and **refuses** if `Europe/Budapest` is missing rather than falling back to a hardcoded `+01:00`/`+02:00`. Guessing the offset is how a post goes out an hour wrong across a DST boundary. - **`list_scheduled()` records which route answered** and returns `None` when both are refused, so a caller says "unproven" instead of claiming a removal it never saw. **Tests: 30.** On DooPlex **all 30 pass, none skipped**. On Windows 2 skip — this interpreter ships no tz database; the command runs on the Linux host, which has the system zoneinfo. **Red-proof of the guard that matters**, as the brief requires. `schedule_form` was given a `published=...` argument, `ScheduleForm` was run, and the test failed: ``` AssertionError: 'true' != 'false' : published changed published ``` Guard restored, all 30 green again. ## 8. Secret scan ``` plant EAAfakeprobe → grep -rl EAA --exclude=README.md = 1 delete → grep -rl EAA --exclude=README.md = 0 access_token in evidence = 0 run.log in evidence = 0 ``` The token comes only from the credentials file on DooPlex, is never printed and never appears in a logged URL. No `run.log` is committed — the probe's stdout carries the key's length and prefix. ## 9. Register - **R-917 → VERIFY.** The text is scheduled; close when the operator confirms it published and is pinned. Post id and time recorded in the row. - **R-914 → noted**, not closed: `schedule-post` exists for **text + link only**. The full skill still needs the photo path (the spike could not prove a scheduled photo stays hidden), the pin, comment moderation, and the insight read-back after a post. - Nothing closed, nothing else opened. ## 10. Observations - **NOT-A-FINDING: the apps page says 56 while carrying 57 cards.** Deliberate — the category line reads „6 alkalmazás + 1 beépített" and the extra card is FileBrowser, built into every box. `index.html` says „56 telepíthető alkalmazás" too. Checked before copying the number into a public post; a "fix" here would have made a live page wrong. - **NOT-A-FINDING: the link preview on a scheduled post.** The brief's edge case asked what to do if the preview card is empty. It is not: Planner shows the card with the og-image, and the Sharing Debugger was re-scraped earlier today for this exact URL. - **FILED earlier today, still open: R-887** — the lost-job CI flake bit this session's earlier commits once (`#875`, "Set up job" 11m48s then every step 0s) and passed on re-run. ## 11. Teardown The dry-check post was deleted and its removal proved from the scheduled-posts list. The real post is **deliberately left in place** — that is the deliverable. Nothing on any box, the hub, or any other Page. The DooPlex worktree used to run the command was removed; nothing was written into the shared clone. The browser tab was closed.