KeiSeiKit-1.0/skills/pet-init/phase-4-emit.md
Parfii-bot 0be354a920 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

167 lines
5.3 KiB
Markdown

# Phase 4 — Emit
Compose the TOML from Phase 1-3 variables, ensure a keypair exists, write
`~/.claude/pet/<user_id>.toml`, display a summary, suggest next steps.
## 4a — User ID (keygen if needed)
Check whether a keypair already exists:
```bash
kei-pet keygen --status 2>/dev/null
```
Expected outputs:
- `keypair exists, user_id=<short-hash>` → reuse; set `USER_ID` to the hash,
set `KEYGEN_ACTION = "reused existing"`
- `no keypair` OR non-zero exit → create one:
```bash
kei-pet keygen --create
```
Capture the new `user_id` short-hash from stdout. Set `USER_ID` to that
hash, set `KEYGEN_ACTION = "newly created"`.
If `kei-pet keygen --create` fails (non-zero exit, no hash in stdout) →
STOP and emit 3 constructive paths:
- (A) check that the `kei-pet` binary is on `$PATH`; point user to
`install.sh --profile=dev`
- (B) invoke the raw primitive at `_primitives/_rust/kei-pet/target/release/kei-pet keygen --create`
- (C) manually set `USER_ID = "anonymous"` for a one-off local pet; warn
that this pet will not be portable across machines
Never silently fall through without a `USER_ID`.
## 4b — Compose TOML in memory
Build the TOML string exactly matching the schema in
`_primitives/_rust/kei-pet/examples/minimal.toml`. Use these variable
substitutions (all gathered in Phases 1-3 unless noted):
```toml
# Pet manifest for <PET_NAME> (owner <USER_NAME>, user_id <USER_ID>)
# Generated by /pet-init on <ISO8601-UTC-NOW>.
schema = 1
[identity]
pet_name = "<PET_NAME>"
user_name = "<USER_NAME>"
addressing = "<ADDRESSING>"
languages = [<comma-separated-quoted-LANGUAGES>]
[voice]
tone_primary = "<TONE_PRIMARY>"
tone_secondary = [<comma-separated-quoted-TONE_SECONDARY>]
humor_style = "<HUMOR_STYLE>"
humor_frequency = "<HUMOR_FREQUENCY>"
[edge]
profanity = "<PROFANITY>"
profanity_languages = []
directness = "<DIRECTNESS>"
initiative = "<INITIATIVE>"
[forbidden]
topics = [<comma-separated-quoted-FORBIDDEN_TOPICS>]
tone_patterns = []
[meta]
schema_version_written_by = "kei-pet 0.1.0"
created_at = "<ISO8601-UTC-NOW>"
last_tuned = "<ISO8601-UTC-NOW>"
tune_count = 0
```
String escaping rules inside double-quoted TOML values:
- escape `\``\\`
- escape `"``\"`
- reject control chars other than TAB (should never appear; guard)
Timestamps: emit current UTC time in RFC 3339 with `Z` suffix, e.g.
`2026-04-23T12:30:00Z`. `created_at` and `last_tuned` are equal on first
init.
## 4c — Write the file
Target path: `~/.claude/pet/<USER_ID>.toml` (absolute: expand `~` to `$HOME`).
```bash
mkdir -p "$HOME/.claude/pet"
```
Then write the composed TOML to `$HOME/.claude/pet/<USER_ID>.toml`. Use
the `Write` tool with the absolute path — do NOT echo TOML through shell
(quoting hazard).
If the file already exists at that path (re-run of `/pet-init` for the
same user_id), rename the existing file to
`~/.claude/pet/<USER_ID>.toml.bak-<ISO8601-UTC-NOW>` BEFORE writing the
new one. Tell the user: `Previous pet.toml backed up to <bak-path>`.
## 4d — Validate (best-effort)
Attempt a schema validation via the primitive:
```bash
kei-pet validate --pet "$HOME/.claude/pet/<USER_ID>.toml"
```
- exit 0 → good; proceed
- non-zero → emit the validator's stderr verbatim, keep the file on disk
(the user can re-run `/pet-init` to fix), set `VALIDATION = "FAILED"`
- command not found → set `VALIDATION = "SKIPPED (kei-pet not on PATH)"`
## 4e — Summary table + next steps
Emit a plain-text summary (NOT AskUserQuestion — this is the closing
message):
```
=== PET-INIT REPORT ===
Pet name: <PET_NAME>
Addressed by: <USER_NAME> via <ADDRESSING>
Languages: <LANGUAGES joined with comma-space>
Voice: <TONE_PRIMARY> (+ <TONE_SECONDARY or "no secondary">)
Humor: <HUMOR_STYLE> @ <HUMOR_FREQUENCY>
Edge: <DIRECTNESS> / <INITIATIVE> / profanity=<PROFANITY>
Forbidden: <FORBIDDEN_TOPICS joined with comma-space, or "(none)">
File: ~/.claude/pet/<USER_ID>.toml
Keygen: <KEYGEN_ACTION>
Validation: <PASSED | FAILED | SKIPPED>
Next:
/pet-chat
kei-pet render --pet ~/.claude/pet/<USER_ID>.toml
```
## Verify-criterion
- `USER_ID` is a non-empty short-hash OR the documented `"anonymous"`
fallback (only via constructive path C in 4a)
- `~/.claude/pet/<USER_ID>.toml` exists on disk and matches the composed
TOML byte-for-byte
- If a prior file existed, a `.bak-<ts>` backup exists alongside it
- Summary table is emitted with all 10 rows filled (no placeholders left)
- `kei-pet validate` was attempted; its verdict is surfaced
## Failure modes (constructive paths)
If `Write` fails (permission denied, read-only filesystem, disk full):
- (A) fall back to `~/Desktop/<USER_ID>.toml` and tell the user to move
the file manually
- (B) print the full TOML to stdout so the user can paste it anywhere
- (C) invite the user to re-run `/pet-init` after fixing the underlying
disk/permission issue
If `kei-pet validate` reports a schema violation that the wizard could
not anticipate (schema drift between this skill and the binary):
- (A) keep the file; tell the user the specific validator error
- (B) suggest `kei-pet migrate --pet <path>` if the primitive ships one
- (C) open an issue link to the KeiSeiKit repo for schema-drift reports
Never silently succeed while validation is failing.