- Add GNS-2 label taxonomy (66 labels) with semantic routing - Tier 2 agents (capability-analyst, agent-architect, evaluator) enabled for self-cascade - GNS agent protocol: checkpoint v2 in issue body, machine-readable event footers - GiteaClient extended: checkpoint CRUD, event parsing, assignee/lock control, triggered issue polling - PipelineRunner rewritten as PollingSupervisor: reactive instead of active dispatch - Security: circuit breakers (is_locked), budget governance, depth limits - Scripts: init-gns-labels.py, validate-gns-agents.py - Milestone #67 + 7 phase issues (#99-#105) tracking evolution Refs: Milestone #67, Issues #99-#105
75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
GNS-2 Agent Protocol Validator
|
|
Validates that agents follow Gitea-Nervous-System v2.0 protocol.
|
|
"""
|
|
import re
|
|
import sys
|
|
import yaml
|
|
import glob
|
|
|
|
CHECKPOINT_PATTERN = re.compile(r'## GNS Checkpoint\s*```yaml\s*(.*?)```', re.DOTALL)
|
|
EVENT_PATTERN = re.compile(r'<!-- GNS_EVENT:\s*(.*?)\s*-->', re.DOTALL)
|
|
|
|
def validate_agent_file(path):
|
|
with open(path) as f:
|
|
content = f.read()
|
|
|
|
errors = []
|
|
agent_name = path.split('/')[-1].replace('.md', '')
|
|
|
|
# Check frontmatter
|
|
if not content.startswith('---'):
|
|
errors.append('Missing YAML frontmatter')
|
|
else:
|
|
parts = content.split('---')
|
|
if len(parts) >= 2:
|
|
try:
|
|
fm = yaml.safe_load(parts[1])
|
|
if not fm.get('description'):
|
|
errors.append('Missing description in frontmatter')
|
|
if 'mode' not in fm:
|
|
errors.append('Missing mode in frontmatter')
|
|
if 'task' not in str(fm.get('permission', {})):
|
|
errors.append('Missing task permission')
|
|
except Exception as e:
|
|
errors.append(f'Invalid YAML frontmatter: {e}')
|
|
|
|
# Check GNS protocol sections
|
|
if 'GNS Checkpoint' not in content:
|
|
errors.append('Missing GNS Checkpoint section')
|
|
if 'GNS_EVENT' not in content:
|
|
errors.append('Missing GNS_EVENT footer example')
|
|
if 'gns-agent-protocol' not in content.lower() and 'GNS' not in content:
|
|
errors.append('Agent not updated for GNS-2 protocol')
|
|
|
|
return errors
|
|
|
|
def main():
|
|
print("GNS-2 Agent Protocol Validator")
|
|
print()
|
|
|
|
all_valid = True
|
|
for path in glob.glob('.kilo/agents/*.md'):
|
|
errors = validate_agent_file(path)
|
|
agent_name = path.split('/')[-1].replace('.md', '')
|
|
|
|
if errors:
|
|
print(f"❌ {agent_name}: {len(errors)} errors")
|
|
for err in errors:
|
|
print(f" - {err}")
|
|
all_valid = False
|
|
else:
|
|
print(f"✅ {agent_name}")
|
|
|
|
print()
|
|
if all_valid:
|
|
print("All agents pass GNS-2 validation")
|
|
return 0
|
|
else:
|
|
print("Some agents need GNS-2 protocol update")
|
|
return 1
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|