Skip to content

Commit c171c3a

Browse files
rafaelscostaclaude
andcommitted
fix(ids): skip unfilled placeholders in extractPurpose priority chain
Follow-up to PR #748. With body-level matching gone, the priority chain still picked up garbage purposes from files that have literal unfilled template placeholders or JS interpolation in the SOURCES the chain reads: YAML frontmatter, `## Purpose` sections, `# Title` headings. The extractor was technically working — the source data was just full of `{Brief description...}`, `{{TASK_TITLE}}`, and `${context.componentName}` strings that nobody ever filled in. ## What this PR does Adds `looksLikePlaceholder(candidate)` that detects: 1. Whole-string single placeholder: `{Brief...}`, `{{var}}`, `${ctx.x}` 2. Leading-token placeholder: `*${name}foo`, `${ctx.x} bar`, `{Title} extra` 3. Dominant interpolation (>30% of string): catches `${icon} @${id} — ${name}${archetype !== 'Specialist' ? ` (${archetype})` : ''} | ${title}` where most of the string is `${}` blocks The detector is conservative on real prose: - `Manage feature flags with { enabled: true } syntax` → keeps - `Use this skill when... ${variable not present}` (<30% interpolation) → keeps - Empty / whitespace / nullish → keeps (caller handles) Wired into all four `extractPurpose` strategies (frontmatter, `## Purpose`, `## Overview`, `# Title`). When a strategy produces a placeholder, it falls through to the next strategy. When all four produce placeholders, the function returns the generic `Entity at <path>` fallback rather than a nonsense purpose. ## Validation Counted placeholders in `.aiox-core/data/entity-registry.yaml` before and after this PR: ``` $ grep -E "purpose: ['\"]?\{[A-Z]|purpose:.*\{\{|purpose:.*\\\$\\{" \ .aiox-core/data/entity-registry.yaml | wc -l # Before: 16 # After: 0 ``` Examples of entries that now have sensible purposes (or sensible generic fallbacks) instead of unfilled templates: - `*${taskName.replace(/-/g, '-')}` → now resolves via header or falls to `Entity at <path>` - `{Brief description of what this task does and when to use it}` → now falls through to the next strategy - `Generated: ${new Date().toISOString()}` → captured by dominant- interpolation heuristic and skipped - `${icon} @${id} — ${name}${archetype !== ...}` → captured by dominant-interpolation heuristic and skipped ## Tests 12 new tests added to `tests/core/ids/populate-entity-registry.test.js`: - 4 cover `extractPurpose` falling through placeholders at each strategy boundary - 8 cover `looksLikePlaceholder` directly (positive cases for each pattern + negative cases for normal prose that should NOT trip it) Suite: 91/91 pass (was 79/79 on PR #748). ## Why not just fix the source files? The placeholders live in templates and generators — they're SUPPOSED to be unfilled when stored in the framework. They get filled at use- time when the template instantiates an output. The registry's inference is reading the template body as if it were a finished doc, which is the actual bug. Fixing the inference (this PR) is correct; trying to fill the templates would break their template-ness. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d3caa47 commit c171c3a

4 files changed

Lines changed: 985 additions & 843 deletions

File tree

0 commit comments

Comments
 (0)