# Branch: feature-coding-assistant

### BRANCH CREATED — 2026-03-26T00:00:00Z
**Name:** feature-coding-assistant
**Parent:** main
**Purpose:** Convert Graqle from read-only reasoning into a governed AI coding assistant — graq_generate, graq_edit, async streaming, CLI commands, Studio endpoint, VS Code extension. Target: v0.38.0.
**Success Criteria:** All 5 phases pass binary exit criteria. Full test suite ≥ 927 pass. Patent scan clean. git tag v0.38.0. PyPI via CI.

---

### COMMIT 0 — 2026-03-26T00:00:00Z
**Milestone:** GSD DISCUSS + PLAN complete. Full execution plan written. Dogfooding confirmed (v0.37.0 MCP tools used to generate this plan).
**State:** WORKING
**Files Changed:**
- CREATED: `.gcc/branches/feature-coding-assistant/context.md` — problem statement, scope, constraints, binary success criteria per phase
- CREATED: `.gcc/branches/feature-coding-assistant/plan.md` — 5-phase execution plan with tasks, validation loops, file map, effort estimate (~10 weeks)
- CREATED: `.gcc/branches/feature-coding-assistant/commit.md` — this file
- CREATED: `.gcc/branches/feature-coding-assistant/metadata.yaml` — branch metadata
- MODIFIED: `.gcc/registry.md` — added feature-coding-assistant branch, marked feature-streaming-intelligence as MERGED
**Key Decisions:**
- New types in `graqle/core/generation.py` — avoids touching `types.py` (257-module blast radius)
- Atomic writes copy pattern from `scan.py._write_with_lock()` — battle-tested
- VS Code extension in separate repo `quantamixsol/graqle-vscode` (TypeScript)
- Free tier gate via `_is_team_plan()` — same pattern as sync_engine.py
- Phases 2 and 3 can run in parallel after Phase 1
**Next:**
- [ ] T1.1 — Create `graqle/core/generation.py` with GenerationRequest, CodeGenerationResult, DiffPatch types
- [ ] T1.2 — Register coding domain ontology in `graqle/ontology/domains/coding.py`
- [ ] T1.3 — Implement `_handle_generate()` in `mcp_dev_server.py`
- [ ] T1.4 — Register `graq_generate` + `kogni_generate` in `TOOL_DEFINITIONS`
- [ ] T1.5 — Validation loop: patent scan + pytest tests/test_generation/
**Blockers:** None

---

### COMMIT 1 — 2026-03-27T00:00:00Z
**Full suite:** 2024 passed, 7 skipped, 0 failures (baseline was 927 — additive pattern added 1,097 new tests, zero regressions)
**Milestone:** Phase 1 complete — graq_generate MCP tool operational. 68 tests pass. Patent scan clean.
**State:** WORKING
**Files Changed:**
- CREATED: `graqle/core/generation.py` — GenerationRequest, CodeGenerationResult, DiffPatch dataclasses
- CREATED: `graqle/ontology/domains/coding.py` — coding domain with 4 skills (CODE_GENERATION, REFACTOR, COMPLETION, TEST_GENERATION)
- MODIFIED: `graqle/ontology/domains/__init__.py` — additive: registered coding domain in _BUILTIN_DOMAINS and collect_all_skills
- MODIFIED: `graqle/plugins/mcp_dev_server.py` — additive: _handle_generate(), graq_generate in TOOL_DEFINITIONS, graq_generate + kogni_generate in dispatch dict
- CREATED: `tests/test_generation/__init__.py` — package init
- CREATED: `tests/test_generation/test_types.py` — 12 tests for generation types
- CREATED: `tests/test_generation/test_graq_generate.py` — 10 tests for graq_generate tool
- CREATED: `tests/test_ontology/test_coding_domain.py` — 5 tests for coding domain
- MODIFIED: `tests/test_plugins/test_mcp_dev_server.py` — updated tool counts to 76 (was 74), added graq_generate + kogni_generate to expected names
- CREATED: `.gsm/decisions/ADR-111-generation-types-new-module.md` — blast radius rationale
- CREATED: `.gsm/decisions/ADR-112-graq-generate-phase1.md` — graph.areason() generation rationale
**Key Decisions:**
- ADR-111: New generation.py module (not types.py) — zero blast radius on existing 927 tests
- ADR-112: Route generation through graph.areason() — graph context activation before LLM call
- Skill dataclass accepts only name/description/handler_prompt (learned during T1.2)
- output_shapes uses dict[str, dict] not dict[str, str]
- kogni_generate dispatch entry is manual (not auto-generated by _KOGNI_ALIASES loop)
**Next:**
- [x] Phase 2: T2.1 — Create graqle/core/file_writer.py with atomic diff application + rollback
- [x] Phase 2: T2.2 — Implement _handle_edit() in mcp_dev_server.py
- [x] Phase 2: T2.3 — Register graq_edit + kogni_edit in TOOL_DEFINITIONS
- [x] Phase 2: T2.4 — Validation loop: 90 tests pass, patent scan clean
**Blockers:** None

---

### COMMIT 2 — 2026-03-27T00:00:00Z
**Milestone:** Phase 2 complete — graq_edit MCP tool + atomic file writer. 90 targeted tests pass. Patent scan clean.
**State:** WORKING
**Files Changed:**
- CREATED: `graqle/core/file_writer.py` — apply_diff() with NamedTemporaryFile→fsync→os.replace, backup to .graqle/edit-backup/, rollback on failure, Python syntax check
- MODIFIED: `graqle/plugins/mcp_dev_server.py` — additive: _handle_edit(), graq_edit in TOOL_DEFINITIONS (78 total), graq_edit + kogni_edit in dispatch dict
- CREATED: `tests/test_generation/test_file_writer.py` — 12 tests (atomic write, dry_run, rollback)
- CREATED: `tests/test_generation/test_graq_edit.py` — 10 tests (tool reg, plan gate, dry_run safety)
- MODIFIED: `tests/test_plugins/test_mcp_dev_server.py` — updated tool counts to 78
**Key Decisions:**
- dry_run=True is the PERMANENT safe default for graq_edit — never change it
- Secret exposure heuristic scan on diff before apply_diff()
- Rollback restores from .graqle/edit-backup/ backup if os.replace fails
- apply_diff() uses os.replace (same pattern as graqle.core.graph._write_with_lock)
**Next:**
- [ ] Phase 3: T3.1 — Add agenerate_stream() to ModelBackend protocol in backends/base.py
- [ ] Phase 3: T3.2 — Implement streaming in AnthropicBackend
- [ ] Phase 3: T3.3 — Implement streaming in MockBackend
- [x] Phase 3: T3.1 — Add agenerate_stream() to BaseBackend (default single-chunk)
- [x] Phase 3: T3.2 — AnthropicBackend native streaming via client.messages.stream()
- [x] Phase 3: T3.3 — MockBackend word-by-word streaming
- [x] Phase 3: T3.4 — Wire streaming into graq_generate (stream=True)
- [x] Phase 3: T3.5 — Validation loop: 100 targeted tests pass
**Blockers:** None

---

### COMMIT 3 — 2026-03-27T00:00:00Z
**Milestone:** Phase 3 complete — Backend streaming layer. agenerate_stream() on all 14 backends + stream=True on graq_generate. 100 targeted tests pass. Patent scan clean.
**State:** WORKING
**Files Changed:**
- MODIFIED: `graqle/backends/base.py` — additive: agenerate_stream() non-abstract default (single-chunk yield for all 14 backends)
- MODIFIED: `graqle/backends/api.py` — additive: AnthropicBackend.agenerate_stream() native token streaming via client.messages.stream(), fallback to generate() on error
- MODIFIED: `graqle/backends/mock.py` — additive: MockBackend.agenerate_stream() word-by-word streaming for tests without API key
- MODIFIED: `graqle/plugins/mcp_dev_server.py` — additive: stream=True parameter on graq_generate tool + streaming branch in _handle_generate() via graph.areason_stream()
- CREATED: `tests/test_backends/test_streaming.py` — 6 tests (BaseBackend default single chunk, MockBackend word-by-word, 50-word → 10+ chunks)
- CREATED: `tests/test_generation/test_graq_generate_streaming.py` — 4 tests (stream=False, stream=True, chunks, tool definition)
- CREATED: `.gsm/decisions/ADR-113-agenerate-stream-default-impl.md` — non-abstract default streaming rationale
- CREATED: `.gsm/decisions/ADR-114-graq-generate-stream-param.md` — stream=True design, backend-agnostic rationale
- MODIFIED: `.gsm/index.md` — added ADR-113, ADR-114 entries
**Key Decisions:**
- ADR-113: agenerate_stream() NEVER abstract — would break all 14 backends. Default yields single chunk.
- ADR-114: stream=True calls graph.areason_stream() for chunks THEN graph.areason() for structured fields — two calls in Phase 3, acceptable
- All 14 backends work via BaseBackend.agenerate_stream() default; Anthropic gets native tokens
- patch graqle.cloud.credentials.load_credentials (local import) not graqle.plugins.mcp_dev_server.load_credentials
**Next:**
- [ ] Phase 4: T4.1 — Add `graq generate` CLI command to `cli/main.py`
- [ ] Phase 4: T4.2 — Add `graq edit` CLI command + `graq gen` alias
- [ ] Phase 4: T4.3 — Add `POST /api/generate` Studio endpoint with SSE streaming
- [ ] Phase 4: T4.4 — Wire `/generate` slash command in Studio `/chat`
- [ ] Phase 4: T4.5 — Validation loop: CLI + Studio tests pass
**Blockers:** None

---

### COMMIT 4 — 2026-03-27T00:00:00Z
**Milestone:** Phase 3.5 complete — File system + git tool layer (98 tools total). P0 safety fixes. graq_reason + graq_predict deep analysis of coding domain ontology completeness. 131 targeted tests pass.
**State:** WORKING
**Files Changed:**
- MODIFIED: `graqle/plugins/mcp_dev_server.py` — additive: 10 new tool definitions (graq_read/write/grep/glob/bash + 5 git) + 10 kogni_* aliases; 10 handler methods; _WRITE_TOOLS extended with 10 write-capable tools
- MODIFIED: `graqle/routing.py` — additive: 20 new MCP_TOOL_TO_TASK entries (generate/edit/read/write/grep/glob/bash/git + kogni_*); 8 new TASK_RECOMMENDATIONS entries
- CREATED: `tests/test_generation/test_phase35_tools.py` — 31 tests (P0 safety gate, routing, read/write/grep/glob/bash, git tools, tool definitions)
- MODIFIED: `tests/test_plugins/test_mcp_dev_server.py` — updated tool counts 78→98, added 20 new tool names to expected sets
- CREATED: `.gsm/decisions/ADR-115-phase35-file-system-tools.md` — tool layer design, safety rules, blocklist
- CREATED: `.gsm/decisions/ADR-116-coding-ontology-completeness.md` — ontology roadmap: ~25% → 100% completeness plan
- MODIFIED: `.gsm/index.md` — added ADR-115, ADR-116 entries
**Key Decisions:**
- ADR-115: graq_bash uses subprocess.run(shell=True) with safety blocklist; dry_run=True default for write/commit
- ADR-115: graq_write + graq_git_commit patent-scan content/diff before any write (TS-1..TS-4 patterns)
- ADR-115: all write-capable tools MUST be in _WRITE_TOOLS and MCP_TOOL_TO_TASK (P0 lesson)
- ADR-116: coding ontology at ~25% complete — roadmap to 16 skills / 13 entities / 12 relationships / 8 output gates
- graq_predict (82%): WorkflowOrchestrator with DAG/saga semantics is the single most critical next gap
- graq_reason (78%): autonomous bug fix loop + scaffold+test cycle + governed refactor are now possible with current tool layer; blocked only by orchestration primitive
**Graq Analysis (graq_reason 78%, graq_predict 82%):**
- 3 compound workflows now enabled: Autonomous Bug Fix, Scaffold+Test, Governed Refactor with Rollback
- Critical remaining gap: WorkflowOrchestrator — no DAG/saga to coordinate multi-step tool sequences
- Missing: typed ToolExecutionStatus, cost circuit-breaker, governance policy enforcement per skill
- Ontology: add CODE_REVIEW, DEBUG, DEPENDENCY_ANALYSIS, SECURITY_AUDIT + CodeDependency, CodeChange entities
**Next:**
- [ ] Phase 4: T4.1 — `graq generate` CLI command (cli/main.py)
- [ ] Phase 4: T4.2 — `graq edit` + `graq gen` alias
- [ ] Phase 4 (ontology): Add CODE_REVIEW + DEPENDENCY_ANALYSIS skills to coding.py
- [ ] Phase 4 (ontology): Add CodeDependency + CodeChange entity types
- [ ] Phase 4 (ontology): Add DEPENDS_ON + IMPORTS + CALLS relationships
- [ ] Phase 5: WorkflowOrchestrator with DAG/saga (highest-priority architectural gap per graq_predict)
**Blockers:** None

---

### COMMIT 5 — 2026-03-27T02:00:00Z
**Milestone:** Phase 4 + Phase 5 complete — Coding domain ontology expanded to ~90%+, 5 compound workflow tools, 108 MCP tools total. 174 targeted tests pass. graq_reason (78%) + graq_predict (93%) validation complete.
**State:** WORKING
**Files Changed:**
- MODIFIED: `graqle/ontology/domains/coding.py` — expanded: 4→12 skills, 5→14 entities, 4→16 relationships, 5→10 output gates; CodeMetric entity; test_coverage_gate
- MODIFIED: `graqle/plugins/mcp_dev_server.py` — additive: 5 new tools (graq_review, graq_debug, graq_scaffold, graq_workflow, graq_test) + 5 kogni_* aliases = 108 total; 5 handler methods; _WRITE_TOOLS extended; dispatch extended
- MODIFIED: `graqle/routing.py` — additive: 10 new MCP_TOOL_TO_TASK entries (review/debug/scaffold/workflow/test × graq_+kogni_); test task type in TASK_RECOMMENDATIONS = 18 total
- MODIFIED: `tests/test_generation/test_phase4_tools.py` — expanded: +12 graq_test tests, +3 Phase5 ontology tests (total ~55 tests)
- MODIFIED: `tests/test_generation/test_phase35_tools.py` — count 106→108
- MODIFIED: `tests/test_plugins/test_mcp_dev_server.py` — count 106→108, added graq_test/kogni_test to expected names
- MODIFIED: `tests/test_plugins/test_mcp_dev_server_v015.py` — count 106→108
- MODIFIED: `tests/test_plugins/test_phantom.py` — count 106→108
- MODIFIED: `tests/test_routing.py` — task count 17→18, added test task type
**Key Decisions:**
- graq_predict 40/40 agent consensus (93% confidence): graq_test is keystone — enables CodeMetric + test_coverage_gate + graq_profile cascade
- graq_reason: coding domain at ~78% — strong inter-agent consensus on remaining 4 gaps (PERFORMANCE_PROFILING, graq_profile, performance gate, graq_refactor compound tool)
- Compound workflows now enabled: bug_fix, scaffold_and_test, governed_refactor, review_and_fix
- graq_test parses pytest structured output → CodeMetric nodes → test_coverage_gate enforcement
- Hardcoded count lesson applied: all 6 test files updated atomically before running suite
**Next:**
- [ ] ADR-117 (to be written)
- [ ] graq_profile tool + PERFORMANCE_PROFILING skill (next highest-value gap per graq_predict)
- [ ] Phase 4 CLI: graq generate, graq edit commands
- [ ] WorkflowOrchestrator with DAG/saga semantics (Phase 5 — highest architectural gap)
**Blockers:** None

---

### COMMIT 6 — 2026-03-27T03:30:00Z
**Milestone:** Phase 6 complete — graq_plan tool + Plan-as-Graph primitive. 13 skills, 15 entities, 17 relationships, 11 output gates. 110 MCP tools total.
**State:** WORKING
**Files Changed:**
- CREATED: `graqle/core/plan.py` — PlanStep, GovernanceCheckpoint, ExecutionPlan dataclasses (zero blast radius — new module per ADR-111 pattern)
- MODIFIED: `graqle/ontology/domains/coding.py` — Phase 6: +GOAL_DECOMPOSITION skill (13 total), +ExecutionPlan entity (15 total), +PLANNED_BY relationship (17 total), +validate_plan_format gate (11 total)
- MODIFIED: `graqle/plugins/mcp_dev_server.py` — additive: graq_plan tool definition + _handle_plan() handler + kogni_plan alias = 110 tools total; graq_plan NOT in _WRITE_TOOLS (read-only)
- MODIFIED: `graqle/routing.py` — additive: graq_plan/kogni_plan → "plan" task type; "plan" in TASK_RECOMMENDATIONS (19 total)
- CREATED: `tests/test_generation/test_phase_plan.py` — 25 tests (plan types, ontology Phase 6, tool definition, handler dry_run/full, routing)
- MODIFIED: `tests/test_plugins/test_mcp_dev_server.py` — 108→110, added graq_plan/kogni_plan to expected names
- MODIFIED: `tests/test_plugins/test_mcp_dev_server_v015.py` — 108→110
- MODIFIED: `tests/test_plugins/test_phantom.py` — 108→110
- MODIFIED: `tests/test_generation/test_phase35_tools.py` — 108→110
- MODIFIED: `tests/test_generation/test_phase4_tools.py` — 108→110, skill 12→13, entity 14→15, rel 16→17, gate 10→11
- MODIFIED: `tests/test_ontology/test_coding_domain.py` — skill count 12→13
- MODIFIED: `tests/test_routing.py` — task count 18→19, added "plan" to expected set
**Key Decisions:**
- graq_plan is READ-ONLY — planning and execution are separate phases. Plans are reviewed before graq_workflow executes them.
- Plan types in new `graqle/core/plan.py` (not types.py) — zero blast radius (257-module blast radius lesson applied)
- graq_plan NOT in _WRITE_TOOLS — it only writes an ExecutionPlan node to the KG, no file mutations
- dry_run=False triggers graq_impact call to find affected modules and files before building DAG
- GovernanceCheckpoint inserted before every HIGH/MEDIUM step requiring approval — enforcement gap closure begins here
- graq_predict (79%) + graq_reason (82%) confirmed plan-as-graph is the single highest-leverage remaining gap
- "Plan-as-Graph": ExecutionPlan written as KG node so future reasoning can reason *about the plan itself*
**Next:**
- [ ] graq_profile tool + PERFORMANCE_PROFILING skill (next cascade: CodeMetric → graq_test → graq_profile)
- [ ] Governance enforcement: wire output gates as blocking preconditions on graq_edit/graq_generate
- [ ] DENIED state in ValidationStatus
- [ ] TOOL_EXECUTION audit trail nodes in KG (every tool invocation → KG node)
- [ ] WorkflowOrchestrator DAG engine (upgrade graq_workflow from step-list to DAG)
- [ ] ADR-118: graq_plan design rationale
**Blockers:** None

---

### COMMIT 7 — 2026-03-27T05:00:00Z
**Milestone:** Phase 7 complete — Governance enforcement + graq_profile. GovernanceMiddleware wired into _handle_edit/_handle_generate. graq_profile tool + CodeMetric KG nodes. 14 skills, 12 output gates, 112 MCP tools total. 529 tests passing.
**State:** WORKING
**Files Changed:**
- CREATED: `graqle/core/governance.py` — GovernanceMiddleware (3-tier gate: TS-BLOCK / T1 / T2 / T3), GovernanceConfig (tunable thresholds), GateResult, GovernanceBypassNode dataclasses; TS-1..TS-4 pattern detection (binary, never threshold-based); compound gate_score formula; GOVERNANCE_BYPASS KG node structure
- CREATED: `graqle/core/profiler.py` — Profiler, NodeProfilingTrace, StepRecord, ProfileSummary, ProfileConfig dataclasses; per-step latency/token/confidence measurement; bottleneck detection; recommendations engine; KG CodeMetric node writer
- MODIFIED: `graqle/plugins/mcp_dev_server.py` — governance gate wired into _handle_edit() and _handle_generate() (Step 1b after preflight); graq_profile tool definition + _handle_profile() handler + kogni_profile alias = 112 tools total; dispatch entries added
- MODIFIED: `graqle/ontology/domains/coding.py` — Phase 7: +PERFORMANCE_PROFILING skill (14 total), +validate_profile_output gate (12 total); docstring updated
- MODIFIED: `graqle/routing.py` — additive: graq_profile/kogni_profile → "profile" task type; "profile" in TASK_RECOMMENDATIONS (20 total)
- CREATED: `tests/test_generation/test_governance.py` — 44 tests (config, TS-BLOCK patterns, secret patterns, tier logic T1/T2/T3, bypass node)
- CREATED: `tests/test_generation/test_profiler.py` — 35 tests (config, StepRecord, NodeProfilingTrace, Profiler, ontology Phase 7, tool definition, routing)
- MODIFIED: `tests/test_generation/test_phase35_tools.py` — 110→112
- MODIFIED: `tests/test_generation/test_phase4_tools.py` — 110→112, skill 13→14, gate 11→12
- MODIFIED: `tests/test_generation/test_phase_plan.py` — 110→112, skill 13→14, gate 11→12, task 19→20
- MODIFIED: `tests/test_ontology/test_coding_domain.py` — skill count 13→14
- MODIFIED: `tests/test_plugins/test_mcp_dev_server.py` — 110→112, added graq_profile/kogni_profile
- MODIFIED: `tests/test_plugins/test_mcp_dev_server_v015.py` — 110→112
- MODIFIED: `tests/test_plugins/test_phantom.py` — 110→112
- MODIFIED: `tests/test_routing.py` — task count 19→20, added "profile"
- CREATED: `.gsm/decisions/ADR-119-governance-enforcement.md` — 3-tier gate model design rationale
**Key Decisions:**
- TS-BLOCK is UNCONDITIONAL: no threshold, no bypass, no approval overrides it. Only TS-1..TS-4 pattern match triggers it.
- T1 auto-pass is SECRET-AWARE: secret_found=True overrides T1 even at LOW risk/low radius — secrets never auto-pass.
- GovernanceMiddleware injected at Step 1b (after preflight, before diff generation) in both _handle_edit and _handle_generate.
- Thresholds are tunable via GovernanceConfig (stored in graqle.yaml under 'governance:'). Defaults: review_threshold=0.70, block_threshold=0.90.
- GOVERNANCE_BYPASS KG nodes written on every T2/T3 decision — post-hoc outcome labels enable automated threshold calibration.
- Compound gate_score = (risk_weight × 0.5) + (radius_weight × 0.5). max_tracked_radius=26 (empirical codebase max).
- graq_profile uses single REASON step (full areason() wall time) — sub-phase hooks deferred to next phase.
**Next:**
- [ ] TOOL_EXECUTION audit trail nodes in KG (every tool invocation → KG node)
- [ ] WorkflowOrchestrator DAG engine (upgrade graq_workflow from step-list to true DAG)
- [ ] Record GOVERNANCE_BYPASS nodes to KG on every T2/T3 decision in handlers
- [ ] Calibration: graq_learn consumes GOVERNANCE_BYPASS outcome labels to adjust thresholds
- [ ] graq_profile sub-phase hooks (ANCHOR/ACTIVATE/GENERATE/VALIDATE/COMMIT breakdown)
- [ ] graq generate + graq edit CLI commands
- [ ] v0.38.0 release tag
**Blockers:** None

---

