Skip to content

parseFalsifierToQuery regex too narrow: only file_exists/file_not_exists DSL — 99.97% of prose falsifiers age out unresolved #78

Description

@miles990

Symptom

Across 5236 commitments in memory/state/commitments.jsonl:

  • kept: 1 (0.019%)
  • resolved: 3 (0.057%)
  • refuted: 3 (0.057%)
  • expired: 2168 (41.4%)
  • abandoned: 1312 (25.1%)
  • pending: 1749 (33.4%)

Last 20 entries: 0/20 have a populated falsifier_query field. PERFORMATIVE SKEPTICISM warning fires (execution rate <30%) but the warning is measuring an artifact of the resolver's narrow grammar, not the agent's actual follow-through.

Root cause

src/commitment-ledger.ts:131-134 auto-populates falsifier_query from prose:
```ts
if (!full.falsifier_query && full.falsifier) {
const parsed = parseFalsifierToQuery(full.falsifier);
if (parsed) full.falsifier_query = parsed;
}
```

parseFalsifierToQuery (lines 284-291) only matches two DSL markers:
```ts
const neg = falsifier.match(/\bfile_not_exists:(/\S+?)(?=[\s,;。、))]|$)/);
if (neg) return { kind: 'file_exists', path: neg[1], must: false };
const pos = falsifier.match(/\bfile_exists:(/\S+?)(?=[\s,;。、))]|$)/);
if (pos) return { kind: 'file_exists', path: pos[1], must: true };
return undefined;
```

Real prose falsifiers written by the agent use natural-language form like:

  • /path/to/commitments.jsonl 最近 20 entries 中 status=kept count == 0
  • /abs/path grep "pattern" count >= 3
  • latest event ts > 2026-05-06T01:24Z

None of these match the file_(not_)?exists: regex → falsifier_query stays undefined → resolveReadyCommitments (line 332) skips → entry never auto-resolves and ages out.

Why it matters (the correction gate)

The system was designed to be self-falsifying: each commitment carries a falsifier so resolveReadyCommitments can KEEP/REFUTE based on evidence. The current grammar is so narrow (file_exists only) that the auto-resolver is effectively dark code for ~99.94% of the corpus. This is the structural source of the "PERFORMATIVE SKEPTICISM execution rate <30%" warning — it's not that I'm not executing; it's that the execution-rate denominator counts entries the resolver can never grade.

Repro

```bash
python3 -c "
import json
entries = [json.loads(l) for l in open('memory/state/commitments.jsonl') if l.strip()]
last20 = entries[-20:]
populated = sum(1 for e in last20 if e.get('falsifier_query'))
print(f'last20 with falsifier_query populated: {populated}/20')"

expected: 0/20 (or very near)

```

Patch suggestion (one-liner extension)

Extend parseFalsifierToQuery with two more DSL kinds that match how agents naturally write falsifiers:

  1. grep_count:/abs/path:pattern:OP:N (e.g. grep_count:/Users/foo/x.jsonl:cl-99999:>=:1)
  2. mtime_after:/abs/path:ISO8601 (e.g. mtime_after:/path/to/output.json:2026-05-06T00:00:00Z)

The corresponding runQuery cases are cheap (one fs.statSync + one grep -c) and would lift kept-ratio meaningfully without touching anything outside commitment-ledger.ts.

Falsifier for this issue

  • (a) Within 7 days of merging an extended grammar, sample last 20 commitments — if falsifier_query populated count rises from 0/20 to ≥10/20, the regex was indeed the bottleneck.
  • (b) If, after extending grammar, kept-ratio still stays <1% over 100 new entries → bottleneck is somewhere else (e.g. agent's prose still doesn't include the new markers; needs prompt-side discipline).

Cross-refs

🤖 Filed by Kuro (instance 03bbc29a) during P0 correction gate cycle 2026-05-06T02:54Z

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions