Skip to content

Fold graduated-discovery removal into /nxs.discover --close #262

Description

@sameera

Problem

A discovery folder is removed by two different owners today, and only one of them is a command.

When a discovery concludes that no build follows, /nxs.discover --close writes the lessons note and removes the folder in one commit. When a discovery concludes that a build does follow, it graduates through /nxs.epic --discovery, and nothing removes the folder. /nxs.epic commits nothing on any path, which is its stated contract, so it only reports that the folder is consumed and can be removed. Actually removing it depends on the user making a plain commit, and the instruction to do so exists only in a session report that scrolls away.

The constraint at .claude/commands/nxs.discover.md:633 states this directly: the folder is removed by exactly two acts, closing a discovery with no build, or a human removing it after graduation.

This was observed on the discovery of "installing Nexus components outside the target repo". It graduated on 2026-08-16 into backlog stubs #247 through #260 and tracking issue #261. The folder at .nexus/discovery/discover-user-level-component-install-c258b359/ is still in the working tree.

A second gap follows from the first. The status field accepts open and closed, and closed means no build follows. A graduated discovery therefore stays status: open, so it cannot be told apart from a discovery that is still in flight. The example above still reads status: open today.

Decision

--close becomes the single terminal act for a discovery and covers both endings. It determines which ending occurred rather than requiring the user to know, and it removes the folder after confirmation in both cases.

Phase C0 already stops and asks, so this grows a third state rather than a new action:

Detected Offer
Every ticket resolved, no filed stubs found Close. Write the lessons note and remove the folder, in one commit. This is today's behaviour.
Every ticket resolved, stubs found, gists verified Remove. Stamp status: graduated with the issue numbers, then remove the folder, in one commit.
Every ticket resolved, stubs found, gists missing Refuse, and name what is missing.

Detection uses the provenance line that /nxs.epic already writes into every stub body, specified at nxs.epic.md:405 and confirmed in #247:

- **source:** discovery of "<destination>" (<YYYY-MM-DD>)

The check that gates removal is not "did this graduate". It is "is the reasoning durable somewhere else", because that is the condition folder removal actually rests on. So on the graduated path, every stub found must carry its <!-- nexus:discovery-gists --> comment before removal is offered. All fourteen stubs of the example discovery do carry it.

status: graduated is stamped in the same commit that removes the folder, for the same reason the no-build path stamps closed before removing. It puts a searchable record in the log, with the issue numbers as the forward pointer.

Edits this takes

  • .claude/commands/nxs.discover.md
    • Phase C0: reframe from one outcome to two, and replace the option table.
    • Phase C1: make the lessons note conditional. It exists to record why no build follows, so the graduated path writes none.
    • Phase C2: stamp status: graduated with the issue numbers on the graduated path.
    • Store schema at line 535: add graduated to the status enum.
    • Constraint at line 633: the folder is removed by one act with two paths, not by two acts.
  • .claude/commands/nxs.epic.md
    • Lines 474 and 803: replace "removing it is a plain commit the user makes" with "run /nxs.discover --close <folder>". The no-commit contract of /nxs.epic is unchanged.

Why

Removal gets one owner and one code path. The precondition that makes removal safe is then enforced in one place, instead of living as prose in a report that disappears with the session.

The user is not asked to classify the outcome before choosing a verb. The command can find the answer, so making the user supply it is the worse interface.

The durability check becomes enforced rather than assumed. Today nothing verifies that the reasoning survived onto the stubs before the folder is deleted, and the folder is the only other place that reasoning exists.

A graduated discovery stops looking identical to one still in flight, both in the tree and in the log.

Rejected alternative

Add a second action, /nxs.discover --graduated <folder>, mirroring --close in shape.

It was rejected because it only half fixes the problem. The user would still have to know which ending occurred in order to pick the verb, and that is exactly the knowledge the command can derive on its own. It also leaves two removal paths that have to be kept in step, when the whole point is to reduce removal to one.

Accepted consequences

The meaning of --close changes. It is currently documented at nxs.discover.md:442 as the terminal act for one outcome only. It becomes the terminal act for the discovery, either way.

A safety rail is removed. Today, running --close on a graduated discovery bounces the user with "run /nxs.epic --discovery instead". Under the new shape it offers removal instead. The mandatory confirmation still stands, and detection makes the bounce unnecessary, but this is a behaviour change rather than a pure addition.

Detection is a full text search, so a miss is possible. It must fail in the safe direction. Finding no stubs reports that and refuses to remove on the graduated path, which the user can override. It must never delete on an unverified match.

Follow-up

The example discovery folder is still in the tree and can be removed either by hand now, or as the first use of this path once it is written.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestpipelineOrchestration of the Nexus stages and human-decision gates

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions