Scanner — Operational Protocol
Protocol
1. DISCOVER
- Read inputs from the orchestrator dispatch context:
source_directory: path to the directory containing source files to scan.
metrics_output_path: path where scanner-metrics.json must be written.
state_path: path to pipeline-state.json for status updates.
run_id: current run identifier.
root: resolved scope root.
- Verify
source_directory exists and is a readable directory. If not: emit NEEDS_CONTEXT with message: "Source directory not found at {source_directory}. Provide a valid path and re-run."
- Enumerate all source files in
source_directory (recursively, using Glob). Common source extensions: .py, .js, .ts, .go, .java, .rb, .rs, .cs. If no matching files found: emit DONE_WITH_CONCERNS with message: "No source files found in {source_directory}. Metrics file written with zero entries."
2. PROCESS
For each source file discovered:
High complexity: flag a file if it contains deeply nested conditionals (4+ levels), or if a single function/method appears to span more than 50 lines AND contains multiple branching paths. Record:
{"file": "{relative_path}", "complexity_score": <integer>, "reason": "<brief reason>"}
Missing docstrings: flag a file if top-level functions, methods, or classes lack a docstring or leading comment block. Record:
{"file": "{relative_path}", "locations": ["<class or function signature>"]}
Long functions: flag any function or method with a line count exceeding 60 lines. Record:
{"file": "{relative_path}", "function": "<function name>", "line_count": <integer>}
Assemble the metrics object:
{
"scanned_directory": "{source_directory}",
"file_count": 0,
"high_complexity": [],
"missing_docstrings": [],
"long_functions": []
}
3. DELIVER
- Write
scanner-metrics.json to metrics_output_path using the Write tool.
- Update
pipeline-state.json:
- Set
phases[0].status = "completed" (or "completed_with_concerns" if any files were unreadable or no source files found).
- Set
phases[0].outputs = [metrics_output_path].
- Emit terminal status:
DONE — metrics written successfully, all files scanned without errors.
DONE_WITH_CONCERNS — metrics written but one or more files were unreadable, or no source files found (note which and why).
NEEDS_CONTEXT — source directory not found or not accessible.
BLOCKED — metrics file could not be written (e.g., disk write failure).
1---2name: scanner-protocol3description: Loaded by the scanner agent to supply operating protocol and invariants for source file metric extraction in the parity-test-d pipeline. Not user-invocable.4---56# Scanner — Operational Protocol78<overview>9The scanner agent reads all source files in a target directory, extracts per-file code health metrics (high complexity, missing docstrings, long functions), and writes a structured JSON metrics file to the pipeline temp directory. It is the first step of the parity-test-d Sequential pipeline (Pattern 1) on Tier 1c (Antigravity CLI). The quality bar is: metrics must be machine-readable JSON that the reporter can consume without ambiguity.10</overview>1112## Protocol1314<protocol>1516### 1. DISCOVER17181. Read inputs from the orchestrator dispatch context:19 - `source_directory`: path to the directory containing source files to scan.20 - `metrics_output_path`: path where `scanner-metrics.json` must be written.21 - `state_path`: path to `pipeline-state.json` for status updates.22 - `run_id`: current run identifier.23 - `root`: resolved scope root.242. Verify `source_directory` exists and is a readable directory. If not: emit `NEEDS_CONTEXT` with message: "Source directory not found at `{source_directory}`. Provide a valid path and re-run."253. Enumerate all source files in `source_directory` (recursively, using `Glob`). Common source extensions: `.py`, `.js`, `.ts`, `.go`, `.java`, `.rb`, `.rs`, `.cs`. If no matching files found: emit `DONE_WITH_CONCERNS` with message: "No source files found in `{source_directory}`. Metrics file written with zero entries."2627### 2. PROCESS2829For each source file discovered:30311. **High complexity**: flag a file if it contains deeply nested conditionals (4+ levels), or if a single function/method appears to span more than 50 lines AND contains multiple branching paths. Record:32 ```json33 {"file": "{relative_path}", "complexity_score": <integer>, "reason": "<brief reason>"}34 ```35362. **Missing docstrings**: flag a file if top-level functions, methods, or classes lack a docstring or leading comment block. Record:37 ```json38 {"file": "{relative_path}", "locations": ["<class or function signature>"]}39 ```40413. **Long functions**: flag any function or method with a line count exceeding 60 lines. Record:42 ```json43 {"file": "{relative_path}", "function": "<function name>", "line_count": <integer>}44 ```4546Assemble the metrics object:4748```json49{50 "scanned_directory": "{source_directory}",51 "file_count": 0,52 "high_complexity": [],53 "missing_docstrings": [],54 "long_functions": []55}56```5758### 3. DELIVER59601. Write `scanner-metrics.json` to `metrics_output_path` using the `Write` tool.612. Update `pipeline-state.json`:62 - Set `phases[0].status` = `"completed"` (or `"completed_with_concerns"` if any files were unreadable or no source files found).63 - Set `phases[0].outputs` = `[metrics_output_path]`.643. Emit terminal status:65 - `DONE` — metrics written successfully, all files scanned without errors.66 - `DONE_WITH_CONCERNS` — metrics written but one or more files were unreadable, or no source files found (note which and why).67 - `NEEDS_CONTEXT` — source directory not found or not accessible.68 - `BLOCKED` — metrics file could not be written (e.g., disk write failure).6970</protocol>7172<invariants>73- NEVER write metrics to a path outside `{ROOT}/superpipelines/temp/parity-test-d/{runId}/`.74- NEVER pass file contents to the orchestrator in the status message — pass only the metrics file path.75- ALWAYS validate that `metrics_output_path` is writable before attempting write.76- ALWAYS update `pipeline-state.json` after writing metrics.77- Emit exactly one terminal status: DONE / DONE_WITH_CONCERNS / NEEDS_CONTEXT / BLOCKED.78</invariants>