import from local vendored copy (2026-05-06)
Some checks failed
CI / validate (push) Failing after 0s
Some checks failed
CI / validate (push) Failing after 0s
This commit is contained in:
commit
af4e0faeef
5
.github/workflows/ci.yml
vendored
Normal file
5
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
validate:
|
||||
uses: Molecule-AI/molecule-ci/.github/workflows/validate-plugin.yml@main
|
||||
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# Credentials — never commit. Use .env.example as the template.
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.sample
|
||||
|
||||
# Private keys + certs
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
*.p12
|
||||
*.pfx
|
||||
|
||||
# Secret directories
|
||||
.secrets/
|
||||
|
||||
# Workspace auth tokens
|
||||
.auth-token
|
||||
.auth_token
|
||||
1
.molecule-ci/scripts/requirements.txt
Normal file
1
.molecule-ci/scripts/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
pyyaml>=6.0
|
||||
52
.molecule-ci/scripts/validate-plugin.py
Normal file
52
.molecule-ci/scripts/validate-plugin.py
Normal file
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate a Molecule AI plugin repo."""
|
||||
import os, sys, yaml
|
||||
|
||||
errors = []
|
||||
|
||||
# 1. plugin.yaml exists
|
||||
if not os.path.isfile("plugin.yaml"):
|
||||
print("::error::plugin.yaml not found at repo root")
|
||||
sys.exit(1)
|
||||
|
||||
with open("plugin.yaml") as f:
|
||||
plugin = yaml.safe_load(f)
|
||||
|
||||
# 2. Required fields
|
||||
for field in ["name", "version", "description"]:
|
||||
if not plugin.get(field):
|
||||
errors.append(f"Missing required field: {field}")
|
||||
|
||||
# 3. Version format
|
||||
v = str(plugin.get("version", ""))
|
||||
if v and not all(c in "0123456789." for c in v):
|
||||
errors.append(f"Invalid version format: {v}")
|
||||
|
||||
# 4. Runtimes type
|
||||
runtimes = plugin.get("runtimes")
|
||||
if runtimes is not None and not isinstance(runtimes, list):
|
||||
errors.append(f"runtimes must be a list, got {type(runtimes).__name__}")
|
||||
|
||||
# 5. Has content
|
||||
content_paths = ["SKILL.md", "hooks", "skills", "rules"]
|
||||
found = [p for p in content_paths if os.path.exists(p)]
|
||||
if not found:
|
||||
errors.append("Plugin must contain at least one of: SKILL.md, hooks/, skills/, rules/")
|
||||
|
||||
# 6. SKILL.md formatting check
|
||||
if os.path.isfile("SKILL.md"):
|
||||
with open("SKILL.md") as f:
|
||||
first_line = f.readline().strip()
|
||||
if first_line and not first_line.startswith("#"):
|
||||
print("::warning::SKILL.md should start with a markdown heading (e.g., # Plugin Name)")
|
||||
|
||||
if errors:
|
||||
for e in errors:
|
||||
print(f"::error::{e}")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"✓ plugin.yaml valid: {plugin['name']} v{plugin['version']}")
|
||||
if found:
|
||||
print(f" Content: {', '.join(found)}")
|
||||
if runtimes:
|
||||
print(f" Runtimes: {', '.join(runtimes)}")
|
||||
155
CLAUDE.md
Normal file
155
CLAUDE.md
Normal file
@ -0,0 +1,155 @@
|
||||
# molecule-dev — Molecule AI Codebase Conventions Plugin
|
||||
|
||||
`molecule-dev` is a **platform conventions plugin** that captures hard-won lessons from Molecule AI's production codebase. Rather than repeating mistakes, every agent working on the platform benefits from rules derived from real bugs and production failures.
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Runtime:** `claude_code`, `deepagents`, `hermes`
|
||||
|
||||
---
|
||||
|
||||
## Repository Layout
|
||||
|
||||
```
|
||||
molecule-dev/
|
||||
├── plugin.yaml — Plugin manifest (runtimes, rules, skills)
|
||||
├── rules/
|
||||
│ └── codebase-conventions.md — Platform-wide conventions (Canvas/Go/Python)
|
||||
├── skills/
|
||||
│ └── review-loop/SKILL.md — Multi-round review orchestration workflow
|
||||
└── adapters/ — Harness adaptors (thin wrappers)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conventions Summary
|
||||
|
||||
See `rules/codebase-conventions.md` for the full ruleset. Key highlights:
|
||||
|
||||
### Canvas (Next.js 15 App Router)
|
||||
|
||||
- **`'use client'` is non-negotiable** — every `.tsx` file using React hooks or event handlers must declare it as the very first line.
|
||||
- **Zustand selectors**: never call a function returning a new object inside a selector — use `useMemo` instead.
|
||||
- **Dark zinc theme** — backgrounds `zinc-900`/`zinc-950`, text `zinc-300`/`zinc-400`. Never use `#ffffff` or light colors.
|
||||
- **Verify API response shapes** with `curl` or Go handler inspection — don't assume.
|
||||
|
||||
### Platform (Go)
|
||||
|
||||
- **SQL safety**: always parameterized queries (`$1`, `$2`), always `ExecContext`/`QueryContext`.
|
||||
- **Access control**: every workspace endpoint must verify ownership; new A2A proxy paths must pass `CanCommunicate()`.
|
||||
- **Container lifecycle**: use `ContainerRemove(Force: true)` — never `ContainerStop` + `ContainerRemove` separately.
|
||||
|
||||
### Workspace Runtime (Python)
|
||||
|
||||
- **Error sanitization**: use `sanitize_agent_error()` — never emit raw exception messages or subprocess stderr to the user.
|
||||
- **System prompt hot-reload**: always use `encoding="utf-8", errors="replace"` when reading prompt files.
|
||||
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js >= 18 (for markdownlint)
|
||||
- Python 3.11+ (for `adapters/`)
|
||||
- `gh` CLI authenticated
|
||||
- Write access to `Molecule-AI/molecule-ai-plugin-molecule-dev`
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Molecule-AI/molecule-ai-plugin-molecule-dev.git
|
||||
cd molecule-ai-plugin-molecule-dev
|
||||
|
||||
# Install markdownlint CLI for pre-commit linting
|
||||
npm install -g markdownlint-cli
|
||||
|
||||
# Validate the plugin structure
|
||||
gh workflow run validate-plugin.yml --ref main
|
||||
```
|
||||
|
||||
### Adapter Dev
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv && source .venv/bin/activate
|
||||
pip install plugins_registry
|
||||
|
||||
python -c "from adapters.claude_code import Adaptor; print('OK')"
|
||||
```
|
||||
|
||||
### Pre-Commit Checklist
|
||||
|
||||
```bash
|
||||
# Markdown lint
|
||||
npx markdownlint '**/*.md' --ignore node_modules
|
||||
|
||||
# YAML validation
|
||||
python3 -c "import yaml; yaml.safe_load(open('plugin.yaml'))"
|
||||
|
||||
# No pycache committed
|
||||
find . -name '__pycache__' -o -name '*.pyc' | grep -v .gitignore && exit 1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test Commands
|
||||
|
||||
There are no unit tests in this plugin — it is a configuration-only package. Validation is done by the shared `validate-plugin.yml` workflow (see CI).
|
||||
|
||||
To run validation locally:
|
||||
```bash
|
||||
gh workflow run validate-plugin.yml --ref main
|
||||
```
|
||||
|
||||
To validate `plugin.yaml` structure:
|
||||
```bash
|
||||
python3 -c "
|
||||
import yaml, os
|
||||
with open('plugin.yaml') as f:
|
||||
data = yaml.safe_load(f)
|
||||
for key in ['rules', 'skills']:
|
||||
for ref in data.get(key, []):
|
||||
path = ref if ref.endswith('.md') else ref + '.md'
|
||||
print(f'[OK] {path}' if os.path.exists(path) else f'[MISSING] {path}')
|
||||
"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Release Process
|
||||
|
||||
1. **Review changes** — `git log origin/main..HEAD --oneline`
|
||||
2. **Validate** — run `npx markdownlint` on all `.md` files
|
||||
3. **Bump version** in `plugin.yaml`
|
||||
4. **Commit** — `chore: bump version to X.Y.Z`
|
||||
5. **Tag** — `git tag -a vX.Y.Z -m "Release vX.Y.Z"` and push
|
||||
6. **Create GitHub Release** with a changelog section
|
||||
7. **Verify CI green** on the release commit
|
||||
|
||||
---
|
||||
|
||||
## Key Contacts
|
||||
|
||||
| Role | Owner |
|
||||
|------|-------|
|
||||
| Platform architecture (Go/Canvas) | Molecule AI Engineering |
|
||||
| Workspace runtime (Python) | Molecule AI Engineering |
|
||||
| Plugin maintenance | Molecule AI Engineering |
|
||||
|
||||
For questions, bugs, or suggestions, open an issue in this repo or reach out via the Molecule AI internal channels.
|
||||
|
||||
---
|
||||
|
||||
## Adding a New Convention
|
||||
|
||||
1. Create `rules/<rule-name>.md` describing the convention.
|
||||
2. Add it to `rules:` in `plugin.yaml` (and add `rules/` section if not present).
|
||||
3. If it affects canvas work, include a concrete code example (BAD / GOOD pattern).
|
||||
4. Run markdownlint validation before committing.
|
||||
|
||||
---
|
||||
|
||||
## Adding a New Skill
|
||||
|
||||
1. Create `skills/<skill-name>/SKILL.md` with YAML frontmatter (`name`, `description`).
|
||||
2. Add it to `skills:` in `plugin.yaml`.
|
||||
3. Skills are the canonical workflow surface — prefer skills over commands.
|
||||
19
README.md
Normal file
19
README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# molecule-dev
|
||||
|
||||
Molecule AI plugin. Install via the Molecule AI platform plugin system.
|
||||
|
||||
## Usage
|
||||
|
||||
### In org template (org.yaml)
|
||||
```yaml
|
||||
plugins:
|
||||
- molecule-dev
|
||||
```
|
||||
|
||||
### From URL (community install)
|
||||
```
|
||||
github://Molecule-AI/molecule-ai-plugin-molecule-dev
|
||||
```
|
||||
|
||||
## License
|
||||
Business Source License 1.1 — © Molecule AI.
|
||||
2
adapters/claude_code.py
Normal file
2
adapters/claude_code.py
Normal file
@ -0,0 +1,2 @@
|
||||
"""Claude Code adaptor — uses the generic rule+skill installer."""
|
||||
from plugins_registry.builtins import AgentskillsAdaptor as Adaptor # noqa: F401
|
||||
2
adapters/deepagents.py
Normal file
2
adapters/deepagents.py
Normal file
@ -0,0 +1,2 @@
|
||||
"""DeepAgents adaptor — uses the generic rule+skill installer."""
|
||||
from plugins_registry.builtins import AgentskillsAdaptor as Adaptor # noqa: F401
|
||||
97
known-issues.md
Normal file
97
known-issues.md
Normal file
@ -0,0 +1,97 @@
|
||||
# Known Issues
|
||||
|
||||
Active and recently resolved issues for `molecule-dev`.
|
||||
|
||||
---
|
||||
|
||||
## Active Issues
|
||||
|
||||
*(None currently open. This section is updated when issues are filed.)*
|
||||
|
||||
---
|
||||
|
||||
## Recently Resolved
|
||||
|
||||
### [RESOLVED] plugin.yaml Merge Conflict Residue
|
||||
|
||||
**Severity:** P2
|
||||
**Resolved in:** v1.0.0
|
||||
|
||||
**Symptoms:** `plugin.yaml` contained residual merge conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) that caused YAML parsing to fail. The `runtimes:` section listed `claude_code`, `deepagents` in the main branch while the working copy attempted to add `hermes`.
|
||||
|
||||
**Cause:** A `git stash` operation was used to temporarily discard local changes; on `git stash pop`, the conflicted state was re-applied and committed without conflict resolution.
|
||||
|
||||
**Fix:** Resolved by overwriting `plugin.yaml` with clean, conflict-free content. The file now has 3 runtimes declared and the `rules:` section populated.
|
||||
|
||||
**Prevention:** Never `git add` a file containing conflict markers. Use `git add <file>` only after `<<<<<<<` markers are fully removed, or use `git mergetool`.
|
||||
|
||||
---
|
||||
|
||||
## Known Gotchas
|
||||
|
||||
These are not bugs but behaviors that may surprise contributors:
|
||||
|
||||
### `rules/` section missing from plugin.yaml
|
||||
|
||||
**Symptoms:** Adding a new rule file and referencing it in `plugin.yaml` may silently fail if the `rules:` key is absent.
|
||||
|
||||
**Workaround:** Verify `plugin.yaml` contains the top-level `rules:` key before adding rule references. If absent, add it:
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- rules/codebase-conventions.md
|
||||
- rules/<new-rule>.md
|
||||
```
|
||||
|
||||
### `hermes` runtime requires adapter
|
||||
|
||||
**Symptoms:** Installing the plugin for a `hermes` workspace runtime works, but at runtime the adapter import may fail if `plugins_registry` is not installed in the harness environment.
|
||||
|
||||
**Workaround:** This is expected in isolated dev environments. The harness handles adapter resolution at runtime. See `runbooks/local-dev-setup.md` in the repo for local adapter testing.
|
||||
|
||||
### No local test runner
|
||||
|
||||
**Symptoms:** `npm test` / `python -m pytest` return no results — there are no unit tests in this plugin.
|
||||
|
||||
**Workaround:** This is by design — the plugin is a configuration package. Validation is done by the shared `validate-plugin.yml` workflow in CI. Run it locally via `gh workflow run validate-plugin.yml --ref main`.
|
||||
|
||||
---
|
||||
|
||||
## How to Update This File
|
||||
|
||||
When a new issue is discovered:
|
||||
|
||||
1. Add it under **Active Issues** using the template below.
|
||||
2. Include: symptom, cause (if known), workaround, and fix (if resolved).
|
||||
3. When fixed, move it to **Recently Resolved** and note the fix version.
|
||||
|
||||
### Issue Template
|
||||
|
||||
```markdown
|
||||
## [TICKET-NUMBER] <Short Title>
|
||||
|
||||
**Severity:** P0 / P1 / P2 / P3
|
||||
**Status:** Workaround / Fix in progress / Fix available / Resolved in vX.Y.Z
|
||||
|
||||
**Symptoms:**
|
||||
**Cause:**
|
||||
**Workaround:**
|
||||
**Fix (if available):**
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Severity Definitions
|
||||
|
||||
| Level | Description |
|
||||
|-------|-------------|
|
||||
| P0 | Plugin fails to load entirely; no workaround |
|
||||
| P1 | Core convention violated; can cause production failures |
|
||||
| P2 | Non-core issue; minor impact or workaround available |
|
||||
| P3 | Cosmetic; edge case; informational |
|
||||
|
||||
---
|
||||
|
||||
## Reporting
|
||||
|
||||
Use the Molecule-AI/internal issue tracker. Tag issues with `plugin-molecule-dev`.
|
||||
16
plugin.yaml
Normal file
16
plugin.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
name: molecule-dev
|
||||
version: 1.0.0
|
||||
description: Molecule AI codebase conventions, past bugs, quality standards, and coordination workflows
|
||||
author: Molecule AI
|
||||
tags: [conventions, quality, coordination, codebase]
|
||||
|
||||
runtimes:
|
||||
- claude_code
|
||||
- deepagents
|
||||
- hermes
|
||||
|
||||
rules:
|
||||
- rules/codebase-conventions.md
|
||||
|
||||
skills:
|
||||
- review-loop
|
||||
101
rules/codebase-conventions.md
Normal file
101
rules/codebase-conventions.md
Normal file
@ -0,0 +1,101 @@
|
||||
# Molecule AI Codebase Conventions
|
||||
|
||||
These rules apply to every agent working on the Molecule AI / Molecule AI codebase.
|
||||
They are lessons learned from real bugs — not style preferences. Violating them
|
||||
causes production failures.
|
||||
|
||||
## Canvas (Next.js 15 App Router)
|
||||
|
||||
### `'use client'` — NON-NEGOTIABLE
|
||||
Every `.tsx` file in `canvas/src/` that uses React hooks (`useState`, `useEffect`,
|
||||
`useCallback`, `useMemo`, `useRef`), Zustand stores (`useCanvasStore`, `useSecretsStore`),
|
||||
or event handlers (`onClick`, `onChange`) MUST have `'use client';` as the very first
|
||||
line. Without it, Next.js renders the component as server HTML and React never hydrates
|
||||
it — buttons appear but silently don't respond to clicks.
|
||||
|
||||
**This has caused two reverted PRs.** Always run this check before reporting done:
|
||||
```bash
|
||||
cd canvas
|
||||
for f in $(grep -rl "useState\|useEffect\|useCallback\|useMemo\|useRef\|useStore\|onClick\|onChange" src/ --include="*.tsx"); do
|
||||
head -3 "$f" | grep -q "use client" || echo "MISSING 'use client': $f"
|
||||
done
|
||||
```
|
||||
|
||||
### Zustand Selectors — No New Objects
|
||||
Never call a function that returns a new object inside a Zustand selector:
|
||||
```typescript
|
||||
// BAD — creates new object every render → infinite re-renders
|
||||
const grouped = useSecretsStore((s) => s.getGrouped());
|
||||
|
||||
// GOOD — use useMemo with stable selector values
|
||||
const secrets = useSecretsStore((s) => s.secrets);
|
||||
const grouped = useMemo(() => groupSecrets(secrets), [secrets]);
|
||||
```
|
||||
|
||||
### Dark Zinc Theme — No Light Colors
|
||||
The canvas is dark-themed. Every new component must use:
|
||||
- Backgrounds: `zinc-900`, `zinc-950`, `#18181b`, `#09090b`
|
||||
- Text: `zinc-300`, `zinc-400`, `#d4d4d8`, `#a1a1aa`
|
||||
- Accents: `blue-500`, `blue-600`, `violet-500`
|
||||
- Borders: `zinc-700`, `zinc-800`
|
||||
- Never: `white`, `#ffffff`, `#f5f5f5`, or any light gray
|
||||
|
||||
### API Response Shapes
|
||||
Always verify the actual platform API response format before writing fetch code.
|
||||
Check the Go handler or test with curl — don't assume. Past bug: FE assumed
|
||||
`GET /settings/secrets` returned a flat array but it returns `{ secrets: [...] }`.
|
||||
|
||||
## Platform (Go)
|
||||
|
||||
### SQL Safety
|
||||
- Always use parameterized queries (`$1`, `$2`), never string concatenation
|
||||
- Use `ExecContext` / `QueryContext` with context, never bare `Exec` / `Query`
|
||||
- Always check `rows.Err()` after iterating result sets
|
||||
- JSONB: convert `[]byte` to `string()` and use `::jsonb` cast
|
||||
|
||||
### Access Control
|
||||
- Every endpoint touching workspace data must verify ownership
|
||||
- A2A proxy calls go through `CanCommunicate()` — new proxy paths must respect it
|
||||
- System callers (`webhook:*`, `system:*`, `test:*`) bypass via `isSystemCaller()`
|
||||
|
||||
### Container Lifecycle
|
||||
- Use `ContainerRemove(Force: true)` to stop containers — never `ContainerStop` +
|
||||
`ContainerRemove` separately (restart policy race condition causes zombies)
|
||||
- Always reap zombie processes: `proc.wait()` after `proc.kill()` with a timeout
|
||||
|
||||
## Workspace Runtime (Python)
|
||||
|
||||
### Error Sanitization
|
||||
Never emit raw exception messages or subprocess stderr to the user. Use
|
||||
`sanitize_agent_error()` which exposes the exception class name but strips
|
||||
the message body (which can leak tokens, paths, and stack traces).
|
||||
|
||||
### System Prompt Hot-Reload
|
||||
System prompts are re-read from `/configs/system-prompt.md` on every message.
|
||||
Always use `encoding="utf-8", errors="replace"` when reading prompt files.
|
||||
|
||||
## Inter-Agent Communication
|
||||
|
||||
### Parallel Delegation
|
||||
Use `delegate_task_async` to send tasks to multiple peers simultaneously.
|
||||
Don't serialize what can be parallel — fire all async delegations, then poll
|
||||
`check_task_status` to collect results as they finish.
|
||||
|
||||
### Side Questions
|
||||
Any agent can ask a peer a direct question via `delegate_task` (sync) without
|
||||
going through the lead. FE can ask BE "what's the API response format?" mid-task.
|
||||
Use this to avoid guessing — it's faster than getting it wrong.
|
||||
|
||||
### Proactive Updates
|
||||
Use `send_message_to_user` to push status updates to the CEO's chat at any time.
|
||||
Don't wait until everything is done to report — acknowledge immediately, update
|
||||
during long work, deliver results when complete.
|
||||
|
||||
## Before Reporting Done
|
||||
|
||||
Every agent, regardless of role, must verify their own work before claiming completion:
|
||||
1. Read back every file you changed — confirm it looks right
|
||||
2. Run the relevant test suite (`npm test`, `go test`, `python -m pytest`)
|
||||
3. Run the relevant build (`npm run build`, `go build`)
|
||||
4. Check for framework-specific gotchas (the `'use client'` grep above)
|
||||
5. If you can imagine a way your change could break, test that scenario
|
||||
73
runbooks/local-dev-setup.md
Normal file
73
runbooks/local-dev-setup.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Local Development Setup
|
||||
|
||||
This runbook covers setting up a local development environment for
|
||||
`molecule-dev`.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.11+
|
||||
- `gh` CLI authenticated
|
||||
- Write access to `Molecule-AI/molecule-ai-plugin-molecule-dev`
|
||||
|
||||
---
|
||||
|
||||
## Clone & Bootstrap
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Molecule-AI/molecule-ai-plugin-molecule-dev.git
|
||||
cd molecule-ai-plugin-molecule-dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validating Plugin Structure
|
||||
|
||||
```bash
|
||||
python3 -c "import yaml; yaml.safe_load(open('plugin.yaml'))"
|
||||
echo "plugin.yaml OK"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing the Dev Tools
|
||||
|
||||
Run the test suite to verify all dev tooling is functional:
|
||||
|
||||
```bash
|
||||
python3 -m pytest tests/ -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Writing New Rules or Skills
|
||||
|
||||
1. Create `rules/<rule-name>/RULES.md` or `skills/<skill-name>/SKILL.md`
|
||||
2. Follow the format of existing rules/skills in the repo
|
||||
3. Validate the plugin structure (above)
|
||||
4. Add tests in `tests/` if applicable
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No module named yaml"
|
||||
|
||||
Install PyYAML:
|
||||
```bash
|
||||
pip install pyyaml
|
||||
```
|
||||
|
||||
### Plugin validation fails
|
||||
|
||||
- Ensure `plugin.yaml` has all required fields: `name`, `version`, `description`
|
||||
- Ensure at least one of: `SKILL.md`, `hooks/`, `skills/`, `rules/`
|
||||
- Check the schema with: `python3 -c "import yaml; yaml.safe_load(open('plugin.yaml'))"`
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- `skills/molecule-dev/SKILL.md` — dev tooling documentation
|
||||
- `rules/` — existing rules
|
||||
78
skills/review-loop/SKILL.md
Normal file
78
skills/review-loop/SKILL.md
Normal file
@ -0,0 +1,78 @@
|
||||
---
|
||||
name: review-loop
|
||||
description: "Orchestrate a multi-round implementation + review cycle. Use when coordinating a feature that requires implementation (FE/BE), design review (UIUX), security review, and QA verification. Ensures QA findings get routed back for fixes until clean."
|
||||
---
|
||||
|
||||
# Review Loop
|
||||
|
||||
Orchestrate implementation through multiple rounds until QA reports zero issues.
|
||||
This prevents the one-shot delegation problem where QA finds bugs but nobody
|
||||
fixes them.
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this when you're a coordinator (Dev Lead, PM) assigning a feature that
|
||||
involves multiple specialists.
|
||||
|
||||
## The Loop
|
||||
|
||||
### Round 1: Design + Implementation (parallel where possible)
|
||||
|
||||
1. **Identify all stakeholders** — before delegating, ask: who needs to be involved?
|
||||
- UI work → UIUX Designer reviews interaction design FIRST
|
||||
- Credentials / auth / secrets → Security Auditor reviews
|
||||
- API changes → Backend Engineer + Frontend Engineer coordinate
|
||||
- Everything → QA Engineer is the final gate
|
||||
|
||||
2. **Delegate design review first** (if UI work):
|
||||
```
|
||||
delegate_task_async → UIUX Designer: "Review the interaction design for [feature]"
|
||||
```
|
||||
|
||||
3. **Delegate implementation** (after design, or parallel if non-UI):
|
||||
```
|
||||
delegate_task_async → Frontend Engineer: "Implement [feature] following UIUX spec"
|
||||
delegate_task_async → Backend Engineer: "Add [endpoint]" (if needed)
|
||||
delegate_task_async → Security Auditor: "Review [feature] for [specific concerns]"
|
||||
```
|
||||
|
||||
4. **Delegate QA** (can start in parallel — QA reads existing code while FE works):
|
||||
```
|
||||
delegate_task_async → QA Engineer: "Review [feature], run full test suite, write missing tests, grep for convention violations"
|
||||
```
|
||||
|
||||
5. **Collect all results** via `check_task_status` on each delegation.
|
||||
|
||||
### Round 2: Fix QA Findings (if any issues found)
|
||||
|
||||
If QA reported issues:
|
||||
|
||||
1. **Send QA's findings back to the implementer:**
|
||||
```
|
||||
delegate_task → Frontend Engineer: "QA found these issues in your implementation:
|
||||
[paste QA's specific findings with file:line references]
|
||||
Fix all of them and report back."
|
||||
```
|
||||
|
||||
2. **Re-run QA on the fixes:**
|
||||
```
|
||||
delegate_task → QA Engineer: "FE applied fixes for your findings. Re-verify:
|
||||
[paste the specific issues that were fixed]
|
||||
Run the test suite again. Report if any issues remain."
|
||||
```
|
||||
|
||||
3. **If QA still finds issues → repeat Round 2.**
|
||||
|
||||
### Round 3: Final Sign-off
|
||||
|
||||
When QA reports zero issues:
|
||||
- Compile the full report: what was implemented, what was fixed, test results
|
||||
- Report to PM / CEO with substance, not just "done"
|
||||
|
||||
## Key Rules
|
||||
|
||||
- **Never skip QA.** Even if FE says "I tested it." QA verifies independently.
|
||||
- **Never skip Security for credential-related features.** A secrets panel without security review is a liability.
|
||||
- **QA findings are not optional.** If QA found it, it gets fixed. Period.
|
||||
- **Use parallel delegation.** `delegate_task_async` to all specialists at once, then collect with `check_task_status`. Don't serialize what can be concurrent.
|
||||
- **Ask side questions.** If FE needs to know the API shape, FE should `delegate_task` directly to BE — don't relay through the lead.
|
||||
Loading…
Reference in New Issue
Block a user