presets/commercial-base/persona.jsonskills/brand-persona-skill/assets/brand.persona.template.jsonskills/brand-persona-skill/references/SERVICE-CONTRACT.template.md./{slug}-skill/Ask the user:
text
Does your brand have any of the following existing content?
[A] Yes → brand guidelines / customer service records / website copy /
founder interviews / marketing materials / social media archives
(any format: .md / .txt / .pdf / chat exports / .json)
[B] No or very little → declare brand parameters directly
If the user selects [A], proceed to Phase 1A. If the user selects [B], proceed to Phase 1B.
Load skills/anyone-skill/SKILL.md and follow its instructions.
When anyone-skill asks "Who do you want to distill?", select **[6] Archetype\\ — composite persona with no single real-world subject. This is the correct type for a brand persona.
Brand content → anyone-skill data type mapping (use this to guide the user on what to provide):
Brand contentanyone-skill data typeBrand guidelines / VI spec / brand manual.md / .pdf → universal adapterCustomer service records / sales scriptsChat export → chat_export adapterWebsite copy / WeChat public account articles.txt / .md → universal adapterFounder interviews / brand story.txt → universal adapterSocial media archives (X/Instagram)Archive directory → social adapterProduct catalog / FAQ document.md / .pdf → universal adapter
Note: if skills/persona-knowledge/SKILL.md is present, anyone-skill will automatically route brand knowledge into the MemPalace persistent store. No extra steps needed.
Output: a structured brand persona draft with four dimensions extracted:
Collect this output and proceed to Phase 2.
Collect the following from the user, one question at a time:
jinguyuan-dumplings)soul.identity.bio)Optional: use WebSearch to research competitors or industry tone references if the user needs inspiration.
Output: structured brand soul fields. Proceed to Phase 2.
Services are skills. Every service capability the brand agent offers maps directly to a skills[] entry in persona.json.
Ask the user the following questions (Questions 1–3 are required; Question 4 is only asked if any service in Question 2 uses A2A delegate):
List every service the agent can handle without human involvement. Think in two categories:
For each service declared above, the implementation method is transparent to this skill — the brand chooses based on what they have:
ImplementationWhen to useExampleKnowledge responseInformation queries, no system integrationBusiness hours, product descriptions, policiesLocal scriptSpecific business operationsQueue number generation, appointment bookingMCP toolHas own service endpointOrder lookup, inventory checkA2A protocolAgent-to-agent collaborationCross-system business flowsWebhook / APIHas existing ERP / CRM / payment systemOrder management, customer dataHuman handoffHigh-risk or complex situationsComplaints, contracts, disputesA2A delegateOperation belongs to a third-party platform that has its own brand agentQueue via Meituan agent, payment via WeChat Pay agent, delivery via platform agentMixedMost real businessesAuto-answer queries + escalate transactions
Record the implementation method in the skill's description field.
A2A delegate requires collecting two extra fields:
shop_id: 4211342 for the BUPT location) — they will be written into the trigger mapping table in Step 4c so the customer agent knows exactly what to pass when calling the third-party agent.List hard limits and escalation triggers:
List every service that this brand agent cannot execute directly but can route to a known third-party brand agent. For each:
This produces the Third-Party Agent Routing table written into SERVICE-CONTRACT.md in Phase 4.
Output mapping:
skills[] with name, description, and optional triggersoul.character.boundariesMerge Phase 1 brand soul and Phase 2 service skills into a complete persona.json using presets/commercial-base as the base. Apply this field mapping:
SourceTarget fieldPhase 1A/1B brand namesoul.identity.personaNamePhase 1A/1B slugsoul.identity.slugPhase 1A/1B one-line biosoul.identity.bioPhase 1A/1B personality keywordssoul.character.personalityPhase 1A/1B speaking stylesoul.character.speakingStylePhase 1A/1B core values + hard limitssoul.character.boundaries (combined as a single string; list items separated by newline)Phase 1A/1B background / brand storysoul.character.background (if available from distillation)Phase 2 service skills listskills[] (each entry: name, description, optional trigger)Phase 2 additional hard limitsappend to soul.character.boundariesBase fieldsall other fields from presets/commercial-base/persona.json
Use skills/brand-persona-skill/assets/brand.persona.template.json as a writing guide. Do not copy the template file directly — it contains _comment fields that will cause schema validation errors. Write a new persona.json based on its structure, with all _comment keys removed.
Gate — Soul Gate: before proceeding, verify:
soul.identity.personaName is non-emptysoul.identity.slug matches ^[a-z0-9-]+$soul.identity.bio is non-emptysoul.character.personality is non-emptyIf any field is missing, return to Phase 1 to collect it.
Gate — Service Gate: verify:
skills[] contains at least one entry with a non-empty namesoul.character.boundaries is non-emptyIf either check fails, return to Phase 2.
Load skills/open-persona/SKILL.md and follow its generation instructions.
bash
npx openpersona create --config persona.json --output ./{slug}-skill
Gate — Generate Gate: if openpersona create exits non-zero, read the validation error, fix persona.json, and retry.
Fill skills/brand-persona-skill/assets/behavior-guide.template.md with brand-specific values and write the result to ./{slug}-skill/soul/behavior-guide.md, overwriting the framework default. Apply this mapping:
PlaceholderSource{{brandName}}Phase 1A/1B brand name{{oneLinerBio}}Phase 1A/1B one-line bio{{onboardingQuestion_1/2/3}}3 realistic first questions a customer would ask this brand{{blindspotRedirect}}Escalation channels declared in Phase 2 (human handoff channel, official website, customer service number, etc.){{confirmationRequiredOps}}Action services from Phase 2 that require confirmation (list each by name){{brandVibe}}Phase 1A/1B vibe / personality keywords{{speakingStyleNote}}Phase 1A/1B speaking style, condensed to one sentence{{brandBoundaries}}``soul.character.boundaries from Phase 3
From the Phase 2 skills[] list, write a trigger mapping table and append it to ./{slug}-skill/SKILL.md under a new section ## Trigger Scenarios. For each declared service skill, produce one or more rows:
markdown
## Trigger Scenarios
| What the customer might ask | Corresponding operation |
|---|---|
| {realistic user phrasing for skill_1} | {skill_1 name and implementation method} |
| {realistic user phrasing for skill_2} | {skill_2 name and implementation method} |
...
Use natural customer language in the left column (questions a real customer would type, not technical names). Use the skill name + implementation method in the right column. For A2A delegate skills, include the ACN address and any routing parameters collected in Phase 2 (e.g. "queue-waitlist — A2A delegate to acn://meituan-queue-agent; shop_id: BUPT store 4211342, Wudaokou store 1756895741; fallback: Meituan app").
text
Copy skills/brand-persona-skill/references/SERVICE-CONTRACT.template.md
→ ./{slug}-skill/references/SERVICE-CONTRACT.md
Fill in all {{placeholder}} values with the information collected in Phase 2.
For the Third-Party Agent Routing section, use the routing table collected in Phase 2 Question 4:
acn://{slug} and set status to activelink-fallbacktbd and fill in a human-readable fallback instructionThe routing table is the most important part of the contract for customer agents — it tells them the complete service map of this brand, including what this agent delegates and where.
Gate — Contract Gate: verify that ./{slug}-skill/agent-card.json has a non-empty skills[] array. agent-card.json is auto-generated by openpersona create — its skills[] maps directly from persona.json's skills[]. If it is empty, the root cause is an empty skills[] in Phase 3; return to Phase 2 to declare at least one service skill and regenerate.
Confirm the generated pack structure with the user:
text
{slug}-skill/
├── SKILL.md ← brand agent behavior rules
├── persona.json ← brand declaration
├── agent-card.json ← A2A discovery credential
├── acn-config.json ← ACN registration config
├── soul/
│ ├── injection.md ← brand soul injection
│ ├── constitution.md ← ethical foundation (inherited)
│ └── behavior-guide.md ← brand behavior guide
├── scripts/
│ └── state-sync.js ← cross-session state management
└── references/
├── SERVICE-CONTRACT.md ← service capabilities and boundaries
└── SIGNAL-PROTOCOL.md ← host integration guide
Optional — Register on ACN:
bash
npx openpersona acn-register {slug} --endpoint https://your-agent-endpoint.example.com
This publishes the brand agent's agent-card.json to the Agent Communication Network so other agents can discover and call it without installing any brand-specific skill. The --endpoint flag is the only value the brand must supply — everything else ( agent-card.json, acn-config.json) was auto-generated by openpersona create.
GateOn failureSoul GateReturn to Phase 1, collect missing fieldsService GateReturn to Phase 2, add at least one service skillGenerate GateRead openpersona validate error, fix persona.json fields, retryContract GateReturn to Phase 2, verify skills[] is populated, regenerate
Always ask for explicit confirmation before:
take_number, place_order, cancel_order, or any state-changing operation