# Evolution Log — ievo-cli

## 2026-03-03: SDD pipeline skip — spec-writer bypassed before implementation

**Trigger:** POST-IMPLEMENTATION
**Agent:** coder (acting as general assistant)
**Confidence:** high

**Finding:** New CLI requirements (auto-init with confirmation, TUI-first model, command deprecation) were planned and partially implemented without first running spec-writer to produce formal REQ specs. The pipeline entry point was user requirements → implementation plan → code, skipping the mandatory Spec Writer step entirely.

**Root cause:** The earliest pipeline point where this could have been caught is at the user→agent handoff. When a user says "let's add X", the responding agent (in this case the general assistant / coder context) interpreted that as a direct work request rather than as a backlog item requiring spec formalization. The IEVO.md pipeline rule "Idea → Spec Writer → REQ-xxx → Architect → Coder" was not enforced at session start.

**Proposed mutation:** coder — add guard rule: "If you are asked to implement a feature and no REQ-xxx file exists for it in `.ievo/spec/requirements/`, STOP. Delegate to spec-writer first. Do not begin planning or coding before a `ready` REQ exists."

**Issue:** https://github.com/ievo-ai/curator/issues/1

---

## 2026-03-03: Git flow assumption — agent committed without checking workflow conventions

**Trigger:** POST-IMPLEMENTATION
**Agent:** coder (acting as general assistant / main session)
**Confidence:** high

**Finding:** The agent committed directly to the current branch (`test/full-cycle-v3`) in response to a user saying "let's commit", without first verifying: (1) the project's git workflow model, (2) whether a feature branch should be created, (3) the branch naming convention, (4) the PR target branch. The coder's File Conventions section lists a branch naming pattern (`feat/REQ-xxx-<short-description>`) but contains no pre-flight gate that enforces actually creating a branch before committing to it.

**Root cause:** The earliest pipeline point is the Architect's plan creation. The Architect defines the implementation plan including commit strategy, but does NOT include a step to confirm git flow conventions before the first commit. This means the Coder inherits no verified git context and fills the gap with a default assumption (commit in place). The secondary root cause is the Coder's own session start: it reads memory files but there was no git flow entry in DECISIONS.md to read, and no rule requiring it to ask if none exists.

**Proposed mutation:** Two-agent change needed.

**Architect** — add to plan format and rules: "Include a Git Workflow step as the first step of every plan. Read DECISIONS.md for a D-xxx entry on git flow. If none exists, create a `Q-NNN-git-flow.md` question before planning commit steps. Do NOT specify commit targets until git flow is confirmed."

**Coder** — add to Pipeline Guard (runs before anything else): "Before the first commit of any requirement: check `.ievo/memory/DECISIONS.md` for an entry documenting git flow (branch naming, PR target, workflow model). If no such entry exists → STOP. Ask the user: 'What is this project's git flow? (e.g., trunk-based with short-lived branches, gitflow, etc.) I need this before committing.' Save the answer as a new D-xxx entry in DECISIONS.md."

**Issue:** https://github.com/ievo-ai/curator/issues/2

---

## 2026-03-03: Mock-over-state — agent mocked a function instead of setting real config state

**Trigger:** POST-IMPLEMENTATION
**Agent:** coder (acting as general assistant)
**Confidence:** high

**Finding:** CI failed because `test_auto_init_creates_project` called `init.init()` which triggered `prompt_github_auth()` → `input()` — stdin is captured in CI. The agent's first fix was to mock `prompt_github_auth` at its import path (`patch("ievo.core.github_auth.prompt_github_auth")`). The user identified this as wrong: the correct fix is to write a real `config.json` with `{"github_auth": "gh_cli"}` into the test's home directory so `get_config()` returns a non-None value and `prompt_github_auth` is never called at all. No function mock is needed.

