Skip to content

[Proposal] Automatic spec catalog discovery during proposal creation #901

Closed as duplicate

Description

@sh940701

Problem

The current proposal instruction says:

Check openspec/specs/ for existing spec names.

This is the only guidance the AI gets for discovering existing specs. In practice:

  1. The AI often skips this step entirely — there's no structured mechanism to enforce it, just a vague hint buried inside a larger instruction block
  2. When it does check, it reads full spec files into context — wasteful when you only need to know what exists and what each spec is about
  3. As specs grow, this scales poorly — a project with 20+ capabilities would dump thousands of lines into context just to decide which are relevant

This is exactly why main specs feel underutilized, as raised in #878 ("What's the point to maintain main specs?") and #872 ("openspec files too many"). The specs exist, but the workflow doesn't actively leverage them at the most critical moment — when deciding what a new change touches.

Why this matters at scale

For small projects with 2-3 specs, manually browsing openspec/specs/ works fine. But for teams adopting OpenSpec as a serious engineering harness — especially at enterprise scale with dozens of capabilities across multiple domains — the current approach breaks down:

  • An AI agent scanning 30+ spec directories and reading full files burns significant context just for discovery
  • Without structured discovery, capabilities get duplicated or contradicted across changes
  • The value proposition of accumulated main specs falls apart if they're not reliably consulted

For OpenSpec to serve as a scalable, enterprise-grade development harness, spec discovery needs to be a first-class, structured step — not an afterthought buried in a paragraph.

Proposed Solution

Replace the vague "check openspec/specs/" instruction with a concrete spec discovery step in the proposal instruction, using the CLI to get a lightweight catalog.

Before (current)

Check `openspec/specs/` for existing spec names.

After (proposed)

Before filling this in, run `openspec list --specs --json --detail` to discover
existing specs. Review each spec's `overview` to understand what it covers.

This gives the AI a structured, repeatable workflow instead of a vague hint. The --detail flag (from #700) provides just enough context — id, title, overview, requirementCount — to determine relevance without loading full spec content.

Example output:

{
  "specs": [
    {
      "id": "routine-routing",
      "title": "routine-routing",
      "overview": "Defines in-app routing, deep links, and push notification routing for routine screens.",
      "requirementCount": 8
    },
    {
      "id": "pool-search",
      "title": "pool-search",
      "overview": "Swimming pool search with map integration and region-based filtering.",
      "requirementCount": 12
    }
  ]
}

An AI reading this can immediately tell whether a new "push notification for pool recommendations" change should modify pool-search, routine-routing, or create a new capability — without reading either spec in full.

Extended Proposal: Sub-agent Optimization

For tools that support sub-agents or parallel task execution (e.g., Claude Code's Agent tool, Codex sub-tasks), the discovery step could be delegated to a separate context:

  • A sub-agent runs openspec list --specs --json --detail, compares each spec's overview against the proposal description, and returns only the related specs with reasons
  • Main context stays clean — the discovery work happens in a disposable context
  • This scales to 50+ capabilities without bloating the proposal context

This is entirely optional — tools without sub-agent support just run the CLI inline. The core proposal (structured CLI-based discovery) works everywhere regardless.

Related Issues

Issue How this helps
#878 ("What's the point to maintain main specs?") Directly answers this — main specs become actively queried during every proposal via their Purpose/Overview
#872 ("openspec files too many") Overview-based filtering avoids loading full spec content, making large spec collections manageable
#700 (PR: list --specs --json --detail) Creates the first real consumer for --detail, giving it a concrete use case in the workflow
#687 ("Incomplete specs after proposal") Structured discovery reduces missed capabilities — the AI sees all existing specs before writing Capabilities

Scope

  • What changes: The proposal artifact instruction in schema.yaml and the proposal guidelines in skill/command templates (continue-change.ts)
  • What doesn't change: No new CLI commands, no new artifacts, no schema structure changes
  • Dependency: Best with feat: list cmd support json for specs and archive #700 (--detail flag) merged. Without it, the fallback is openspec spec show <id> --json per spec, which still works but requires N calls instead of one.

Alternatives Considered

  1. New artifact (discovery.md) — Rejected. Discovery is input to the proposal, not a standalone deliverable. Adds overhead to every change even when there are only 2 specs.

  2. Separate /opsx:discover command — Rejected. If it's manual, people won't use it. The whole point is that spec discovery should be embedded in the proposal workflow.

  3. Inject full spec catalog into openspec instructions output — Possible but heavy. The proposed approach lets the AI call the CLI on-demand, which is simpler and doesn't bloat the instruction payload.

Activity

  1. added 3 commits that reference this issue on Apr 2, 2026
    4023bd7
    eca7a04
    9ae8e0b
  2. TabishB commented on Apr 7, 2026

    @TabishB
    Contributor

    I definitely agree that subagent optimization is important; we'll add it after we do some refactoring. Not all coding agents support subagents, and the way to embed them in the skill varies by coding agent.

    We can even be smarter and use multiple subagents for search and retrieval.

    I'm little unsure about making the process more structured, from the trend in the last 6 months, it seems like models work better when using standard bash tools like grep, find etc to be able to figure out what files exist then figure out what they need to go read in that file.

    Most likely, we'll have to add some evals to figure this part out. My current intuition is that there's nothing wrong with telling the model, "Hey, here's our spec directory. Go figure out what specs are relevant to the task at hand."

    but thanks, this is a well thought out proposal.

  3. alesky78 commented on Apr 10, 2026

    @alesky78

    Hello @TabishB

    let me describe my Use case

    I’m facing a very similar situation to @sh940701 .

    I work on enterprise scale applications with very long lifecycles (often 10+ years).
    Over such long periods of time, teams change completely, original developers leave, and institutional knowledge is gradually lost.
    One of the main reasons why I chose OpenSpec over other SDD tools was spec-linking: the ability to explicitly link requirements, past specifications, and behavior to generated artifacts and code.

    The scale, in this UC, is the critical factor.
    In applications with 300k–500k lines of code, witch continuous software development, is very easy to end up with hundreds of specifications covering functional behavior, edge cases, and domain rules in just 1 year.

    At that scale, an unstructured approach simply does not work...
    I already seen cases when the agent miss the spec, and this open also another topic:
    "How to drive openSpec to impact spec already exist instead that crete brand new" and avoid the spec fragmentation/pollution
    but this is for another post...

    A structured, spec-centric way to organise, discover, and navigate specifications becomes fundamental in this UC.
    We have teams of multiple developer analyst and architect that debate on the proposal.md and spec.md before proceed whit the implementation

    For us, structure spec-linking is therefore not a nice-to-have, but a core requirement for long-term maintainability, scalability of specifications, and continuity across team changes.

    I'm little unsure about making the process more structured, from the trend in the last 6 months, it seems like models work better when using standard bash tools like grep, find etc to be able to figure out what files exist then figure out what they need to go read in that file.

    this opinion is comprensibile but how it will work when we will arrive to hundreds of spec?

  4. fsmw commented on Jul 3, 2026

    @fsmw

    +1 to this. I hit the same issue in my own repo (~30 specs).
    Concrete example: when proposing a "dark mode" change, the AI
    just skipped the spec check entirely and created proposal.md
    without listing existing capabilities like theme-handling or
    ui-config that it should have been comparing against.

    The current Check openspec/specs/ for existing spec names.
    instruction in schema.yaml is a vague hint — the AI treats
    it as optional. I read through the code in
    src/core/artifact-graph/instruction-loader.ts:generateInstructions
    and confirmed: nothing in the proposal workflow injects
    existing specs into the model's context. The model has to
    discover them on its own, and it usually doesn't.

    I just opened PR sh940701#1 that addresses both
    CodeRabbit review items from #902. Discovery now reads
    ## Purpose from each openspec/specs/<id>/spec.md as a
    fallback if --detail isn't available. Tests + lint + typecheck
    pass.

  5. buchenzhang commented on Jul 30, 2026

    @buchenzhang

    @fsmw

    Sharing our experience from an enterprise setup, as a data point for this discussion.
    We're a finance-tech team (invoice systems, 500k+ LOC Java monorepo) using OpenSpec with a customized spec-driven schema. Instead of waiting for structured CLI discovery, we worked around the exact problem described here — by rewriting the vague hint in schema.yaml into operationalized, step-by-step instructions:
    In the proposal instruction, we upgraded "Check openspec/specs/ for existing spec names" to a hard contract: "The capability list is the contract between proposal and specs stages. You MUST research existing specs before filling it in."
    For modified capabilities, we added a concrete 4-step workflow into the specs instruction:
    Locate the existing requirement in openspec/specs//spec.md
    Copy the full requirement block (from ### Requirement: through all scenarios)
    Paste it under ## Modified Requirements and edit to reflect the new behavior
    Ensure the heading text matches exactly
    Our observation after several real changes: the model consistently reads existing specs and prior artifacts when the instruction is written as explicit numbered steps, and treats it as optional when it's a one-line hint. This independently corroborates @sh940701's key insight in #902 — the difference between "guidance text" and "first-class workflow steps" is dramatic in practice.
    On @TabishB's point about models doing well with bash tools (grep/find): we do see the model spontaneously exploring openspec/changes/ history on its own sometimes — but it's not reliable. It happens on some tasks and not others. For anything that must happen every time (like spec discovery before writing the Capabilities section), we found prompt-level free exploration is not a substitute for an explicit step.
    So from our experience, the two approaches aren't mutually exclusive: let the model explore freely for context-gathering, but make spec discovery an explicit, numbered step in the workflow. The structured step doesn't even need --detail or new CLI features to be useful — even "read the ## Purpose section of each spec before classifying capabilities" (as sh940701#1 does) already changes model behavior significantly.
    Hope this helps as real-world evidence. +1 to landing #902.

  6. clay-good commented on Oct 27, 2026

    @clay-good
    Collaborator

    Thanks, @sh940701, and everyone who shared their setup here. This is now tracked in #2021, which has the CLI give the agent a short list of existing specs (name, purpose, requirement count) before it writes a proposal. Closing in favor of that one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    design-reviewNeeds product/design decision

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions