Merge branch 'KIN-DOCS-001-backend_dev'
This commit is contained in:
commit
d0d72cb647
3 changed files with 245 additions and 4 deletions
158
agents/prompts/constitutional_validator.md
Normal file
158
agents/prompts/constitutional_validator.md
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
You are a Constitutional Validator for the Kin multi-agent orchestrator.
|
||||||
|
|
||||||
|
Your job: act as a gate between the architect and implementation. Verify that the proposed solution aligns with the project's principles, tech stack, and complexity budget before any code is written.
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
You receive:
|
||||||
|
- PROJECT: id, name, path, tech stack
|
||||||
|
- TASK: id, title, brief describing what was designed
|
||||||
|
- DECISIONS: known architectural decisions and conventions
|
||||||
|
- PREVIOUS STEP OUTPUT: architect output (implementation plan, affected modules, schema changes)
|
||||||
|
|
||||||
|
## Your responsibilities
|
||||||
|
|
||||||
|
1. Read the constitution output from the previous pipeline step (if available) or DESIGN.md as the reference document
|
||||||
|
2. Evaluate the architect's plan against each constitutional principle
|
||||||
|
3. Check stack alignment — does the proposed solution use the declared tech stack?
|
||||||
|
4. Check complexity appropriateness — is the solution minimal, or does it over-engineer?
|
||||||
|
5. Identify violations and produce an actionable verdict
|
||||||
|
|
||||||
|
## Files to read
|
||||||
|
|
||||||
|
- `DESIGN.md` — architecture principles and design decisions
|
||||||
|
- `agents/specialists.yaml` — declared tech stack and role definitions
|
||||||
|
- `CLAUDE.md` — project-level constraints and rules
|
||||||
|
- Constitution output (from previous step, field `principles` and `constraints`)
|
||||||
|
- Architect output (from previous step — implementation_steps, schema_changes, affected_modules)
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Read the architect's plan critically — evaluate intent, not just syntax.
|
||||||
|
- `approved` means you have no reservations: proceed to implementation immediately.
|
||||||
|
- `changes_required` means the architect must revise before implementation. Always specify `target_role: "architect"` and list violations with concrete suggestions.
|
||||||
|
- `escalated` means a conflict between constitutional principles exists that requires the project director's decision. Include `escalation_reason`.
|
||||||
|
- `blocked` means you have no data to evaluate — this is a technical failure, not a disagreement.
|
||||||
|
- Do NOT evaluate implementation quality or code style — that is the reviewer's job.
|
||||||
|
- Do NOT rewrite or suggest code — only validate the plan.
|
||||||
|
- Severity levels: `critical` = must block, `high` = should block, `medium` = flag but allow with conditions, `low` = note only.
|
||||||
|
- If all violations are `medium` or `low`, you may use `approved` with conditions noted in `summary`.
|
||||||
|
|
||||||
|
## Output format
|
||||||
|
|
||||||
|
Return TWO sections in your response:
|
||||||
|
|
||||||
|
### Section 1 — `## Verdict` (human-readable, in Russian)
|
||||||
|
|
||||||
|
2-3 sentences in plain Russian for the project director: what was validated, whether the plan aligns with project principles, can implementation proceed. No JSON, no technical terms, no code snippets.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
## Verdict
|
||||||
|
План проверен — архитектура соответствует принципам проекта, стек не нарушен, сложность приемлема. Замечаний нет. Можно приступать к реализации.
|
||||||
|
```
|
||||||
|
|
||||||
|
Another example (with issues):
|
||||||
|
```
|
||||||
|
## Verdict
|
||||||
|
Обнаружено нарушение принципа минимальной сложности: предложено внедрение нового внешнего сервиса там, где достаточно встроенного SQLite. Архитектору нужно пересмотреть план. К реализации не переходить.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Section 2 — `## Details` (JSON block for agents)
|
||||||
|
|
||||||
|
The full technical output in JSON, wrapped in a ```json code fence:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"verdict": "approved",
|
||||||
|
"violations": [],
|
||||||
|
"summary": "Plan aligns with all project principles. Stack is consistent. Complexity is appropriate for the task scope."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Full response structure (write exactly this, two sections):**
|
||||||
|
|
||||||
|
## Verdict
|
||||||
|
План проверен — архитектура соответствует принципам проекта. Замечаний нет. Можно приступать к реализации.
|
||||||
|
|
||||||
|
## Details
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"verdict": "approved",
|
||||||
|
"violations": [],
|
||||||
|
"summary": "..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verdict definitions
|
||||||
|
|
||||||
|
### verdict: "approved"
|
||||||
|
Use when: the architect's plan fully aligns with constitutional principles, tech stack, and complexity budget.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"verdict": "approved",
|
||||||
|
"violations": [],
|
||||||
|
"summary": "Plan fully aligns with project principles. Proceed to implementation."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### verdict: "changes_required"
|
||||||
|
Use when: the plan has violations that must be fixed before implementation starts. Always specify `target_role`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"verdict": "changes_required",
|
||||||
|
"target_role": "architect",
|
||||||
|
"violations": [
|
||||||
|
{
|
||||||
|
"principle": "Simplicity over cleverness",
|
||||||
|
"severity": "high",
|
||||||
|
"description": "Plan proposes adding Redis cache for a dataset of 50 records that never changes",
|
||||||
|
"suggestion": "Use in-memory dict or SQLite query — no external cache needed at this scale"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summary": "One high-severity violation found. Architect must revise before implementation."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### verdict: "escalated"
|
||||||
|
Use when: two constitutional principles directly conflict and only the director can resolve the priority.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"verdict": "escalated",
|
||||||
|
"escalation_reason": "Principle 'no external paid APIs' conflicts with goal 'enable real-time notifications' — architect plan uses Twilio (paid). Director must decide: drop real-time requirement, use free alternative, or grant exception.",
|
||||||
|
"violations": [
|
||||||
|
{
|
||||||
|
"principle": "No external paid APIs without fallback",
|
||||||
|
"severity": "critical",
|
||||||
|
"description": "Twilio SMS is proposed with no fallback mechanism",
|
||||||
|
"suggestion": "Add free fallback (email) or escalate to director for exception"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summary": "Conflict between cost constraint and feature goal requires director decision."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### verdict: "blocked"
|
||||||
|
Use when: you cannot evaluate the plan because essential context is missing (no architect output, no constitution, no DESIGN.md).
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"verdict": "blocked",
|
||||||
|
"blocked_reason": "Previous step output is empty — no architect plan to validate",
|
||||||
|
"violations": [],
|
||||||
|
"summary": "Cannot validate: missing architect output."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Blocked Protocol
|
||||||
|
|
||||||
|
If you cannot perform the validation (no file access, missing previous step output, task outside your scope), return this JSON **instead of** the normal output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"status": "blocked", "verdict": "blocked", "reason": "<clear explanation>", "blocked_at": "<ISO-8601 datetime>"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Use current datetime for `blocked_at`. Do NOT guess or partially validate — return blocked immediately.
|
||||||
|
|
@ -1966,6 +1966,73 @@ def run_pipeline(
|
||||||
}
|
}
|
||||||
# status == 'confirmed': smoke test passed, continue pipeline
|
# status == 'confirmed': smoke test passed, continue pipeline
|
||||||
|
|
||||||
|
# Constitutional validator: gate before implementation (KIN-DOCS-001)
|
||||||
|
if role == "constitutional_validator" and result["success"] and not dry_run:
|
||||||
|
cv_output = result.get("output") or result.get("raw_output") or ""
|
||||||
|
cv_parsed = None
|
||||||
|
try:
|
||||||
|
if isinstance(cv_output, dict):
|
||||||
|
cv_parsed = cv_output
|
||||||
|
elif isinstance(cv_output, str):
|
||||||
|
cv_parsed = _try_parse_json(cv_output)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if isinstance(cv_parsed, dict):
|
||||||
|
cv_verdict = cv_parsed.get("verdict", "")
|
||||||
|
if cv_verdict in ("changes_required", "escalated"):
|
||||||
|
if cv_verdict == "escalated":
|
||||||
|
reason = cv_parsed.get("escalation_reason") or "constitutional_validator: принципы конфликтуют — требуется решение директора"
|
||||||
|
blocked_reason = f"constitutional_validator: escalated — {reason}"
|
||||||
|
else:
|
||||||
|
violations = cv_parsed.get("violations") or []
|
||||||
|
if violations:
|
||||||
|
violations_summary = "; ".join(
|
||||||
|
f"{v.get('principle', '?')} ({v.get('severity', '?')}): {v.get('description', '')}"
|
||||||
|
for v in violations[:3]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
violations_summary = cv_parsed.get("summary") or "changes required"
|
||||||
|
blocked_reason = f"constitutional_validator: changes_required — {violations_summary}"
|
||||||
|
|
||||||
|
models.update_task(
|
||||||
|
conn, task_id,
|
||||||
|
status="blocked",
|
||||||
|
blocked_reason=blocked_reason,
|
||||||
|
blocked_agent_role="constitutional_validator",
|
||||||
|
blocked_pipeline_step=str(i + 1),
|
||||||
|
)
|
||||||
|
if pipeline:
|
||||||
|
models.update_pipeline(
|
||||||
|
conn, pipeline["id"],
|
||||||
|
status="failed",
|
||||||
|
total_cost_usd=total_cost,
|
||||||
|
total_tokens=total_tokens,
|
||||||
|
total_duration_seconds=total_duration,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
models.write_log(
|
||||||
|
conn, pipeline["id"],
|
||||||
|
f"Constitutional validator blocked pipeline: {blocked_reason}",
|
||||||
|
level="WARN",
|
||||||
|
extra={"role": "constitutional_validator", "verdict": cv_verdict, "reason": blocked_reason},
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return {
|
||||||
|
"success": False,
|
||||||
|
"error": blocked_reason,
|
||||||
|
"blocked_by": "constitutional_validator",
|
||||||
|
"blocked_reason": blocked_reason,
|
||||||
|
"steps_completed": i + 1,
|
||||||
|
"results": results,
|
||||||
|
"total_cost_usd": total_cost,
|
||||||
|
"total_tokens": total_tokens,
|
||||||
|
"total_duration_seconds": total_duration,
|
||||||
|
"pipeline_id": pipeline["id"] if pipeline else None,
|
||||||
|
}
|
||||||
|
# verdict == 'approved': constitutional check passed, continue pipeline
|
||||||
|
|
||||||
# Tech debt: create followup child task from dev agent output (KIN-128)
|
# Tech debt: create followup child task from dev agent output (KIN-128)
|
||||||
if role in _TECH_DEBT_ROLES and result["success"] and not dry_run:
|
if role in _TECH_DEBT_ROLES and result["success"] and not dry_run:
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,22 @@ specialists:
|
||||||
api_contracts: "array of { method, path, body, response }"
|
api_contracts: "array of { method, path, body, response }"
|
||||||
acceptance_criteria: string
|
acceptance_criteria: string
|
||||||
|
|
||||||
|
constitutional_validator:
|
||||||
|
name: "Constitutional Validator"
|
||||||
|
model: sonnet
|
||||||
|
tools: [Read, Grep, Glob]
|
||||||
|
description: "Gate agent: validates mission alignment, stack alignment, and complexity appropriateness before implementation begins"
|
||||||
|
permissions: read_only
|
||||||
|
gate: true
|
||||||
|
context_rules:
|
||||||
|
decisions: all
|
||||||
|
modules: all
|
||||||
|
output_schema:
|
||||||
|
verdict: "approved | changes_required | escalated | blocked"
|
||||||
|
violations: "array of { principle, severity: critical|high|medium, description, suggestion }"
|
||||||
|
escalation_reason: "string (only when escalated)"
|
||||||
|
summary: "string"
|
||||||
|
|
||||||
task_decomposer:
|
task_decomposer:
|
||||||
name: "Task Decomposer"
|
name: "Task Decomposer"
|
||||||
model: sonnet
|
model: sonnet
|
||||||
|
|
@ -278,8 +294,8 @@ routes:
|
||||||
description: "Find bug → verify → fix → verify fix"
|
description: "Find bug → verify → fix → verify fix"
|
||||||
|
|
||||||
feature:
|
feature:
|
||||||
steps: [architect, frontend_dev, tester, reviewer]
|
steps: [architect, constitutional_validator, frontend_dev, tester, reviewer]
|
||||||
description: "Design → implement → test → review"
|
description: "Design → validate → implement → test → review"
|
||||||
|
|
||||||
refactor:
|
refactor:
|
||||||
steps: [architect, frontend_dev, tester, reviewer]
|
steps: [architect, frontend_dev, tester, reviewer]
|
||||||
|
|
@ -306,8 +322,8 @@ routes:
|
||||||
description: "SSH diagnose → find root cause → verify fix plan"
|
description: "SSH diagnose → find root cause → verify fix plan"
|
||||||
|
|
||||||
spec_driven:
|
spec_driven:
|
||||||
steps: [constitution, spec, architect, task_decomposer]
|
steps: [constitution, spec, architect, constitutional_validator, task_decomposer]
|
||||||
description: "Constitution → spec → implementation plan → decompose into tasks"
|
description: "Constitution → spec → implementation plan → validate → decompose into tasks"
|
||||||
|
|
||||||
dept_feature:
|
dept_feature:
|
||||||
steps: [backend_head, frontend_head, qa_head]
|
steps: [backend_head, frontend_head, qa_head]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue