Install
$ agentstack add skill-voicenterteam-claude-marketplace-voicenter-bot-json-assembler ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Skill 3 — JSON Assembler & Publish
This skill produces the deployable Bot JSON by mechanically projecting a fully-detailed Agent Spec into Voicenter wire-format. It is the third and final skill in the Voicenter Bot generation pipeline:
- Skill 1 (Agent Spec Designer): structural design via interview → fills sections 1, 2, 3, 4, 4.5; creates section 5 stubs marked
[structural]. - Skill 2 (Intent Detail Author): language-heavy per-intent content → fills section 5 entries, marks them
[detailed]. - Skill 3 (this skill): mechanical assembly of spec → wire-format JSON.
Operating principle: pure parser, not interpreter. Skill 3 makes no creative decisions. It does not best-effort interpret ambiguous spec content; if the spec deviates from the strict template, Skill 3 reports a structured parse error and refuses to assemble. The entire skill architecture depends on Skill 3 being deterministic — if Skill 3 interprets, "what JSON does this spec produce?" depends on Skill 3's mood, and the source-of-truth contract dies. Discipline is the design.
The risk vector for this skill is doing too much: filling in plausible-looking values for unknowns, smoothing over template deviations, auto-fixing cross-reference violations, deciding RT-specific defaults the spec didn't specify. The anti-list (§8) is the longest and most opinionated section — read it before doing anything else.
1. Required reading at invocation
Before touching the spec, load context from these references.
| Read | Why | |---|---| | Doc 1 §4 — Bot top-level wrapper | Mapping for spec section 1 root fields | | Doc 1 §5 — ActiveVersionInfo envelope | Mapping for version-level fields | | Doc 1 §6 — The two AIModelConfig objects | Top-level vs version-level + created payload duplication | | Doc 1 §7 — Crosswalk: training-doc → JSON paths | Field-name reconciliation reference | | Doc 1 §8 — intentList six parallel collections | The bulk of assembly | | Doc 1 §9 — intents[] 16-field skeleton | Per-intent shape | | Doc 1 §10 — IntentParameters slot definitions | Per-slot shape | | Doc 1 §11 — ResponseTypeId reference (RT=1/2/3/4) | RT-specific Configuration assembly (§4.4) | | Doc 1 §11.2 — RT=2 pairing rule | Cross-reference check 5 + 6 | | Doc 1 §12 — ParameterTypeId catalog | Slot type emission | | Doc 1 §13 — Mustache + variable categories | Cross-reference check 7 | | Doc 1 §15.3 — ID placeholder strategy (Option A) | §4.1 allocation | | Doc 1 §15.4 — Cross-reference pass spec | §6 — the seven checks | | Doc 1 §16 — Schema quirks summary | §4.5 + Appendix A | | Doc 2 §3.7 — Strict-template enforcement | §3 parse rules | | Doc 2 §6 — Skill 3 architecture | Everything in this file implements this | | Doc 2 §7.5 — Routing failures back | Appendix B | | locked-decisions.md decision B | Sentinel strategy | | locked-decisions.md decision M | Section 4.5 inventory drives Mustache check |
Also load this file from Skill 1's package:
skills/voicenter-bot-spec-designer/model-catalog.md— required for resolving named catalog entries toAIModelConfigID/AIModelTypeIdand provider model string (§4.2.3).
Skill 3 does not load Skill 2's conversation-routines-style-guide.md. The style of validationPrompt and intentInstructions text is Skill 2's concern; Skill 3 emits the text verbatim from the spec, regardless of style.
2. Setup
2.1 Detect runtime
| Signal | Runtime | |---|---| | Conversation in claude.ai or mobile app, no workspace file system, no agent-spec.md accessible | Single-conversation | | Workspace file system available (Claude Code), agent-spec.md readable as a file | Claude Code |
State the detected runtime. The user can correct.
2.2 Read the spec
Single-conversation: read backward through the conversation context to find the most recent spec emission. The spec is identifiable by its ## 1. Bot Identity header and ## 7. Generation Metadata footer. If both Skill 1 and Skill 2 ran in this conversation, take the most recent (Skill 2's output).
Claude Code: read agent-spec.md from the workspace (or whatever filename the user references).
No spec found: abort with: "No Agent Spec found. Skill 3 requires a fully-detailed spec produced by Skill 1 → Skill 2. Invoke Skill 1 (Agent Spec Designer) first."
2.3 Pre-flight gates
Two gates run before any assembly work. Both are blocking. Refusal at either gate emits a clear message and halts; no JSON is produced.
Gate A — Completeness
Walk section 5. Count entries with status [structural] or [detailed-revisit]. If the count is greater than zero, refuse:
> Skill 3 will not assemble an incomplete spec. Section 5 has [N] intents still pending: [list with status per intent]. Run Skill 2 (Intent Detail Author) to detail them, then re-invoke Skill 3.
The list shows identifier + status (e.g., validate_customer_address [structural], confirm_appointment [detailed-revisit]), not detail level.
Cross-check against section 7.5 (which Skill 2 maintains). If 7.5 says zero pending but section 5 has pending entries, that's a Skill 2 bookkeeping bug — surface it: "Spec inconsistency: section 7.5 reports 0 pending, but section 5 has [N] intents in non-detailed state. Re-run Skill 2 once to refresh, then re-invoke Skill 3."
Gate B — Parseability
Run the strict-template parser (§3) over the spec. The first deviation halts parsing and produces a structured error. No partial assembly.
Parseability is checked before completeness in cases where the file is malformed at the section-header level (e.g., section headers missing entirely) — in that case, Skill 3 cannot even tell which intents are pending. Practical order: try a quick scan for the seven ## N. section headers first; if they're missing, Gate B fires first. If headers are present, Gate A fires first.
3. Strict-template parsing
3.1 The deterministic parse principle
The Agent Spec template is documented in Doc 2 §3 and codified in Skill 1's spec-skeleton.md. Skill 3 reads it as a fixed grammar — no synonyms, no flexibility, no creative tolerance.
Specifically, the parser expects:
- Section headers exact:
## 1. Bot Identity,## 2. Persona Bundle,## 3. Caller Silence Behavior,## 4. Intent List (Structural),## 4.5 Available Variables,## 5. Intent Details,## 6. Cross-References,## 7. Generation Metadata. Exact strings, exact numbering, exact punctuation.## 1: Bot Identityis a parse error.## Bot Identityis a parse error. - Field labels exact:
**Bot Name:**,**Identifier:**,**Description:**,**Account ID:**,**Primary Language:**,**Channels Active:**,**Voice Name:**,**AI Model Config:**. Bold markdown around the colon-terminated label, exactly as written. - Status markers exact:
[structural],[detailed],[detailed-revisit]. No synonyms (e.g.,[done],[in progress]). - Unknown markers exact:
>,>,[not configured]. The angle-bracket format is not optional;(UNKNOWN: ...)is a parse error. - Intent header in section 4:
### Intent N:where N is the 1-based ordinal and identifier is snake_case. The number determines section 4 ordering (used for first-intent start-marker logic inbotIntents[]). - Intent header in section 5:
### Intent:(no ordinal). Identifier matches a section 4 entry. - Slot lines in section 4: numbered list under
**Slots:**heading, format[slot_name] — \ParameterTypeId\[N], Required [\true\|\false\], Order [N], OptionList [if ENUM]. - Transition lines in section 4: numbered list under
**Transitions out:**heading, each item is a target intent identifier optionally followed by a parenthetical role label (e.g.,1. get_available_slots (success path)). - RT-specific sub-labels in section 4: for RT=1 intents,
**Layer:**followed by an integer. For RT=2 intents,**URL:**,**Method:**,**Headers:**,**Body:**, and**API silence behavior:**(the silence block has six sub-bullets exact:silence_duration:,silence_loops:,silence_sentence:,silence_ending_sentence:,silence_instructions:,fallback intent:). For RT=3 intents, the RT-specific block is empty (no sub-bullets). For RT=4 intents,**Dial source:**(parameter|static), then either**Parameter phone:**(slot identifier, when dial-source=parameter) or**Phone1:** / **Phone2:** / **Phone3:**(when dial-source=static); plus**selectdial_option:**,**NEXT_VO_ID:**,**MAX_DIAL_DURATION:**,**Record:**, optional**Announcement:**/**Loading announcement:**/**Post-execution intent instructions:**, and**Response success:**(object withinstructionskey).
3.2 Parse error format
When a deviation is detected, halt and emit:
Skill 3 parse error.
Location: line in
Section:
Expected:
Found:
Fix:
Skill 3 will not assemble. Re-run Skill 1 patch mode (if the spec was hand-edited or structurally invalid) or fix the deviation manually, then re-invoke Skill 3.
The `` is the conversation message reference (single-conv) or the file path (Claude Code). Line numbers are within that source.
Skill 3 does not attempt to interpret around the deviation. It does not emit a partial JSON. It does not flag and continue. One deviation, one error, one halt.
3.3 Common deviations and example messages
These are illustrative — the parser is grammar-driven, not pattern-matched, so anything off-grammar surfaces. The examples here are the most common shapes the user will see.
| Deviation | Example error | |---|---| | Missing section header | Expected: '## 4. Intent List (Structural)'. Found: '## Intent List'. Fix: restore the section number and exact heading. | | Bold field label punctuation off | Expected: '**Bot Name:** '. Found: 'Bot Name: '. Fix: wrap the label in bold markdown. | | Unknown marker shape wrong | Expected: '>'. Found: '(UNKNOWN: ...)'. Fix: use angle brackets and the literal token UNKNOWN. | | Status marker synonym | Expected: one of '[structural]', '[detailed]', '[detailed-revisit]'. Found: '[done]'. Fix: re-run Skill 2 to set the canonical marker. | | Intent identifier in section 5 has no match in section 4 | Section 5 entry 'verify_caller_id' has no matching intent in section 4. Fix: re-run Skill 1 patch mode to add the intent or remove the orphan section 5 entry. | | Section 4 reference to undeclared transition target | Intent 'validate_customer_address' transitions to 'get_slots', but no intent 'get_slots' exists in section 4 (closest match: 'get_available_slots'). Fix: re-run Skill 1 patch mode to correct the transition target. | | Spec ends mid-intent (truncated upload) | Section 5 entry 'confirm_appointment' has no closing structure (no following section 6 header). Fix: re-attach the complete spec. | | RT-specific sub-label punctuation off | Expected: '**URL:** '. Found: 'URL: '. Fix: wrap the sub-label in bold markdown. |
The transition-target check (last two rows) blurs into cross-reference territory — it's caught at parse time because it's a dangling identifier discoverable from sections 4-5 alone, and Skill 3 already has the data. Treating it as a parse error rather than waiting for §15.4 lets the user fix one thing at a time.
4. Spec-to-wire-format assembly
Run only if both pre-flight gates pass and the parser succeeds. Assembly happens in memory; nothing is emitted until §6 (cross-reference pass) also passes.
4.1 ID placeholder allocation
Per Doc 1 §15.3 Option A and Doc 2 §6.5: sequential negative integers, range-coded so the kind of ID is identifiable at a glance.
| ID kind | Placeholder range | Allocation rule | |---|---|---| | BotID | -1 | Single value | | BotVersionId | -2 | Single value | | IntentCategoryId | -3 | Single default category | | IntentId | -10, -11, -12, ... | One per intent in section 4 ordering (Intent 1 → -10, Intent 2 → -11, ...) | | BotIntentID | -100, -101, -102, ... | One per intent, same ordering | | ParameterId | -1000, -1001, -1002, ... | One per slot, walked intent-by-intent then slot-by-slot |
AccountID is user-supplied (spec section 1). If the spec marks `, emit the sentinel -999` per §4.6.
AIModelConfigID and AIModelTypeId come from spec section 1 + the model catalog (§4.2.3). If the catalog has TODO placeholders or the spec marks them unknown, emit -999 sentinels.
Allocation procedure:
- Walk section 4 in order. For each intent: assign
IntentIdfrom the-10series andBotIntentIDfrom the-100series. Cache the mapping→ (IntentId, BotIntentID). - Within each intent's section 5 entry, walk slots in
Ordervalue. For each slot: assignParameterIdfrom the-1000series. Cache the mapping. → ParameterId. - Emit
BotID = -1,BotVersionId = -2,IntentCategoryId = -3as fixed values.
The cached mappings are used in §4.3 wherever an ID is referenced (transition rows, parameter parent-ID, api-silence relations, botIntents references).
The numerical ranges are wide so a human reading the JSON can identify what kind of ID a placeholder represents at a glance. Real platform-assigned IDs after import will be positive integers, so there's no collision risk on re-export.
4.2 Top-level wrapper and version envelope
4.2.1 Top-level fields (spec section 1 → root)
| Spec field | Wire-format path | Source | |---|---|---| | Bot Name | .Name | Direct copy | | Description | .Description | Direct copy | | (allocated) | .BotID | -1 | | Account ID | .AccountID | Direct copy, or -999 sentinel if ` | | (constant) | .BotStatusId | 1 (per Doc 1 §4) | | (constant) | .BotLanguages | [] (preserved per §16, even though the bot has a language elsewhere) | | (generated) | .CreatedDate | ISO timestamp at assembly time, format "YYYY-MM-DD HH:MM:SS" | | (constant) | .ModifiedDate | null (no modifications yet) | | (resolved) | .AiModelConfig | §4.2.3 below | | (assembled) | .ActiveVersionInfo | §4.2.2 below | | (assembled) | .intentList` | §4.3 below |
4.2.2 ActiveVersionInfo envelope
| Wire-format path | Value | |---|---| | BotVersionId | -2 (placeholder) | | VersionNumber | "0.0.1" (per Doc 1 §5; v1 always emits this) | | BotVersionStatusId | 3 (per Doc 1 §5) | | IsActive | 1 | | Description | "" (matches both production samples) | | CreatedDate | Same ISO timestamp as root | | ModifiedDate | null | | SystemPrompt | "" (preserved per §16; NOT the same as the bot's system prompt, which lives in AIModelConfig.prompts) | | AIModelConfigId | Same value as .AiModelConfig.AIModelConfigID (mirror) | | AIModelConfig | §4.2.3 + 4.2.4 + 4.2.5 below |
4.2.3 The two AIModelConfig objects
Doc 1 §6 defines two distinct objects with confusingly similar names. Both must be emitted, and their created payloads must be identical.
Top-level .AiModelConfig (catalog reference, Doc 1 §6.A):
| Field | Source | |---|---| | AIModelConfigID | From model-catalog.md if spec section 1 names a catalog entry; from spec if raw: ID=N, TypeID=M; -999 if unknown | | Name | From model-catalog.md "Display name"; ` if raw override | | Description | From model-catalog.md "Notes" if available; null otherwise | | BaseUrl | null (matches both production samples) | | AIModelTypeId | Same source rule as AIModelConfigID | | Type | { "AIModelTypeId": , "Name": , "Description": null } — type name is the catalog entry's display name; null if unknown | | created` | The runtime LLM API payload; see §4.2.4 below |
Version-level .ActiveVersionInfo.AIModelConfig (runtime config, Doc 1 §6.B):
| Field | Source | |---|---| | prompts | §4.2.4 below | | created | Identical to .AiModelConfig.created (same object; per §16 quirk, both are required) | | silence_behaviour | §4.2.5 below; omitted entirely if spec sect
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: VoicenterTeam
- Source: VoicenterTeam/claude-marketplace
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.