{
  "schemaVersion": "ziwei-compatibility-replay-v1",
  "observedAt": "2026-09-25",
  "scope": {
    "cases": 300,
    "seed": 20260925,
    "strata": {
      "random": 200,
      "leapMonth": 30,
      "ziHour": 30,
      "lunarNewYear": 30,
      "unknownTime": 10
    },
    "referenceDate": "2026-06-15",
    "referenceLunarYear": 2026,
    "timingYears": [
      2026,
      2031
    ],
    "scenarios": {
      "marriage": "marriage",
      "friends": "social",
      "business": "work",
      "besties": "social",
      "mother_in_law": "family",
      "boss_subordinate": "work",
      "parent_child": "family",
      "father_son": "family",
      "mother_son": "family"
    },
    "description": "300 seeded synthetic birth-data pairs: 200 uniform over 1900-02-01…2025-12-31 (10% on the midnight day boundary), 30 with both people born in leap months (days 15, 16, earlier, later and last, across all 47 leap months), 30 with both people born in a 子 hour (23:xx on the eve of the Spring Festival, on the last day of a lunar month and on day 15 of a leap month, or 00:xx), alternating the 23:00 and midnight day boundaries, 30 on the day before or the day of the Spring Festival or between 立春 and the Spring Festival, and 10 with at least one unknown birth time. OpenFate's engine charts every person and computes the pair facts for all nine scenarios; the public replay recomputes the pair facts from those charts.",
    "inputBoundary": "Charts are the engine's own (placement is checked by the single-chart replay). Civil time at UTC+8 without True Solar Time or DST; solar-calendar input only. Pair facts are compared at the reference date 2026-06-15 (lunar year 2026, 丙午); timing windows cover lunar years 2026–2031."
  },
  "comparedFields": [
    "Degrade gate: each side's birth-time flag and whether timing windows are withheld",
    "Branch relations on four 命宮/夫妻宮 axes: relation, pair name, trine strength, tone",
    "Key-palace overlaps under each of the four scenario lenses",
    "Cross birth-year 四化 landings (star, transformation, palace, branch, tone) and their key-palace flags per lens",
    "Spouse-palace profiles: resident or borrowed majors with brightness",
    "Peach-blossom landings: own palace, branch, partner palace, both key flags, tone",
    "Current-decade sync: each active decade palace and range at 2026-06-15, same-name flag",
    "Six timing windows per lens: 干支, tone, every trigger with its own-key and partner-branch flags",
    "All 144 ordered branch pairs of the relation table"
  ],
  "notCompared": [
    "reliability.coverage/level and its reasons — a weighting of input conditions, not a chart fact",
    "The version, school and scenario stamps of the envelope",
    "Row order within a list",
    "Prompt wording, narrative and any compatibility judgement"
  ],
  "results": {
    "cases": 300,
    "identical": 300,
    "withDifferences": 0,
    "byLens": {
      "marriage": 300,
      "work": 300,
      "family": 300,
      "social": 300
    },
    "byReason": {
      "convention": 0,
      "calendar-boundary": 0,
      "engine-bug": 0,
      "replay-bug": 0
    },
    "byField": {},
    "casesByKnownIssue": {
      "friends-palace-name": 0
    },
    "reproducedWithKnownIssues": 8,
    "chartChecks": {
      "parties": 600,
      "ageMatches": 600,
      "decadeMatches": 600,
      "birthSihuaMatches": 600
    },
    "relationTable": {
      "pairs": 144,
      "identical": 144
    }
  },
  "knownIssues": [
    {
      "id": "friends-palace-name",
      "category": "engine-bug",
      "title": "Before the fix, the work and social lenses never found 交友宫, so every fact on that palace was missing",
      "detail": "OpenFate's scenario policy declares 交友宫 a key palace for business/boss_subordinate (work lens) and friends/besties (social lens). keyPalaces() resolves each key with findPalace(), which compares stripGong(palace.name) with stripGong(key); the engine prints that palace as 仆役, so 交友 never matches and the lens silently shrinks to four palaces. Overlaps on that palace, key-palace flags of cross 四化 landing there, and yearly triggers landing there are all dropped, while the reading prompt still lists 交友宫 among the key palaces. The combination report resolves the same key correctly through normalizeZiweiPalaceName.",
      "location": [
        "internal implementation findPalace (before the fix: stripGong(p.name) === stripGong(key))",
        "internal implementation (keyPalaces reads the scenario policy keys)",
        "internal implementation and :36 (交友宫 in the work and social lenses)",
        "internal implementation (normalizeZiweiPalaceName resolves 仆役 → 交友宫 correctly)",
        "internal implementation,198 (the prompt lists 交友宫 as a key palace)"
      ],
      "scenarios": [
        "business",
        "boss_subordinate",
        "friends",
        "besties"
      ],
      "lensOverride": {
        "work": [
          "命宫",
          "官禄",
          "财帛",
          "迁移"
        ],
        "social": [
          "命宫",
          "兄弟",
          "福德",
          "迁移"
        ]
      },
      "status": "Fixed on 2026-09-25 after this replay found it: findPalace now compares canonical palace names (normalizeZiweiPalaceName), so 仆役 resolves to 交友宮, and the engine version is ziwei-synastry-v5. Reports saved before the fix keep their frozen facts. The counterfactual lens above describes what the engine did before the fix; no current case needs it.",
      "affectedCases": 0
    }
  ],
  "differences": [],
  "conventionVariants": [
    {
      "id": "sihuaTableQuanShu",
      "kind": "rule",
      "label": "四化表採《紫微斗數全書》通行本（戊右弼科、庚太陰科、壬左輔科），而非中州派王亭之表（戊太陽科、庚天府科、壬天府科）",
      "description": "OpenFate declares the Zhongzhou (王亭之) 四化 table: 戊 太陽科, 庚 天府科, 壬 天府科, with 左輔/右弼 never transforming. The table printed in most editions and shipped as the default of the iztro library OpenFate wraps gives 戊 右弼科, 庚 太陰科, 壬 左輔科; the other seven stems agree. This variant recomputes every cross-chart 生年四化 landing and every 流年四化 trigger with that table, so it moves the cross facts of people born in 戊/庚/壬 years and the 2028 (戊申) and 2030 (庚戌) timing windows.",
      "citations": [
        {
          "source": "王亭之《中州派紫微斗數深造講義》",
          "note": "The table OpenFate declares (internal implementation sihuaCitation; internal implementation STEM_FOUR_TRANSFORMATIONS)."
        },
        {
          "source": "《紫微斗數全書》十干四化",
          "note": "戊 貪狼祿、太陰權、右弼科、天機忌；庚 太陽祿、武曲權、太陰科、天同忌；壬 天梁祿、紫微權、左輔科、武曲忌."
        },
        {
          "source": "internal implementation (iztro@2.5.8)",
          "note": "The library default mutagen table is 戊 右弼 / 庚 太阴 / 壬 左辅 科; internal implementation records that OpenFate overrides it."
        }
      ],
      "impact": {
        "casesAffected": 295,
        "totalFactChanges": 4751
      }
    },
    {
      "id": "palaceGeometryOnly",
      "kind": "rule",
      "label": "宮位地支只讀紫微的三方四正與六合（同宮、沖、六合、半合、拱），不套用子平八字的相刑、六害、六破與自刑",
      "description": "OpenFate classifies palace-branch pairs with the same tables its Bazi (子平) engine uses, so 相刑, 六害, 六破 and 自刑 also label Zi Wei palace pairs. Zi Wei's own palace relations are geometric: the 三方四正 (the three 三合 positions and the opposite palace) plus the 六合 pairing. Under a geometry-only reading, 刑/害/破 pairs carry no relation and a same-branch pair is 同宮 even on 辰/午/酉/亥. Only the four branch-relation rows can change.",
      "citations": [
        {
          "source": "internal implementation and :202-235",
          "note": "OpenFate's own statement that the pair classification reuses the Bazi compatibility tables, and the priority it applies."
        },
        {
          "source": "《三命通會》論三刑、論六害",
          "note": "The Zi Ping (Bazi) source of the 刑/害 doctrines the shared table applies to palace pairs."
        },
        {
          "source": "Zi Wei 三方四正 palace geometry",
          "note": "The palace relations Zi Wei charts read throughout their 格局 rules (本宮, 對宮, 三合宮); a school practice described here, not a single canonical text."
        }
      ],
      "impact": {
        "casesAffected": 149,
        "totalFactChanges": 470
      }
    },
    {
      "id": "gongDiscounted",
      "kind": "rule",
      "label": "拱（缺帝旺中神的三合兩端，如申辰、寅戌）不計為關係",
      "description": "A branch pair made of the two ends of a 三合 group without its 帝旺 middle (申辰, 寅戌, 亥未, 巳丑) is reported by OpenFate as 拱 (implied trine, the weakest trine strength, supportive tone). OpenFate's own source notes that some schools do not count 拱 at all; under that reading those pairs carry no relation. Only the four branch-relation rows can change.",
      "citations": [
        {
          "source": "internal implementation and :205-210",
          "note": "OpenFate's comment: \"拱 (the two endpoints without the middle — weakest, some schools discount it)\"."
        },
        {
          "source": "三合以中神為主 (子午卯酉 as the pivot of a 三合)",
          "note": "Why a pair without the middle branch is at most 拱: the 帝旺 branch carries the combination; a school practice shared with Zi Ping, described here rather than quoted."
        }
      ],
      "impact": {
        "casesAffected": 60,
        "totalFactChanges": 146
      }
    },
    {
      "id": "bodyPalaceNotKey",
      "kind": "rule",
      "label": "合婚關鍵宮不含身宮（只取命宮、夫妻宮、福德宮）",
      "description": "OpenFate's 合盤 marriage lens is 命宮, 身宮, 夫妻宮, 福德宮 (ZIWEI_SYNASTRY_KEY_PALACES), while OpenFate's own combination report uses 命宮, 夫妻宮, 福德宮 for the same romantic scenario. Practitioners differ on whether the 身宮 (where the acquired self attaches) belongs in a marriage comparison. This variant drops it from the marriage lens: overlaps, key-palace flags, peach-blossom key flags and marriage timing triggers change only when the 身宮 sits outside 命/夫妻/福德.",
      "citations": [
        {
          "source": "internal implementation (ZIWEI_SYNASTRY_KEY_PALACES)",
          "note": "The declared marriage lens with 身宮."
        },
        {
          "source": "internal implementation",
          "note": "OpenFate's romantic lens for the combination report, without 身宮."
        }
      ],
      "impact": {
        "casesAffected": 184,
        "totalFactChanges": 1390
      }
    },
    {
      "id": "leapMonthSameMonth",
      "kind": "chart",
      "label": "閏月整月依本月排盤（same-month），而非前十五日屬本月、十六日起屬下月（split-halves）",
      "description": "For a birth on day 16 or later of a leap month, OpenFate's declared split-halves policy charts it as the following month; the other school keeps the whole leap month as its numbered month. OpenFate's rulebook calls this a genuine dispute between schools, and its engine supports both. This variant recharts every such party with OpenFate's own engine under leapMonthPolicy \"same-month\" (stored per case under variants.leapMonthSameMonth) and recomputes the pair facts from that chart.",
      "citations": [
        {
          "source": "internal implementation (leapMonthSplitHalves)",
          "note": "\"这是流派间真实存在争议的规则\" — the declared split-halves choice and why it is recorded."
        },
        {
          "source": "internal implementation (ZIWEI_LEAP_MONTH_POLICIES)",
          "note": "The engine's supported alternative, used to produce the variant charts."
        },
        {
          "source": "tests/fixtures/disclosure-private/ziwei-independent-replay-v1.json",
          "note": "The single-chart replay checks chart placement under both leap-month policies."
        }
      ],
      "impact": {
        "casesAffected": 43,
        "totalFactChanges": 4660
      }
    },
    {
      "id": "lateZiSameDay",
      "kind": "chart",
      "label": "夜子時（23:00–23:59）仍屬出生當日（MIDNIGHT_00），而非歸入次日（ZI_HOUR_23）",
      "description": "OpenFate's default day boundary moves a 23:00–23:59 birth to the next civil day as that day's 子 hour (早子/晚子 split at 23:00). The other reading keeps the late 子 hour (夜子時) on the civil birth date, which OpenFate offers as the MIDNIGHT_00 option. This variant recharts every 23:xx birth that used the default with OpenFate's own engine under MIDNIGHT_00 (stored per case under variants.lateZiSameDay) and recomputes the pair facts from that chart.",
      "citations": [
        {
          "source": "internal implementation (dayBoundaryMode)",
          "note": "ZI_HOUR_23 pushes 23:xx to the next day; MIDNIGHT_00 keeps it on the civil day."
        },
        {
          "source": "internal implementation ziweiAstroConfig (dayDivide: forward)",
          "note": "The declared default: 晚子時 belongs to the next day."
        }
      ],
      "impact": {
        "casesAffected": 31,
        "totalFactChanges": 2784
      }
    }
  ],
  "limitations": [
    "Charts are taken from OpenFate's engine as input; star placement, the calendar and the leap-month and 子-hour conventions are checked by the single-chart replay (public/ziwei-independent-replay-v1.json), not here.",
    "Interpretation and weighting (解讀與權重) are outside the replay: tones are the engine's fixed labels on a fact, and no compatibility judgement, score or reliability percentage is recomputed.",
    "Both sides apply OpenFate's declared rule choices (school, 四化 table, lenses, relation priority, 童限); a shared declared choice is not independently validated. Disputed choices are quantified in conventionVariants instead.",
    "The reference date is fixed at 2026-06-15, so decade sync is checked at that date and timing windows cover lunar years 2026–2031 only.",
    "Civil UTC+8 time without True Solar Time, DST or zone resolution, and solar-calendar input only; those steps are tested elsewhere.",
    "Synthetic pairs, not real couples. An engine-bug entry is about how a rule is applied, not about any stored customer report.",
    "Palace-stem (宮干) 飛化 across two charts is not part of OpenFate's pair layer and is not replayed.",
    "The test suite rechecks every case's pair layer from the stored charts and reruns the full engine on a fixed sample; rerunning the engine for all charts is internal implementation --check (about ten minutes)."
  ],
  "citations": [
    {
      "source": "internal implementation",
      "note": "The pair rules under test; read, not imported, by the public script."
    },
    {
      "source": "internal implementation",
      "note": "OpenFate's branch tables (沖, 六合, 半合, 三合, 刑, 自刑, 害, 破) reused by the pair classification."
    },
    {
      "source": "internal implementation",
      "note": "Scenario groups and the declared key palaces of the work, family and social lenses."
    },
    {
      "source": "internal implementation, internal implementation",
      "note": "Declared school, 四化 table, Spring Festival boundaries and leap-month policy."
    },
    {
      "source": "王亭之《中州派紫微斗數深造講義》",
      "note": "The 四化 table OpenFate declares."
    },
    {
      "source": "《三命通會》",
      "note": "Zi Ping source of the 三刑/六害 doctrines the shared branch table applies."
    },
    {
      "source": "internal implementation (iztro@2.5.8)",
      "note": "The 童限 order 一命二財三疾厄、四歲夫妻五福德、六歲事業 used before the first decade, as the engine applies it."
    },
    {
      "source": "private verification implementation, public/ziwei-independent-replay-v1.json",
      "note": "The single-chart replay that checks the chart placement this pair replay takes as input."
    }
  ],
  "title": "OpenFate Zi Wei Dou Shu compatibility (紫微合盤) pair-rule verification summary",
  "publicationKind": "first-party-verification-summary",
  "claimBoundary": "OpenFate performed this comparison using a separately written implementation. This is a publisher-reported result, not independent certification, a public replay kit, or evidence of predictive accuracy. Full execution records and implementation remain private.",
  "receiptSha256": "f9bbf70bdb10cd46e64d91b576948c81951fab2658b2f6e21d0fe31acc807175"
}