**Root cause:** The agent defaulted to "mock the symptom" (the function that throws) rather than "satisfy the guard condition" (provide real state that the guard reads). The guard condition is `get_config(home, "github_auth") is None` — this was ignored. The CLAUDE.md working rule "Mocks are acceptable ONLY for true external boundaries (Docker daemon, network APIs, subprocess calls). Everything else should use real objects and real filesystems (tmp_path)" was present but not applied. `prompt_github_auth` is not an external boundary — it is application logic with a guard, and the correct approach is to satisfy the guard, not bypass the function.

**Proposed mutation:** coder — add to testing rules: "When a CI failure is caused by a function that reads user input, do NOT mock that function unless it is a true external boundary. Instead, find the guard condition that prevents the function from being called and satisfy it with real state (e.g., write config.json with the expected key). Mocking internal application logic hides the real code path and silently passes after import changes. The rule: identify the guard, satisfy it, verify real behaviour."

**Issue:** https://github.com/ievo-ai/curator/issues/3

---

## 2026-03-03: Information disclosure — sensitive details posted to public repository

**Trigger:** POST-ACCEPTANCE (process violation caught by user review)
**Agent:** evolution (self)
**Confidence:** high

**Finding:** The evolution agent posted three GitHub issues to a public repository. Each issue contained internal implementation details — literal code snippets, internal config key names, module paths, file structure conventions, and agent instruction text. The user had to manually redact all three issues. No harm was done to users, but internal architecture was exposed publicly.

**Root cause:** The evolution agent's sanitization rule existed only as a general guideline ("relative paths only, no tokens/secrets") and covered credentials, not architecture. The agent optimized for analytical completeness — concrete examples make findings actionable — without recognising that "public repository" changes the audience from "project team" to "anyone on the internet". The gap: the rule drew the line at secrets but said nothing about structural/architectural details that reveal how the system works.

**Proposed mutation:** evolution agent — add an explicit audience check as a mandatory pre-posting step. Before creating any external issue: (1) identify the audience (public repo = anyone), (2) strip all structural details (config key names, file paths, module names, code snippets, agent instruction text, naming conventions), (3) replace with abstract descriptions of the PATTERN (e.g., "the agent lacked a rule about X" not "the agent's rule in section Y says Z"). The issue body must be passable as a blog post with no context — readers should understand the error class and proposed fix without learning anything about the project's internals.

**Issue:** https://github.com/ievo-ai/curator/issues/4

---

## 2026-03-03: Narrow-scope PR diagnosis — agent stopped at first blocker found

**Trigger:** POST-IMPLEMENTATION (process failure caught by user intervention)
**Agent:** coder (acting as general assistant)
**Confidence:** high

**Finding:** When asked "why is the PR blocked?", the agent checked only CI status. It found a test failure, fixed it, and treated the task as complete. Two other blockers were present: the branch was behind the base branch (requiring a rebase/update), and a reviewer bot had filed change requests. The user had to prompt the agent twice to surface these additional blockers. The agent's diagnosis procedure was one-dimensional — it mapped "PR blocked" to "CI failed" and stopped at the first matching signal.

**Root cause:** The earliest pipeline point where this could have been caught is in the agent's session start for any PR-check task. No systematic PR health check procedure existed. When tasked with "find why this PR is blocked", the correct procedure is to collect all blocking signals in parallel before acting on any one of them: CI status, merge state, review decisions, and branch freshness relative to base. The agent had no mental model distinguishing between "the first blocking thing I found" and "all blocking things". The narrowness is a process gap — no checklist existed for PR health diagnosis, so the agent defaulted to the single signal it checked first.

**Proposed mutation:** coder — add a PR health check procedure to the toolkit of known multi-step operations. When the task is "check why this PR is blocked" or equivalent, the correct sequence is: (1) check CI status, (2) check merge state and review decisions, (3) check branch freshness relative to the base branch, (4) check for open review requests. Report ALL blocking signals before beginning any fix. Do not assume the first signal found is the only signal.

**Issue:** https://github.com/ievo-ai/curator/issues/5

---

## 2026-03-03: Evolution lesson propagation gap — lessons logged but never applied to working docs

**Trigger:** POST-ACCEPTANCE (process failure caught by user review)
**Agent:** evolution (self)
**Confidence:** high

**Finding:** After logging E-001 through E-005 and decisions D-012 through D-015, the evolution agent stopped without propagating those lessons to the working documentation agents actually read (CLAUDE.md). All five evolution entries and four decisions existed in `.ievo/` reference files but produced zero changes to agent behavior — none of the new rules appeared in CLAUDE.md. The user confirmed this with a grep check.

**Root cause:** The earliest pipeline point where this could have been caught is the evolution agent's own workflow definition. The evolution workflow as specified ends at: (1) log locally to evolution.md, (2) sanitize, (3) file curator issue. No step exists for "propagate lessons to working docs". This means evolution can complete a full cycle without producing any behavior change in future sessions — a silent no-op.

**Proposed mutation:** evolution agent — add a fourth mandatory step after curator issue creation: "Propagate to working docs." For any lesson that affects agent behavior rules: identify the governing document (CLAUDE.md for project-wide rules, agent ROLE.md for agent-specific rules), add a concise one-liner rule to the appropriate "Working rules" section, verify the rule is consistent with existing rules. Evolution is not complete until the lesson is in the document agents read.

**Issue:** https://github.com/ievo-ai/curator/issues/6

---

## 2026-03-03: Documentation gap — public API committed without meaningful docstrings

**Trigger:** POST-IMPLEMENTATION (quality gap caught by user review)
**Agent:** coder
**Confidence:** high

**Finding:** Two new modules (a business logic module and a command module) were committed and merged without meaningful docstrings. The enum class had no class-level docstring at all. The command function's docstring was a one-liner that did not explain the flow, exit conditions, or side effects. The user had to explicitly ask why the code was undocumented before a fix commit was made.

**Root cause:** The Coder's acceptance self-review checklist ("Acceptance before done" rule) enumerates test types, coverage thresholds, and user-facing docs updates. It does not mention code-level documentation (docstrings on public functions, classes, and enums). Without an explicit rule, docstrings are treated as optional and skipped under time pressure. The earliest pipeline point where this could have been caught: the Coder's pre-commit self-review — a docstring presence check was absent from the definition of done.

**Proposed mutation:** coder — extend the "Acceptance before done" checklist with: "All new public functions, classes, and enums must have a docstring that explains WHAT it does, key parameters/return values, and any non-obvious behavior (e.g., exit codes, side effects, fallback logic). A one-liner that restates the function name is insufficient."

**Issue:** https://github.com/ievo-ai/curator/issues/7

---

## 2026-03-03: Dual-check inconsistency — two functions checking the same logical condition used different physical predicates, causing deadlock

**Trigger:** POST-ACCEPTANCE (bug reported after implementation)
**Agent:** coder
**Confidence:** high

**Finding:** A project-existence check in the init command used a weaker predicate (directory present) than the project-root detection function (manifest file present). This created a dead state: the project-root detector saw no project and offered to initialize; when the user accepted, the init command saw the directory and refused — locking the user out.

**Root cause:** The earliest pipeline point where this could have been caught is the Architect's plan. The plan did not specify a single canonical predicate for "project is initialized". The Coder implemented the guard independently in two places, choosing different physical checks. The test for the init guard used an unrealistic fixture (directory without manifest) that exactly matches the dead state — but it was not combined with the integration path that leads there (root-detector → auto-init → init-guard), so the deadlock was never exercised.

**Proposed mutation:**

**Coder** — add to implementation rules: "When the same logical condition (e.g., 'project exists') must be checked in multiple places, define a single canonical predicate and use it everywhere. Never re-implement the check inline. If the condition already has a canonical implementation, call it; do not copy it with slight variations."

**Coder** — add to testing rules: "For guard conditions that gate user-facing actions, write an integration test that exercises the full trigger path — not just the guard in isolation. If guard A leads to action B which has guard C, test the sequence A→B→C end-to-end with the state that triggers the deadlock."

**Issue:** https://github.com/ievo-ai/curator/issues/8

---

## 2026-03-03: Mock-only TUI tests — focus, rendering, and interaction bugs invisible without real widget lifecycle

