[{"data":1,"prerenderedAt":686},["ShallowReactive",2],{"install-doctrine":3},{"data":4,"body":7,"toc":680},{"title":5,"description":6},"The kit pipeline — how framework targets get made","",{"type":8,"children":9},"root",[10,18,34,56,63,160,232,258,268,274,298,306,339,464,495,543,583,600,617,625,659,665],{"type":11,"tag":12,"props":13,"children":15},"element","h1",{"id":14},"the-kit-pipeline-how-framework-targets-get-made",[16],{"type":17,"value":5},"text",{"type":11,"tag":19,"props":20,"children":21},"blockquote",{},[22],{"type":11,"tag":23,"props":24,"children":25},"p",{},[26,28],{"type":17,"value":27},"Ratified 2026-08-19 with the first framework-target batch (C# \u002F\nReact \u002F WordPress). Answers the standing question: ",{"type":11,"tag":29,"props":30,"children":31},"em",{},[32],{"type":17,"value":33},"how automatic\nis this, and where do the superPOD panels fit?",{"type":11,"tag":23,"props":35,"children":36},{},[37,39,46,48,54],{"type":17,"value":38},"TUX serves consumers on platforms that can't run the Nuxt layer —\n.NET report generators, plain React apps, WordPress marcom sites,\nPower BI. The kit (",{"type":11,"tag":40,"props":41,"children":43},"code",{"className":42},[],[44],{"type":17,"value":45},"kit\u002F",{"type":17,"value":47},", shipped inside the ",{"type":11,"tag":40,"props":49,"children":51},{"className":50},[],[52],{"type":17,"value":53},"@tti\u002Ftti-ux",{"type":17,"value":55}," npm\npackage) is how they consume the system. Two tiers, two very\ndifferent automation stories.",{"type":11,"tag":57,"props":58,"children":60},"h2",{"id":59},"tier-1-deterministic-emitters-tokens-themes",[61],{"type":17,"value":62},"Tier 1 — deterministic emitters (tokens & themes)",{"type":11,"tag":23,"props":64,"children":65},{},[66,72,74,80,82,88,90,96,98,104,106,112,114,120,122,128,130,136,138,144,145,151,152,158],{"type":11,"tag":67,"props":68,"children":69},"strong",{},[70],{"type":17,"value":71},"What:",{"type":17,"value":73}," anything derivable from ",{"type":11,"tag":40,"props":75,"children":77},{"className":76},[],[78],{"type":17,"value":79},"design\u002Ftokens.json",{"type":17,"value":81}," by pure\ncomputation. Today: ",{"type":11,"tag":40,"props":83,"children":85},{"className":84},[],[86],{"type":17,"value":87},"kit\u002Fcss",{"type":17,"value":89}," (custom properties), ",{"type":11,"tag":40,"props":91,"children":93},{"className":92},[],[94],{"type":17,"value":95},"kit\u002Fscss",{"type":17,"value":97},"\n(Bootstrap partial), ",{"type":11,"tag":40,"props":99,"children":101},{"className":100},[],[102],{"type":17,"value":103},"kit\u002Fenv",{"type":17,"value":105}," (brand env), ",{"type":11,"tag":40,"props":107,"children":109},{"className":108},[],[110],{"type":17,"value":111},"kit\u002Fpowerbi",{"type":17,"value":113}," (report\nthemes), ",{"type":11,"tag":40,"props":115,"children":117},{"className":116},[],[118],{"type":17,"value":119},"kit\u002Fcsharp",{"type":17,"value":121}," (",{"type":11,"tag":40,"props":123,"children":125},{"className":124},[],[126],{"type":17,"value":127},"TuxTokens.cs",{"type":17,"value":129},"), ",{"type":11,"tag":40,"props":131,"children":133},{"className":132},[],[134],{"type":17,"value":135},"kit\u002Freact",{"type":17,"value":137},"\n(",{"type":11,"tag":40,"props":139,"children":141},{"className":140},[],[142],{"type":17,"value":143},"tux-tokens.ts",{"type":17,"value":129},{"type":11,"tag":40,"props":146,"children":148},{"className":147},[],[149],{"type":17,"value":150},"kit\u002Fwp",{"type":17,"value":121},{"type":11,"tag":40,"props":153,"children":155},{"className":154},[],[156],{"type":17,"value":157},"theme.json",{"type":17,"value":159},").",{"type":11,"tag":23,"props":161,"children":162},{},[163,168,170,176,178,184,186,192,194,199,201,207,208,214,216,222,224,230],{"type":11,"tag":67,"props":164,"children":165},{},[166],{"type":17,"value":167},"How:",{"type":17,"value":169}," ",{"type":11,"tag":40,"props":171,"children":173},{"className":172},[],[174],{"type":17,"value":175},"npm run build:kit",{"type":17,"value":177}," runs the emitters\n(",{"type":11,"tag":40,"props":179,"children":181},{"className":180},[],[182],{"type":17,"value":183},"scripts\u002Fbuild-tokens.mjs",{"type":17,"value":185},", ",{"type":11,"tag":40,"props":187,"children":189},{"className":188},[],[190],{"type":17,"value":191},"build-framework-targets.mjs",{"type":17,"value":193},", …);\noutputs are ",{"type":11,"tag":67,"props":195,"children":196},{},[197],{"type":17,"value":198},"committed",{"type":17,"value":200},", and lock tests\n(",{"type":11,"tag":40,"props":202,"children":204},{"className":203},[],[205],{"type":17,"value":206},"tests\u002Ftux-kit-targets.test.ts",{"type":17,"value":185},{"type":11,"tag":40,"props":209,"children":211},{"className":210},[],[212],{"type":17,"value":213},"build-tokens --check",{"type":17,"value":215},") fail CI if\na committed output drifts from its generator. Publishing is the tag\ntrain: merge → tag ",{"type":11,"tag":40,"props":217,"children":219},{"className":218},[],[220],{"type":17,"value":221},"vX.Y.Z",{"type":17,"value":223}," → ",{"type":11,"tag":40,"props":225,"children":227},{"className":226},[],[228],{"type":17,"value":229},"publish-package.yml",{"type":17,"value":231}," ships the whole\nkit to the Forgejo npm registry.",{"type":11,"tag":23,"props":233,"children":234},{},[235,240,242,248,250,256],{"type":11,"tag":67,"props":236,"children":237},{},[238],{"type":17,"value":239},"Automation status: fully automatic, zero AI — by design.",{"type":17,"value":241}," Same\ninput, same bytes, forever. A token edit in ",{"type":11,"tag":40,"props":243,"children":245},{"className":244},[],[246],{"type":17,"value":247},"tokens.json",{"type":17,"value":249}," propagates\nto every target in one ",{"type":11,"tag":40,"props":251,"children":253},{"className":252},[],[254],{"type":17,"value":255},"build:kit",{"type":17,"value":257}," run, and no model is ever asked to\ntranscribe a hex value. AI has negative value at this tier: the\nfailure mode of generative transcription (plausible-but-wrong\nliterals) is exactly what the lock tests exist to make impossible.",{"type":11,"tag":23,"props":259,"children":260},{},[261,266],{"type":11,"tag":67,"props":262,"children":263},{},[264],{"type":17,"value":265},"Adding a target",{"type":17,"value":267}," (Compose-for-Android, iOS asset catalog, Figma\nvariables push, …) = one emitter function + one lock test + a README\nconsumption note. An ordinary minor release.",{"type":11,"tag":57,"props":269,"children":271},{"id":270},"tier-2-component-ports-the-bff-superpod-panel-tier",[272],{"type":17,"value":273},"Tier 2 — component ports (the BFF \u002F superPOD panel tier)",{"type":11,"tag":23,"props":275,"children":276},{},[277,281,283,289,291,296],{"type":11,"tag":67,"props":278,"children":279},{},[280],{"type":17,"value":71},{"type":17,"value":282}," actual component implementations on other frameworks — a\nReact ",{"type":11,"tag":40,"props":284,"children":286},{"className":285},[],[287],{"type":17,"value":288},"TuxCard",{"type":17,"value":290},", a WPF chart family. These are ",{"type":11,"tag":29,"props":292,"children":293},{},[294],{"type":17,"value":295},"translations of\nbehavior",{"type":17,"value":297},", not derivations of data: slots, a11y contracts, keyboard\nmodels, container queries. No deterministic emitter can produce them.",{"type":11,"tag":23,"props":299,"children":300},{},[301],{"type":11,"tag":67,"props":302,"children":303},{},[304],{"type":17,"value":305},"How it works (ratified 2026-08-19, first piece SHIPPED — owner\ndecision: build on existing access only, no new BFF endpoints or\ntokens minted):",{"type":11,"tag":23,"props":307,"children":308},{},[309,311,316,317,323,325,330,332,337],{"type":17,"value":310},"The estate already has the judgment infrastructure: this repo's CI\ncalls the ",{"type":11,"tag":67,"props":312,"children":313},{},[314],{"type":17,"value":315},"TTI AI BFF",{"type":17,"value":121},{"type":11,"tag":40,"props":318,"children":320},{"className":319},[],[321],{"type":17,"value":322},"\u002Fv1\u002Freview",{"type":17,"value":324},") on every PR — a multi-model\nsuperPOD panel with per-actor attribution. So the pipeline doesn't\nneed generation ",{"type":11,"tag":29,"props":326,"children":327},{},[328],{"type":17,"value":329},"access",{"type":17,"value":331},"; it needs drift ",{"type":11,"tag":29,"props":333,"children":334},{},[335],{"type":17,"value":336},"detection",{"type":17,"value":338}," and a PR for\nthe panel to judge. That's cheap and deterministic:",{"type":11,"tag":340,"props":341,"children":342},"ol",{},[343,410,427,437,447],{"type":11,"tag":344,"props":345,"children":346},"li",{},[347,368,370,376,378,384,386,392,394,400,402,408],{"type":11,"tag":67,"props":348,"children":349},{},[350,352,358,360,366],{"type":17,"value":351},"Detect (SHIPPED — ",{"type":11,"tag":40,"props":353,"children":355},{"className":354},[],[356],{"type":17,"value":357},"ports-sync.yml",{"type":17,"value":359}," + ",{"type":11,"tag":40,"props":361,"children":363},{"className":362},[],[364],{"type":17,"value":365},"scripts\u002Fports-manifest.mjs",{"type":17,"value":367},"):",{"type":17,"value":369},"\nevery merge to main touching ",{"type":11,"tag":40,"props":371,"children":373},{"className":372},[],[374],{"type":17,"value":375},"app\u002Fcomponents\u002FTux*.vue",{"type":17,"value":377}," updates the\nport ledger (",{"type":11,"tag":40,"props":379,"children":381},{"className":380},[],[382],{"type":17,"value":383},"kit\u002Fports\u002Fmanifest.json",{"type":17,"value":385},": source hash per component,\nlast-ported hash per target) and the human-readable\n",{"type":11,"tag":40,"props":387,"children":389},{"className":388},[],[390],{"type":17,"value":391},"kit\u002Fports\u002FQUEUE.md",{"type":17,"value":393},", on a bot branch (",{"type":11,"tag":40,"props":395,"children":397},{"className":396},[],[398],{"type":17,"value":399},"bots\u002Fports-sync",{"type":17,"value":401},"), as a PR.\nAuth reuses the job token (git push) and the existing ai-review\nbot PAT (PR creation). ",{"type":11,"tag":40,"props":403,"children":405},{"className":404},[],[406],{"type":17,"value":407},"--check",{"type":17,"value":409}," mode runs in the test suite so a\ncomponent can't land without the ledger following it.",{"type":11,"tag":344,"props":411,"children":412},{},[413,418,420,425],{"type":11,"tag":67,"props":414,"children":415},{},[416],{"type":17,"value":417},"Judge with the bots we already have:",{"type":17,"value":419}," the bot PR flows through\nthe SAME gates as any human PR — baseline-security, the full test\nsuite, and the ai-review superPOD panel. When port code appears in\nthese PRs, the panel debates ",{"type":11,"tag":29,"props":421,"children":422},{},[423],{"type":17,"value":424},"that code",{"type":17,"value":426}," with zero pipeline\nchanges.",{"type":11,"tag":344,"props":428,"children":429},{},[430,435],{"type":11,"tag":67,"props":431,"children":432},{},[433],{"type":17,"value":434},"Generate — the slot the ledger feeds, in maturity order:",{"type":17,"value":436},"\n(a) hand\u002Fsession-authored ports working down QUEUE.md;\n(b) a mechanical Vue→target scaffolder for the template+CSS-heavy\ncomponents (most of the catalog), output landing in the same bot\nPR; (c) agent-authored ports if\u002Fwhen a generation endpoint ever\nearns its keep. Each stage rides the identical PR shape, so\nupgrading the generator never changes the pipeline contract.",{"type":11,"tag":344,"props":438,"children":439},{},[440,445],{"type":11,"tag":67,"props":441,"children":442},{},[443],{"type":17,"value":444},"Verify mechanically, not rhetorically:",{"type":17,"value":446}," ports must pass a\nbehavior-lock harness — prop\u002Femit vocabulary conformance against\nthe components.md table, rendered-output snapshots, axe. Panels\nargue; tests decide.",{"type":11,"tag":344,"props":448,"children":449},{},[450,455,457,462],{"type":11,"tag":67,"props":451,"children":452},{},[453],{"type":17,"value":454},"Deliver as a PR, never a direct publish; publish rides the tag\ntrain.",{"type":17,"value":456}," Auto-merge on all-green is a ",{"type":11,"tag":29,"props":458,"children":459},{},[460],{"type":17,"value":461},"policy dial",{"type":17,"value":463}," the owner can\nturn later — start with human merge, earn the automation.",{"type":11,"tag":23,"props":465,"children":466},{},[467,472,474,479,481,486,488,493],{"type":11,"tag":67,"props":468,"children":469},{},[470],{"type":17,"value":471},"Why the PR gate is load-bearing:",{"type":17,"value":473}," the deterministic tier can ship\nunreviewed because it cannot be wrong in new ways. Generated\ncomponent code can be — and a port that subtly breaks a keyboard\ncontract damages the system's core promise (accessible by default).\nThe gate is what makes \"automatically review and publish\" honest:\nautomatic ",{"type":11,"tag":29,"props":475,"children":476},{},[477],{"type":17,"value":478},"generation",{"type":17,"value":480},", automatic ",{"type":11,"tag":29,"props":482,"children":483},{},[484],{"type":17,"value":485},"verification",{"type":17,"value":487},", automatic\n",{"type":11,"tag":29,"props":489,"children":490},{},[491],{"type":17,"value":492},"delivery to a merge decision",{"type":17,"value":494}," — with the merge itself starting\nhuman and becoming automatic only when the harness has earned trust.",{"type":11,"tag":23,"props":496,"children":497},{},[498,503,505,510,511,517,519,525,527,533,535,541],{"type":11,"tag":67,"props":499,"children":500},{},[501],{"type":17,"value":502},"Where ports live (owner-ratified 2026-08-20): in THIS repo — a\nmulti-language monorepo.",{"type":17,"value":504}," npm workspaces; the root stays the Nuxt\nlayer (",{"type":11,"tag":40,"props":506,"children":508},{"className":507},[],[509],{"type":17,"value":53},{"type":17,"value":129},{"type":11,"tag":40,"props":512,"children":514},{"className":513},[],[515],{"type":17,"value":516},"packages\u002Freact\u002F",{"type":17,"value":518}," is ",{"type":11,"tag":40,"props":520,"children":522},{"className":521},[],[523],{"type":17,"value":524},"@tti\u002Ftti-ux-react",{"type":17,"value":526},"\n(version-locked to the root, published by the same tag train), and a\nfuture ",{"type":11,"tag":40,"props":528,"children":530},{"className":529},[],[531],{"type":17,"value":532},"packages\u002Fdotnet\u002F",{"type":17,"value":534}," follows the same shape. First port shipped\nas proof: ",{"type":11,"tag":40,"props":536,"children":538},{"className":537},[],[539],{"type":17,"value":540},"TuxBigStat",{"type":17,"value":542}," — same props, same BEM classes, byte-equivalent\nCSS, port-fidelity tests, ledger entry recording the source hash it\nwas generated against.",{"type":11,"tag":23,"props":544,"children":545},{},[546,551,553,558,560,566,568,574,576,581],{"type":11,"tag":67,"props":547,"children":548},{},[549],{"type":17,"value":550},"The port-writer bot (owner-ratified direction, account pending):",{"type":17,"value":552},"\ngeneration gets its own ",{"type":11,"tag":67,"props":554,"children":555},{},[556],{"type":17,"value":557},"service account",{"type":17,"value":559}," — working name\n",{"type":11,"tag":40,"props":561,"children":563},{"className":562},[],[564],{"type":17,"value":565},"tux-port-bot",{"type":17,"value":567}," — that leverages the superPOD models through the BFF\nexactly the way the existing bots do (dedicated PAT, ",{"type":11,"tag":40,"props":569,"children":571},{"className":570},[],[572],{"type":17,"value":573},"X-TTI-Actor",{"type":17,"value":575},"\nattribution). Scopes: repo content write (push to ",{"type":11,"tag":40,"props":577,"children":579},{"className":578},[],[580],{"type":17,"value":399},{"type":17,"value":582},")",{"type":11,"tag":584,"props":585,"children":586},"ul",{},[587],{"type":11,"tag":344,"props":588,"children":589},{},[590,592,598],{"type":17,"value":591},"PR create; BFF access for generation calls. It writes port drafts\ninto the same bot-PR shape the drift bot already opens, where the\nai-review panel and the port-fidelity harness judge them. Creating\nthe account and its PAT is an owner\u002Fadmin action; the workflow reads\nit as a ",{"type":11,"tag":40,"props":593,"children":595},{"className":594},[],[596],{"type":17,"value":597},"PORT_BOT_TOKEN",{"type":17,"value":599}," secret and degrades to detection-only when\nabsent.",{"type":11,"tag":23,"props":601,"children":602},{},[603,608,610,615],{"type":11,"tag":67,"props":604,"children":605},{},[606],{"type":17,"value":607},"Platform direction (recorded for the forgejo-stack workstream):",{"type":17,"value":609},"\nonce the port-writer proves out here, TTI Code should expose bots as\na per-repo capability — site\u002Frepo owners see the available bots\n(review panel, port writer, …) and can toggle them, with the\n",{"type":11,"tag":67,"props":611,"children":612},{},[613],{"type":17,"value":614},"security review permanently non-optional",{"type":17,"value":616},". This repo is the pilot.",{"type":11,"tag":23,"props":618,"children":619},{},[620],{"type":11,"tag":67,"props":621,"children":622},{},[623],{"type":17,"value":624},"Remaining prerequisites before generated ports land:",{"type":11,"tag":584,"props":626,"children":627},{},[628,647],{"type":11,"tag":344,"props":629,"children":630},{},[631,633,638,640,645],{"type":17,"value":632},"The ",{"type":11,"tag":40,"props":634,"children":636},{"className":635},[],[637],{"type":17,"value":565},{"type":17,"value":639}," service account + ",{"type":11,"tag":40,"props":641,"children":643},{"className":642},[],[644],{"type":17,"value":597},{"type":17,"value":646}," secret\n(owner\u002Fadmin).",{"type":11,"tag":344,"props":648,"children":649},{},[650,651,657],{"type":17,"value":632},{"type":11,"tag":40,"props":652,"children":654},{"className":653},[],[655],{"type":17,"value":656},"PACKAGE_TOKEN",{"type":17,"value":658}," secret (already required for the tag train).",{"type":11,"tag":57,"props":660,"children":662},{"id":661},"the-rule-of-thumb",[663],{"type":17,"value":664},"The rule of thumb",{"type":11,"tag":19,"props":666,"children":667},{},[668],{"type":11,"tag":23,"props":669,"children":670},{},[671,673,678],{"type":17,"value":672},"If a target can be a function of ",{"type":11,"tag":40,"props":674,"children":676},{"className":675},[],[677],{"type":17,"value":247},{"type":17,"value":679},", it is tier 1 and\nships this week. If it needs judgment, it is tier 2, the judgment\ngets a panel, the panel gets a harness, and the harness gets a PR.",{"title":6,"searchDepth":681,"depth":681,"links":682},2,[683,684,685],{"id":59,"depth":681,"text":62},{"id":270,"depth":681,"text":273},{"id":661,"depth":681,"text":664},1788285285831]