Skip to content

Commit 1f97f6f

Browse files
rafaelscostaclaude
andauthored
fix(ids): scope purpose inference + sync self-entry on regen (#748)
* fix(ids): scope purpose inference + sync self-entry on regen Closes the cosmetic follow-up noted after PR #747 — CodeRabbit's "Outside diff range" comments about entity-registry self-entry drift and the `component-creation-guide` purpose field reading "Analyzes provided dataset to identify patterns and insights" (clearly unrelated to a component creation guide). ## Bug 1: purpose inference matched body text it shouldn't have `extractPurpose()` in `populate-entity-registry.js` had a fallback regex: ```js const descMatch = content.match(/(?:description|purpose|summary)[:]\s*(.+)/i); ``` This is case-insensitive and unanchored — it matched ANY occurrence in the file body, including example output inside installer transcripts and fenced code blocks. For `component-creation-guide.md`, it picked up line 132: ``` ? Task description: Analyzes provided dataset to identify patterns and insights ``` …which is example output showing what a user might type, not a description of the guide itself. Fix: restructured `extractPurpose()` to a stricter priority chain: 1. **YAML frontmatter** — `description:` (or aliases) inside the `---` block at the top of the file. Anchored to the frontmatter region so body matches can't leak in. 2. **`## Purpose` section** — first non-empty line. 3. **`## Overview` section** — same shape as Purpose. Many guides use Overview instead (e.g. component-creation-guide.md itself). 4. **First `# Title` heading** — the document's name. 5. **Generic fallback** — `Entity at <path>`. The previous body-level `(?:description|purpose|summary)[:]` regex was REMOVED deliberately. Its false-positive rate (matching example output, installer transcripts, code block content) outweighed the narrow legitimate case it covered, which is now handled by the frontmatter branch. ## Bug 2: self-entry drift in `entities.data.entity-registry` The registry contains a record for itself because the data layer scan picks up every `.yaml`. That record's `lastVerified` was stuck at whatever value the previous scan happened to write, and the `checksum` was likewise stale relative to the regenerated file. Fix: added `syncSelfRegistryEntry()` which runs after the registry object is assembled but before yaml.dump. It: - Sets `lastVerified` to the same `lastUpdated` timestamp written into `metadata.lastUpdated` (single source of truth for this regen event). - Sets `checksum` to a sentinel value `sha256:<self-reference>` because hashing the registry from inside the registry is circular — any computed hash invalidates itself the moment it's written. The sentinel signals "skip this comparison" to downstream validators; trying to compute a "real" hash here would just produce a number that doesn't match its own input. The sync is guarded: it only fires when the self-entry's `path` field is `.aiox-core/data/entity-registry.yaml`. The companion `entity-registry.js` module under `entities.modules.*` is NOT self-referential and is left alone. ## Validation Regenerated the registry on this branch. After the fix: - `grep -c "Analyzes provided dataset" .aiox-core/data/entity-registry.yaml` → `0` - `grep -c "Add MCP Server Task" .aiox-core/data/entity-registry.yaml` → `0` (was the wrong purpose on the yaml self-entry) - The yaml self-entry's `lastVerified` now matches `metadata.lastUpdated` exactly - The yaml self-entry's `checksum` is the sentinel as expected The `component-creation-guide` entity is no longer in the registry at all — the file lives under `.aiox-core/core/docs/` which is not in `SCAN_CONFIG` (the `modules` scan covers `.aiox-core/core` but only for `*.js`/`*.mjs`, not `*.md`). Its previous presence was an artifact of a prior scan run with broader config; this regen cleans it up. If we want to start tracking framework docs as entities, that's a separate concern handled in a follow-up to SCAN_CONFIG. ## Out of scope for this commit A second-order cleanup that this PR does NOT do: there are still some purposes in the registry that look like leaked template placeholders (`'{Brief description of what this task does...}'`, `'{{TASK_TITLE}}'`, `'*${taskName.replace(...)}'`). Those come from files whose own bodies contain unfilled handlebars or JS literals — the inference is technically working, the source is the problem. Separate from this fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(ids): align extractPurpose tests with refactored priority chain The previous suite had a test "extracts from description field" that fed a bare `description: ...` string and expected it to be matched. That was exactly the body-level fallback regex that produced the "Analyzes provided dataset" false purpose on component-creation-guide.md (reported by CodeRabbit on PR #747). The refactor in this PR intentionally removed that match, so the test must be updated to reflect the new contract. Changes to the test file: * Replaced "extracts from description field" with two replacement tests: - "extracts from YAML frontmatter `description:` field" — feeds a `---\ndescription: X\n---` block and expects extraction from it. - "handles quoted YAML frontmatter description" — feeds `description: "X"` inside frontmatter and expects the quotes to be stripped. * Added "falls back to ## Overview when no Purpose section" — covers the new strategy 3 in the priority chain (many guides like component-creation-guide.md use Overview instead of Purpose). * Added TWO regression tests for the bug that motivated the refactor: - "does NOT match body-level `description:` outside frontmatter" — reproduces the exact component-creation-guide pattern (Overview section + a fenced code block with `Task description:` inside) and asserts the Overview wins. - "does NOT extract from `description:` lines without YAML frontmatter delimiters" — bare `description: X` without `---` delimiters falls through to the `# Title` header, NOT to the body line. Test result: 79/79 pass. Existing 5 tests in the suite still pass. Two new tests cover the YAML frontmatter branch (priority 1) and the new `## Overview` branch (priority 3). Two regression tests lock in the removal of the body-level matcher so it can't silently come back. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e5cd355 commit 1f97f6f

4 files changed

Lines changed: 1498 additions & 1285 deletions

File tree

0 commit comments

Comments
 (0)