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.
Files changed (175) hide show
  1. ref_agents/__init__.py +9 -0
  2. ref_agents/api_keys.json.example +8 -0
  3. ref_agents/auth.py +129 -0
  4. ref_agents/codemap/..md +62 -0
  5. ref_agents/codemap/CODE_MAP.md +37 -0
  6. ref_agents/codemap/core.md +43 -0
  7. ref_agents/codemap/models.md +43 -0
  8. ref_agents/codemap/prompts.md +40 -0
  9. ref_agents/codemap/security.md +45 -0
  10. ref_agents/codemap/tools.md +94 -0
  11. ref_agents/codemap/tools_browser.md +44 -0
  12. ref_agents/codemap/utils.md +42 -0
  13. ref_agents/codemap/workflow.md +42 -0
  14. ref_agents/config/ai_patterns.yaml +101 -0
  15. ref_agents/config/frameworks/angular.yaml +104 -0
  16. ref_agents/config/frameworks/aspnet.yaml +84 -0
  17. ref_agents/config/frameworks/ef_core.yaml +81 -0
  18. ref_agents/config/frameworks/react.yaml +111 -0
  19. ref_agents/config/frameworks/spring_boot.yaml +117 -0
  20. ref_agents/config/languages/csharp.yaml +153 -0
  21. ref_agents/config/languages/java.yaml +188 -0
  22. ref_agents/config/languages/javascript.yaml +172 -0
  23. ref_agents/config/languages/python.yaml +153 -0
  24. ref_agents/config/languages/typescript.yaml +193 -0
  25. ref_agents/constants.py +553 -0
  26. ref_agents/core/__init__.py +15 -0
  27. ref_agents/core/config_loader.py +160 -0
  28. ref_agents/core/config_models.py +167 -0
  29. ref_agents/core/config_parsing.py +84 -0
  30. ref_agents/core/language_detector.py +388 -0
  31. ref_agents/core/validation_models.py +66 -0
  32. ref_agents/core/validation_primitives.py +176 -0
  33. ref_agents/errors.py +34 -0
  34. ref_agents/license_client.py +247 -0
  35. ref_agents/models/__init__.py +22 -0
  36. ref_agents/models/gherkin.py +45 -0
  37. ref_agents/models/hierarchy.py +80 -0
  38. ref_agents/models/invest.py +59 -0
  39. ref_agents/models/version.py +49 -0
  40. ref_agents/prompts/__init__.py +9 -0
  41. ref_agents/prompts/start_agent.py +772 -0
  42. ref_agents/rules/architecture/backend_patterns.md +43 -0
  43. ref_agents/rules/architecture/diagramming.md +100 -0
  44. ref_agents/rules/architecture/frontend_patterns.md +40 -0
  45. ref_agents/rules/architecture/impact_analysis.md +129 -0
  46. ref_agents/rules/architecture/migration_strategy.md +208 -0
  47. ref_agents/rules/architecture/regression_protocol.md +77 -0
  48. ref_agents/rules/architecture/system_design.md +97 -0
  49. ref_agents/rules/common/codemap_standard.md +97 -0
  50. ref_agents/rules/common/core_protocol.md +59 -0
  51. ref_agents/rules/common/prompt_engineering.md +294 -0
  52. ref_agents/rules/development/debugging.md +32 -0
  53. ref_agents/rules/development/implementation.md +205 -0
  54. ref_agents/rules/operations/completion.md +119 -0
  55. ref_agents/rules/operations/cutover_protocol.md +218 -0
  56. ref_agents/rules/operations/discovery.md +179 -0
  57. ref_agents/rules/operations/fix_workflow.md +87 -0
  58. ref_agents/rules/operations/forensics.md +278 -0
  59. ref_agents/rules/operations/platform.md +263 -0
  60. ref_agents/rules/operations/synchronous_flow.md +25 -0
  61. ref_agents/rules/product/ac_validation.md +25 -0
  62. ref_agents/rules/product/brainstorming.md +27 -0
  63. ref_agents/rules/product/ref_flow.md +101 -0
  64. ref_agents/rules/product/requirements_std.md +114 -0
  65. ref_agents/rules/product/spec_writing.md +235 -0
  66. ref_agents/rules/product/strategy.md +96 -0
  67. ref_agents/rules/quality/documentation_standards.md +46 -0
  68. ref_agents/rules/quality/parity_testing.md +234 -0
  69. ref_agents/rules/quality/project_documentation.md +56 -0
  70. ref_agents/rules/quality/qa_lead.md +111 -0
  71. ref_agents/rules/quality/test_design.md +146 -0
  72. ref_agents/rules/quality/testing_standards.md +293 -0
  73. ref_agents/rules/review/pr_review.md +116 -0
  74. ref_agents/rules/security/security_audit.md +83 -0
  75. ref_agents/security/__init__.py +22 -0
  76. ref_agents/security/dependency_audit.py +188 -0
  77. ref_agents/security/file_audit.py +208 -0
  78. ref_agents/security/network_scan.py +179 -0
  79. ref_agents/security/report_generator.py +313 -0
  80. ref_agents/security/secret_scan.py +252 -0
  81. ref_agents/security/url_scan.py +240 -0
  82. ref_agents/security_scan.py +236 -0
  83. ref_agents/server.py +1586 -0
  84. ref_agents/session.py +100 -0
  85. ref_agents/tool_names.py +55 -0
  86. ref_agents/tools/__init__.py +8 -0
  87. ref_agents/tools/agents_generator.py +315 -0
  88. ref_agents/tools/ai_pattern_detector.py +815 -0
  89. ref_agents/tools/brownfield_populator.py +529 -0
  90. ref_agents/tools/browser/__init__.py +50 -0
  91. ref_agents/tools/browser/evidence_verifier.py +302 -0
  92. ref_agents/tools/browser/execution_logger.py +249 -0
  93. ref_agents/tools/browser/playwright_mcp_client.py +259 -0
  94. ref_agents/tools/browser/screenshot_utils.py +184 -0
  95. ref_agents/tools/browser/test_executor.py +537 -0
  96. ref_agents/tools/code_quality_scanner.py +629 -0
  97. ref_agents/tools/codemap/..md +93 -0
  98. ref_agents/tools/codemap/CODE_MAP.md +30 -0
  99. ref_agents/tools/codemap/browser.md +44 -0
  100. ref_agents/tools/codemap.py +403 -0
  101. ref_agents/tools/codemap_freshness.py +234 -0
  102. ref_agents/tools/comment_smell_scanner.py +346 -0
  103. ref_agents/tools/complexity.py +436 -0
  104. ref_agents/tools/complexity_ast.py +333 -0
  105. ref_agents/tools/compliance.py +246 -0
  106. ref_agents/tools/compliance_remediation.py +846 -0
  107. ref_agents/tools/context_graph.py +839 -0
  108. ref_agents/tools/context_manager.py +550 -0
  109. ref_agents/tools/context_tools.py +121 -0
  110. ref_agents/tools/cross_repo_linker.py +393 -0
  111. ref_agents/tools/dead_code_scanner.py +637 -0
  112. ref_agents/tools/debt_scanner.py +1092 -0
  113. ref_agents/tools/dependency_graph.py +272 -0
  114. ref_agents/tools/discovery_audit.py +372 -0
  115. ref_agents/tools/docs_scanner.py +600 -0
  116. ref_agents/tools/evaluate_gate.py +119 -0
  117. ref_agents/tools/external_detector.py +524 -0
  118. ref_agents/tools/features_generator.py +282 -0
  119. ref_agents/tools/flow_gap_detector.py +373 -0
  120. ref_agents/tools/flow_mapper.py +327 -0
  121. ref_agents/tools/full_suite_runner.py +740 -0
  122. ref_agents/tools/gherkin_parser.py +227 -0
  123. ref_agents/tools/guard_tools.py +139 -0
  124. ref_agents/tools/handoff_tools.py +282 -0
  125. ref_agents/tools/health_scanner.py +1211 -0
  126. ref_agents/tools/hierarchy_manager.py +289 -0
  127. ref_agents/tools/invest_scorer.py +249 -0
  128. ref_agents/tools/jira_confluence_export.py +306 -0
  129. ref_agents/tools/json_output.py +76 -0
  130. ref_agents/tools/migration_mapper.py +946 -0
  131. ref_agents/tools/migration_readiness_scanner.py +209 -0
  132. ref_agents/tools/pattern_learner.py +522 -0
  133. ref_agents/tools/report_utils.py +155 -0
  134. ref_agents/tools/requirements_serializer.py +225 -0
  135. ref_agents/tools/security_audit_tool.py +106 -0
  136. ref_agents/tools/sequencing_engine.py +288 -0
  137. ref_agents/tools/summary_generator.py +275 -0
  138. ref_agents/tools/symbol_resolver.py +306 -0
  139. ref_agents/tools/symbol_smoke_runner.py +336 -0
  140. ref_agents/tools/test_plan_validator.py +189 -0
  141. ref_agents/tools/test_smell_walker.py +902 -0
  142. ref_agents/tools/tier1_fixer.py +502 -0
  143. ref_agents/tools/validators/__init__.py +419 -0
  144. ref_agents/tools/validators/architect.py +268 -0
  145. ref_agents/tools/validators/cutover_engineer.py +167 -0
  146. ref_agents/tools/validators/developer.py +180 -0
  147. ref_agents/tools/validators/discovery.py +150 -0
  148. ref_agents/tools/validators/forensic_engineer.py +191 -0
  149. ref_agents/tools/validators/impact_architect.py +181 -0
  150. ref_agents/tools/validators/migration_planner.py +166 -0
  151. ref_agents/tools/validators/parity_tester.py +155 -0
  152. ref_agents/tools/validators/platform_engineer.py +134 -0
  153. ref_agents/tools/validators/pr_reviewer.py +129 -0
  154. ref_agents/tools/validators/product_manager.py +291 -0
  155. ref_agents/tools/validators/qa_lead.py +172 -0
  156. ref_agents/tools/validators/scrum_master.py +212 -0
  157. ref_agents/tools/validators/security_owner.py +162 -0
  158. ref_agents/tools/validators/specifier.py +134 -0
  159. ref_agents/tools/validators/strategist.py +149 -0
  160. ref_agents/tools/validators/tester.py +121 -0
  161. ref_agents/tools/version_manager.py +202 -0
  162. ref_agents/tools/workflow_tools.py +1549 -0
  163. ref_agents/utils/__init__.py +21 -0
  164. ref_agents/utils/git_utils.py +351 -0
  165. ref_agents/utils/handoff_logger.py +368 -0
  166. ref_agents/utils/ignore_matcher.py +270 -0
  167. ref_agents/workflow/__init__.py +19 -0
  168. ref_agents/workflow/capabilities.py +328 -0
  169. ref_agents/workflow/state_machine.py +708 -0
  170. ref_agents/workflow/transitions.py +658 -0
  171. ref_agents-1.0.0.dist-info/METADATA +365 -0
  172. ref_agents-1.0.0.dist-info/RECORD +175 -0
  173. ref_agents-1.0.0.dist-info/WHEEL +4 -0
  174. ref_agents-1.0.0.dist-info/entry_points.txt +2 -0
  175. 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
@@ -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,8 @@
1
+ """REF Agents Tools.
2
+
3
+ This package contains tools for the REF Agents server.
4
+ """
5
+
6
+ from ref_agents.tools import browser, codemap, compliance, report_utils
7
+
8
+ __all__ = ["browser", "codemap", "compliance", "report_utils"]
@@ -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}`"