Skip to content

Hierarchical path-scoped resource section references (no flat-slug flattening) + anchor validation #141

Description

@m2ux

Summary

This issue is about the general resource-reference mechanism in get_resource — not any one workflow's resource files.

Today get_resource resolves a section anchor as a single flat slug: extractMarkdownSection matches the first heading at any level whose GitHub-style slug equals the anchor (src/tools/resource-tools.ts:89-98), and parseResourceRef splits the section on the first "#" only (src/tools/resource-tools.ts:55-71). A leaf section therefore cannot be addressed through its parent, and the only namespace is the filename — two resources can each carry a "## Rule" heading only because they live in different files.

Add path-scoped section references so a section is addressed by its heading path and resolved hierarchically, with no flattening. Example shape:

get_resource { resource_id: "some-resource#parent-section/child-section" }
  -> narrow to parent-section, then resolve child-section ONLY within it

Motivation

This surfaced while discussing whether a workflow could merge several single-concept resource files into one file referenced by section. Under flat addressing such a merged file would need globally-unique heading slugs (or filename-prefixed slugs) — hand-maintained discipline replacing the free, filesystem-enforced namespace that separate files give today. Path-scoped addressing removes that constraint: duplicate leaf names are disambiguated by their parent path.

Proposed change (backward-compatible)

  • parseResourceRef: treat the section part as a delimiter-separated path (parent/child -> ["parent", "child"]).
  • extractMarkdownSection: walk the path — match segment 1 to its [start,end) window (heading + body up to the next same-or-higher heading); search segment 2 ONLY within that window; repeat; return the final window. Stay fence-aware.
  • A single-segment path is exactly today's behavior, so every existing anchor reference across all workflows keeps working unchanged.
  • Contained to src/tools/resource-tools.ts (+ unit tests).

Delimiter

Recommend extending only the section part: id#parent/child ("#" already means section, "/" is unused inside it, and it stays visually distinct from the technique "::" delimiter). "::" was floated but overloads the technique-ref delimiter and blurs resource-vs-technique refs. Decide on adoption.

Close the static-validation gap

Resource anchor references are not validated anywhere today — validate-workflow-yaml only checks designator bracing (scripts/validate-workflow-yaml.ts:61-80) and check-all-refs does not touch resource links; a broken anchor surfaces only at runtime when get_resource throws. Add a validator that resolves every resource section-path reference in technique .md files against real headings (extend check-all-refs or add a new script), so path-scoped refs gain a compile-time guard.

Acceptance criteria

  • get_resource resolves multi-segment section paths (a/b/c) hierarchically, each segment scoped to the prior segment's window; fence-aware.
  • Single-segment refs behave exactly as today (backward compatible); existing workflows' resource refs unaffected.
  • An unmatched or ambiguous path segment errors clearly (which segment failed, in which scope).
  • Static validator resolves all resource section-path refs in technique files; an npm run guard is added.
  • Tests cover nested resolution, duplicate leaf slugs under different parents, single-segment back-compat, and fenced-code headings being ignored.

Out of scope

Refactoring any specific workflow's resource files (for example, merging multiple resource files into one). That is an optional follow-up this change would enable, tracked separately if pursued — it is NOT part of this issue.

Status

Postponed; not blocking any current PR.

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