Spike: Facebook Page reached after the operator's Page click; scheduled post + photo created, read back byte-equal, deleted
gates / gates (push) Successful in 4m35s

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.
This commit is contained in:
2026-10-08 18:38:25 +02:00
parent ff276ed7d9
commit e9e6300cfc
43 changed files with 1216 additions and 111 deletions
+7
View File
@@ -1,3 +1,10 @@
## facebook — fb_probe: a deleted post answers (#10) „Object does not exist" (2026-10-08, fixed without a row)
- The first write run proved a text post gone only on code 100; Meta v26.0 answers a deleted scheduled post with
code 10 „Object does not exist, cannot be loaded due to missing permission…" (photo: code 100/33). `gone_error()`
accepts code 100, or code 10 carrying „Object does not exist"; counted only after the same token read the object
before the DELETE. 4 new tests (code-10 text, code 100, a permission-only code 10 refused, no error refused).
## facebook — the Page access probe `scripts/facebook/fb_probe.py` (2026-10-08, spike)
- Stdlib probe for the Meta Graph API (v26.0): `read` (debug_token, /me, /me/accounts, Page fields, feed, insights) and
+12 -1
View File
@@ -263,9 +263,20 @@ def hexs(s):
return (s or "").encode("utf-8").hex()
def gone_error(err):
"""True when a GET's error says the object does not exist. MEASURED 2026-10-08 (v26.0, Page token): a deleted
scheduled post answers code 10 „(#10) Object does not exist, cannot be loaded due to missing permission…", not
code 100. Code 10 also means a missing permission, so callers count it only after the SAME token read the object
successfully before the DELETE (the readback is the control)."""
if not isinstance(err, dict):
return False
msg = err.get("message") or ""
return err.get("code") == 100 or (err.get("code") == 10 and "Object does not exist" in msg)
def prove_removed(g, step, obj_id, ptok):
c = g.call(step, "GET", obj_id, ptok, query={"fields": "id"})
gone = (not c.ok) and isinstance(c.err, dict) and c.err.get("code") == 100
gone = (not c.ok) and gone_error(c.err)
log(" GET after DELETE %s: HTTP %s, removed=%s, error=%s"
% (obj_id, c.status, gone, json.dumps(c.err, ensure_ascii=False)))
return gone
+14
View File
@@ -67,5 +67,19 @@ class Redact(unittest.TestCase):
self.assertEqual(fb_probe.redact(fb_probe.TEST_TEXT, secrets=[]), fb_probe.TEST_TEXT)
class GoneError(unittest.TestCase):
def test_measured_code_10_does_not_exist(self):
self.assertTrue(fb_probe.gone_error({"code": 10, "message": "(#10) Object does not exist, cannot be loaded due to missing permission"}))
def test_code_100(self):
self.assertTrue(fb_probe.gone_error({"code": 100, "message": "Unsupported get request"}))
def test_other_code_10_is_not_removal(self):
self.assertFalse(fb_probe.gone_error({"code": 10, "message": "(#10) Application does not have permission"}))
def test_success_body_is_not_removal(self):
self.assertFalse(fb_probe.gone_error(None))
if __name__ == "__main__":
unittest.main()