ref-agents 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ref_agents/__init__.py +9 -0
- ref_agents/api_keys.json.example +8 -0
- ref_agents/auth.py +129 -0
- ref_agents/codemap/..md +62 -0
- ref_agents/codemap/CODE_MAP.md +37 -0
- ref_agents/codemap/core.md +43 -0
- ref_agents/codemap/models.md +43 -0
- ref_agents/codemap/prompts.md +40 -0
- ref_agents/codemap/security.md +45 -0
- ref_agents/codemap/tools.md +94 -0
- ref_agents/codemap/tools_browser.md +44 -0
- ref_agents/codemap/utils.md +42 -0
- ref_agents/codemap/workflow.md +42 -0
- ref_agents/config/ai_patterns.yaml +101 -0
- ref_agents/config/frameworks/angular.yaml +104 -0
- ref_agents/config/frameworks/aspnet.yaml +84 -0
- ref_agents/config/frameworks/ef_core.yaml +81 -0
- ref_agents/config/frameworks/react.yaml +111 -0
- ref_agents/config/frameworks/spring_boot.yaml +117 -0
- ref_agents/config/languages/csharp.yaml +153 -0
- ref_agents/config/languages/java.yaml +188 -0
- ref_agents/config/languages/javascript.yaml +172 -0
- ref_agents/config/languages/python.yaml +153 -0
- ref_agents/config/languages/typescript.yaml +193 -0
- ref_agents/constants.py +553 -0
- ref_agents/core/__init__.py +15 -0
- ref_agents/core/config_loader.py +160 -0
- ref_agents/core/config_models.py +167 -0
- ref_agents/core/config_parsing.py +84 -0
- ref_agents/core/language_detector.py +388 -0
- ref_agents/core/validation_models.py +66 -0
- ref_agents/core/validation_primitives.py +176 -0
- ref_agents/errors.py +34 -0
- ref_agents/license_client.py +247 -0
- ref_agents/models/__init__.py +22 -0
- ref_agents/models/gherkin.py +45 -0
- ref_agents/models/hierarchy.py +80 -0
- ref_agents/models/invest.py +59 -0
- ref_agents/models/version.py +49 -0
- ref_agents/prompts/__init__.py +9 -0
- ref_agents/prompts/start_agent.py +772 -0
- ref_agents/rules/architecture/backend_patterns.md +43 -0
- ref_agents/rules/architecture/diagramming.md +100 -0
- ref_agents/rules/architecture/frontend_patterns.md +40 -0
- ref_agents/rules/architecture/impact_analysis.md +129 -0
- ref_agents/rules/architecture/migration_strategy.md +208 -0
- ref_agents/rules/architecture/regression_protocol.md +77 -0
- ref_agents/rules/architecture/system_design.md +97 -0
- ref_agents/rules/common/codemap_standard.md +97 -0
- ref_agents/rules/common/core_protocol.md +59 -0
- ref_agents/rules/common/prompt_engineering.md +294 -0
- ref_agents/rules/development/debugging.md +32 -0
- ref_agents/rules/development/implementation.md +205 -0
- ref_agents/rules/operations/completion.md +119 -0
- ref_agents/rules/operations/cutover_protocol.md +218 -0
- ref_agents/rules/operations/discovery.md +179 -0
- ref_agents/rules/operations/fix_workflow.md +87 -0
- ref_agents/rules/operations/forensics.md +278 -0
- ref_agents/rules/operations/platform.md +263 -0
- ref_agents/rules/operations/synchronous_flow.md +25 -0
- ref_agents/rules/product/ac_validation.md +25 -0
- ref_agents/rules/product/brainstorming.md +27 -0
- ref_agents/rules/product/ref_flow.md +101 -0
- ref_agents/rules/product/requirements_std.md +114 -0
- ref_agents/rules/product/spec_writing.md +235 -0
- ref_agents/rules/product/strategy.md +96 -0
- ref_agents/rules/quality/documentation_standards.md +46 -0
- ref_agents/rules/quality/parity_testing.md +234 -0
- ref_agents/rules/quality/project_documentation.md +56 -0
- ref_agents/rules/quality/qa_lead.md +111 -0
- ref_agents/rules/quality/test_design.md +146 -0
- ref_agents/rules/quality/testing_standards.md +293 -0
- ref_agents/rules/review/pr_review.md +116 -0
- ref_agents/rules/security/security_audit.md +83 -0
- ref_agents/security/__init__.py +22 -0
- ref_agents/security/dependency_audit.py +188 -0
- ref_agents/security/file_audit.py +208 -0
- ref_agents/security/network_scan.py +179 -0
- ref_agents/security/report_generator.py +313 -0
- ref_agents/security/secret_scan.py +252 -0
- ref_agents/security/url_scan.py +240 -0
- ref_agents/security_scan.py +236 -0
- ref_agents/server.py +1586 -0
- ref_agents/session.py +100 -0
- ref_agents/tool_names.py +55 -0
- ref_agents/tools/__init__.py +8 -0
- ref_agents/tools/agents_generator.py +315 -0
- ref_agents/tools/ai_pattern_detector.py +815 -0
- ref_agents/tools/brownfield_populator.py +529 -0
- ref_agents/tools/browser/__init__.py +50 -0
- ref_agents/tools/browser/evidence_verifier.py +302 -0
- ref_agents/tools/browser/execution_logger.py +249 -0
- ref_agents/tools/browser/playwright_mcp_client.py +259 -0
- ref_agents/tools/browser/screenshot_utils.py +184 -0
- ref_agents/tools/browser/test_executor.py +537 -0
- ref_agents/tools/code_quality_scanner.py +629 -0
- ref_agents/tools/codemap/..md +93 -0
- ref_agents/tools/codemap/CODE_MAP.md +30 -0
- ref_agents/tools/codemap/browser.md +44 -0
- ref_agents/tools/codemap.py +403 -0
- ref_agents/tools/codemap_freshness.py +234 -0
- ref_agents/tools/comment_smell_scanner.py +346 -0
- ref_agents/tools/complexity.py +436 -0
- ref_agents/tools/complexity_ast.py +333 -0
- ref_agents/tools/compliance.py +246 -0
- ref_agents/tools/compliance_remediation.py +846 -0
- ref_agents/tools/context_graph.py +839 -0
- ref_agents/tools/context_manager.py +550 -0
- ref_agents/tools/context_tools.py +121 -0
- ref_agents/tools/cross_repo_linker.py +393 -0
- ref_agents/tools/dead_code_scanner.py +637 -0
- ref_agents/tools/debt_scanner.py +1092 -0
- ref_agents/tools/dependency_graph.py +272 -0
- ref_agents/tools/discovery_audit.py +372 -0
- ref_agents/tools/docs_scanner.py +600 -0
- ref_agents/tools/evaluate_gate.py +119 -0
- ref_agents/tools/external_detector.py +524 -0
- ref_agents/tools/features_generator.py +282 -0
- ref_agents/tools/flow_gap_detector.py +373 -0
- ref_agents/tools/flow_mapper.py +327 -0
- ref_agents/tools/full_suite_runner.py +740 -0
- ref_agents/tools/gherkin_parser.py +227 -0
- ref_agents/tools/guard_tools.py +139 -0
- ref_agents/tools/handoff_tools.py +282 -0
- ref_agents/tools/health_scanner.py +1211 -0
- ref_agents/tools/hierarchy_manager.py +289 -0
- ref_agents/tools/invest_scorer.py +249 -0
- ref_agents/tools/jira_confluence_export.py +306 -0
- ref_agents/tools/json_output.py +76 -0
- ref_agents/tools/migration_mapper.py +946 -0
- ref_agents/tools/migration_readiness_scanner.py +209 -0
- ref_agents/tools/pattern_learner.py +522 -0
- ref_agents/tools/report_utils.py +155 -0
- ref_agents/tools/requirements_serializer.py +225 -0
- ref_agents/tools/security_audit_tool.py +106 -0
- ref_agents/tools/sequencing_engine.py +288 -0
- ref_agents/tools/summary_generator.py +275 -0
- ref_agents/tools/symbol_resolver.py +306 -0
- ref_agents/tools/symbol_smoke_runner.py +336 -0
- ref_agents/tools/test_plan_validator.py +189 -0
- ref_agents/tools/test_smell_walker.py +902 -0
- ref_agents/tools/tier1_fixer.py +502 -0
- ref_agents/tools/validators/__init__.py +419 -0
- ref_agents/tools/validators/architect.py +268 -0
- ref_agents/tools/validators/cutover_engineer.py +167 -0
- ref_agents/tools/validators/developer.py +180 -0
- ref_agents/tools/validators/discovery.py +150 -0
- ref_agents/tools/validators/forensic_engineer.py +191 -0
- ref_agents/tools/validators/impact_architect.py +181 -0
- ref_agents/tools/validators/migration_planner.py +166 -0
- ref_agents/tools/validators/parity_tester.py +155 -0
- ref_agents/tools/validators/platform_engineer.py +134 -0
- ref_agents/tools/validators/pr_reviewer.py +129 -0
- ref_agents/tools/validators/product_manager.py +291 -0
- ref_agents/tools/validators/qa_lead.py +172 -0
- ref_agents/tools/validators/scrum_master.py +212 -0
- ref_agents/tools/validators/security_owner.py +162 -0
- ref_agents/tools/validators/specifier.py +134 -0
- ref_agents/tools/validators/strategist.py +149 -0
- ref_agents/tools/validators/tester.py +121 -0
- ref_agents/tools/version_manager.py +202 -0
- ref_agents/tools/workflow_tools.py +1549 -0
- ref_agents/utils/__init__.py +21 -0
- ref_agents/utils/git_utils.py +351 -0
- ref_agents/utils/handoff_logger.py +368 -0
- ref_agents/utils/ignore_matcher.py +270 -0
- ref_agents/workflow/__init__.py +19 -0
- ref_agents/workflow/capabilities.py +328 -0
- ref_agents/workflow/state_machine.py +708 -0
- ref_agents/workflow/transitions.py +658 -0
- ref_agents-1.0.0.dist-info/METADATA +365 -0
- ref_agents-1.0.0.dist-info/RECORD +175 -0
- ref_agents-1.0.0.dist-info/WHEEL +4 -0
- ref_agents-1.0.0.dist-info/entry_points.txt +2 -0
- ref_agents-1.0.0.dist-info/licenses/LICENSE +115 -0
ref_agents/session.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from threading import RLock
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SessionState:
|
|
7
|
+
"""Holds the state for a single session."""
|
|
8
|
+
|
|
9
|
+
def __init__(self) -> None:
|
|
10
|
+
self.active_agent: Optional[str] = None
|
|
11
|
+
self.project_root: Optional[Path] = None
|
|
12
|
+
self.active_story: Optional[str] = None
|
|
13
|
+
self._migration_mode: bool = False
|
|
14
|
+
# Validator-foundation state (STORY-021)
|
|
15
|
+
self.validator_retry_counts: dict[tuple[str, str, str], int] = {}
|
|
16
|
+
self.halt_flags: set[str] = set()
|
|
17
|
+
self._story_locks: dict[str, RLock] = {}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SessionManager:
|
|
21
|
+
"""Manages session state.
|
|
22
|
+
Currently implements a Singleton pattern for local single-user context,
|
|
23
|
+
but designed to be extensible for multi-session handling.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
_instance = None
|
|
27
|
+
_state = SessionState()
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def get(cls) -> "SessionManager":
|
|
31
|
+
if cls._instance is None:
|
|
32
|
+
cls._instance = cls()
|
|
33
|
+
return cls._instance
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def active_agent(self) -> Optional[str]:
|
|
37
|
+
return self._state.active_agent
|
|
38
|
+
|
|
39
|
+
@active_agent.setter
|
|
40
|
+
def active_agent(self, agent: str) -> None:
|
|
41
|
+
self._state.active_agent = agent
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def project_root(self) -> Optional[Path]:
|
|
45
|
+
return self._state.project_root
|
|
46
|
+
|
|
47
|
+
@project_root.setter
|
|
48
|
+
def project_root(self, path: Path) -> None:
|
|
49
|
+
self._state.project_root = path
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def active_story(self) -> Optional[str]:
|
|
53
|
+
return self._state.active_story
|
|
54
|
+
|
|
55
|
+
@active_story.setter
|
|
56
|
+
def active_story(self, story_id: Optional[str]) -> None:
|
|
57
|
+
self._state.active_story = story_id
|
|
58
|
+
|
|
59
|
+
def is_migration_mode(self) -> bool:
|
|
60
|
+
"""Return True if current session has migration mode active."""
|
|
61
|
+
return self._state._migration_mode
|
|
62
|
+
|
|
63
|
+
def set_migration_mode(self, value: bool) -> None:
|
|
64
|
+
"""Activate or deactivate migration mode for this session."""
|
|
65
|
+
self._state._migration_mode = value
|
|
66
|
+
|
|
67
|
+
def clear(self) -> None:
|
|
68
|
+
"""Reset session state."""
|
|
69
|
+
self._state = SessionState()
|
|
70
|
+
|
|
71
|
+
# --- Validator-foundation accessors (STORY-021) ---
|
|
72
|
+
|
|
73
|
+
def get_retry_count(self, story_id: str, phase: str, artifact_hash: str) -> int:
|
|
74
|
+
return self._state.validator_retry_counts.get(
|
|
75
|
+
(story_id, phase, artifact_hash), 0
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def increment_retry_count(
|
|
79
|
+
self, story_id: str, phase: str, artifact_hash: str
|
|
80
|
+
) -> int:
|
|
81
|
+
key = (story_id, phase, artifact_hash)
|
|
82
|
+
new_value = self._state.validator_retry_counts.get(key, 0) + 1
|
|
83
|
+
self._state.validator_retry_counts[key] = new_value
|
|
84
|
+
return new_value
|
|
85
|
+
|
|
86
|
+
def set_halt(self, story_id: str) -> None:
|
|
87
|
+
self._state.halt_flags.add(story_id)
|
|
88
|
+
|
|
89
|
+
def clear_halt(self, story_id: str) -> None:
|
|
90
|
+
self._state.halt_flags.discard(story_id)
|
|
91
|
+
|
|
92
|
+
def is_halted(self, story_id: str) -> bool:
|
|
93
|
+
return story_id in self._state.halt_flags
|
|
94
|
+
|
|
95
|
+
def story_lock(self, story_id: str) -> RLock:
|
|
96
|
+
lock = self._state._story_locks.get(story_id)
|
|
97
|
+
if lock is None:
|
|
98
|
+
lock = RLock()
|
|
99
|
+
self._state._story_locks[story_id] = lock
|
|
100
|
+
return lock
|
ref_agents/tool_names.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Namespaced tool call strings for agent-facing output.
|
|
2
|
+
|
|
3
|
+
Use these constants in tool output and rules so model instructions stay correct
|
|
4
|
+
after namespace consolidation. Avoids hardcoded flat tool names that break when
|
|
5
|
+
tools are renamed to log(event=...), scan(target=...), etc.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# Log events (use in instructions / remediation strings)
|
|
9
|
+
TOOL_LOG_ESCALATION = 'log(event="escalation", level=..., reason=..., to_agents=...)'
|
|
10
|
+
TOOL_LOG_OWNERSHIP = 'log(event="ownership", to_owner=..., reason=...)'
|
|
11
|
+
TOOL_LOG_REPLAN = 'log(event="replan", trigger=..., impact=...)'
|
|
12
|
+
TOOL_LOG_DEBT = 'log(event="debt", debt_type=..., severity=..., location=...)'
|
|
13
|
+
TOOL_LOG_PHASE = 'log(event="phase", phase=..., outcome=..., next_phase=...)'
|
|
14
|
+
TOOL_LOG_ARTIFACT = 'log(event="artifact", story_id=..., artifact=...)'
|
|
15
|
+
|
|
16
|
+
# Scan targets (directory/files/file_path as needed)
|
|
17
|
+
TOOL_SCAN_HEALTH = 'scan(target="health", directory="{directory}")'
|
|
18
|
+
TOOL_SCAN_DEBT = 'scan(target="debt", directory="{directory}", summary=...)'
|
|
19
|
+
TOOL_SCAN_DEAD_CODE = 'scan(target="dead_code", directory="{directory}", summary=...)'
|
|
20
|
+
TOOL_SCAN_COMPLEXITY = 'scan(target="complexity", files=...)'
|
|
21
|
+
TOOL_SCAN_EXTERNAL = 'scan(target="external", directory="{directory}")'
|
|
22
|
+
TOOL_SCAN_REGRESSION = 'scan(target="regression", files=...)'
|
|
23
|
+
TOOL_SCAN_COMPLIANCE = 'scan(target="compliance", file_path=...)'
|
|
24
|
+
TOOL_SCAN_DOCS = 'scan(target="docs", directory="{directory}")'
|
|
25
|
+
TOOL_SCAN_AI_PATTERNS = 'scan(target="ai_patterns", file_path=...)'
|
|
26
|
+
TOOL_SCAN_SECURITY = 'scan(target="security", directory="{directory}")'
|
|
27
|
+
# code_quality is internal to health scan — use TOOL_SCAN_HEALTH as entry point
|
|
28
|
+
|
|
29
|
+
# Workflow (use in tool output / rules)
|
|
30
|
+
TOOL_WORKFLOW_INIT = (
|
|
31
|
+
'workflow(action="init", story_id=..., epic_id=..., requirements_path=...)'
|
|
32
|
+
)
|
|
33
|
+
TOOL_WORKFLOW_LIST = 'workflow(action="list")'
|
|
34
|
+
TOOL_WORKFLOW_PARALLEL_START = (
|
|
35
|
+
'workflow(action="parallel_start", story_id="{story_id}")'
|
|
36
|
+
)
|
|
37
|
+
TOOL_AGENT_ACTIVATE = 'agent(action="activate", name="{name}")'
|
|
38
|
+
TOOL_CONTEXT_GRAPH_EMPTY_HINT = 'scan(target="health", directory=...)'
|
|
39
|
+
|
|
40
|
+
# Compliance Remediation
|
|
41
|
+
TOOL_REMEDIATE_START = (
|
|
42
|
+
'remediate(action="start", story_id=..., directory=..., scan_output=...)'
|
|
43
|
+
)
|
|
44
|
+
TOOL_REMEDIATE_STATE = 'remediate(action="state", session_id=...)'
|
|
45
|
+
TOOL_REMEDIATE_EXECUTE = 'remediate(action="execute", session_id=..., tier="tier1")'
|
|
46
|
+
TOOL_REMEDIATE_APPROVE = 'remediate(action="approve", session_id=...)'
|
|
47
|
+
TOOL_REMEDIATE_DEFER = (
|
|
48
|
+
'remediate(action="defer", session_id=..., violation_id=..., reason=...)'
|
|
49
|
+
)
|
|
50
|
+
TOOL_REMEDIATE_UPDATE = 'remediate(action="update", session_id=..., violation_ids=[...], status="auto_fixed")'
|
|
51
|
+
TOOL_REMEDIATE_COMPLETE = 'remediate(action="complete", session_id=...)'
|
|
52
|
+
|
|
53
|
+
# Validators (FEAT-003 onwards)
|
|
54
|
+
TOOL_VALIDATE = 'validate(role="{role}", artifact_id="{artifact_id}")'
|
|
55
|
+
VALIDATE = "validate"
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"""REF Agents Generator.
|
|
2
|
+
|
|
3
|
+
Generates AGENTS.md with REF protocol and mandatory fix workflow.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
from ref_agents.tools.agents_generator import generate_agents_file
|
|
7
|
+
result = generate_agents_file("/path/to/project")
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import structlog
|
|
13
|
+
|
|
14
|
+
logger = structlog.get_logger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
AGENTS_MD_CONTENT = """# AI Coding Assistant Protocol — REF v3.2
|
|
18
|
+
|
|
19
|
+
> This file is read by Cursor, Windsurf, Antigravity, and GitHub Copilot at session start.
|
|
20
|
+
> It is the always-on context layer. Rules here are non-negotiable and apply to every task.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## ⚠️ NEW STORY ENTRY POINT (MANDATORY — NO EXCEPTIONS)
|
|
25
|
+
|
|
26
|
+
**For ANY new story, requirement, or feature request:**
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
ALWAYS start with: agent(action="activate", name="scrum_master")
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The Scrum Master is the **mandatory intake gate**. It:
|
|
33
|
+
1. Validates the story file exists and meets Definition of Ready
|
|
34
|
+
2. Calls `workflow(action="init", story_id="...")` to initialize the phase state machine
|
|
35
|
+
3. Hands off to `product_manager`
|
|
36
|
+
|
|
37
|
+
**DO NOT** activate `product_manager`, `developer`, or any other agent directly for a new story.
|
|
38
|
+
**DO NOT** call `workflow(action="init")` yourself — only `scrum_master` does this.
|
|
39
|
+
|
|
40
|
+
If no story file exists, `scrum_master` activates `product_manager` in **BA mode** to elicit and write the story first.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Non-Negotiable: REF-Agents Entry Point
|
|
45
|
+
|
|
46
|
+
If `ref-agents` MCP is enabled and available, **ALL tasks run via a REF agent**.
|
|
47
|
+
Direct code edits that bypass agent roles are prohibited.
|
|
48
|
+
|
|
49
|
+
**Before any task:**
|
|
50
|
+
1. Call `agent(action="list")` to confirm MCP is active.
|
|
51
|
+
2. For new stories: `agent(action="activate", name="scrum_master")` (see above).
|
|
52
|
+
3. For other tasks: `agent(action="activate", name="<role>")` matching the task type.
|
|
53
|
+
|
|
54
|
+
If MCP is unavailable, apply the rules in this file manually and note the deviation.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Context Entry Point (Non-Negotiable)
|
|
59
|
+
|
|
60
|
+
`CODE_MAP.md` is the mandatory first read before any code task.
|
|
61
|
+
|
|
62
|
+
**Before writing, modifying, or reviewing any code:**
|
|
63
|
+
1. Read `CODE_MAP.md` at project root (fallback: `docs/CODE_MAP.md`).
|
|
64
|
+
2. If missing: activate `discovery` to generate it before proceeding.
|
|
65
|
+
3. After any change that adds, removes, or renames a file/class/function: update `CODE_MAP.md` in the same task. This is not optional.
|
|
66
|
+
|
|
67
|
+
Agents that skip this step produce context-free changes. PR Reviewer will REQUEST CHANGES if `CODE_MAP.md` is stale.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Communication Protocol (Non-Negotiable)
|
|
72
|
+
|
|
73
|
+
BE LACONIC. Every sentence ≤ 15 words. Active voice. Technical vocabulary only.
|
|
74
|
+
|
|
75
|
+
| Rule | Target |
|
|
76
|
+
|---|---|
|
|
77
|
+
| Sentence length | 15–20 words max |
|
|
78
|
+
| Prose style | Active voice. "Service scales." Not "Scaling is handled by." |
|
|
79
|
+
| Forbidden phrases | "It is important to note", "In order to", "As discussed", "Here is the code" |
|
|
80
|
+
| Output format | Tables and bullets over paragraphs. Code over explanation. |
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Core Engineering Principles (Universal)
|
|
85
|
+
|
|
86
|
+
- **Simplicity First**: Make every change as simple as possible. Minimal code impact. No new abstractions unless strictly necessary.
|
|
87
|
+
- **No Laziness**: Find root causes. No temporary patches. Every fix meets senior developer standards.
|
|
88
|
+
- **Minimal Impact**: Touch only what is necessary. Do not expand scope without explicit user approval.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Agent Registry
|
|
93
|
+
|
|
94
|
+
### SDLC Agents — Standard Flow
|
|
95
|
+
|
|
96
|
+
| Agent | Activate With | Primary Duty | Escalates To |
|
|
97
|
+
|---|---|---|---|
|
|
98
|
+
| `scrum_master` | `agent(action="activate", name="scrum_master")` | **Story bookend**: intake gate (validate story, init workflow, hand to PM) AND close (verify artifacts, update REQ.md, log handoffs, generate project_status.md) | User |
|
|
99
|
+
| `discovery` | `agent(action="activate", name="discovery")` | Scan codebase, generate `codemap/`, `FEATURES.md`, `AGENTS.md` | User |
|
|
100
|
+
| `product_manager` | `agent(action="activate", name="product_manager")` | **Dual-mode**: BA mode (no story file → elicit requirements, write STORY-XXX.md, return to SM) or PM mode (story exists → review + refine, hand to Specifier) | User |
|
|
101
|
+
| `specifier` | `agent(action="activate", name="specifier")` | Write formal SPEC with FRs, data shapes, failure modes. Output: `docs/specs/SPEC-{story_id}.md`. Runs after PM, before Architect. | PM + User |
|
|
102
|
+
| `architect` | `agent(action="activate", name="architect")` | System design, ADRs, regression risk check. Reads SPEC as primary input. Plan-first for 3+ component decisions. | PM + User |
|
|
103
|
+
| `qa_lead` | `agent(action="activate", name="qa_lead")` | Validate SPEC FRs for testability against architecture. Runs after Architect. Parallel with `test_designer`. | PM + Architect |
|
|
104
|
+
| `test_designer` | `agent(action="activate", name="test_designer")` | Design test strategy and conceptual cases from SPEC FRs. Parallel with `qa_lead`. | QA Lead + PM |
|
|
105
|
+
| `impact_architect` | `agent(action="activate", name="impact_architect")` | **Pre-implementation gate**: calculate blast radius, score regression risk, enforce best practices, issue Go/No-Go. Runs after QA Gate, before Developer. Produces `docs/analysis/CHANGE-{story_id}.md`. | Architect + User |
|
|
106
|
+
| `developer` | `agent(action="activate", name="developer")` | Implement per Elite Quality Protocol. Plan-first for 3+ step tasks. Log debt. Do not fix debt without approval. | Architect + PM |
|
|
107
|
+
| `pr_reviewer` | `agent(action="activate", name="pr_reviewer")` | Compliance check: types, logging, exceptions, tests, debt logging. Apply Staff Engineer Gate before any verdict. | Developer + Architect |
|
|
108
|
+
| `tester` | `agent(action="activate", name="tester")` | Write real-execution tests from AC. No mocking the unit under test. | PM + QA Lead |
|
|
109
|
+
| `security_owner` | `agent(action="activate", name="security_owner")` | Vulnerability audit: input validation, auth/authz, secrets | Developer + User |
|
|
110
|
+
|
|
111
|
+
### Utility Agents — On-Demand
|
|
112
|
+
|
|
113
|
+
| Agent | Activate With | When to Use |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| `forensic_engineer` | `agent(action="activate", name="forensic_engineer")` | Any bug, incident, or unexpected behavior. Always before `developer` on fixes. Owns lessons learned: appends to `ref-reports/post-mortem-*.md` after every resolved incident or L2/L3 escalation. |
|
|
116
|
+
| `strategist` | `agent(action="activate", name="strategist")` | Design decisions with multiple viable approaches. Trade-off analysis. Delegates independent analysis tracks in parallel via `workflow(action="parallel_start")` for complex multi-domain decisions. |
|
|
117
|
+
| `platform_engineer` | `agent(action="activate", name="platform_engineer")` | Codebase health scans, CI/CD, DevEx issues. Delegates findings across agents in parallel via `workflow(action="parallel_start")` for multi-domain analysis. |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Mandatory Fix Workflow
|
|
122
|
+
|
|
123
|
+
**A fix is any change addressing a defect, regression, or unexpected behavior.**
|
|
124
|
+
New features are NOT fixes.
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
1. forensic_engineer → Root cause analysis (RCA). Output: ref-reports/post-mortem-*.md
|
|
128
|
+
2. impact_architect → Blast radius + regression risk gate. Output: docs/analysis/FIX-{timestamp}.md
|
|
129
|
+
3. strategist → Solution design, trade-off analysis. Output: recommendation
|
|
130
|
+
4. developer → Implementation + tests
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Skipping `forensic_engineer` or `impact_architect` on a fix is blocked at PR review. No exceptions.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## SDLC Phase Sequence
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
Intake: scrum_master → Validate story + init workflow
|
|
141
|
+
Phase 0: discovery → (brownfield only) Generate CODE_MAP.md
|
|
142
|
+
Phase 1: product_manager → BA mode (write story) OR PM mode (review + refine)
|
|
143
|
+
Phase 1.5: specifier → Formal SPEC: FRs, data shapes, failure modes
|
|
144
|
+
Phase 2: architect → System design, ADRs (reads SPEC)
|
|
145
|
+
Phase 3: qa_lead → Validate SPEC FRs for testability } parallel
|
|
146
|
+
test_designer → Design test strategy from SPEC FRs } parallel
|
|
147
|
+
Phase 4: developer → Scope declaration → impact_architect gate (if needed) → Implementation
|
|
148
|
+
Phase 5: pr_reviewer → Stage 0: CHANGE artifact check → Code review
|
|
149
|
+
Phase 6: tester → Tests pass } parallel
|
|
150
|
+
security_owner → Security } parallel (both must pass)
|
|
151
|
+
Close: scrum_master → Artifacts verified, REQ.md → Done, project_status.md
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Parallel phases require `workflow(action="parallel_start", story_id="...")` before proceeding.
|
|
155
|
+
Both parallel agents must pass before the phase advances.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Escalation Protocol
|
|
160
|
+
|
|
161
|
+
Apply at every decision point where a blocker exists.
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
L1 — Auto-resolve: Route to the responsible agent. Example: design unclear → architect.
|
|
165
|
+
L2 — Collaborate: Bring in related agents. Example: architect + PM together.
|
|
166
|
+
L3 — HALT: Stop. Ask the user. Call log(event="escalation", level="L3", ...) first.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
L3 is mandatory when:
|
|
170
|
+
- Regression risk cannot be scoped without user input
|
|
171
|
+
- Debt fix discovered mid-feature (user decides: fix now or log only)
|
|
172
|
+
- Critical vulnerability found (always HALT, no exception)
|
|
173
|
+
- AC is not testable after L1+L2 attempts
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Debt Guardrail (Critical)
|
|
178
|
+
|
|
179
|
+
When debt is found during feature work:
|
|
180
|
+
|
|
181
|
+
1. Call `log(event="debt", debt_type="...", severity="...", location="...")`.
|
|
182
|
+
2. HALT. Ask the user: fix now or log for later?
|
|
183
|
+
3. User says fix: update status to `Approved`, fix in same PR or new `DEBT-XXX` story.
|
|
184
|
+
4. User says log: continue with feature. Status stays `Open`.
|
|
185
|
+
|
|
186
|
+
**Agents do NOT decide on their own.** Silent debt fixes are scope creep.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Tool Reference (REF-Agents MCP)
|
|
191
|
+
|
|
192
|
+
### Primary Tools — Call These First
|
|
193
|
+
|
|
194
|
+
| Tool | When to Call |
|
|
195
|
+
|---|---|
|
|
196
|
+
| `agent(action="list")` | Session start. Confirm MCP active. |
|
|
197
|
+
| `agent(action="activate", name="scrum_master")` | **NEW STORY START** — always first. |
|
|
198
|
+
| `agent(action="activate", name="<role>")` | For non-story tasks (fix, review, scan). |
|
|
199
|
+
| `set_project_root(path="...")` | First call in any new project session. |
|
|
200
|
+
| `set_story_context(story_id="...")` | At start of each story (done by SM). |
|
|
201
|
+
| `workflow(action="init", story_id="...")` | Called by scrum_master only — do not call directly. |
|
|
202
|
+
| `workflow(action="state", story_id="...")` | To check current phase and blockers. |
|
|
203
|
+
| `workflow(action="next", story_id="...")` | After completing any phase. |
|
|
204
|
+
|
|
205
|
+
### Logging — Call on Every State Change
|
|
206
|
+
|
|
207
|
+
| Event | Call |
|
|
208
|
+
|---|---|
|
|
209
|
+
| Escalation | `log(event="escalation", level="L1|L2|L3", reason="...", to_agents="...")` |
|
|
210
|
+
| Ownership transfer | `log(event="ownership", to_owner="...", reason="...")` |
|
|
211
|
+
| Phase complete | `log(event="phase", phase="...", outcome="passed|failed", next_phase="...")` |
|
|
212
|
+
| Debt found | `log(event="debt", debt_type="...", severity="...", location="...")` |
|
|
213
|
+
| Replan triggered | `log(event="replan", trigger="...", impact="...")` |
|
|
214
|
+
| Artifact done | `log(event="artifact", artifact="...")` |
|
|
215
|
+
|
|
216
|
+
### Analysis — Use scan() for all codebase reads
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
scan(target="health", directory="...") — Primary entry point. Runs ALL scanners. Auto-starts remediation session on Critical/High findings.
|
|
220
|
+
scan(target="debt", directory="...") — Technical debt registry.
|
|
221
|
+
scan(target="security", directory="...") — Vulnerability audit.
|
|
222
|
+
scan(target="compliance", file_path="...") — REF quality check on a single file.
|
|
223
|
+
scan(target="complexity", files="...") — Cyclomatic/cognitive complexity.
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Compliance Remediation — Use remediate() after any scan with violations
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
remediate(action="execute", session_id=..., tier="tier1") — Run autonomous Tier 1 fixes. Call immediately after scan(target="health") returns session ID.
|
|
230
|
+
remediate(action="approve", session_id=...) — Single approval gate for all Tier 2 fixes.
|
|
231
|
+
remediate(action="execute", session_id=..., tier="tier2") — Run approved Tier 2 fixes.
|
|
232
|
+
remediate(action="state", session_id=...) — Check progress at any point.
|
|
233
|
+
remediate(action="defer", session_id=..., violation_id=..., reason=...) — Defer violation to TECH_DEBT.md.
|
|
234
|
+
remediate(action="complete", session_id=...) — Close after PR Reviewer gate passes.
|
|
235
|
+
|
|
236
|
+
remediate(action="start") is called automatically by scan(). Do not call it manually.
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Session starts automatically on scan. Tier 1 runs on agent command. Tier 2 needs one approval. Tier 3 always halts.
|
|
240
|
+
Tier 1: type hints, bare except, print(), logging, imports, docstrings — fully autonomous.
|
|
241
|
+
Tier 2: complexity refactors, dead code, AI patterns, test coverage — one user approval.
|
|
242
|
+
Tier 3: security, architectural boundaries, high regression risk — always HALT.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Elite Code Quality Protocol (Non-Negotiable)
|
|
247
|
+
|
|
248
|
+
### Python
|
|
249
|
+
- 100% type hints on all function signatures.
|
|
250
|
+
- `structlog` only. `print()` is forbidden in production.
|
|
251
|
+
- Derive all exceptions from `AppError`.
|
|
252
|
+
- Google-style docstrings. No AI fluff in docstrings.
|
|
253
|
+
- `ruff check --fix && ruff format && pyright` must exit 0.
|
|
254
|
+
|
|
255
|
+
### TypeScript
|
|
256
|
+
- `any` is forbidden. Use explicit `interface` or `type`.
|
|
257
|
+
- `Zod` schema required for all external inputs.
|
|
258
|
+
- `TanStack Query` for all server-side state.
|
|
259
|
+
|
|
260
|
+
### Universal
|
|
261
|
+
- Cyclomatic complexity ≤ 15 per function.
|
|
262
|
+
- Test coverage ≥ 85% on changed files.
|
|
263
|
+
- No mocking the unit under test (UUT). Only mock external third-party APIs.
|
|
264
|
+
- Paste actual shell execution output in the PR compliance section.
|
|
265
|
+
|
|
266
|
+
### Staff Engineer Gate (PR Reviewer)
|
|
267
|
+
Before any verdict, ask: "Would a staff engineer approve this?"
|
|
268
|
+
- Diff behaviour between main and proposed changes.
|
|
269
|
+
- Run tests, check logs, demonstrate correctness. Never mark complete without proof.
|
|
270
|
+
- If the answer is no: REQUEST CHANGES regardless of other checks passing.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Artifacts
|
|
275
|
+
|
|
276
|
+
| Artifact | Owner | Location |
|
|
277
|
+
|---|---|---|
|
|
278
|
+
| `codemap/CODE_MAP.md` | Discovery, Architect | `codemap/` |
|
|
279
|
+
| `REQ.md` | Product Manager | `docs/requirements/` |
|
|
280
|
+
| `TECH_DEBT.md` | Discovery, PR Reviewer | `docs/` |
|
|
281
|
+
| `handoff_log.jsonl` | Scrum Master | `ref-reports/` |
|
|
282
|
+
| `project_status.md` | Scrum Master | `docs/` |
|
|
283
|
+
| `FEATURES.md` | Discovery | Project root |
|
|
284
|
+
| `EXTERNAL_DEPS.md` | Discovery, Architect | `docs/` |
|
|
285
|
+
| `ref-reports/` | Platform Engineer, Security | `ref-reports/` |
|
|
286
|
+
| `ref-reports/post-mortem-*.md` | Forensic Engineer | `ref-reports/` — lessons learned, append-only |
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
*Generated by REF Discovery Agent v3.2. Regenerate with `generate_agents_md(directory=".")` after major protocol changes.*
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def generate_agents_file(directory: str) -> str:
|
|
295
|
+
"""Generate AGENTS.md at project root.
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
directory: Path to project root.
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
Status message.
|
|
302
|
+
"""
|
|
303
|
+
root = Path(directory)
|
|
304
|
+
|
|
305
|
+
if not root.exists():
|
|
306
|
+
return f"Error: Directory {directory} does not exist."
|
|
307
|
+
|
|
308
|
+
agents_path = root / "AGENTS.md"
|
|
309
|
+
|
|
310
|
+
# Always overwrite - this is a protocol file
|
|
311
|
+
agents_path.write_text(AGENTS_MD_CONTENT, encoding="utf-8")
|
|
312
|
+
|
|
313
|
+
logger.info("agents_md_generated", path=str(agents_path))
|
|
314
|
+
|
|
315
|
+
return f"✅ AGENTS.md generated at `{agents_path}`"
|