[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6R9B7DR4RVAF4V282MVYV1H":3,"skill-same:01M6R9B7DR4RVAF4V282MVYV1H":72},{"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":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":50,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M6R9B7DR4RVAF4V282MVYV1H","principle-type-system-discipline",null,"Apply when designing types, reviewing a function signature, or writing code in any statically-typed language. Make illegal states unrepresentable, brand semantic primitives, parse external data at boundaries, refuse to lie to the compiler, exhaust variants, derive from authoritative schemas.","Nairon-AI\u002Fagentic-starter-pack","Nairon-AI","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F260662138?v=4","01M6R8PZ1Y8CSQGFN61VACZGTH","Nairon AI","01M6R8PZ6184VR3BA88YZFBC3N",4,"MIT","https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fengineering\u002Fprinciple-type-system-discipline\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"principle type system discipline","system","discipline","type system","type","when","writing","parse","variants","apply","at","states","types","make","language","primitives","brand","data","compiler","code","2026-11-10 10:12:30",false,"---\nname: principle-type-system-discipline\ndescription: \"Apply when designing types, reviewing a function signature, or writing code in any statically-typed language. Make illegal states unrepresentable, brand semantic primitives, parse external data at boundaries, refuse to lie to the compiler, exhaust variants, derive from authoritative schemas.\"\n---\n\n# Type System Discipline\n\nThe type checker is a proof assistant. Use it to eliminate impossible states, mismatched primitives, and unhandled variants at compile time. Anything you let through as runtime data becomes a runtime failure the compiler could have stopped.\n\nApplies to any typed language. Skills like `typescript-best-practices` ground it in specific syntax.\n\n**The patterns:**\n\n- **Make illegal states unrepresentable.** Model variants as sum types: discriminated unions in TypeScript, enums with payloads in Rust\u002FSwift\u002FKotlin, sealed classes in Scala, ADTs in Haskell\u002FOCaml. Don't model state as a bag of optional fields where contradictory combinations compile. A subtle anti-pattern worth naming: `{ completed: boolean; completedAt?: Date }` admits `completed: true; completedAt: undefined`, which is meaningless. Derive the boolean from a single source like `completedAt !== null`, or model the variants explicitly as `{ kind: 'open' } | { kind: 'done'; at: Date }`. If a bug forces the question \"wait, can this combination actually happen?\", the type is too loose.\n- **Brand semantic primitives.** `UserId` and `OrderId` are strings underneath but should not be interchangeable. Newtypes in Rust, opaque types in Swift, value classes in Kotlin, phantom types in Haskell, branded intersections in TypeScript. Validate once at creation, trust the type downstream.\n- **External data is untyped until parsed.** RPC payloads, JSON, IPC messages, CLI args, config files, environment variables, database rows. Have a parse function at every boundary that turns unstructured input into the typed model. Read `brain\u002Fprinciples\u002Fboundary-discipline.md` for validation placement.\n- **Don't lie to the type system.** Casts, unsafe coercions, and assertion functions that bypass the compiler are runtime crashes waiting to happen. If the compiler can't prove a fact, prove it (validate, narrow, refine the model) or accept that the cast is a hazard. The cast you bury today is the postmortem you write next week.\n- **Exhaustive matching is the compiler's job.** When you match on a sum type, the compiler must fail compilation if a new variant is added without handling. Use the idiom your language provides: `never`-typed binding in TypeScript, unannotated `match` in Rust, `-Wincomplete-patterns` in Haskell, sealed-class match exhaustiveness in Kotlin.\n- **Derive types from authoritative schemas.** When a protocol buffer, OpenAPI spec, GraphQL schema, database migration, or design-system token file defines a shape, derive from it instead of hand-rolling a parallel type. Manual duplication drifts. Read `brain\u002Fprinciples\u002Fencode-lessons-in-structure.md`.\n- **Prefer compile-time over runtime.** Every runtime assertion, null check, and `instanceof` is admitting the type system isn't carrying its weight. Push the check up to the type.\n\n**The tests:**\n\n- \"Can I write a comment explaining when this combination of fields is valid?\" If yes, the type is too loose. Split it into a sum type.\n- \"Do two of my function arguments share a primitive type but mean different things?\" Brand them.\n- \"Where did this `any`, this `as`, this `assertNotNull` come from?\" Trace it to the boundary and validate there instead.\n- \"If a new variant is added next month, will the compiler tell the next agent where to add a case?\" If no, the match isn't exhaustive.\n- \"Is this type duplicating a shape another file owns?\" Derive instead.\n","# Type System Discipline\n\nThe type checker is a proof assistant. Use it to eliminate impossible states, mismatched primitives, and unhandled variants at compile time. Anything you let through as runtime data becomes a runtime failure the compiler could have stopped.\n\nApplies to any typed language. Skills like `typescript-best-practices` ground it in specific syntax.\n\n**The patterns:**\n\n- **Make illegal states unrepresentable.** Model variants as sum types: discriminated unions in TypeScript, enums with payloads in Rust\u002FSwift\u002FKotlin, sealed classes in Scala, ADTs in Haskell\u002FOCaml. Don't model state as a bag of optional fields where contradictory combinations compile. A subtle anti-pattern worth naming: `{ completed: boolean; completedAt?: Date }` admits `completed: true; completedAt: undefined`, which is meaningless. Derive the boolean from a single source like `completedAt !== null`, or model the variants explicitly as `{ kind: 'open' } | { kind: 'done'; at: Date }`. If a bug forces the question \"wait, can this combination actually happen?\", the type is too loose.\n- **Brand semantic primitives.** `UserId` and `OrderId` are strings underneath but should not be interchangeable. Newtypes in Rust, opaque types in Swift, value classes in Kotlin, phantom types in Haskell, branded intersections in TypeScript. Validate once at creation, trust the type downstream.\n- **External data is untyped until parsed.** RPC payloads, JSON, IPC messages, CLI args, config files, environment variables, database rows. Have a parse function at every boundary that turns unstructured input into the typed model. Read `brain\u002Fprinciples\u002Fboundary-discipline.md` for validation placement.\n- **Don't lie to the type system.** Casts, unsafe coercions, and assertion functions that bypass the compiler are runtime crashes waiting to happen. If the compiler can't prove a fact, prove it (validate, narrow, refine the model) or accept that the cast is a hazard. The cast you bury today is the postmortem you write next week.\n- **Exhaustive matching is the compiler's job.** When you match on a sum type, the compiler must fail compilation if a new variant is added without handling. Use the idiom your language provides: `never`-typed binding in TypeScript, unannotated `match` in Rust, `-Wincomplete-patterns` in Haskell, sealed-class match exhaustiveness in Kotlin.\n- **Derive types from authoritative schemas.** When a protocol buffer, OpenAPI spec, GraphQL schema, database migration, or design-system token file defines a shape, derive from it instead of hand-rolling a parallel type. Manual duplication drifts. Read `brain\u002Fprinciples\u002Fencode-lessons-in-structure.md`.\n- **Prefer compile-time over runtime.** Every runtime assertion, null check, and `instanceof` is admitting the type system isn't carrying its weight. Push the check up to the type.\n\n**The tests:**\n\n- \"Can I write a comment explaining when this combination of fields is valid?\" If yes, the type is too loose. Split it into a sum type.\n- \"Do two of my function arguments share a primitive type but mean different things?\" Brand them.\n- \"Where did this `any`, this `as`, this `assertNotNull` come from?\" Trace it to the boundary and validate there instead.\n- \"If a new variant is added next month, will the compiler tell the next agent where to add a case?\" If no, the match isn't exhaustive.\n- \"Is this type duplicating a shape another file owns?\" Derive instead.\n",{"name":5,"description":7},"main","c9d0c408715983e993b2f9ebffdbfa7f10153bcb","engineering\u002Fprinciple-type-system-discipline",0,"https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack","https:\u002F\u002Fgithub.com\u002FNairon-AI","https:\u002F\u002Fwww.naironai.com\u002F","Building the future of Work","2026-09-20 17:40:05",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add Nairon-AI\u002Fagentic-starter-pack --skill principle-type-system-discipline",{"tool":59,"command":60},"bunx","bunx skills add Nairon-AI\u002Fagentic-starter-pack --skill principle-type-system-discipline",{"tool":62,"command":63},"pnpm","pnpm dlx skills add Nairon-AI\u002Fagentic-starter-pack --skill principle-type-system-discipline","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fengineering\u002Fprinciple-type-system-discipline\u002FSKILL.md",true,[67],{"path":68,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":70,"sourceHtmlUrl":71},"LICENSE","许可证",1067,"https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fengineering\u002Fprinciple-type-system-discipline\u002FLICENSE",[73,107,129,150,170,190],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":89,"publishedAt":39},"01M6RBCG630Y8X99XWR9Q4GYNY","writing-shape","Take a markdown file of raw material and shape it into an article through a conversational session — drafting candidate openings, growing the piece paragraph by paragraph, arguing about format (lists, tables, callouts, quotes) at each step. Use when the user has a pile of notes, fragments, or a rough draft and wants help turning it into something publishable.","https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fwriting\u002Fwriting-shape\u002FSKILL.md",[79,84],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[25,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,29,106,24],"writing shape","shape","notes","help","file","markdown","format","session","use","take","draft","article","material","it","about","quotes","candidate",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":115,"publishedAt":39},"01M6RBCCCB1KMF01P5SYGFWBSW","writing-fragments","Grilling session that mines the user for fragments — heterogeneous nuggets of writing (claims, vignettes, sharp sentences, half-thoughts) — and appends them to a single document as raw material for a future article. Use when the user wants to develop ideas before imposing structure, or mentions \"fragments\", \"ideate\", or \"raw material\" for writing.","https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fwriting\u002Fwriting-fragments\u002FSKILL.md",[113,114],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},[25,116,117,118,119,120,97,98,121,122,123,101,124,102,125,126,127,128,24],"writing fragments","grilling","ideate","develop","user","document","structure","ideas","as","sharp","claims","for","single",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":137,"publishedAt":39},"01M6RBC8V7NHHKMTAZB4BPXVYQ","writing-beats","Shape an article as a journey of beats, choose-your-own-adventure style. The user picks a starting beat from the raw material, you write only that beat, then offer options for where to pivot next, beat by beat, until the article reaches a natural end. Use when the user has raw material and wants to assemble it as a narrative rather than an argument.","https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fwriting\u002Fwriting-beats\u002FSKILL.md",[135,136],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},[25,138,139,140,98,141,142,91,143,144,145,101,146,124,147,102,148,149,127,24],"writing beats","choose","write","assemble","only","journey","next","options","end","style","narrative","argument",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":158,"publishedAt":39},"01M6RBC58SG5Y5SC4ZV4ZNEFHC","stop-slop","Remove AI writing patterns from prose. Use when drafting, editing, or reviewing text to eliminate predictable AI tells.","https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fwriting\u002Fstop-slop\u002FSKILL.md",[156,157],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},[159,160,161,25,162,163,164,165,166,98,167,168,169,127,24],"stop","stop slop","slop","content","https","text","editing","remove","prose","patterns","drafts",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":178,"publishedAt":39},"01M6RBBJTTCJ7KZCP16G9JDFZH","humanizer","Remove signs of AI-generated writing from text. Use when editing or reviewing\ntext to make it sound more natural and human-written. Based on Wikipedia's\ncomprehensive \"Signs of AI writing\" guide. Detects and fixes patterns including:\ninflated symbolism, promotional language, superficial -ing analyses, vague\nattributions, em dash overuse, rule of three, AI vocabulary words, passive\nvoice, negative parallelisms, and filler phrases.","https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fwriting\u002Fhumanizer\u002FSKILL.md",[176,177],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},[172,25,38,179,164,180,140,181,182,166,183,184,168,185,186,32,187,188,189,24],"em dash","read","edit","generated","guide","opencode","three","human","wikipedia","vague","dash",{"skillNo":191,"name":192,"nameZh":6,"description":193,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":194,"categories":195,"keywords":196,"publishedAt":39},"01M6RBBEQKJ5HRH8AV9J85QB1T","feedback","Prepare, deliver, and debrief timely interpersonal feedback using a question-first coaching flow, observable behavior, owned experience, and concrete impact. Use when drafting feedback, coaching managers, rehearsing a feedback conversation, praising specific behavior, or reviewing whether feedback landed.","https:\u002F\u002Fgithub.com\u002FNairon-AI\u002Fagentic-starter-pack\u002Fblob\u002Fmain\u002Fwriting\u002Ffeedback\u002FSKILL.md",[],[192,197,198,199,200,201,98,202,203,204,205,206,24,207],"prepare","flow","first","question","behavior","conversation","coaching","debrief","impact","managers","deliver"]