Thank you for your interest in contributing to the Human Voice plugin.
- main: Stable release branch. Do not commit directly to main.
- develop: Active development branch. All work starts here.
All pull requests target develop. When develop is stable and tested, it is merged into main as a release.
- Fork the repository
- Clone your fork locally
- Create a feature branch from
develop:git checkout -b feature/your-feature develop - Run the setup script:
bash scripts/setup.sh - Test locally:
claude --plugin-dir .
# Run scoring tests
python3 -m pytest scoring/tests/ -v
# Test the plugin in current directory
claude --plugin-dir /path/to/human-voice
# Validate character restrictions
node skills/human-voice/scripts/validate-character-restrictions.js docs/
# Test specific commands
/human-voice:voice-review test-content/
/human-voice:voice-fix test-content/ --dry-run| Directory | Purpose |
|---|---|
skills/human-voice/ |
Core skill and detection patterns |
skills/voice/ |
Voice elicitation interview skill |
commands/ |
Slash command definitions |
agents/ |
Agent configurations (interview, synthesizer, reviewer) |
hooks/ |
Plugin hooks (SessionStart observer) |
bin/ |
CLI tools (voice-session, voice-scoring, etc.) |
question-bank/ |
Interview modules, schemas, scoring config |
scoring/src/voice_scoring/ |
Self-report scoring engine |
nlp/src/voice_nlp/ |
NLP stylometric analysis pipeline |
lib/ |
Core library (session, branching, quality, config) |
docs/ |
Documentation (Diataxis framework) |
.github/agents/ |
GitHub Copilot custom agents |
.github/workflows/ |
CI workflows |
The scoring pipeline is at scoring/src/voice_scoring/. Key files:
cli.py: CLI entry point, metadata discovery, question bank loadingself_report.py: Per-dimension subscale scoring, scoring_map resolutionsemantic_differential.py: SD normalization and dimension mappingquality_checks.py: Post-hoc satisficing detectioncalibration.py: Self-report vs NLP observed score calibrationprofile_builder.py: Tier-weighted profile merging
When modifying scoring_maps in question bank modules:
- Every scoring_map entry must include a key matching the target dimension name in
dimension-item-mapping.json - Use exact match or underscore-separated prefix (e.g.,
formality_baselinematches dimensionformality) - Run
python3 -m pytest scoring/tests/ -vafter any scoring_map change
The NLP pipeline requires spacy and the en_core_web_sm model. Install via scripts/setup.sh or manually:
pip install spacy
python3 -m spacy download en_core_web_smQuestion bank modules are JSON files in question-bank/modules/. Each question needs:
question_id: Unique ID (e.g.,M03-Q04)type: One oflikert,forced_choice,select,scenario,projective,calibration,open_ended,writing_sample,process_narrationscoring.scoring_map: Required for all non-open-ended types if the question is mapped to a dimension indimension-item-mapping.json
See docs/guides/adding-questions.md for the full guide.
- Identify the pattern tier (character, language, structural, voice)
- Add documentation to appropriate
references/*.mdfile - Update
SKILL.mdif the pattern affects the workflow - Add before/after examples to
examples/before-after.md
Commands are markdown files in commands/ with YAML frontmatter:
---
name: command-name
description: What the command does
allowed-tools:
- Read
- Write
- Glob
---The scoring engine has a dedicated test suite under scoring/tests/. Run all tests with:
python3 -m pytest scoring/tests/ -vIndividual test modules cover calibration, profile building and self-report scoring. The conftest.py file provides shared fixtures for session data and question bank metadata.
Question bank modules are JSON files in question-bank/modules/ following the naming pattern Mxx-<slug>.json (e.g., M02-voice-personality.json). Each file contains an array of question definition objects.
Requirements for question definitions:
- Every question must have a unique
question_idmatching the patternMxx-Qyy - Questions that contribute to dimension scoring must include a
scoring_mapobject mapping response values to numeric scores - Dimension keys in
scoring_mapmust match keys defined inquestion-bank/scoring/dimension-item-mapping.json - See the Adding Questions guide for step-by-step instructions
The NLP pipeline depends on spaCy and the en_core_web_sm language model. Install dependencies:
pip install spacy
python3 -m spacy download en_core_web_smRun NLP analysis on a session:
voice-nlp analyze-session --session-dir ${CLAUDE_PLUGIN_DATA}/sessions/{id}/Analysis output files are written as *.analysis.json alongside the source writing samples.
The scoring pipeline follows a linear five-stage flow implemented in scoring/src/voice_scoring/cli.py:
run_quality_checksvalidates response data for satisficing patternsnormalize_semantic_differentialsconverts raw bipolar ratings to dimension scoresscore_self_reportcomputes per-dimension self-report scores using weighted item meanscalibratecompares self-report scores against observed NLP scores (when available)build_profilemerges all scores into the final voice profile
Each stage is a pure function that accepts data and returns results. The CLI orchestrates the pipeline and handles file I/O.
- Create a feature branch from
develop(not main) - Make focused, atomic commits
- Run tests:
python3 -m pytest scoring/tests/ -v - Update
CHANGELOG.mdunder[Unreleased] - Ensure your changes work without optional dependencies (Subcog)
- Submit a pull request targeting
develop
Use conventional commit format:
feat:New featuresfix:Bug fixesdocs:Documentation changesrefactor:Code refactoringtest:Test additions or changes
Add your changes to CHANGELOG.md:
## [Unreleased]
### Added
- **[Component]**: Description of new feature
### Fixed
- **[Component]**: Description of bug fixBe respectful and constructive. Focus on the work, not the person.
Open an issue for questions or discussion.