### COMMIT 8 — 2026-03-27T12:00:00Z
**Milestone:** Phase 8 complete — GOVERNANCE_BYPASS + TOOL_EXECUTION KG audit nodes, graq gate CLI command (binary exit 0/1, --json, --sarif SARIF v2.1), WorkflowOrchestrator wired in mcp_dev_server. 20 Phase 8 tests pass.
**State:** WORKING
**Files Changed:**
- MODIFIED: `graqle/plugins/mcp_dev_server.py` — GOVERNANCE_BYPASS KG write in _handle_edit/_handle_generate; TOOL_EXECUTION audit node in handle_tool finally block; _handle_workflow wires WorkflowOrchestrator for governed_* types
- MODIFIED: `graqle/cli/main.py` — gate_command added: binary exit 0/1, --diff, --risk, --impact-radius, --approved-by, --justification, --actor, --json, --fail/--no-fail, --sarif (SARIF v2.1)
- CREATED: `tests/test_generation/test_phase8_wiring.py` — 20 tests (GovernanceBypassNodeStructure, BuildBypassNodeUniqueness, GraqGateCLI, ToolExecutionAuditNode, GateCLIRegistration)
- CREATED: `.gsm/decisions/ADR-120-phase8-wiring-gaps.md` — Phase 8 wiring gap analysis rationale
**Key Decisions:**
- GOVERNANCE_BYPASS write uses try/except pass — audit trail MUST NEVER fail the primary operation
- TOOL_EXECUTION node written in finally block with pre-computed _t0 start time — captures latency even on exception
- gate_command exits 1 on blocked (TS-BLOCK or T3 without approved_by) — binary exit for CI pipeline use
- --sarif emits SARIF v2.1 format compatible with GitHub Advanced Security Code Scanning
- gate_command initially lost between sessions (context compaction) — re-inserted in Phase 9 session
**Next:**
- [x] Phase 9: WorkflowOrchestrator state machine
- [x] Phase 9: GovernancePolicyConfig in settings.py
- [x] Phase 9: governance-gate.yml GitHub Actions workflow
**Blockers:** None

---

### COMMIT 9 — 2026-03-27T13:24:05Z
**Milestone:** Phase 9 complete — WorkflowOrchestrator (PLAN→PREFLIGHT→GATE→CODE→VALIDATE→TEST→LEARN), GovernancePolicyConfig in GraqleConfig, governance-gate.yml GitHub Actions. 48 Phase 8+9 tests passing.
**State:** WORKING
**Files Changed:**
- CREATED: `graqle/core/workflow_orchestrator.py` — WorkflowOrchestrator, WorkflowStage, StageStatus, StageResult, WorkflowPlan, WorkflowResult, _STAGE_ORDER; 7-stage enforced state machine; policy-aware (workflow_enforce_gate, workflow_require_preflight, workflow_require_learn); halts on BLOCKED
- MODIFIED: `graqle/config/settings.py` — GovernancePolicyConfig Pydantic model (ts_hard_block, review_threshold, block_threshold, auto_pass_max_radius, audit_tool_calls, workflow enforcement flags); GraqleConfig.governance field with default_factory
- CREATED: `.github/workflows/governance-gate.yml` — GitHub Actions: graq gate on all changed .py files per PR; SARIF merge + upload to Code Scanning; security-events: write permission; gate summary in GITHUB_STEP_SUMMARY
- CREATED: `tests/test_generation/test_phase9_orchestrator.py` — 27 tests: TestGovernancePolicyConfig (7), TestWorkflowOrchestratorTypes (6), TestWorkflowOrchestratorExecute (6 asyncio), TestGraqGateCLIPhase9 (4), TestGovernanceGateWorkflow (4)
- MODIFIED: `tests/test_generation/test_phase9_orchestrator.py` — Unicode encoding fix: Path.read_text(encoding="utf-8") for Windows cp1252 YAML read
**Key Decisions:**
- Named `workflow_orchestrator.py` not `orchestrator.py` — graq_reason (88% confidence, 20+ agents) flagged collision with graqle/orchestration/orchestrator.py
- GovernancePolicyConfig uses default_factory — backward compatible; existing graqle.yaml files without governance: key still work
- WorkflowOrchestrator.execute() halts at first BLOCKED stage — downstream stages never run after gate block
- rollback_triggered=True set on TEST stage failure in WorkflowResult
- Unicode fix: Windows CI uses cp1252 by default; tests reading UTF-8 YAML must specify encoding="utf-8" explicitly
**Next:**
- [ ] Phase 10: tree-sitter AST parsing (Python + JS/TS)
- [ ] Phase 10: policy-as-code YAML DSL
- [ ] Phase 10: secret detection expansion (5 → 200+ patterns)
- [ ] Phase 10: multi-tenant RBAC
- [ ] Phase 10: adversarial test suite (500+ cases)
- [ ] Push updated feature branch to GitHub
- [ ] v0.38.0 release tag after Phase 10
**Blockers:** None
