Files
felhom.eu/REPORT-facebook-page-details.md
T
admin 59f1ad2b86
gates / gates (push) Successful in 5m52s
facebook: verify COPY.md section 5 even though Meta refused the paste
The task asked for a hex compare between what is pasted into Messenger and
COPY.md section 5. There was nothing to paste (R-920), so the half that is
still checkable was checked:

  all four questions BYTE-IDENTICAL to website/gyik.html (hex equal)
  each answer at most three sentences (2/3/3/3), each ending in the gyik link

A refused edit is not a reason to leave the copy unverified.
2026-10-09 10:42:12 +02:00

265 lines
15 KiB
Markdown

# Facebook Page details — contact, place, categories, hours, Messenger FAQ, link preview
2026-10-09 · operator's Windows workstation, his own Chrome · Page `1360018983863273`,
`facebook.com/felhom.eu` · evidence `documentation/audits/facebook-page-details-2026-10-09/`
Own file on purpose: the shared `REPORT.md` belongs to whoever else is in this clone.
---
## In plain words
Two of the five edits were **already done** when I arrived — the operator had set the contact e-mail
and phone himself, and the place was already city-only Budapest, exactly as he chose. One edit I
made: the Page now carries **three categories** instead of one. Two could not be made at all, and
neither is a failure of nerve — Facebook will not let them happen:
- **Opening hours need a street address.** The fences forbid entering one. That turns out not to
matter: with no hours set the Page shows no „Zárva" at all, which was the whole point of the edit.
- **The Messenger FAQ feature does not exist for this Page any more.** The copy is written and
committed; it waits, exactly like the long description does.
The link preview was checked and is correct in both languages. Nothing was posted, nothing was paid
for, nothing on the website changed.
**The one thing to decide:** R-920 — where the four FAQ answers go, now that Messenger has no FAQ box.
---
## 1. Baseline and commit
| | |
|---|---|
| baseline | `9a55f0bbc7`, clean tree, `HEAD == origin/main` |
| pushed | see §9 |
| repos touched | `felhom.eu` only — `marketing/`, `scripts/facebook/`, `documentation/` |
## 2. The edits, each read back from another channel
Meta's toasts are not proof: on 2026-10-08 „A módosítás nincs mentve" arrived **with** a partial
save. So every edit below was read back from a channel other than the one that made it — the Graph
probe runs on DooPlex under a system-user token, the UI runs in the operator's Chrome.
| # | edit | outcome | read-back, and from where |
|---|---|---|---|
| **B1** | contact e-mail / phone | **ALREADY SET — not by this run** | Graph: `emails = ["info@felhom.eu"]`, `phone = "+36702378499"`. Page UI „Elérhetőségek" shows both. Hex-equal trivially (ASCII); the address is the one in `website/kapcsolat.html` |
| **B2** | place | **ALREADY AS CHOSEN** (city only, no street). Service area **REFUSED** | Graph: `location = {city: Budapest, country: Hungary}`, `single_line_address = "Budapest, Hungary"` |
| **B3** | categories | **DONE** — two added | Graph: `Information Technology Company`, `Internet Company`, `Software Company` |
| **B4** | hours | **CANNOT BE SET — and does not need to be** | rendered page, measured with controls (§4) |
| **B5** | Messenger FAQ | **REFUSED — the feature is gone** | the catalogue itself (§5) → **R-920** |
The task's own baseline said „there is no contact e-mail". There is. I did not type it and I am not
claiming it: the operator set it between the task being written and this run, and I verified the
value is the right one rather than assuming.
## 3. B3 — the two categories, and why these
**Chosen: „Internetes cég" and „Szoftvercég".** „Informatikai vállalat" kept, and kept **first** —
Facebook shows only the first on the Page, which the editor states and the rendered page confirms
(neither new category appears there; that is correct, not a failed save).
Facebook's Hungarian list has **no IT-support, no IT-consulting and no cloud category.** Eleven terms
searched: `informatikai`, `informatikai szolgáltatás`, `szoftver`, `internet`, `számítógép`, `felhő`,
`adat`, `adattárol`, `technológ`, `szolgáltatás`, `tanácsad`. What exists nearby:
- **Számítógépszerviz** — the only true „computer support" match, and a repair counter. Fenced out.
- **Internetszolgáltató** — an ISP. Felhom is not one; it would be a false claim.
- **Üzleti szolgáltatás**, **Technológia** — accurate but so broad they help nobody searching.
- **Internetes cég** — an internet company. True, and the nearest thing to „internet / cloud service".
- **Szoftvercég** — true in the strict sense: Felhom writes the hub, the agent and the controller.
Neither implies a shop or a repair counter.
## 4. B4 — hours, and the measurement that made it a non-issue
Facebook disables the row outright:
> **„A nyitvatartási idő megadása előtt add meg előbb a vállalkozásod címét."**
Hours require a street address; the fences forbid entering one. The task's fallback („pick the option
that shows no hours; if none exists, leave as is and report") applies — **no such option exists**,
because with no address there are no hours to label. The outcome the edit wanted is already true, and
I measured it rather than assuming:
```
POSITIVE CONTROLS Budapest 1 · Informatikai vállalat 1 · felhom.eu 1
HOURS LABELS Zárva 0 · Nyitva 0 · Nyitvatartás 0 · nyitvatart 0
```
The controls carry the argument. Four zeroes on their own are equally consistent with „no hours
shown" and „I was reading the wrong part of the page"; the three ones say the details box was in the
text being searched. **The Page will never show „Zárva".**
**Service area, refused.** Facebook offers the field, but its picker returns neighbourhoods and
cities, never a country — „Magyarország" matches nothing. Control: „Szeged" → Szeged, Újszeged,
Kiskundorozsma, so the search works and the term genuinely misses. I left it **unset**. Setting
„Budapest" was available and I did not take it: it would narrow Felhom's stated coverage from
„Hungarian households" to one city, which is a change to a promise, not a form field.
## 5. B5 — the Messenger FAQ is gone (R-920)
Searched, not assumed absent — four observations, one of them a control:
1. The create-automation catalogue („Az összes automatizálás") holds **exactly three** templates:
Automatikus válasz, Távolléti üzenet, A megválaszolatlan üzenetek azonosítása.
2. Template search „kérdés" → **„Nincs a keresésnek megfelelő automatizálási sablon."**
3. **Positive control:** the same search for „üzenet" → **two** templates. The search works.
4. The existing instant-reply automation has channel, message and media only — no FAQ, no quick
replies. Business-portfolio settings carry no messaging/FAQ entry either.
**`COPY.md` §5 is written anyway** and committed: the four questions **verbatim** from `gyik.html`,
each answer condensed from *that question's own answer* with no new claim, each ending in
`https://felhom.eu/gyik.html`, each with its source line. The delicate one is „Ti hozzáfértek az
adataimhoz?" — the condensation keeps the admission that Felhom **does** hold remote access by
default, because dropping it to save characters would have turned a frank answer into a privacy
boast. It is three sentences: remote access exists; the backup key is yours alone; no profiling.
**The copy was verified even though it could not be pasted.** The task asked for a hex comparison
between what is pasted into Messenger and `COPY.md` §5; with nothing to paste, the half that is still
checkable was checked — the four questions against `gyik.html` itself:
```
hex_equal=True len= 45 Mi az a Felhom.eu, és mit csináltok pontosan?
hex_equal=True len= 27 Milyen gépre van szükségem?
hex_equal=True len= 29 Ti hozzáfértek az adataimhoz?
hex_equal=True len= 24 Mennyibe kerül az egész?
ALL FOUR BYTE-IDENTICAL TO gyik.html: True
```
And each answer against its own rule — at most three sentences, ending in the FAQ link:
```
answer 1 371 chars 2 sentences ends with gyik.html link: True
answer 2 305 chars 3 sentences ends with gyik.html link: True
answer 3 448 chars 3 sentences ends with gyik.html link: True
answer 4 380 chars 3 sentences ends with gyik.html link: True
```
Same shape as R-917: copy with nowhere to go, because Meta removed the field.
## 6. Phase C — the link preview
Both URLs scraped again, once each.
| | `https://felhom.eu/` | `https://felhom.eu/en/` |
|---|---|---|
| title | Felhom.eu — Saját felhőd, saját szabályaid | Felhom.eu — Your own cloud, your own rules |
| description | „Otthoni szerver a te otthonodban… Most zárt teszt indul." | „A home server in your own home in Hungary… A closed test is starting now." |
| image | `assets/og-image.png` | `assets/og-image-en.png` |
| warnings | *The following required properties are missing: fb:app_id* | same, verbatim |
| response code | **206** | **206** |
Both previews render correctly, image included. The `fb:app_id` warning is the **expected** one and
was deliberately **not** fixed — adding it would tie the public website to the Meta app for no gain
today. Nothing on the website was changed.
**The 206 is worth a line.** `206 Partial Content` where a scraper would normally see 200. A plain
`curl` from DooPlex gets **200** on both URLs, so this is Facebook's own fetch (a Range request the
nginx in front of the site answers literally), not a site fault — and the preview it built is
complete, which is the observable that matters. Recorded rather than chased; nothing is broken.
## 7. The probe change
`scripts/facebook/fb_probe.py read` now also reports `emails, phone, category_list, location,
single_line_address, hours` — **one field per Graph call**, not one batched `fields=` list. Graph
fails the whole call when any single member is unreadable, so a batch would let one refused field
hide the other five; that is the same reason `INSIGHT_METRICS` was already called one at a time. A
refusal is logged with Meta's error **verbatim and not retried** — retrying would convert „Meta
refuses this field" into „the field is empty", which is a different fact. „Returned as `null`" and
„not returned at all" are logged apart.
`hours` is in the third state: the call succeeds and **the field is simply not in the response**.
That is why B4's read-back had to come from the rendered page.
## 8. Channels, and one I had to correct myself about
| channel | proves |
|---|---|
| Business Suite / Page UI, signed in | makes the edits; shows admin-side state |
| Graph probe, DooPlex, system-user token | the stored field values |
| cookie-free `curl` from DooPlex | the logged-out server response — **with a real limit** |
The cookie-free fetch needs browser-like headers: a bare user agent gets **HTTP 400**; with
`Accept`, `Accept-Language`, `Upgrade-Insecure-Requests` and the `Sec-Fetch-*` trio it returns **200**
and ~163 KB.
**I first called two markers in it a positive control, and they are not.** `Budapest` matched an
`og:url` meta tag and `Information Technology` sits inside an embedded JSON blob
(`delegate_page.category_name`) — the visible details box is rendered by JavaScript and is absent
from that HTML altogether. So the absence of „Zárva" there proves nothing, and I did not use it for
B4. The limit is written into `logged-out/logged-out-before.txt` beside the data rather than dropped,
because the next session will otherwise read those zeroes as evidence. What the channel *can* still
show is the embedded `category_name` and the `og:*` tags, and it confirms only the first category is
exposed to a logged-out visitor.
## 9. Gates, commit, CI
| | |
|---|---|
| baseline | `9a55f0bbc7` |
| pushed | **`97d3c29f9c`** (rebased onto `02a54e26`, which another session pushed mid-task) |
| CI | **run #863** (internal id 1596 — the R-417 offset), commit `97d3c29f9c`, **Success**, 1 job, 100 %, 5m27s (`D2-ci-run-863-green.jpg`) |
**The Windows run of the gates was red, on two Windows-only causes, and DooPlex is green.** Saying so
rather than quoting the convenient number:
```
Windows python scripts/repo_gates.py --fast rc=1 CONVICTED: instructions, script-tests
DooPlex python3 scripts/repo_gates.py --fast rc=0 all 18 felhom.eu gates OK @ 97d3c29f9c
```
- **`instructions`** — „`E:\git\CLAUDE.md` and `documentation/runbooks/workspace-CLAUDE.md` have
diverged." They are *supposed* to differ: the Windows file says so in its own second paragraph
(„That file is canonical and stays DooPlex-shaped. Do not edit it to match this one."). This gate
cannot pass on this workstation and the failure predates this task.
- **`script-tests`** — 11 of 24 suites fail on Windows for environment reasons:
`PermissionError: [WinError 32]` (Windows will not unlink an open temp file), no `sqlite3` CLI, and
POSIX shell tests. **`scripts/facebook/test_fb_probe.py`, the suite covering the file I changed,
passes on Windows too.**
The DooPlex run was done in a **throwaway `git worktree` at the pushed commit**, placed beside the
sibling repos inside `/mnt/5_hdd/felhom.eu/git/` — a gate run at the wrong path convicts the layout,
not the commit. Nothing was written into the shared clone; the worktree was removed afterwards and
`git worktree list` is back to one entry. The pre-push hook is not armed in this clone, so nothing
was bypassed and no `--no-verify` was used.
## 10. Secret scan
`FACEBOOK_API` was read on DooPlex by `read_credential.py`, never printed, never copied to Windows.
The probe strips `access_token` from the recorded response before writing it — verified in the
`me/accounts` evidence, which carries `id`, `name`, `tasks` and no token.
The probe's **stdout** does print `key FACEBOOK_API: 201 chars, starts EAA`. That line is why the
2026-10-08 evidence needed redacting, so **no `run.log` is committed from this run** at all.
```
plant EAAfakeprobe → grep -r EAA --exclude=README.md = 1 file, 1 line
delete → grep -r EAA --exclude=README.md = 0 files, 0 lines
access_token in evidence = 0
run.log in evidence = 0
```
`--exclude=README.md` because the audit README quotes the search strings — the same self-match that
produced four false positives on 2026-10-08.
## 11. Register
- **R-920 opened** (Business & legal, P4) — the Messenger FAQ automation does not exist; `COPY.md` §5
has nowhere to go. Options a/b/c/d for the operator, recommended (a) now and (c) later.
- **R-915, R-916, R-917 untouched**, as the task required.
- **One drifted header corrected in the section I touched.** „Business & legal" read *12 rows
(P2 5, P3 1, P4 6)* while the section held **11** rows (P2 4, P3 1, P4 6). With R-920 added it now
holds 12 (P2 4, P3 1, P4 7) and the header says so. I corrected only the section I edited; the five
other headers named as drifting in the previous session's report are still drifting and still
belong to a session that owns the register.
## 12. Teardown
Nothing posted — no post, story, reel, comment, reply, message sent, like, follow or invite. The
setup checklist's „invite friends" and „introduce yourself" were left alone. No money: no Boost, no
Ads Manager, no Meta Verified, no payment settings; Meta's ad suggestion card on the Page was not
clicked into. No change to the Meta app (still **development mode**), the business portfolio, Page
roles, tokens or permissions. No pixel, no Conversions API, no Facebook script on the website. The
website is unchanged. No password was typed. The throwaway DooPlex worktree used to run the probe was
removed; nothing was written into the shared clone. The browser tab was closed.