Skip to content

Add /gen-survey skill for SurveyJS JSON authoring#67

Open
countercheck wants to merge 1 commit into
mainfrom
chore/gen-survey-skill
Open

Add /gen-survey skill for SurveyJS JSON authoring#67
countercheck wants to merge 1 commit into
mainfrom
chore/gen-survey-skill

Conversation

@countercheck

Copy link
Copy Markdown
Owner

Summary

  • New project-level Claude Code skill at .claude/skills/gen-survey/SKILL.md. Invoked as /gen-survey <input>; turns a question list (loose markdown or structured YAML/JSON) into a gate-valid SurveyJS JSON file written to /tmp/<slug>.json.
  • Grounded in patterns/ — the skill body directs the model to copy the nearest pattern's shape rather than invent structure. Restricted to the gate-allowed type surface from patterns/README.md; refuses anything else.
  • Stops to ask on the methodological judgments CLAUDE.md / the design doc forbid defaulting: free-text PII downgrade (default stays high, downgrade requires a user-supplied rationale), visibleIf branching, choice value keys, matrix row/col ids, paneldynamic template. Never writes parent_question_id / parent_question_rationale.
  • Pre-write validation covers unique names, unique choice values, matrix row ids, PII annotation presence, dangling visibleIf refs, and forbidden parent-question fields.

Scope

Authoring tool only. Does not publish, hash, or load into the API — the user runs the publish gate separately. No runtime, API, dbt, or schema changes.

Test plan

  • In a fresh Claude Code session in this repo, confirm /gen-survey appears in the skill list.
  • Run /gen-survey against a loose markdown question list and verify it stops to ask on PII downgrade, choice values, and any branching cues.
  • Run /gen-survey against a structured YAML/JSON input and verify 1:1 translation without extra prompts.
  • Verify the emitted JSON passes validate_definition (publish gate).
  • Verify the skill refuses a request for a non-gate type (e.g. imagepicker) with a clear explanation and an alternative.

Notes

Portability caveat is documented at the bottom of SKILL.md: the gate-specific sections (narrow type surface, pii_risk routing, no parent_question_id) are survey-engine invariants and would need extraction if this is ever lifted to a generic SurveyJS skill for other repos.

🤖 Generated with Claude Code

Project-level Claude Code skill that turns a question list into a
gate-valid SurveyJS JSON file. Grounded in patterns/ rather than
inventing structure; stops to ask on the methodological judgments the
design doc forbids defaulting (PII downgrade, branching, choice values,
matrix row ids). Refuses types outside the gate-allowed surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Claude Code skill (/gen-survey) intended to help authors generate publish-gate-valid SurveyJS JSON from either loose question lists or structured YAML/JSON, by grounding output in the repo’s patterns/ fixtures and explicitly avoiding methodological “silent defaults” (PII downgrades, branching, etc.).

Changes:

  • Introduces a new project-level skill definition at .claude/skills/gen-survey/SKILL.md.
  • Documents an authoring workflow that copies gate-valid shapes from patterns/, prompts on key methodological judgments, and performs local pre-write validation.
  • Defines a gate-allowed question type surface and refusal behavior for unsupported types.


1. **Read input.** Resolve `<arg>` per above.
2. **Read the relevant pattern.** Pick the closest match from [patterns/](../../../patterns/) for each question type you'll emit, and copy its element shape. The pattern files are the source of truth for field names, choice format, and `pii_risk` handling.
3. **Walk the question list.** For each item, build a SurveyJS element. Generate `name` as a stable kebab/snake-case slug from the prompt (e.g. "How many years…" → `years_gaming`). For choices, `value` is a stable key, `text` is the human label.
Comment on lines +81 to +83
| `matrix` | grid of single-selects | rows + columns required |
| `matrixdropdown` | grid of typed cells | option-typed cells only at top level |
| `paneldynamic` | repeating group | template elements per occurrence |
Comment on lines +93 to +99
- Every element has a unique `name` within the survey.
- Every `choices` entry on single/multi-select has a unique `value`.
- Every `matrix`/`matrixdropdown` has a non-empty `rows` and `columns` with unique ids.
- Every `text`/`comment` (free text, no numeric/date `inputType`) carries `pii_risk`. If `"low"`, it also carries `pii_risk_rationale`.
- No element references `parent_question_id` or `parent_question_rationale`.
- No `visibleIf` references a `name` that doesn't exist in the survey.
- The whole thing parses as JSON.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants