PR Checklist
Every pull request to FrootAI is validated by CI automation. Use this checklist before submitting to ensure a smooth review.
Automated CI Checksโ
These checks run automatically on every PR:
| Pipeline | What It Validates |
|---|---|
validate-primitives.yml | Schema, naming, frontmatter, secrets scan |
validate-plays.yml | Solution play structure (4-kit model) |
auto-generate.yml | Regenerates marketplace.json on merge |
Pre-Submit Checklistโ
โ File Namingโ
# Run validation
npm run validate:primitives
- All files follow lowercase-hyphen naming (no underscores, no camelCase)
- Agents:
fai-{name}.agent.md - Instructions:
{name}.instructions.md - Skills:
{name}/SKILL.md(folder name matchesnamein frontmatter) - Hooks:
{name}/hooks.json - Plugins:
{name}/plugin.json(folder name matchesnamein manifest)
โ Frontmatter Requirementsโ
Every primitive type has required YAML frontmatter fields:
| Primitive | Required Fields |
|---|---|
.agent.md | description (10+ chars) |
.instructions.md | description (10+ chars), applyTo (glob pattern) |
SKILL.md | name (must match folder), description (10โ1024 chars) |
hooks.json | version: 1, at least one valid event |
plugin.json | name, description, version (semver), author.name, license |
fai-manifest.json | play, version, context.knowledge[], context.waf[], primitives |
โ Schema Validationโ
# Validate all primitives against JSON schemas
npm run validate:primitives
# Verify individual JSON files parse correctly
node -e "require('./path/to/file.json'); console.log('โ
OK')"
-
npm run validate:primitivespasses with 0 errors - All JSON files parse without syntax errors
-
fai-manifest.jsonconforms toschemas/fai-manifest.schema.json
โ Securityโ
- No secrets, API keys, or connection strings in any file
- Azure services use Managed Identity (not API keys)
- Secrets stored in Azure Key Vault (referenced, not inlined)
- MCP config uses
inputsfor secrets,envFilefor.env, never hardcoded
danger
CI will block any PR that contains detected secrets. The frootai-secrets-scanner hook runs automatically.
โ WAF Alignmentโ
-
wafarray values use valid pillar names from the 6-pillar set - Valid values:
security,reliability,cost-optimization,operational-excellence,performance-efficiency,responsible-ai - At least one WAF pillar declared for agents and plays
โ Solution Play Structure (if applicable)โ
If your PR adds or modifies a solution play:
-
fai-manifest.jsonexists at play root withcontext+primitives+guardrails - Play folder follows
NN-kebab-casenaming - DevKit (
.github/) contains at minimum:copilot-instructions.md+ one agent - TuneKit (
config/) containsopenai.jsonandguardrails.json -
copilot-instructions.mdis < 150 lines (knowledge only, not behavioral override) - Builder/reviewer/tuner agent triad exists in
.github/agents/
โ Plugin (if applicable)โ
If your PR adds or modifies a plugin:
-
plugin.jsonexists with validname,description,version,author,license -
README.mdexists alongsideplugin.json - Run
npm run generate:marketplaceto regeneratemarketplace.json
โ Content Qualityโ
- No placeholder text (e.g., "TODO", "Lorem ipsum", "Add content here")
- Agent files are 1500+ bytes with real content
- Skill files are 150+ lines with step-by-step procedures
- Code examples are syntactically correct and runnable
Validation Commandsโ
# Full validation suite
npm run validate:primitives # Schema + naming + frontmatter
# Individual JSON validation
node -e "require('./fai-manifest.json')"
node -e "require('./config/openai.json')"
node -e "require('./config/guardrails.json')"
# FAI Engine wiring check
node engine/index.js fai-manifest.json --status
# Regenerate marketplace (after plugin changes)
npm run generate:marketplace
Common Rejection Reasonsโ
| Issue | How to Fix |
|---|---|
validate:primitives fails | Check error output โ usually missing frontmatter field |
| Secrets detected | Remove API keys, use inputs in MCP config |
| Invalid WAF pillar | Use exact values: security, reliability, etc. |
| Skill name mismatch | Ensure name in SKILL.md matches parent folder name |
| copilot-instructions.md too long | Keep under 150 lines โ knowledge only, no behavioral overrides |
| Plugin not in marketplace | Run npm run generate:marketplace after creating plugin.json |
After Mergeโ
CI automatically:
- Regenerates
marketplace.jsonfrom allplugins/*/plugin.json - Updates website data feeds
- Validates the merged state passes all checks
Next Stepsโ
- Naming Conventions โ detailed file naming rules
- How to Contribute โ the full contribution workflow