[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M79M75XTY0RA4XZ2MGFTHZXK":3,"skill-same:01M79M75XTY0RA4XZ2MGFTHZXK":56},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":27,"repositoryHtmlUrl":28,"repositoryHomepageUrl":29,"ownerHtmlUrl":30,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":31,"install":32,"resources":45},"01M79M75XTY0RA4XZ2MGFTHZXK","contact-data-fidelity",null,"Use when changing contact fields, the neutral Card model, vCard\u002FJSContact\u002FCSV conversion, sanitization, or loss handling.","DrewBrunning\u002Fmycorrhizal-crm","DrewBrunning","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6752526?v=4","01M79M5Q84HEMNMKVCSH7RXV78","Drew Brunning","01M79M5Q90WKHZRQC3MEBRYB4Y",4,"MIT","https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fcontact-data-fidelity\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: contact-data-fidelity\ndescription: Use when changing contact fields, the neutral Card model, vCard\u002FJSContact\u002FCSV conversion, sanitization, or loss handling.\nlicense: MIT\n---\n\n# Contact data fidelity\n\nOutcome: a contact change that survives every representation without silently\ndropping data. Read `backend\u002FAGENTS.md` (traps #2 and #3) and\n`docs\u002Fadrs\u002F0001-neutral-hub-and-spoke-contact-model.md` first.\n\nThe canonical flow is: request\u002Fimport → neutral `contactmodel.Card` → flat\n`contacts` columns → projections (`RecordForContact`) → exporters. The e2e\nsetup in `frontend\u002Fe2e\u002Fglobal-setup.ts` hardcodes `http:\u002F\u002Flocalhost:7300`; it is\ntest infrastructure, not a production default.\n\n## Steps\n\n1. Open [data-flow](references\u002Fdata-flow.md) and identify every hop your field\n   touches. A field with no flat-column home must still round-trip through\n   `RecordForContact`; `RecordFromContact` rebuilds from flat fields and drops it.\n2. Write through `ApplyRecordToContact` (never set `Contact.Card`\u002F`CRM` directly).\n   On update, merge through `backend\u002Fmodels\u002Fcontact_card_merge.go`; preserve its\n   `mergeMedia` remote-photo rule.\n3. Decide sensitivity (`normal|private|secret`). Anything above `normal` is\n   filtered in the query for sync\u002Fshares\u002Fneutral-`Card` exports and re-included\n   only through that surface's explicit include flag; CSV export, account bundle,\n   and contact map are the three deliberate full-fidelity exceptions.\n4. Update the correspondence oracle (`backend\u002Fcorrespondence\u002Ftestdata\u002Fcorrespondence.tsv`)\n   when the field's cross-format mapping changes, then regenerate the DATA-01\n   matrix with `go run .\u002Fcmd\u002Fgencompatmatrix`.\n5. Open [fidelity test matrix](references\u002Ffidelity-test-matrix.md) to choose the\n   owning test rather than duplicating round-trip assertions in a new package.\n6. Keep the web and Android clients on the same generated contract; run the\n   frontend type check even when you only touched Go.\n\n## DoD\n\n```bash\ncd backend && go test .\u002Fcorrespondence\u002F... .\u002Fvcard3\u002F... .\u002Fvcard4\u002F... .\u002Fjscontact\u002F... .\u002Finternal\u002Frfctest\u002F...\ncd backend && go run .\u002Fcmd\u002Fgencompatmatrix\ncd frontend && npx tsc --noEmit\n```\n\nReport any check you could not run; never imply it passed.\n\n## Stop and ask\n\n- The field has no neutral-model or flat-column home and the proposal is to\n  expose it only in one exporter.\n- A conversion would be lossy in a way the compatibility matrix cannot express.\n- The change would weaken the sensitivity filter on a leaving copy.\n\nCanonical detail: `docs\u002Fdata-model.md`, `backend\u002FAGENTS.md` (Domain notes),\n`docs\u002Fdata-01-field-compatibility-matrix.md`.\n","# Contact data fidelity\n\nOutcome: a contact change that survives every representation without silently\ndropping data. Read `backend\u002FAGENTS.md` (traps #2 and #3) and\n`docs\u002Fadrs\u002F0001-neutral-hub-and-spoke-contact-model.md` first.\n\nThe canonical flow is: request\u002Fimport → neutral `contactmodel.Card` → flat\n`contacts` columns → projections (`RecordForContact`) → exporters. The e2e\nsetup in `frontend\u002Fe2e\u002Fglobal-setup.ts` hardcodes `http:\u002F\u002Flocalhost:7300`; it is\ntest infrastructure, not a production default.\n\n## Steps\n\n1. Open [data-flow](references\u002Fdata-flow.md) and identify every hop your field\n   touches. A field with no flat-column home must still round-trip through\n   `RecordForContact`; `RecordFromContact` rebuilds from flat fields and drops it.\n2. Write through `ApplyRecordToContact` (never set `Contact.Card`\u002F`CRM` directly).\n   On update, merge through `backend\u002Fmodels\u002Fcontact_card_merge.go`; preserve its\n   `mergeMedia` remote-photo rule.\n3. Decide sensitivity (`normal|private|secret`). Anything above `normal` is\n   filtered in the query for sync\u002Fshares\u002Fneutral-`Card` exports and re-included\n   only through that surface's explicit include flag; CSV export, account bundle,\n   and contact map are the three deliberate full-fidelity exceptions.\n4. Update the correspondence oracle (`backend\u002Fcorrespondence\u002Ftestdata\u002Fcorrespondence.tsv`)\n   when the field's cross-format mapping changes, then regenerate the DATA-01\n   matrix with `go run .\u002Fcmd\u002Fgencompatmatrix`.\n5. Open [fidelity test matrix](references\u002Ffidelity-test-matrix.md) to choose the\n   owning test rather than duplicating round-trip assertions in a new package.\n6. Keep the web and Android clients on the same generated contract; run the\n   frontend type check even when you only touched Go.\n\n## DoD\n\n```bash\ncd backend && go test .\u002Fcorrespondence\u002F... .\u002Fvcard3\u002F... .\u002Fvcard4\u002F... .\u002Fjscontact\u002F... .\u002Finternal\u002Frfctest\u002F...\ncd backend && go run .\u002Fcmd\u002Fgencompatmatrix\ncd frontend && npx tsc --noEmit\n```\n\nReport any check you could not run; never imply it passed.\n\n## Stop and ask\n\n- The field has no neutral-model or flat-column home and the proposal is to\n  expose it only in one exporter.\n- A conversion would be lossy in a way the compatibility matrix cannot express.\n- The change would weaken the sensitivity filter on a leaving copy.\n\nCanonical detail: `docs\u002Fdata-model.md`, `backend\u002FAGENTS.md` (Domain notes),\n`docs\u002Fdata-01-field-compatibility-matrix.md`.\n",{"name":5,"license":15,"description":7},"main","9536dc2059e7970271680a546c4beef69e191b1b",".agents\u002Fskills\u002Fcontact-data-fidelity",2,"https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm","https:\u002F\u002Fdrewbrunning.github.io\u002Fmycorrhizal-crm\u002F","https:\u002F\u002Fgithub.com\u002FDrewBrunning","2026-11-14 11:31:00",{"source":8,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add DrewBrunning\u002Fmycorrhizal-crm --skill contact-data-fidelity",{"tool":38,"command":39},"bunx","bunx skills add DrewBrunning\u002Fmycorrhizal-crm --skill contact-data-fidelity",{"tool":41,"command":42},"pnpm","pnpm dlx skills add DrewBrunning\u002Fmycorrhizal-crm --skill contact-data-fidelity","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fcontact-data-fidelity\u002FSKILL.md",true,[46,52],{"path":47,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":50,"sourceHtmlUrl":51},"references\u002Fdata-flow.md","REFERENCE","参考文档",2872,"https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fcontact-data-fidelity\u002Freferences\u002Fdata-flow.md",{"path":53,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":54,"sourceHtmlUrl":55},"references\u002Ffidelity-test-matrix.md",2327,"https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fcontact-data-fidelity\u002Freferences\u002Ffidelity-test-matrix.md",[57,64,71,78,85,91],{"skillNo":58,"name":59,"nameZh":6,"description":60,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":61,"categories":62,"keywords":63,"publishedAt":19},"01M79M8PCVKS3QREKY3QXJEBR9","valid","Use when exercising a well-formed skill fixture in the agent-context tests.","https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002Fbackend\u002Finternal\u002Fagentcontext\u002Ftestdata\u002Fskills\u002Fvalid\u002FSKILL.md",[],[],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":19},"01M79M8KBDD3M00TXB79N8794H","unregistered-dod","Use when a fixture must carry a DoD command no Suite registers.","https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002Fbackend\u002Finternal\u002Fagentcontext\u002Ftestdata\u002Fskills\u002Funregistered-dod\u002FSKILL.md",[],[],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M79M8H040AE9HFB8P8J394G9","orphan-reference","Use when a fixture must exercise an unlinked reference file.","https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002Fbackend\u002Finternal\u002Fagentcontext\u002Ftestdata\u002Fskills\u002Forphan-reference\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":19},"01M79M8FHJVP35DG9MAGFV6P2W","missing-reference","Use when a fixture must link to a reference file that does not exist.","https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002Fbackend\u002Finternal\u002Fagentcontext\u002Ftestdata\u002Fskills\u002Fmissing-reference\u002FSKILL.md",[],[],{"skillNo":86,"name":87,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":90,"publishedAt":19},"01M79M8D1PNZ7JA7N8MCGXQ5JH","missing-description","https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002Fbackend\u002Finternal\u002Fagentcontext\u002Ftestdata\u002Fskills\u002Fmissing-description\u002FSKILL.md",[],[],{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":19},"01M79M8AT8A2GD6CJPEJXW21C4","long-reference","Use when a fixture must exceed the reference line maximum.","https:\u002F\u002Fgithub.com\u002FDrewBrunning\u002Fmycorrhizal-crm\u002Fblob\u002Fmain\u002Fbackend\u002Finternal\u002Fagentcontext\u002Ftestdata\u002Fskills\u002Flong-reference\u002FSKILL.md",[],[]]