[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71S54Y4B0C53HA6CEZPZD1Z":3,"skill-same:01M71S54Y4B0C53HA6CEZPZD1Z":80},{"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":31,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":6,"ownerHtmlUrl":65,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":66,"install":67,"resources":79},"01M71S54Y4B0C53HA6CEZPZD1Z","compose-persona",null,"Design-time meta-skill (v1). Given a persona brief (YAML) or a free-text\nidea, produce a complete Persona artefact set: a SKILL.md\n(frontmatter + executable decision_policy + prose body), a\nPython registry entry pasteable into `api\u002Fshared\u002Fpersonas.py`, and a\ngraduate.sh script that mechanically wires the persona into the live\ntrees.\n\nSandbox-only; never touches real trees directly. Calls `author-persona`\nas its sole sub-skill.\n\nSister to `compose-domain`. Where `compose-domain` graduates a whole\nDurable workflow + skills + personae for one new business process,\n`compose-persona` graduates ONE persona — useful when an existing\ndomain needs an additional approver \u002F reviewer, or when a new\nfunction (finance, legal, IT) needs its cast filling out before its\ndomain lands.","arturcrmbot\u002Fzava-control-plane","arturcrmbot","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F156445312?v=4","01M71R9QBEJ4ZSX5AXBGBYH82C","Artur Zielinski","01M71R9QCJSV19ESCAF5773TWH",1,"MIT","https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane\u002Fblob\u002Fmain\u002Fdocs\u002Fsuperpowers\u002Fskills\u002Fcompose-persona\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"compose persona","persona","compose","only","needs","new","when","free","shared","time","meta-skill","design","never","reviewer","decision","api","SET","Meta","brief","workflow","2026-11-10 13:02:02",false,"---\nname: compose-persona\ndescription: |\n  Design-time meta-skill (v1). Given a persona brief (YAML) or a free-text\n  idea, produce a complete Persona artefact set: a SKILL.md\n  (frontmatter + executable decision_policy + prose body), a\n  Python registry entry pasteable into `api\u002Fshared\u002Fpersonas.py`, and a\n  graduate.sh script that mechanically wires the persona into the live\n  trees.\n\n  Sandbox-only; never touches real trees directly. Calls `author-persona`\n  as its sole sub-skill.\n\n  Sister to `compose-domain`. Where `compose-domain` graduates a whole\n  Durable workflow + skills + personae for one new business process,\n  `compose-persona` graduates ONE persona — useful when an existing\n  domain needs an additional approver \u002F reviewer, or when a new\n  function (finance, legal, IT) needs its cast filling out before its\n  domain lands.\naudience: design-time-only\nforbidden-runtime: true\n---\n\n# compose-persona (v1)\n\nYou are the orchestrator for a five-step procedure that turns a persona\nbrief into a complete sandboxed persona artefact set. You do not\nimprovise. You follow this skill literally. When you are uncertain,\nyou stop and ask the operator — you do not invent.\n\n> **Forbidden.** This skill, and any sub-skill it invokes, **MUST NOT**\n> write to any path outside `tools\u002Fscratch\u002Fcompose-persona\u002F\u003Crun-id>\u002F`\n> and `docs\u002Fsuperpowers\u002Fspecs\u002F`. In particular: never edit\n> `api\u002Fserver\u002Fpersonae\u002F`, `api\u002Fshared\u002Fpersonas.py`,\n> `api\u002Fserver\u002Fservices\u002Fpersona_responder.py`, or any other live tree.\n> Graduation is a separate, manual step (the operator runs the\n> generated `graduate.sh`).\n\n## Inputs\n\nYou are invoked one of two ways:\n\n1. **With a brief path.** \"Run compose-persona against\n   `docs\u002Fsuperpowers\u002Fspecs\u002F\u003Crole>-persona-brief.yaml`.\" Skip step 1.\n2. **With a free-text idea.** \"Compose a new persona for X.\" Run step 1\n   to produce the brief, then continue.\n\n## The five steps\n\n### Step 1 — Brief intake (only if no YAML brief was supplied)\n\nHand off to the existing `brainstorming` skill. It will elicit the\nbrief through one-question-at-a-time dialogue with the operator.\nCapture the operator's answers into the YAML schema below and write\nto `docs\u002Fsuperpowers\u002Fspecs\u002F\u003Crole>-persona-brief.yaml`. Read it back\nto the operator. Wait for explicit approval. Then continue to step 2.\n\nIf the operator gives you a YAML brief path on entry, skip this step.\n\n#### Brief schema (authoritative, v1)\n\n```yaml\npersona:\n  role: \u003Csnake_case role name, used as folder\u002Ffile prefix>\n  archetype: approver | subject | reviewer | delegate | notifier\n  scope_function: finance | hr | it | procurement | legal | legal_privacy | commercial | candidate\n  scope_business_unit: \u003Cstring or \"*\">    # OPTIONAL; default \"*\"\n  scope_geography: \u003Cstring or \"*\">        # OPTIONAL; default \"*\"\n  workflow_label: \u003Chuman label of the domain this persona belongs to>\n  external_event: \u003Csnake_case>            # OPTIONAL; default \u003Crole>_decision\n  default_authority_band: \u003Cfree-text>     # OPTIONAL; documentation only\n  uses_authority_mcp: true | false        # OPTIONAL; default false\n  description: \u003Cone sentence>\n  decision_policy_paragraph: |\n    One paragraph stating the rule the persona uses to decide.\n  decision_inputs:                        # OPTIONAL; documentation\n    - \u003Ccontext_key_the_policy_reads>\n    - ...\n  decision_authority_action: \u003Caction>     # REQUIRED iff uses_authority_mcp=true.\n                                          # Must match an `action` in\n                                          # data\u002Fsynthetic\u002Fauthority\u002Fmatrix.json.\n  decision_code: |\n    # Python source the persona_responder compiles. Reads `context`,\n    # assigns `decision` (\"approve\" | \"reject\" | \"escalate\") and\n    # `reason` (str). Mirror the decision_policy_paragraph above.\n    # The responder runs this in a sandboxed namespace with a small\n    # whitelist of safe builtins (see api\u002Fserver\u002Fservices\u002Fpersona_responder.py\n    # _DECISION_BUILTINS — currently includes `authority_check` for\n    # personae that consult the delegated-authority MCP).\n    pass\n```\n\nValidate the brief before continuing:\n\n- `role` matches `^[a-z][a-z0-9_]*$`.\n- `archetype` is one of the five allowed strings.\n- `scope_function` is one of the eight allowed strings.\n- `external_event` is `^[a-z][a-z0-9_]*$` if provided.\n- If `uses_authority_mcp: true`, `decision_authority_action` is set\n  AND the decision_code contains `authority_check(...)`.\n- The decision_code uses only the safe builtins from\n  `api\u002Fserver\u002Fservices\u002Fpersona_responder.py` `_DECISION_BUILTINS`\n  (no `import`, no `open`, no `os`, no `subprocess`, no `eval`).\n- The decision_code assigns both `decision` and `reason`.\n\nIf validation fails, stop and tell the operator what's wrong. Do not\nproceed to step 2.\n\n### Step 2 — Plan\n\nFrom the brief, produce the artefact list. **Print this list back to\nthe operator before you write a single file.** Wait for \"go\".\n\nAlways:\n\n- 1 persona SKILL.md at\n  `\u003CRUN_ROOT>\u002Fapi\u002Fserver\u002Fpersonae\u002F\u003Crole>\u002FSKILL.md`.\n- 1 `REGISTRY-ENTRY.py` at the run root containing the Python snippet\n  to splice into `api\u002Fshared\u002Fpersonas.py` `PERSONAS` dict.\n- 1 `GRADUATION.md` describing what `graduate.sh` will do.\n- 1 executable `graduate.sh` that mechanically performs the live-tree\n  edits.\n\n### Step 3 — Inventory and isomorphism\n\nBefore invoking `author-persona`, read **exactly these 3 files**\nend-to-end. They are the canonical examples this skill mirrors.\n\n| # | Canonical file                                              | Why                                                  |\n|---|-------------------------------------------------------------|------------------------------------------------------|\n| 1 | `api\u002Fserver\u002Fpersonae\u002Ffinance_bp\u002FSKILL.md`                   | Authority-MCP-using persona (template for `uses_authority_mcp: true`) |\n| 2 | `api\u002Fserver\u002Fpersonae\u002Fline_manager\u002FSKILL.md`                 | Inline-logic persona (template for `uses_authority_mcp: false`)        |\n| 3 | `api\u002Fserver\u002Fservices\u002Fpersona_responder.py` (`_DECISION_BUILTINS`) | Sandbox surface — whitelist of callables the decision_code may use |\n\nDrift in any of these means downstream output will be stale-shaped —\nstop and update this SKILL before continuing.\n\n### Step 4 — Generate into sandbox\n\nCompute `RUN_ID = \u003CYYYYMMDD-HHMMSS>-\u003Crole>` from current UTC\n(`date -u +\"%Y%m%d-%H%M%S\"`). Create\n`tools\u002Fscratch\u002Fcompose-persona\u002F\u003CRUN_ID>\u002F`.\n\n#### 4.1 — Invoke `author-persona`\n\n```\noutput_path: \u003CRUN_ROOT>\u002Fapi\u002Fserver\u002Fpersonae\u002F\u003Crole>\u002FSKILL.md\nbrief: \u003Cpersona block from the YAML brief>\ndomain_display_name: \u003Cpersona.workflow_label>\ndefault_external_event: \u003Cpersona.external_event or persona.role + \"_decision\">\ncanonical_example_path:\n  - api\u002Fserver\u002Fpersonae\u002Ffinance_bp\u002FSKILL.md   (when uses_authority_mcp: true)\n  - api\u002Fserver\u002Fpersonae\u002Fline_manager\u002FSKILL.md (when uses_authority_mcp: false)\nresponder_path: api\u002Fserver\u002Fservices\u002Fpersona_responder.py\n```\n\n`author-persona` writes the SKILL.md to the sandbox path.\n\n#### 4.2 — Write `\u003CRUN_ROOT>\u002FREGISTRY-ENTRY.py`\n\n```python\n# Splice into api\u002Fshared\u002Fpersonas.py inside the PERSONAS dict.\n# Place under the matching domain section comment block.\n\"\u003Crole>\": Persona(\n    role=\"\u003Crole>\",\n    archetype=\"\u003Carchetype>\",\n    scope_function=\"\u003Cscope_function>\",\n    workflow_label=\"\u003Cworkflow_label>\",\n    external_event_default=\"\u003Cexternal_event>\",\n    scope_business_unit=\"\u003Cscope_business_unit>\",   # default \"*\"\n    scope_geography=\"\u003Cscope_geography>\",           # default \"*\"\n    default_authority_band=\u003CNone or \"\u003Ctext>\">,\n    uses_authority_mcp=\u003CTrue | False>,\n    description=\"\u003Cdescription>\",\n),\n```\n\n#### 4.3 — Write `\u003CRUN_ROOT>\u002FGRADUATION.md`\n\nHuman-readable explanation of what `graduate.sh` does:\n\n1. Copy `\u003CRUN_ROOT>\u002Fapi\u002Fserver\u002Fpersonae\u002F\u003Crole>\u002FSKILL.md` →\n   `api\u002Fserver\u002Fpersonae\u002F\u003Crole>\u002FSKILL.md`.\n2. Splice `\u003CRUN_ROOT>\u002FREGISTRY-ENTRY.py` content into\n   `api\u002Fshared\u002Fpersonas.py` `PERSONAS` dict (between the appropriate\n   per-domain comment markers — operator's manual call where exactly).\n3. Add `\u003Crole>` to `PERSONA_AUTO_CLOSE` env var ONLY if the demo\n   profile expects this persona to auto-close gates. Default: do not\n   add (production-honest default).\n4. Run `pytest tests\u002Fapi\u002Fshared\u002Ftest_personas_registry.py` to confirm\n   the registry validates with the new entry.\n\n#### 4.4 — Write `\u003CRUN_ROOT>\u002Fgraduate.sh`\n\nExecutable script:\n\n```bash\n#!\u002Fusr\u002Fbin\u002Fenv bash\n# graduate.sh — mechanically promote the persona generated at this run root\n# into the live trees. Re-runnable; idempotent on the SKILL.md copy.\n# The registry-entry splice is intentionally manual — printed to stdout for\n# the operator to paste into the right per-domain section of personas.py.\nset -euo pipefail\n\nRUN_ROOT=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\nREPO_ROOT=\"$(cd \"$RUN_ROOT\u002F..\u002F..\u002F..\" && pwd)\"\nROLE=\"\u003Crole>\"\n\nSKILL_SRC=\"$RUN_ROOT\u002Fapi\u002Fserver\u002Fpersonae\u002F$ROLE\u002FSKILL.md\"\nSKILL_DST=\"$REPO_ROOT\u002Fapi\u002Fserver\u002Fpersonae\u002F$ROLE\u002FSKILL.md\"\n\nif [ ! -f \"$SKILL_SRC\" ]; then\n    echo \"ERROR: missing SKILL.md at $SKILL_SRC\" >&2\n    exit 1\nfi\n\nmkdir -p \"$(dirname \"$SKILL_DST\")\"\ncp \"$SKILL_SRC\" \"$SKILL_DST\"\necho \"wrote $SKILL_DST\"\n\ncat \u003C\u003CEOF\n\n  Manual splice required:\n  -----------------------\n  Open $REPO_ROOT\u002Fapi\u002Fshared\u002Fpersonas.py and paste the entry below\n  inside the PERSONAS dict, under the matching domain's comment block.\n\nEOF\n\ncat \"$RUN_ROOT\u002FREGISTRY-ENTRY.py\"\n\necho\necho \"  Then run: uv run pytest tests\u002Fapi\u002Fshared\u002Ftest_personas_registry.py\"\n```\n\n`chmod +x` the file.\n\n### Step 5 — Self-check + operator handoff\n\nBefore returning, verify:\n\n- All four files exist at `\u003CRUN_ROOT>\u002F`.\n- `SKILL.md` parses as YAML frontmatter + markdown body\n  (`yaml.safe_load(frontmatter_block)` works; body has the three\n  required `##` sections from `author-persona`).\n- `SKILL.md` `decision_policy` block compiles (`compile(source,\n  \"\u003Ctest>\", \"exec\")` doesn't raise).\n- `REGISTRY-ENTRY.py` is valid Python and uses one of the\n  documented `archetype` values.\n- `graduate.sh` is executable (`-x` bit set).\n\nReturn a one-paragraph summary to the operator naming the four\ngenerated paths and the next-step command (the manual splice + the\npytest command).\n\n## Anti-patterns\n\n- Letting the prose paragraph and the executable block disagree. The\n  prose tracks the code; if they diverge, the brief author needs to\n  resolve it before this skill runs.\n- Generating a persona that uses the authority MCP without setting\n  `uses_authority_mcp: true` in the registry entry. The registry flag\n  is the auditable signal that this persona doesn't inline thresholds.\n- Modifying the live `api\u002Fshared\u002Fpersonas.py`. Always emit the\n  `REGISTRY-ENTRY.py` snippet for the operator to splice manually.\n  Mechanical splicing risks placing the entry under the wrong\n  per-domain comment block.\n- Adding the persona to `PERSONA_AUTO_CLOSE` automatically.\n  Production-honest default: every gate stays open until explicitly\n  opted in. Demo profiles set the allow-list explicitly.\n","# compose-persona (v1)\n\nYou are the orchestrator for a five-step procedure that turns a persona\nbrief into a complete sandboxed persona artefact set. You do not\nimprovise. You follow this skill literally. When you are uncertain,\nyou stop and ask the operator — you do not invent.\n\n> **Forbidden.** This skill, and any sub-skill it invokes, **MUST NOT**\n> write to any path outside `tools\u002Fscratch\u002Fcompose-persona\u002F\u003Crun-id>\u002F`\n> and `docs\u002Fsuperpowers\u002Fspecs\u002F`. In particular: never edit\n> `api\u002Fserver\u002Fpersonae\u002F`, `api\u002Fshared\u002Fpersonas.py`,\n> `api\u002Fserver\u002Fservices\u002Fpersona_responder.py`, or any other live tree.\n> Graduation is a separate, manual step (the operator runs the\n> generated `graduate.sh`).\n\n## Inputs\n\nYou are invoked one of two ways:\n\n1. **With a brief path.** \"Run compose-persona against\n   `docs\u002Fsuperpowers\u002Fspecs\u002F\u003Crole>-persona-brief.yaml`.\" Skip step 1.\n2. **With a free-text idea.** \"Compose a new persona for X.\" Run step 1\n   to produce the brief, then continue.\n\n## The five steps\n\n### Step 1 — Brief intake (only if no YAML brief was supplied)\n\nHand off to the existing `brainstorming` skill. It will elicit the\nbrief through one-question-at-a-time dialogue with the operator.\nCapture the operator's answers into the YAML schema below and write\nto `docs\u002Fsuperpowers\u002Fspecs\u002F\u003Crole>-persona-brief.yaml`. Read it back\nto the operator. Wait for explicit approval. Then continue to step 2.\n\nIf the operator gives you a YAML brief path on entry, skip this step.\n\n#### Brief schema (authoritative, v1)\n\n```yaml\npersona:\n  role: \u003Csnake_case role name, used as folder\u002Ffile prefix>\n  archetype: approver | subject | reviewer | delegate | notifier\n  scope_function: finance | hr | it | procurement | legal | legal_privacy | commercial | candidate\n  scope_business_unit: \u003Cstring or \"*\">    # OPTIONAL; default \"*\"\n  scope_geography: \u003Cstring or \"*\">        # OPTIONAL; default \"*\"\n  workflow_label: \u003Chuman label of the domain this persona belongs to>\n  external_event: \u003Csnake_case>            # OPTIONAL; default \u003Crole>_decision\n  default_authority_band: \u003Cfree-text>     # OPTIONAL; documentation only\n  uses_authority_mcp: true | false        # OPTIONAL; default false\n  description: \u003Cone sentence>\n  decision_policy_paragraph: |\n    One paragraph stating the rule the persona uses to decide.\n  decision_inputs:                        # OPTIONAL; documentation\n    - \u003Ccontext_key_the_policy_reads>\n    - ...\n  decision_authority_action: \u003Caction>     # REQUIRED iff uses_authority_mcp=true.\n                                          # Must match an `action` in\n                                          # data\u002Fsynthetic\u002Fauthority\u002Fmatrix.json.\n  decision_code: |\n    # Python source the persona_responder compiles. Reads `context`,\n    # assigns `decision` (\"approve\" | \"reject\" | \"escalate\") and\n    # `reason` (str). Mirror the decision_policy_paragraph above.\n    # The responder runs this in a sandboxed namespace with a small\n    # whitelist of safe builtins (see api\u002Fserver\u002Fservices\u002Fpersona_responder.py\n    # _DECISION_BUILTINS — currently includes `authority_check` for\n    # personae that consult the delegated-authority MCP).\n    pass\n```\n\nValidate the brief before continuing:\n\n- `role` matches `^[a-z][a-z0-9_]*$`.\n- `archetype` is one of the five allowed strings.\n- `scope_function` is one of the eight allowed strings.\n- `external_event` is `^[a-z][a-z0-9_]*$` if provided.\n- If `uses_authority_mcp: true`, `decision_authority_action` is set\n  AND the decision_code contains `authority_check(...)`.\n- The decision_code uses only the safe builtins from\n  `api\u002Fserver\u002Fservices\u002Fpersona_responder.py` `_DECISION_BUILTINS`\n  (no `import`, no `open`, no `os`, no `subprocess`, no `eval`).\n- The decision_code assigns both `decision` and `reason`.\n\nIf validation fails, stop and tell the operator what's wrong. Do not\nproceed to step 2.\n\n### Step 2 — Plan\n\nFrom the brief, produce the artefact list. **Print this list back to\nthe operator before you write a single file.** Wait for \"go\".\n\nAlways:\n\n- 1 persona SKILL.md at\n  `\u003CRUN_ROOT>\u002Fapi\u002Fserver\u002Fpersonae\u002F\u003Crole>\u002FSKILL.md`.\n- 1 `REGISTRY-ENTRY.py` at the run root containing the Python snippet\n  to splice into `api\u002Fshared\u002Fpersonas.py` `PERSONAS` dict.\n- 1 `GRADUATION.md` describing what `graduate.sh` will do.\n- 1 executable `graduate.sh` that mechanically performs the live-tree\n  edits.\n\n### Step 3 — Inventory and isomorphism\n\nBefore invoking `author-persona`, read **exactly these 3 files**\nend-to-end. They are the canonical examples this skill mirrors.\n\n| # | Canonical file                                              | Why                                                  |\n|---|-------------------------------------------------------------|------------------------------------------------------|\n| 1 | `api\u002Fserver\u002Fpersonae\u002Ffinance_bp\u002FSKILL.md`                   | Authority-MCP-using persona (template for `uses_authority_mcp: true`) |\n| 2 | `api\u002Fserver\u002Fpersonae\u002Fline_manager\u002FSKILL.md`                 | Inline-logic persona (template for `uses_authority_mcp: false`)        |\n| 3 | `api\u002Fserver\u002Fservices\u002Fpersona_responder.py` (`_DECISION_BUILTINS`) | Sandbox surface — whitelist of callables the decision_code may use |\n\nDrift in any of these means downstream output will be stale-shaped —\nstop and update this SKILL before continuing.\n\n### Step 4 — Generate into sandbox\n\nCompute `RUN_ID = \u003CYYYYMMDD-HHMMSS>-\u003Crole>` from current UTC\n(`date -u +\"%Y%m%d-%H%M%S\"`). Create\n`tools\u002Fscratch\u002Fcompose-persona\u002F\u003CRUN_ID>\u002F`.\n\n#### 4.1 — Invoke `author-persona`\n\n```\noutput_path: \u003CRUN_ROOT>\u002Fapi\u002Fserver\u002Fpersonae\u002F\u003Crole>\u002FSKILL.md\nbrief: \u003Cpersona block from the YAML brief>\ndomain_display_name: \u003Cpersona.workflow_label>\ndefault_external_event: \u003Cpersona.external_event or persona.role + \"_decision\">\ncanonical_example_path:\n  - api\u002Fserver\u002Fpersonae\u002Ffinance_bp\u002FSKILL.md   (when uses_authority_mcp: true)\n  - api\u002Fserver\u002Fpersonae\u002Fline_manager\u002FSKILL.md (when uses_authority_mcp: false)\nresponder_path: api\u002Fserver\u002Fservices\u002Fpersona_responder.py\n```\n\n`author-persona` writes the SKILL.md to the sandbox path.\n\n#### 4.2 — Write `\u003CRUN_ROOT>\u002FREGISTRY-ENTRY.py`\n\n```python\n# Splice into api\u002Fshared\u002Fpersonas.py inside the PERSONAS dict.\n# Place under the matching domain section comment block.\n\"\u003Crole>\": Persona(\n    role=\"\u003Crole>\",\n    archetype=\"\u003Carchetype>\",\n    scope_function=\"\u003Cscope_function>\",\n    workflow_label=\"\u003Cworkflow_label>\",\n    external_event_default=\"\u003Cexternal_event>\",\n    scope_business_unit=\"\u003Cscope_business_unit>\",   # default \"*\"\n    scope_geography=\"\u003Cscope_geography>\",           # default \"*\"\n    default_authority_band=\u003CNone or \"\u003Ctext>\">,\n    uses_authority_mcp=\u003CTrue | False>,\n    description=\"\u003Cdescription>\",\n),\n```\n\n#### 4.3 — Write `\u003CRUN_ROOT>\u002FGRADUATION.md`\n\nHuman-readable explanation of what `graduate.sh` does:\n\n1. Copy `\u003CRUN_ROOT>\u002Fapi\u002Fserver\u002Fpersonae\u002F\u003Crole>\u002FSKILL.md` →\n   `api\u002Fserver\u002Fpersonae\u002F\u003Crole>\u002FSKILL.md`.\n2. Splice `\u003CRUN_ROOT>\u002FREGISTRY-ENTRY.py` content into\n   `api\u002Fshared\u002Fpersonas.py` `PERSONAS` dict (between the appropriate\n   per-domain comment markers — operator's manual call where exactly).\n3. Add `\u003Crole>` to `PERSONA_AUTO_CLOSE` env var ONLY if the demo\n   profile expects this persona to auto-close gates. Default: do not\n   add (production-honest default).\n4. Run `pytest tests\u002Fapi\u002Fshared\u002Ftest_personas_registry.py` to confirm\n   the registry validates with the new entry.\n\n#### 4.4 — Write `\u003CRUN_ROOT>\u002Fgraduate.sh`\n\nExecutable script:\n\n```bash\n#!\u002Fusr\u002Fbin\u002Fenv bash\n# graduate.sh — mechanically promote the persona generated at this run root\n# into the live trees. Re-runnable; idempotent on the SKILL.md copy.\n# The registry-entry splice is intentionally manual — printed to stdout for\n# the operator to paste into the right per-domain section of personas.py.\nset -euo pipefail\n\nRUN_ROOT=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\nREPO_ROOT=\"$(cd \"$RUN_ROOT\u002F..\u002F..\u002F..\" && pwd)\"\nROLE=\"\u003Crole>\"\n\nSKILL_SRC=\"$RUN_ROOT\u002Fapi\u002Fserver\u002Fpersonae\u002F$ROLE\u002FSKILL.md\"\nSKILL_DST=\"$REPO_ROOT\u002Fapi\u002Fserver\u002Fpersonae\u002F$ROLE\u002FSKILL.md\"\n\nif [ ! -f \"$SKILL_SRC\" ]; then\n    echo \"ERROR: missing SKILL.md at $SKILL_SRC\" >&2\n    exit 1\nfi\n\nmkdir -p \"$(dirname \"$SKILL_DST\")\"\ncp \"$SKILL_SRC\" \"$SKILL_DST\"\necho \"wrote $SKILL_DST\"\n\ncat \u003C\u003CEOF\n\n  Manual splice required:\n  -----------------------\n  Open $REPO_ROOT\u002Fapi\u002Fshared\u002Fpersonas.py and paste the entry below\n  inside the PERSONAS dict, under the matching domain's comment block.\n\nEOF\n\ncat \"$RUN_ROOT\u002FREGISTRY-ENTRY.py\"\n\necho\necho \"  Then run: uv run pytest tests\u002Fapi\u002Fshared\u002Ftest_personas_registry.py\"\n```\n\n`chmod +x` the file.\n\n### Step 5 — Self-check + operator handoff\n\nBefore returning, verify:\n\n- All four files exist at `\u003CRUN_ROOT>\u002F`.\n- `SKILL.md` parses as YAML frontmatter + markdown body\n  (`yaml.safe_load(frontmatter_block)` works; body has the three\n  required `##` sections from `author-persona`).\n- `SKILL.md` `decision_policy` block compiles (`compile(source,\n  \"\u003Ctest>\", \"exec\")` doesn't raise).\n- `REGISTRY-ENTRY.py` is valid Python and uses one of the\n  documented `archetype` values.\n- `graduate.sh` is executable (`-x` bit set).\n\nReturn a one-paragraph summary to the operator naming the four\ngenerated paths and the next-step command (the manual splice + the\npytest command).\n\n## Anti-patterns\n\n- Letting the prose paragraph and the executable block disagree. The\n  prose tracks the code; if they diverge, the brief author needs to\n  resolve it before this skill runs.\n- Generating a persona that uses the authority MCP without setting\n  `uses_authority_mcp: true` in the registry entry. The registry flag\n  is the auditable signal that this persona doesn't inline thresholds.\n- Modifying the live `api\u002Fshared\u002Fpersonas.py`. Always emit the\n  `REGISTRY-ENTRY.py` snippet for the operator to splice manually.\n  Mechanical splicing risks placing the entry under the wrong\n  per-domain comment block.\n- Adding the persona to `PERSONA_AUTO_CLOSE` automatically.\n  Production-honest default: every gate stays open until explicitly\n  opted in. Demo profiles set the allow-list explicitly.\n",{"name":5,"audience":57,"description":58,"forbidden-runtime":59},"design-time-only","Design-time meta-skill (v1). Given a persona brief (YAML) or a free-text\nidea, produce a complete Persona artefact set: a SKILL.md\n(frontmatter + executable decision_policy + prose body), a\nPython registry entry pasteable into `api\u002Fshared\u002Fpersonas.py`, and a\ngraduate.sh script that mechanically wires the persona into the live\ntrees.\n\nSandbox-only; never touches real trees directly. Calls `author-persona`\nas its sole sub-skill.\n\nSister to `compose-domain`. Where `compose-domain` graduates a whole\nDurable workflow + skills + personae for one new business process,\n`compose-persona` graduates ONE persona — useful when an existing\ndomain needs an additional approver \u002F reviewer, or when a new\nfunction (finance, legal, IT) needs its cast filling out before its\ndomain lands.\n",true,"main","db273d7d646605c0bf0175dc9c8057b9ad2628b5","docs\u002Fsuperpowers\u002Fskills\u002Fcompose-persona",2,"https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane","https:\u002F\u002Fgithub.com\u002Farturcrmbot","2026-09-28 17:47:06",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":59},[69,72,75],{"tool":70,"command":71},"npx","npx skills add arturcrmbot\u002Fzava-control-plane --skill compose-persona",{"tool":73,"command":74},"bunx","bunx skills add arturcrmbot\u002Fzava-control-plane --skill compose-persona",{"tool":76,"command":77},"pnpm","pnpm dlx skills add arturcrmbot\u002Fzava-control-plane --skill compose-persona","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane\u002Fblob\u002Fmain\u002Fdocs\u002Fsuperpowers\u002Fskills\u002Fcompose-persona\u002FSKILL.md",[],[81,102,118,132,140,147],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":52},"01M71SJECD4KXSSJV1B0HSY4T4","proactive-customer-care","Proactively notifies and, where warranted, extends a small bounded goodwill gesture to a customer whose itinerary materially changed.","https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane\u002Fblob\u002Fmain\u002Fverticals\u002Ftravel\u002Fskills\u002Fproactive-customer-care\u002FSKILL.md",[],[88,89,90,91,92,93,94,95,96,97,98,99,100,101],"proactive","customer","proactive customer care","customer care","gesture","action","bounded","status","check","booking","operations","travel","issue","itinerary",{"skillNo":103,"name":104,"nameZh":6,"description":105,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":52},"01M71SJ9VHGNNTB6452H1KRZD6","payment-exception","Resolves a failed balance payment by retrying it to complete the booking, or releasing the booking's inventory when retry is not viable.","https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane\u002Fblob\u002Fmain\u002Fverticals\u002Ftravel\u002Fskills\u002Fpayment-exception\u002FSKILL.md",[],[109,110,111,112,113,97,38,114,115,95,116,117,96,98,99],"payment","payment exception","it","retry","balance","release","complete","capacity","inventory",{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":52},"01M71SJ6S6XREB0J6CCVCSFZ9E","hotel-supplier-recovery","Restores accommodation for a shortfall-hit hotel allotment by moving contracted rooms from a donor allotment with headroom, resolving the reported supplier shortfall.","https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane\u002Fblob\u002Fmain\u002Fverticals\u002Ftravel\u002Fskills\u002Fhotel-supplier-recovery\u002FSKILL.md",[],[125,126,127,128,96,98,99,129,130,131],"hotel supplier recovery","hotel","recovery","with","move","for","headroom",{"skillNo":133,"name":134,"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":135,"categories":136,"keywords":137,"publishedAt":52},"01M71SJ4G5MPM50WZ6F66M3PNS","holiday-sales-booking","https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane\u002Fblob\u002Fmain\u002Fverticals\u002Ftravel\u002Fskills\u002Fholiday-sales-booking\u002FSKILL.md",[],[138,97,139],"holiday sales booking","sales",{"skillNo":141,"name":142,"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":143,"categories":144,"keywords":145,"publishedAt":52},"01M71SJ2AHHWN2C4YV2RKEE947","flight-disruption-recovery","https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane\u002Fblob\u002Fmain\u002Fverticals\u002Ftravel\u002Fskills\u002Fflight-disruption-recovery\u002FSKILL.md",[],[146,127],"flight disruption recovery",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":52},"01M71SHYPK8HNQ80C9XAWSER53","destination-operations","Dispatches a replacement resort transfer when an arrival is at risk, rebinding any travellers on the at-risk transfer to the replacement.","https:\u002F\u002Fgithub.com\u002Farturcrmbot\u002Fzava-control-plane\u002Fblob\u002Fmain\u002Fverticals\u002Ftravel\u002Fskills\u002Fdestination-operations\u002FSKILL.md",[],[154,98,155,156,96,157,99,158,38,159],"destination operations","destination","risk","dispatch","at","transfer"]