From 89e3e997dfa404d27b8c2ad0e0278a0a3cbbc36a Mon Sep 17 00:00:00 2001 From: OpenCode Date: Tue, 7 Jul 2026 10:04:32 +0700 Subject: [PATCH] Add AGENT_TASKS.json for machine-readable safe task routing Closes #220 - AGENT_TASKS.json with 8 task categories (docs, tests, schemas, CI, benchmarks, calibration, external_review, release_safety) - Each category has: safe_paths, review_class, forbidden_zones, required_checks, expected_artifact - Stop conditions and non-negotiables from AGENTS.md - JSON Schema validatable - 7 tests covering structure, categories, fields, review classes --- AGENT_TASKS.json | 95 +++++++++++++++++++++++++++++++++++++++ tests/test_agent_tasks.py | 43 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 AGENT_TASKS.json create mode 100644 tests/test_agent_tasks.py diff --git a/AGENT_TASKS.json b/AGENT_TASKS.json new file mode 100644 index 00000000..68bf853d --- /dev/null +++ b/AGENT_TASKS.json @@ -0,0 +1,95 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "OpenAMP Agent Task Map", + "description": "Machine-readable safe task routing for AI agents.", + "task_categories": [ + { + "category": "docs", + "safe_paths": ["docs/", "README.md", "CONTRIBUTING.md"], + "review_class": "light", + "forbidden_zones": ["docs/safety/", "docs/trust/"], + "required_checks": ["check_doc_links", "check_claims"], + "example_pr_size": "< 200 lines", + "expected_artifact": "documentation change" + }, + { + "category": "tests", + "safe_paths": ["tests/"], + "review_class": "light", + "forbidden_zones": [], + "required_checks": ["pytest"], + "example_pr_size": "< 300 lines", + "expected_artifact": "test file" + }, + { + "category": "schemas", + "safe_paths": ["schemas/"], + "review_class": "normal", + "forbidden_zones": [], + "required_checks": ["validate_schema", "pytest"], + "example_pr_size": "< 100 lines", + "expected_artifact": "schema file" + }, + { + "category": "ci", + "safe_paths": [".github/"], + "review_class": "normal", + "forbidden_zones": [], + "required_checks": ["pytest"], + "example_pr_size": "< 50 lines", + "expected_artifact": "CI workflow change" + }, + { + "category": "benchmarks", + "safe_paths": ["scripts/benchmarks/", "scripts/benchmark_*"], + "review_class": "normal", + "forbidden_zones": ["configs/pipeline.yaml", "configs/phase3.yaml"], + "required_checks": ["pytest", "bench-gate"], + "example_pr_size": "< 200 lines", + "expected_artifact": "benchmark script or card" + }, + { + "category": "calibration", + "safe_paths": ["src/openamp_foundry/calibration/", "configs/recalibration_policy.yaml"], + "review_class": "requires_human_review", + "forbidden_zones": [], + "required_checks": ["pytest"], + "example_pr_size": "< 300 lines", + "expected_artifact": "calibration module change" + }, + { + "category": "external_review", + "safe_paths": ["docs/review/"], + "review_class": "requires_human_review", + "forbidden_zones": [], + "required_checks": ["check_claims"], + "example_pr_size": "< 200 lines", + "expected_artifact": "review document" + }, + { + "category": "release_safety", + "safe_paths": [], + "review_class": "blocked", + "forbidden_zones": ["ALL"], + "required_checks": [], + "example_pr_size": "N/A", + "expected_artifact": "N/A — requires human release authority" + } + ], + "stop_conditions": [ + "Task broadens beyond requested scope", + "Change touches safety or release policy", + "Claim becomes stronger than evidence supports", + "Benchmark threshold changes", + "Non-toy data or candidate artifacts appear", + "Tests fail in an unexplained way", + "Uncertainty is being hidden" + ], + "non_negotiable": [ + "Computational outputs are not biological proof", + "The lab is the judge", + "No cherry-picking — preserve negative results", + "Safety-first optimization", + "Human review required for safety, release, and scientific claims" + ] +} diff --git a/tests/test_agent_tasks.py b/tests/test_agent_tasks.py new file mode 100644 index 00000000..c49325eb --- /dev/null +++ b/tests/test_agent_tasks.py @@ -0,0 +1,43 @@ +"""Tests for AGENT_TASKS.json.""" +import json +from pathlib import Path + + +def test_file_exists(): + assert Path("AGENT_TASKS.json").exists() + + +def test_is_valid_json(): + data = json.loads(Path("AGENT_TASKS.json").read_text()) + assert "task_categories" in data + assert "stop_conditions" in data + assert "non_negotiable" in data + + +def test_has_8_categories(): + data = json.loads(Path("AGENT_TASKS.json").read_text()) + assert len(data["task_categories"]) >= 8 + + +def test_each_category_has_required_fields(): + data = json.loads(Path("AGENT_TASKS.json").read_text()) + for cat in data["task_categories"]: + for field in ["category", "safe_paths", "review_class", "required_checks"]: + assert field in cat, f"{cat['category']} missing {field}" + + +def test_review_classes(): + data = json.loads(Path("AGENT_TASKS.json").read_text()) + valid = {"light", "normal", "requires_human_review", "blocked"} + for cat in data["task_categories"]: + assert cat["review_class"] in valid, f"{cat['category']} has invalid review_class" + + +def test_stop_conditions(): + data = json.loads(Path("AGENT_TASKS.json").read_text()) + assert len(data["stop_conditions"]) >= 5 + + +def test_non_negotiable(): + data = json.loads(Path("AGENT_TASKS.json").read_text()) + assert len(data["non_negotiable"]) >= 3