**Trigger:** POST-ACCEPTANCE (bug reported after implementation)
**Agent:** coder
**Confidence:** high

**Finding:** The TUI app launched with focus on an internal navigation widget (tab strip) instead of the primary interactive widget (agent list). Users could not interact with the agent list without first pressing Tab. The bug was present from the first commit of the TUI. All existing TUI tests passed — zero tests detected the broken focus state.

**Root cause:** All TUI tests were written as unit-level tests that mocked widget internals or patched data-loading functions. None mounted the real application or exercised the widget lifecycle. Focus is assigned by the framework at mount time, after the full widget tree is composed. A mock-based test never triggers mounting, so the initial focus state is never established and never observable. The CLAUDE.md rule "don't just mock widgets, test the real Textual app lifecycle" existed but did not explicitly identify focus, keyboard navigation, or post-mount interaction state as behaviors that require real lifecycle tests. Without that specificity, the coder's test coverage appeared complete while an entire class of observable behavior — what the app looks like and how it responds to keyboard input from the first frame — was untested.

**Proposed mutation:**

**Coder** — extend the TUI testing rule with explicit required coverage: "TUI Pilot tests MUST verify at minimum: (1) which widget holds focus on launch, (2) keyboard navigation between focusable widgets, (3) primary interactive actions (selection, toggle, confirmation). These behaviors are invisible to mock-based tests and must be covered by tests that mount the real application via the framework's test runner."

**Issue:** https://github.com/ievo-ai/curator/issues/9

---

## 2026-03-04: Context-document pollution — visual artifact added to machine-read context file

**Trigger:** POST-IMPLEMENTATION (error caught by user review)
**Agent:** coder (acting as general assistant)
**Confidence:** high

**Finding:** An ASCII diagram was added to a context-critical document that is auto-loaded into every agent session. The user rejected the change immediately: the diagram serves human communication but inflates context size for no machine benefit. The change had to be reverted.

**Root cause:** When the user asked "что добавить?" (what to add?) after a diagram was shown in chat, the agent interpreted this as a file-editing directive rather than a conversational question about whether documentation was needed. The agent defaulted to modifying the most semantically relevant file it knew about — the context document — without considering whether that file's purpose (machine-read context) was compatible with the content type (human-readable visual). No rule existed distinguishing between files that serve agent context loading versus files that serve human documentation. The earliest pipeline point where this could have been caught: before any edit to a context-loaded file, classify the content being added and verify it is not a human-only artifact.

**Proposed mutation:** coder — add to working rules: "Context-loaded files (files that agents load at session start) must stay concise and machine-actionable. Visual artifacts — ASCII diagrams, illustrative flowcharts, large tables for human orientation — belong in README, docs/, or chat output only. Before editing any context-loaded file, ask: does this content serve agent reasoning, or human reading? If human reading only, do not add it to context files."

**Issue:** https://github.com/ievo-ai/curator/issues/11

---

## 2026-03-04: Convention-documentation gap — new structure created without updating pipeline reference

**Trigger:** POST-IMPLEMENTATION (gap caught by user review)
**Agent:** coder (acting as general assistant)
**Confidence:** high

**Finding:** A new `.ievo/` subdirectory and naming convention were established during a session. The pipeline reference document was NOT updated at the same time. The convention existed in practice but was absent from the document agents load at session start. The user had to explicitly point this out before documentation was written.

**Root cause:** The pipeline reference document was treated as a place for user-requested rules, not as a document that must be updated proactively whenever any agent establishes a new convention. No rule existed requiring that "creating a new structure" and "documenting the convention" are one atomic action. The gap was structural — there was a rule for retrospective documentation after explicit feedback, but no trigger for proactive documentation at the moment of creation.

**Proposed mutation:** kernel (iEVO.md Best Practices) — add rule: "Any time a new `.ievo/` directory, file type, or naming convention is established — document it in the pipeline reference under the relevant Best Practices section before the session ends. Creating a structure and documenting the convention are one atomic action."

**Issue:** https://github.com/ievo-ai/curator/issues/10
