KeiSeiKit-1.0/skills/pet-init/phase-2-voice.md
Parfii-bot a4e667de10 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

4.4 KiB

Phase 2 — Voice

Gather the four [voice] fields: tone_primary, tone_secondary, humor_style, humor_frequency. Entirely click-driven — no free text.

2a — Voice batch (AskUserQuestion, 1 batch with 4 questions)

Emit a single AskUserQuestion call:

{
  "questions": [
    {
      "question": "Primary tone of the pet?",
      "header": "Primary tone",
      "multiSelect": false,
      "options": [
        {"label": "Warm",     "description": "Friendly, supportive, caring default"},
        {"label": "Neutral",  "description": "Even-keel, factual, no emotional color"},
        {"label": "Formal",   "description": "Polite, structured, keeps a professional distance"},
        {"label": "Playful",  "description": "Light, curious, uses wordplay and side-remarks"}
      ]
    },
    {
      "question": "Secondary tones (pick up to 2, or none)?",
      "header": "Secondary tones",
      "multiSelect": true,
      "options": [
        {"label": "Warm",     "description": "Add warmth on top of primary"},
        {"label": "Neutral",  "description": "Temper intensity of primary"},
        {"label": "Formal",   "description": "Add politeness on top of primary"},
        {"label": "Playful",  "description": "Add light tangents on top of primary"},
        {"label": "Direct",   "description": "Shorter, more to-the-point"},
        {"label": "Gentle",   "description": "Softer phrasing on hard topics"}
      ]
    },
    {
      "question": "Humor style?",
      "header": "Humor",
      "multiSelect": false,
      "options": [
        {"label": "None",    "description": "No jokes, no wordplay — task-focused"},
        {"label": "Dry",     "description": "Understated, deadpan, rare smirks"},
        {"label": "Witty",   "description": "Clever, observational, occasional puns"},
        {"label": "Silly",   "description": "Absurd, playful, freely silly"}
      ]
    },
    {
      "question": "How often should humor appear?",
      "header": "Humor frequency",
      "multiSelect": false,
      "options": [
        {"label": "Rare",         "description": "Only when the moment clearly invites it"},
        {"label": "Occasional",   "description": "A few light remarks per long conversation"},
        {"label": "Frequent",     "description": "Frequent jokes, side-remarks, playful asides"}
      ]
    }
  ]
}

2b — Map clicks to variables

TONE_PRIMARY — lowercase the chosen label:

Label Value
Warm warm
Neutral neutral
Formal formal
Playful playful

TONE_SECONDARY — lowercase each ticked label. Rules:

  • if the user ticked more than 2 → keep the first 2 in the order they appeared in the response; tell the user: Kept first 2 secondary tones; re-run /pet-init to adjust.
  • if the user ticked zero → TONE_SECONDARY = [] (valid per schema)
  • if the user ticked the SAME label as TONE_PRIMARY → drop the duplicate silently; if that leaves 0, leave TONE_SECONDARY = []

HUMOR_STYLE — lowercase:

Label Value
None none
Dry dry
Witty witty
Silly silly

HUMOR_FREQUENCY — lowercase:

Label Value
Rare rare
Occasional occasional
Frequent frequent

2c — Consistency check

If HUMOR_STYLE == "none" and HUMOR_FREQUENCY != "rare", emit a regular message:

Humor style is "none" but frequency is "". "None" overrides frequency — the pet will simply not attempt humor. Continue? (yes / change)

  • yes → set HUMOR_FREQUENCY = "rare" (schema-valid + semantically honest)
  • change → re-emit the Phase-2 batch (no partial re-runs; the whole voice set is asked again)

Verify-criterion

  • TONE_PRIMARY is one of warm / neutral / formal / playful
  • TONE_SECONDARY is a list of 0-2 entries, no duplicates, none equal to TONE_PRIMARY
  • HUMOR_STYLE is one of none / dry / witty / silly
  • HUMOR_FREQUENCY is one of rare / occasional / frequent
  • Consistency rule (2c) has been applied

Failure modes (constructive paths)

If the user bails mid-batch (closes without answering):

  • (A) keep whatever is set; emit defaults for unset: neutral / [] / none / rare; show the user what was defaulted and ask confirm
  • (B) abort /pet-init cleanly, no file written
  • (C) re-emit the whole batch once more