Skip to content

[Bug] project.py phase extraction matches stray "phase:" prose in log entries #68

Description

@francescostanzo1-hub

Description

project.py's log-entry parser extracts the walnut phase with a greedy, unanchored regex over the entire latest log entry (scripts/project.py, ~line 125):

phase = "unknown"
phase_match = re.search(r"phase:\s*(.+)", entry_text, re.IGNORECASE)
if phase_match:
    phase = phase_match.group(1).strip()
else:
    # narrative keyword fallback (launching/building/designing/...)
    ...

Two problems compound:

  1. re.search returns the first phase: occurrence anywhere in the entry — including ordinary narrative prose, a quoted sentence, or a code block — not a designated structured/frontmatter field.
  2. (.+) greedily captures the rest of that line. So an entry containing a sentence like ...revisited the phase: still early design work and vendor research... sets now.json's phase to that whole prose fragment instead of a clean state word.

The keyword fallback (the else branch) only runs when no phase: token exists at all, so it cannot rescue a false positive once any phase: substring is present in prose.

Impact

now.json's phase field is surfaced in the world dashboard, the load-context brief pack, and the generated world index. When it captures stray prose, every one of those surfaces misrepresents walnut state (e.g. a phase shown as a full sentence rather than designing).

Expected Behaviour

Phase should be read from a designated structured location (log-entry frontmatter, or an anchored state line) and validated against the known phase vocabulary, rather than a greedy first-match over free text.

Suggested Fix

  • Anchor the match to a line start after stripping (e.g. ^\s*phase:\s*(\S+)), or read the phase from the entry's frontmatter rather than the body.
  • Validate the captured value against the existing phase_keywords set; if it isn't a known phase, fall through to the narrative keyword scan instead of trusting the raw capture.
  • Optionally capture only a single token ((\S+)) rather than (.+).

System

  • Plugin: 3.2.0
  • Engine: claude-opus-4-7
  • OS: MINGW64_NT-10.0-26200 (Windows 11)
  • Context: unavailable

Sent via /alive:feedback

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions