[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M752ST3BRHZ4DATZE5TYC9TY":3,"skill-same:01M752ST3BRHZ4DATZE5TYC9TY":42},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":8,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":14,"categories":15,"keywords":16,"publishedAt":17,"linkOnly":18,"markdownContent":19,"markdownBody":19,"frontMatter":20,"refName":21,"commitSha":22,"skillDirectory":23,"forksCount":24,"repositoryHtmlUrl":25,"repositoryHomepageUrl":6,"ownerHtmlUrl":26,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":27,"install":28,"resources":41},"01M752ST3BRHZ4DATZE5TYC9TY","sd-port-fidelity",null,"developzoneio\u002Fspecwright","developzoneio","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F288244965?v=4","01M752S4GQXBCH6H67H28M9HTN","01M752S4HXZ73BTCHG2K1VCYQA",10,"MIT","https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright\u002Fblob\u002Fmain\u002Fskills\u002Fsd-port-fidelity\u002FSKILL.md",[],[],"2026-11-12 13:55:43",false,"# sd-port-fidelity\n\nCross-project port fidelity policy for specwright. A port reproduces a donor implementation inside\na host repo; the donor's form is the specification, and every departure from it is a citable\ndecision rather than a preference. Authored into port specs by `sd-spec-architect` and enforced\nagainst the changeset by `sd-reviewer`.\n\nRead the section matching your role. The core rule and the deviation allowlist apply to everyone.\n\n---\n\n## The core rule\n\n**Mirror the donor structurally. Every departure is a row in the deviation table, or it is a\ndefect.**\n\nStructural mirror means the host reproduces, as far as the target permits: the donor's file\nlayout, member set, member order, symbol names, local variable names, step order within each\nmember, attribute order, and log message text. Judgement is not the mechanism here. A departure\ncarrying a deviation row is legal; a departure carrying none is a defect; and nobody is asked to\ndecide which of the two a given hunk is.\n\n---\n\n## Deviation allowlist\n\nExactly four groups force a departure. Each requires its own citation - a row citing nothing is\ninvalid, and the hunk it claims to cover is unjustified.\n\n| Group | Forced by | Citation required |\n|---|---|---|\n| 1 | Compiler, namespace, or assembly conflict | the conflicting identifier |\n| 2 | Host constitution | the constitution section, `§N.M` |\n| 3 | Host precedent | `file:line` in the host |\n| 4 | Behavior parity fix on an agreed donor defect | the parity criterion it satisfies |\n\nAnything outside these four reverts to the donor form. \"Cleaner\", \"more idiomatic to me\", and \"the\nhost does it differently somewhere\" are not groups.\n\n---\n\n## Anti-simplification rules\n\nThese bind the implementer through the task blocks the architect writes, not by the implementer\nloading this file: `sd-spec-architect` puts each applicable rule into the port task's `Acceptance`\nand cites the donor `file:line` in `Pattern refs` (see **sd-atomic-task-format**).\n\n- **No unrequested simplification.** Shorter is not better. Collapsing branches, merging members,\n  or replacing a loop with a library call is a departure and needs a row.\n- **No gratuitous rename.** Donor identifier names carry over even where host style would differ.\n  Group 1, group 3, or nothing.\n- **No reordering.** Statement order, parameter order, and member order follow the donor, even\n  where another order reads better.\n- **No opportunistic fix.** A donor defect is reproduced as-is and recorded for a follow-up spec.\n  Fixing it inline is group 4 only when the fix was agreed at the gate before implementation began.\n- **Host constitution beats donor precedent.** \"It is only a copy\" exempts nothing. A donor form\n  that violates the host constitution is a cited group 2 deviation, never a verbatim import.\n\n---\n\n## Gate tables (sd-spec-architect)\n\nA port spec carries three tables. Each has a completeness condition the gate evaluates\nmechanically - it counts and matches, it never assesses whether a reason is good. A table failing\nits condition is incomplete and the gate refuses it.\n\nThe spec must also carry a **fidelity acceptance criterion**: the criterion these tables are\nevidence for. It is what review findings anchor to, and without it a fidelity finding has no legal\nanchor (see **sd-severity-taxonomy**). A port spec missing it fails the gate.\n\n### Path mapping table\n\n| Column | Contents |\n|---|---|\n| `Donor path` | repo-relative path in the donor |\n| `Host path` | repo-relative destination in the host |\n| `Kind` | `mirror` \u002F `merge` \u002F `omit` |\n| `Reason` | required when `Kind` is not `mirror`; `-` when it is |\n\n**Complete when**: one row per file in the declared donor scope and no others; every `Host path`\nunique; no empty cell; every non-`mirror` row carries a non-empty `Reason`.\n\n### Member manifest\n\n| Column | Contents |\n|---|---|\n| `Donor path` | the donor file the member comes from |\n| `Member` | donor symbol name, verbatim |\n| `Ordinal` | 1-based position of the member within that donor file |\n| `Host path` | destination, copied from the path mapping table |\n| `Status` | `ported` \u002F `deviated` \u002F `omitted` |\n| `Deviation ID` | `D\u003CNN>` when `Status` is not `ported`; `-` when it is |\n\n**Complete when**: one row per member of every non-`omit` donor file; the `Ordinal` values within\neach `Donor path` form `1..N` with no gap and no duplicate; each `Host path` equals the mapping row\nfor its `Donor path`; every non-`ported` row names a `Deviation ID` present in the deviation table.\n\n### Deviation table\n\n| Column | Contents |\n|---|---|\n| `ID` | `D\u003CNN>`, unique, ascending |\n| `Donor form` | the donor name, order, or text departed from |\n| `Host form` | what the host uses instead |\n| `Group` | `1`, `2`, `3`, or `4` from the allowlist |\n| `Citation` | the citation that group requires, verbatim |\n\n**Complete when**: every `ID` unique; every `Group` is one of `1` to `4`; every `Citation` is\nnon-empty and in the shape its group requires; every `Deviation ID` named in the member manifest\nappears here exactly once; no row here is unreferenced by the manifest.\n\n---\n\n## Snapshot artifacts (sd-spec-architect)\n\nUnder a port spec's `04-artifacts\u002Fsource\u002F`: the bridged contract always, and under\n`snapshot: contract+source`, the donor files too. `MANIFEST.md` sits at that directory's root.\n\n### Snapshot manifest format\n\n- **Donor**: \u003Crepo url or path>\n- **Commit**: \u003Cfull sha>\n- **Captured**: \u003CYYYY-MM-DD>\n- **Mode**: contract | contract+source\n- **Hash algorithm**: sha256, lowercase hex, over the bytes as captured\n\n| Snapshot path | Donor path | Commit | Bytes | SHA-256 | Member ranges |\n|---|---|---|---|---|---|\n| `orders\u002Forder-intake` | `src\u002Forders\u002Forder-intake` | `\u003Csha>` | 4821 | `3f9a...` | `1: CreateOrder 12-58; 2: ValidateTotals 60-93` |\n\nOne row per captured file. `Member ranges` is `\u003Cordinal>: \u003Cmember> \u003CfirstLine>-\u003ClastLine>`,\nsemicolon-separated, ordinals contiguous from 1 - the same ordinals the Member manifest table uses.\n\n### Two snapshot rules\n\n1. **Cite the snapshot, not the donor.** Path mapping and Member manifest rows cite `Snapshot\n   path`, never a donor-repo path - donor line numbers rot the moment the donor changes; the\n   snapshot is frozen. Donor paths, the commit, and line ranges live only in `MANIFEST.md`,\n   addressed by `(Snapshot path, Ordinal)` - the Member manifest table carries no line-range\n   column of its own.\n2. **Quarantine.** The snapshot directory is evidence, never a copy source handed to an\n   implementer without a Member manifest row and an allowed-deviation list scoping it.\n\n### Immutability\n\nAt freeze, every file under `04-artifacts\u002Fsource\u002F` plus `MANIFEST.md` is appended as an\n**individual literal string** to `paths.protected` in `.claude\u002Fproject-config.json`. Both\n`spec-gate` hooks match `paths.protected` by exact string equality, not glob - the enumeration\n*is* the mechanism, not a workaround for one. The append must be idempotent. `\u002Fsd:spec` cannot\nperform this step itself (it never touches `.claude\u002F`); `\u002Fsd:port` Phase 2 performs the freeze.\nOutside that pipeline it stays a documented manual step. `spec-gate` guards `Edit`\u002F`Write` only -\nit does not stop a shell delete.\n\nPer-file hashes are recorded now so a later drift check (re-hashing the donor at a newer commit)\nremains possible; consuming them is out of scope for this story.\n\n---\n\n## Parity artifacts (main thread)\n\nThe diff `sd-reviewer` adjudicates is produced by the main thread, never by an agent. The reviewer\nhas no `Bash` and no write tool - that allowlist is what structurally stops the adjudicator from\nfixing what it judges - so the diff must already be a file on disk when the reviewer is invoked.\n\nOutput root is `04-artifacts\u002Fparity\u002F`, a sibling of the frozen `04-artifacts\u002Fsource\u002F`: same spec,\nsame artifacts folder, evidence produced at a later phase by a different actor. Nothing under\n`parity\u002F` is frozen or appended to `paths.protected` - it is regenerated on every parity run and\noverwrites the previous one.\n\n- One diff per non-`omit` path mapping row, snapshot side first, host side second, unified format,\n  at least 3 lines of context. File name is the `Host path` with `\u002F` replaced by `__`, suffix\n  `.diff`.\n- A mapping row whose `Host path` does not exist still gets its diff - an all-deletion one. That is\n  what makes a `missing` member visible without the reviewer listing the host tree itself.\n- Every changeset file with no mapping row gets an all-addition diff, named the same way. Path\n  conformance is then a property of the diff set rather than a second traversal.\n- `INDEX.md` at the parity root, one row per diff file: `Diff file`, `Snapshot path`, `Host path`,\n  `Mapping row` (the path mapping row number, or `-` when there is none).\n\n`INDEX.md` is the reviewer's `DIFF_REF`. A run that cannot produce a diff for a row says so in that\nrow's `Mapping row` cell instead of dropping the row - a silently absent row reads as a clean file.\n\n---\n\n## Hunk classification (sd-reviewer)\n\nClassify every hunk of the port changeset into exactly one class. The vocabulary is closed - there\nis no sixth class and no \"probably fine\".\n\n| Class | Condition | Verdict |\n|---|---|---|\n| `justified` | maps to a deviation row whose citation satisfies its group | accept |\n| `unjustified` | departs from the donor form with no deviation row covering it | BLOCK |\n| `missing` | a manifest member has no host counterpart and no `omitted` status | BLOCK |\n| `extra` | host content with no donor counterpart and no deviation row | BLOCK |\n| `overreached` | a deviation row covers the hunk, but the hunk changes more than that row's `Host form` states | BLOCK |\n\n`overreached` is where a rubber stamp hides: one legitimately cited rename carrying an unrelated\nreordering in the same hunk. Judge the hunk against the row's `Host form` text, never against the\nmere existence of a row.\n\nA `justified` hunk is a PASS and is not written up as a finding - report the count in the summary\nline. Listing them individually buries the BLOCKs they outnumber.\n\nAnchor every fidelity BLOCK to the port spec's fidelity acceptance criterion - a spec acceptance\ncriterion is a legal anchor for a code target under **sd-severity-taxonomy**. Cite the deviation\nrow, or its absence, as the supporting `file:line` per **sd-evidence-citation**. A deviation row is\nevidence; it is never the anchor by itself.\n\n### Whole-artifact checks\n\nTwo checks no hunk class can express, because each is a property of the changeset as a whole. Both\nrun once per parity review, both are BLOCK, and both are reported even when they pass - the count\nis the evidence the check ran.\n\n| Check | Question | Reported as |\n|---|---|---|\n| Member completeness | does every manifest row with `Status` `ported` or `deviated` have a host counterpart? | `\u003Cn>\u002F\u003Ctotal> members present`, plus one BLOCK naming the `Donor path`, `Member` and `Ordinal` of each absent row |\n| Path conformance | does every changeset file appear as a `Host path` in the path mapping table? | one BLOCK per unmapped file, citing the file and the table it is missing from |\n\nBoth belong to the reviewer rather than to `\u002Fsd:verify`, which decides everything from the spec's\nown artifacts and reads no host source - the reasoning is recorded in `docs\u002Farchitecture.md`.\n\n### The parity gate\n\nA HARD gate. Any BLOCK from the classification or from either whole-artifact check refuses\nclose-out. Two resolutions exist: revert the host toward the snapshot, or add a deviation row whose\ngroup and citation hold up, then regenerate the parity artifacts and re-run. There is no third, and\nno override - a gate that can be waived measures nothing. Deriving the missing rows from the\nunexplained hunks is not a resolution either; it makes the diff justify itself.\n\n---\n\n## Anti-patterns\n\n- **Improving the donor while porting.** The port is not the moment. Reproduce it, record it, and\n  raise the follow-up.\n- **A deviation row citing nothing.** \"Host style\" is not a citation; group 3 needs `file:line`.\n- **Renaming to local taste.** Taste is not one of the four groups.\n- **Reordering for readability.** Donor order is the order, attribute order included.\n- **Waving a table through because it looks right.** The completeness conditions are counted, not\n  judged. An incomplete table is refused without a discussion of intent.\n- **Treating a donor defect as an invitation.** Record it; fix it in its own spec.\n",{},"main","cb6a2aef549bb625b9ba1869d220d40938e83c18","skills\u002Fsd-port-fidelity",0,"https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright","https:\u002F\u002Fgithub.com\u002Fdevelopzoneio","2026-11-11 17:12:43",{"source":7,"skillName":5,"commands":29,"prompt":39,"zipAvailable":40},[30,33,36],{"tool":31,"command":32},"npx","npx skills add developzoneio\u002Fspecwright --skill sd-port-fidelity",{"tool":34,"command":35},"bunx","bunx skills add developzoneio\u002Fspecwright --skill sd-port-fidelity",{"tool":37,"command":38},"pnpm","pnpm dlx skills add developzoneio\u002Fspecwright --skill sd-port-fidelity","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright\u002Fblob\u002Fmain\u002Fskills\u002Fsd-port-fidelity\u002FSKILL.md",true,[],[43,49,54,60,65,70],{"skillNo":44,"name":45,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":8,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":46,"categories":47,"keywords":48,"publishedAt":17},"01M752V2C4FNMKBZTZETKKN70B","sd-model-escalation","https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright\u002Fblob\u002Fmain\u002Ftests\u002Fcontract-lint\u002Ffixtures\u002Ffp-cl605-alias-list\u002Foverlay\u002Fskills\u002Fsd-model-escalation\u002FSKILL.md",[],[],{"skillNo":50,"name":45,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":8,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":51,"categories":52,"keywords":53,"publishedAt":17},"01M752V0C3S0BHSXZ4JM3B7MF2","https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright\u002Fblob\u002Fmain\u002Ftests\u002Fcontract-lint\u002Ffixtures\u002Ffp-cl601-allow-comment\u002Foverlay\u002Fskills\u002Fsd-model-escalation\u002FSKILL.md",[],[],{"skillNo":55,"name":56,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":8,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":57,"categories":58,"keywords":59,"publishedAt":17},"01M752TYQZVASA2BTDRZB4N8W6","sd-demo-guard","https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright\u002Fblob\u002Fmain\u002Ftests\u002Fcontract-lint\u002Ffixtures\u002Ffp-cl009-phrase-outside-phase0\u002Foverlay\u002Fskills\u002Fsd-demo-guard\u002FSKILL.md",[],[],{"skillNo":61,"name":45,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":8,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":62,"categories":63,"keywords":64,"publishedAt":17},"01M752TXBFQHK7NCDTZEBHZRFN","https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright\u002Fblob\u002Fmain\u002Ftests\u002Fcontract-lint\u002Ffixtures\u002Fcl605-command-restates-ladder\u002Foverlay\u002Fskills\u002Fsd-model-escalation\u002FSKILL.md",[],[],{"skillNo":66,"name":45,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":8,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":17},"01M752TVDG89BJRTGFET80RCK2","https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright\u002Fblob\u002Fmain\u002Ftests\u002Fcontract-lint\u002Ffixtures\u002Fcl604-row-skips-rung\u002Foverlay\u002Fskills\u002Fsd-model-escalation\u002FSKILL.md",[],[],{"skillNo":71,"name":45,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":8,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":74,"publishedAt":17},"01M752TT6SD0SSK6Z0GQ4HM68P","https:\u002F\u002Fgithub.com\u002Fdevelopzoneio\u002Fspecwright\u002Fblob\u002Fmain\u002Ftests\u002Fcontract-lint\u002Ffixtures\u002Fcl603-full-model-id-in-row\u002Foverlay\u002Fskills\u002Fsd-model-escalation\u002FSKILL.md",[],[]]