[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7A48CAQ7FVC78ERPHSAPMPX":3,"skill-same:01M7A48CAQ7FVC78ERPHSAPMPX":44},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":26,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":29,"install":30,"resources":43},"01M7A48CAQ7FVC78ERPHSAPMPX","sandcastle-run",null,"Traduire une consigne d'opérateur — « traite le ticket","softnextapp\u002Fsoftware-factory","softnextapp","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F281865661?v=4","01M7A46XND13PBZATN9YV5VP94","01M7A46XP2R65ZN8WS9B5GQRJ8",1,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory\u002Fblob\u002Fmain\u002Fskills\u002Fsandcastle-run\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: sandcastle-run\ndescription: Traduire une consigne d'opérateur — « traite le ticket #42 en AFK avec Sandcastle en mode split en partant de main » — en gestes corrects sur une instance Software Factory : distinguer l'identité (config.ts, à faire confirmer) de l'invocation (variables SANDCASTLE_*), vérifier les préalables, passer par un dry-run, puis lancer en tâche de fond. À charger dès qu'on demande de lancer, relancer, restreindre ou reconfigurer une boucle Sandcastle \u002F Factory.\n---\n\n# Lancer une boucle Software Factory\n\nCette skill ne récite pas les réglages. Elle tient **une seule frontière** : ce qui\nrelève de l'**identité du projet** (`.sandcastle\u002Fconfig.ts`, réglé une fois, tracé\ndans git) et ce qui relève de l'**invocation** (variables d'environnement du run).\nConfondre les deux est l'erreur coûteuse : éditer `baseBranch` alors qu'il n'y avait\nrien à faire, ou coder en dur un numéro de ticket dans l'identité du dépôt.\n\n## La table de frontière\n\n| Ce que dit l'humain | Où ça vit | Geste |\n|---|---|---|\n| « le ticket #42 » | `SANDCASTLE_ONLY=42` **+ label de file** | env + `gh issue edit 42 --add-label \u003Clabel>` (ou `glab issue update 42 --label \u003Clabel>`) |\n| « mode split » \u002F « opus » | `SANDCASTLE_PROFILE` | env (défaut `split`) |\n| « chaîné », « empile les MR » | `SANDCASTLE_CHAIN=1` | env (exige un `chainableBases` non vide dans l'identité) |\n| « refais-le », « relance-le » | `SANDCASTLE_FORCE=1` | env — **exige** `SANDCASTLE_ONLY` |\n| « juste un tour », « n tours » | `SANDCASTLE_MAX_ITERATIONS` | env |\n| « n tickets à la fois » | `SANDCASTLE_MAX_PARALLEL` | env (forcé à 1 en chaîné) |\n| « montre-moi d'abord », « à blanc » | `SANDCASTLE_DRYRUN=1` | env |\n| « en partant de main », « depuis l'epic » | `baseBranch` \u002F `labelBases` | `config.ts`, **avec confirmation** |\n| `gitHost`, `queueLabels`, `assignee`, `mergeStrategy`, `commitStyle`, `hooks`, `report`… | `config.ts` | identité — **avec confirmation** |\n\nCes sept variables sont l'intégralité de la surface d'invocation : elle est lue en un\nseul endroit, `loadRunConfig` dans `.sandcastle\u002Fconfig.ts`. Tout le reste est identité.\n\n**N'énumère pas les valeurs et les défauts de mémoire.** La seule source qui ne mente\njamais est `.sandcastle\u002Fconfig.ts` et ses commentaires de doc ; lis-le avant de\nrépondre sur un champ précis.\n\n## Le piège n° 1 : `SANDCASTLE_ONLY` restreint, il n'élargit pas\n\nLa file du tour est construite côté hôte depuis `queueLabels` (`host.queueIssues`).\n`SANDCASTLE_ONLY` **filtre** cette file (`applyOnly`, `plan.ts`) — il ne va pas\nchercher un ticket qui n'y est pas.\n\nConséquence : `SANDCASTLE_ONLY=42` sur un ticket **sans label de file** donne un\n**tour vide, sans aucune erreur**. C'est le mode d'échec le plus cher en AFK : on part,\non revient, rien ne s'est passé et rien ne l'a dit.\n\nDonc : « traite le ticket #42 » = poser le label de file **et** restreindre. Les deux.\n\n## Procédure\n\n### 1. Préalables — en lecture seule, sauf le label\n\nVérifie, nomme ce qui manque avec le geste correspondant, et **ne corrige rien** :\n\n- **Label de file** — `gh issue view \u003Cn> --json labels` croisé avec `queueLabels` de\n  `config.ts`. **Seule exception à la règle : pose-le.** C'est le sens littéral de\n  « traite ce ticket », et un `--remove-label` l'annule. Quand `queueLabels` en liste\n  plusieurs, prends celui que portent déjà les autres tickets de la file plutôt que le\n  premier de la liste : le dépôt en utilise un en pratique, les autres sont de la\n  compatibilité.\n- **Token de fournisseur** — le `tokenKey` de chaque provider du profil actif, dans\n  l'environnement ou dans `.sandcastle\u002F.env.secrets`. **Ne lis jamais la valeur, ne\n  l'affiche jamais** : constate la présence de la clé. Le dry-run le dit mieux que toi\n  (`requiredTokens`, source `env` \u002F `.env.secrets` \u002F `MISSING`).\n- **Hôte authentifié et d'accord avec `origin`** — `gh auth status` (ou `glab auth\n  status`), et `git remote get-url origin` cohérent avec `gitHost`. Le dry-run reporte\n  ce désaccord (`hostMismatch`).\n- **Base à jour** — la base locale ne doit pas être en retard sur le remote :\n  `git fetch origin && git status -sb`. Un run réel la fast-forwarde lui-même ; le\n  dry-run se contente d'avertir. Le geste, si tu dois le nommer :\n  `git fetch origin && git switch \u003Cbase> && git pull`.\n\nCe qui ne s'automatise pas depuis une skill : authentifier un hôte, écrire un secret.\nDemande le geste à l'humain.\n\n### 2. Dry-run — systématique, avant tout lancement réel\n\n```sh\nSANDCASTLE_DRYRUN=1 SANDCASTLE_ONLY=42 npx tsx .sandcastle\u002Fmain.ts\n```\n\nMets les **mêmes** variables que le run réel : c'est la seule façon de voir le profil,\nles tokens, les bases, l'état du chaînage et la file tels qu'ils seront. Montre le\nverdict à l'opérateur. Il lance rien et sort 0 même avec des tokens manquants.\n\nC'est le sens d'« AFK » : ce qui coûte cher n'est pas la minute du dry-run, c'est de\npartir et de découvrir au retour que le tour était vide ou le profil faux.\n\n### 3. Lancement — en tâche de fond, sans redemander\n\nLe dry-run a servi de confirmation. Lance, puis donne le chemin du log et la façon de\nsuivre :\n\n```sh\nmkdir -p .sandcastle\u002Flogs\nSANDCASTLE_ONLY=42 npx tsx .sandcastle\u002Fmain.ts > .sandcastle\u002Flogs\u002Frun-42.log 2>&1 &\ntail -f .sandcastle\u002Flogs\u002Frun-42.log\n```\n\n### 4. Lire la fin du run — le bloc `=== Run summary ===`\n\nUn run ne se termine plus par « All done » : il imprime des compteurs (itérations\nmenées, MR publiées, tickets abandonnés) et **la cause nommée de chaque abandon**\n(`implementer-failed`, `no-commits`, `push-failed`, `mr-not-opened`,\n`host-unavailable`, ou `unknown` quand le run ne sait pas). Le mode chaîné y est\ndonné tel qu'il a été **appliqué**, pas tel qu'il a été demandé.\n\nLe code de sortie porte le même verdict — c'est lui qu'on lit dans un script :\n\n| Code | Verdict | Ce que ça veut dire |\n| --- | --- | --- |\n| `0` | `published` | Au moins une MR est ouverte grâce à ce run. |\n| `1` | `sterile` | Le run avait du travail et rien n'en est sorti. Un `SANDCASTLE_ONLY` qui ne matche rien compte comme du travail : l'opérateur a nommé des tickets et n'en a eu aucun. |\n| `1` | `all-iterations-lost` | **Toutes** les itérations ont été perdues sur l'hôte. Le code reste `1` même si la reprise du ledger a ouvert la MR d'un run précédent. |\n| `1` | `published, then died` | Le run a publié, puis une panne définitive l'a arrêté. |\n| `2` | `idle` | Il n'y avait rien à faire : la file était vide. Ni échec, ni succès. |\n\nNe conclus jamais « le run a réussi » sur la seule absence d'erreur dans le log :\nlis le verdict. Un `1` sur `implementer-failed`, `host-unavailable` ou\n`all-iterations-lost` se relance tel quel ; un `1` sur `mr-not-opened` **ne se\nrelance pas** — la branche est poussée et le run suivant ouvrira la MR manquante\ntout seul (relancer dupliquerait le ticket). Un `2` avec `SANDCASTLE_ONLY` est\nimpossible : si ton ticket n'a pas été pioché, tu auras un `1` sur\n`only-no-match`, et la cause est presque toujours le label de file manquant.\n\n### 5. Toute édition de `config.ts` se fait confirmer\n\nPropose le diff, attends l'accord. L'identité est tracée dans le dépôt du consommateur\net une erreur y contamine **tous** les runs suivants — pas seulement celui-ci. « En\npartant de main » n'est presque jamais une édition : `baseBranch` vaut déjà `main` dans\nla plupart des instances. Lis avant de proposer.\n\n## Ce que cette skill ne fait pas\n\n- Elle ne remplit pas le `CLAUDE.md` ni le `CONTEXT.md` du projet — ça reste chez le\n  consommateur.\n- Elle n'authentifie pas l'hôte et n'écrit pas de secret.\n- Elle ne récite pas `ProjectConfig` : elle renvoie à `.sandcastle\u002Fconfig.ts`.\n","# Lancer une boucle Software Factory\n\nCette skill ne récite pas les réglages. Elle tient **une seule frontière** : ce qui\nrelève de l'**identité du projet** (`.sandcastle\u002Fconfig.ts`, réglé une fois, tracé\ndans git) et ce qui relève de l'**invocation** (variables d'environnement du run).\nConfondre les deux est l'erreur coûteuse : éditer `baseBranch` alors qu'il n'y avait\nrien à faire, ou coder en dur un numéro de ticket dans l'identité du dépôt.\n\n## La table de frontière\n\n| Ce que dit l'humain | Où ça vit | Geste |\n|---|---|---|\n| « le ticket #42 » | `SANDCASTLE_ONLY=42` **+ label de file** | env + `gh issue edit 42 --add-label \u003Clabel>` (ou `glab issue update 42 --label \u003Clabel>`) |\n| « mode split » \u002F « opus » | `SANDCASTLE_PROFILE` | env (défaut `split`) |\n| « chaîné », « empile les MR » | `SANDCASTLE_CHAIN=1` | env (exige un `chainableBases` non vide dans l'identité) |\n| « refais-le », « relance-le » | `SANDCASTLE_FORCE=1` | env — **exige** `SANDCASTLE_ONLY` |\n| « juste un tour », « n tours » | `SANDCASTLE_MAX_ITERATIONS` | env |\n| « n tickets à la fois » | `SANDCASTLE_MAX_PARALLEL` | env (forcé à 1 en chaîné) |\n| « montre-moi d'abord », « à blanc » | `SANDCASTLE_DRYRUN=1` | env |\n| « en partant de main », « depuis l'epic » | `baseBranch` \u002F `labelBases` | `config.ts`, **avec confirmation** |\n| `gitHost`, `queueLabels`, `assignee`, `mergeStrategy`, `commitStyle`, `hooks`, `report`… | `config.ts` | identité — **avec confirmation** |\n\nCes sept variables sont l'intégralité de la surface d'invocation : elle est lue en un\nseul endroit, `loadRunConfig` dans `.sandcastle\u002Fconfig.ts`. Tout le reste est identité.\n\n**N'énumère pas les valeurs et les défauts de mémoire.** La seule source qui ne mente\njamais est `.sandcastle\u002Fconfig.ts` et ses commentaires de doc ; lis-le avant de\nrépondre sur un champ précis.\n\n## Le piège n° 1 : `SANDCASTLE_ONLY` restreint, il n'élargit pas\n\nLa file du tour est construite côté hôte depuis `queueLabels` (`host.queueIssues`).\n`SANDCASTLE_ONLY` **filtre** cette file (`applyOnly`, `plan.ts`) — il ne va pas\nchercher un ticket qui n'y est pas.\n\nConséquence : `SANDCASTLE_ONLY=42` sur un ticket **sans label de file** donne un\n**tour vide, sans aucune erreur**. C'est le mode d'échec le plus cher en AFK : on part,\non revient, rien ne s'est passé et rien ne l'a dit.\n\nDonc : « traite le ticket #42 » = poser le label de file **et** restreindre. Les deux.\n\n## Procédure\n\n### 1. Préalables — en lecture seule, sauf le label\n\nVérifie, nomme ce qui manque avec le geste correspondant, et **ne corrige rien** :\n\n- **Label de file** — `gh issue view \u003Cn> --json labels` croisé avec `queueLabels` de\n  `config.ts`. **Seule exception à la règle : pose-le.** C'est le sens littéral de\n  « traite ce ticket », et un `--remove-label` l'annule. Quand `queueLabels` en liste\n  plusieurs, prends celui que portent déjà les autres tickets de la file plutôt que le\n  premier de la liste : le dépôt en utilise un en pratique, les autres sont de la\n  compatibilité.\n- **Token de fournisseur** — le `tokenKey` de chaque provider du profil actif, dans\n  l'environnement ou dans `.sandcastle\u002F.env.secrets`. **Ne lis jamais la valeur, ne\n  l'affiche jamais** : constate la présence de la clé. Le dry-run le dit mieux que toi\n  (`requiredTokens`, source `env` \u002F `.env.secrets` \u002F `MISSING`).\n- **Hôte authentifié et d'accord avec `origin`** — `gh auth status` (ou `glab auth\n  status`), et `git remote get-url origin` cohérent avec `gitHost`. Le dry-run reporte\n  ce désaccord (`hostMismatch`).\n- **Base à jour** — la base locale ne doit pas être en retard sur le remote :\n  `git fetch origin && git status -sb`. Un run réel la fast-forwarde lui-même ; le\n  dry-run se contente d'avertir. Le geste, si tu dois le nommer :\n  `git fetch origin && git switch \u003Cbase> && git pull`.\n\nCe qui ne s'automatise pas depuis une skill : authentifier un hôte, écrire un secret.\nDemande le geste à l'humain.\n\n### 2. Dry-run — systématique, avant tout lancement réel\n\n```sh\nSANDCASTLE_DRYRUN=1 SANDCASTLE_ONLY=42 npx tsx .sandcastle\u002Fmain.ts\n```\n\nMets les **mêmes** variables que le run réel : c'est la seule façon de voir le profil,\nles tokens, les bases, l'état du chaînage et la file tels qu'ils seront. Montre le\nverdict à l'opérateur. Il lance rien et sort 0 même avec des tokens manquants.\n\nC'est le sens d'« AFK » : ce qui coûte cher n'est pas la minute du dry-run, c'est de\npartir et de découvrir au retour que le tour était vide ou le profil faux.\n\n### 3. Lancement — en tâche de fond, sans redemander\n\nLe dry-run a servi de confirmation. Lance, puis donne le chemin du log et la façon de\nsuivre :\n\n```sh\nmkdir -p .sandcastle\u002Flogs\nSANDCASTLE_ONLY=42 npx tsx .sandcastle\u002Fmain.ts > .sandcastle\u002Flogs\u002Frun-42.log 2>&1 &\ntail -f .sandcastle\u002Flogs\u002Frun-42.log\n```\n\n### 4. Lire la fin du run — le bloc `=== Run summary ===`\n\nUn run ne se termine plus par « All done » : il imprime des compteurs (itérations\nmenées, MR publiées, tickets abandonnés) et **la cause nommée de chaque abandon**\n(`implementer-failed`, `no-commits`, `push-failed`, `mr-not-opened`,\n`host-unavailable`, ou `unknown` quand le run ne sait pas). Le mode chaîné y est\ndonné tel qu'il a été **appliqué**, pas tel qu'il a été demandé.\n\nLe code de sortie porte le même verdict — c'est lui qu'on lit dans un script :\n\n| Code | Verdict | Ce que ça veut dire |\n| --- | --- | --- |\n| `0` | `published` | Au moins une MR est ouverte grâce à ce run. |\n| `1` | `sterile` | Le run avait du travail et rien n'en est sorti. Un `SANDCASTLE_ONLY` qui ne matche rien compte comme du travail : l'opérateur a nommé des tickets et n'en a eu aucun. |\n| `1` | `all-iterations-lost` | **Toutes** les itérations ont été perdues sur l'hôte. Le code reste `1` même si la reprise du ledger a ouvert la MR d'un run précédent. |\n| `1` | `published, then died` | Le run a publié, puis une panne définitive l'a arrêté. |\n| `2` | `idle` | Il n'y avait rien à faire : la file était vide. Ni échec, ni succès. |\n\nNe conclus jamais « le run a réussi » sur la seule absence d'erreur dans le log :\nlis le verdict. Un `1` sur `implementer-failed`, `host-unavailable` ou\n`all-iterations-lost` se relance tel quel ; un `1` sur `mr-not-opened` **ne se\nrelance pas** — la branche est poussée et le run suivant ouvrira la MR manquante\ntout seul (relancer dupliquerait le ticket). Un `2` avec `SANDCASTLE_ONLY` est\nimpossible : si ton ticket n'a pas été pioché, tu auras un `1` sur\n`only-no-match`, et la cause est presque toujours le label de file manquant.\n\n### 5. Toute édition de `config.ts` se fait confirmer\n\nPropose le diff, attends l'accord. L'identité est tracée dans le dépôt du consommateur\net une erreur y contamine **tous** les runs suivants — pas seulement celui-ci. « En\npartant de main » n'est presque jamais une édition : `baseBranch` vaut déjà `main` dans\nla plupart des instances. Lis avant de proposer.\n\n## Ce que cette skill ne fait pas\n\n- Elle ne remplit pas le `CLAUDE.md` ni le `CONTEXT.md` du projet — ça reste chez le\n  consommateur.\n- Elle n'authentifie pas l'hôte et n'écrit pas de secret.\n- Elle ne récite pas `ProjectConfig` : elle renvoie à `.sandcastle\u002Fconfig.ts`.\n",{"name":5,"description":7},"main","51032bdc0574d21161f65cfb720e549cc58065c9","skills\u002Fsandcastle-run",0,"https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory","https:\u002F\u002Fgithub.com\u002Fsoftnextapp","2026-09-28 17:11:48",{"source":8,"skillName":5,"commands":31,"prompt":41,"zipAvailable":42},[32,35,38],{"tool":33,"command":34},"npx","npx skills add softnextapp\u002Fsoftware-factory --skill sandcastle-run",{"tool":36,"command":37},"bunx","bunx skills add softnextapp\u002Fsoftware-factory --skill sandcastle-run",{"tool":39,"command":40},"pnpm","pnpm dlx skills add softnextapp\u002Fsoftware-factory --skill sandcastle-run","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory\u002Fblob\u002Fmain\u002Fskills\u002Fsandcastle-run\u002FSKILL.md",true,[],[45,52,59,66,73,80],{"skillNo":46,"name":47,"nameZh":6,"description":48,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":49,"categories":50,"keywords":51,"publishedAt":18},"01M7A48AJN5895WNZ629A5BF5K","teach","Teach the user a new skill or concept, within this workspace.","https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fproductivity\u002Fteach\u002FSKILL.md",[],[],{"skillNo":53,"name":54,"nameZh":6,"description":55,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":56,"categories":57,"keywords":58,"publishedAt":18},"01M7A489020KZ03FRHZFXY7N6K","handoff","Compact the current conversation into a handoff document for another agent to pick up.","https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fproductivity\u002Fhandoff\u002FSKILL.md",[],[],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":65,"publishedAt":18},"01M7A487ACWMA4RYZHJAKH19KC","grilling","Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.","https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fproductivity\u002Fgrilling\u002FSKILL.md",[],[],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":70,"categories":71,"keywords":72,"publishedAt":18},"01M7A48661DXMC4M9XV4EEB53Z","grill-me","A relentless interview to sharpen a plan or design.","https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fproductivity\u002Fgrill-me\u002FSKILL.md",[],[],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":79,"publishedAt":18},"01M7A483HNCQMXWJR9QBR84XYY","wayfinder","Plan a huge chunk of work — more than one agent session can hold — as a shared map of decision tickets on your issue tracker, and resolve them one at a time until the way to the destination is clear.","https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fengineering\u002Fwayfinder\u002FSKILL.md",[],[],{"skillNo":81,"name":82,"nameZh":6,"description":83,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":18},"01M7A4810NMGMG455X0ZCE8HZD","triage","Move issues and external PRs through a state machine of triage roles — categorise, verify, grill if needed, and write agent-ready briefs.","https:\u002F\u002Fgithub.com\u002Fsoftnextapp\u002Fsoftware-factory\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fengineering\u002Ftriage\u002FSKILL.md",[],[]]