Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions openspec/specs/openspec-cli-integration/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -713,3 +713,110 @@ reading SHALL NOT redefine the CLI progress denominator or phase.
- **THEN** CLI-owned progress evidence SHALL remain the authoritative implementation progress
- **AND** the divergence badge SHALL NOT fire when the CLI apply tasks and the local tracked projection
describe the same widened-syntax document

### Requirement: Apply Task Tracking Evidence Contract

OpenSpecUI SHALL decode the OpenSpec 1.13.2 `instructions apply --json` task-tracking members as typed
facts: `taskTrackingConfigured` (boolean, `true` when the schema sets a non-null `apply.tracks` even if
no file matches) and `unavailableTrackingFiles` (array of `{path, reason}` for every matched tracking
file that could not be read). Because the admission window `>=1.13.0 <1.14.0` also admits 1.13.0/1.13.1
executables that never emit `taskTrackingConfigured`, the decode schemas SHALL treat both members as
optional with absent-when-upstream-absent semantics: absence of `taskTrackingConfigured` SHALL mean
"unknown (pre-1.13.2 CLI)" and SHALL NEVER be synthesized as `false`; `unavailableTrackingFiles` SHALL
be absent when every matched file is readable (never `null`, never an empty synthesized array). Both
members SHALL project verbatim through the Apply instructions projection chain as evidence and SHALL
NOT gate apply state, CLI progress authority, or any action unlock.

#### Scenario: Decode and project tracking evidence from a 1.13.2 payload

- **GIVEN** an `instructions apply --json` success payload carrying
`taskTrackingConfigured: true` and `unavailableTrackingFiles: [{path: "/abs/tasks.md", reason: "EACCES: permission denied"}]`
- **WHEN** the payload is decoded through the CLI contract schema and projected through the Apply
instructions schema
- **THEN** both members SHALL be retained as typed facts with the path and reason verbatim
- **AND** the projected `state` and `applyInstructionProgress` SHALL be exactly what the payload's own
`state` and `progress` imply (no local gating from the new members)

#### Scenario: Absent members on pre-1.13.2 payloads stay absent

- **GIVEN** an `instructions apply --json` payload produced by a 1.13.0/1.13.1 executable (neither
member present)
- **WHEN** the payload is decoded and projected
- **THEN** the projection SHALL carry neither member
- **AND** SHALL NOT synthesize `taskTrackingConfigured: false` or an empty `unavailableTrackingFiles`
array

#### Scenario: Glob-tracked task aggregation is the CLI's count

- **GIVEN** a change whose schema sets `apply.tracks` to a glob matching more than one concrete file
- **WHEN** the 1.13.2 CLI apply instructions are read
- **THEN** `tasks` and `progress` SHALL reflect every readable matched file as the CLI aggregated them
- **AND** the local tracked-task divergence projection SHALL compare against that aggregated truth
without redefining the CLI denominators (2026-08-18 law)

#### Scenario: Tracking configured with zero matched files stays configured

- **GIVEN** a 1.13.2 payload whose schema sets a non-null `apply.tracks` that matches zero concrete
files
- **WHEN** the payload is decoded
- **THEN** `taskTrackingConfigured` SHALL be `true` with empty `tasks`
- **AND** the projection SHALL NOT recode the fact as no-tracking (`false`) or as missing evidence

#### Scenario: Unreadable tracking evidence keeps all_done unreachable

- **GIVEN** a 1.13.2 payload whose `apply.tracks` matches one unreadable and one readable file, the
readable file holding only complete tasks, and whose CLI-resolved `state` is `ready` (the upstream
state chain excludes `all_done` while any matched file is unreadable)
- **WHEN** the payload is decoded and projected
- **THEN** the projected `state` SHALL be the payload's `ready` verbatim (not rewritten, not
`all_done`) and `unavailableTrackingFiles` SHALL name the unreadable path with its reason

### Requirement: Agent Registry Kilo Command Path Rotation

The Agent delivery registry snapshot for the `'1.13'` series SHALL carry Kilo Code's command delivery
path as `.kilo/command/opsx-{workflow}.md` (the pinned 1.13.2 physical reality) while preserving the
previous in-series path `.kilocode/workflows/opsx-{workflow}.md` as legacy path evidence. The skills
directory SHALL remain `.kilocode`. Cleanup patterns SHALL cover both legacy generations in the old
folder (`.kilocode/workflows/opsx-*.md` and `.kilocode/workflows/openspec-*.md`) and SHALL NOT mark the
live `.kilo/command/` folder as cleanup-owned. OpenSpecUI continues to never hand-write or delete Agent
artifacts; the registry is delivery/inventory evidence mirrored from the pinned CLI.

#### Scenario: Registry projects the rotated path

- **WHEN** the Agent registry inventory is selected for an admitted 1.13.x CLI
- **THEN** the Kilo Code command artifact SHALL carry pathTemplate `.kilo/command/opsx-{workflow}.md`
with plain-markdown content and `legacyPathTemplates` containing
`.kilocode/workflows/opsx-{workflow}.md`
- **AND** the registry's raw cleanup patterns SHALL list exactly the two legacy generations of the old
folder (`.kilocode/workflows/opsx-*.md`, `.kilocode/workflows/openspec-*.md`) — distinct from the
runtime cleanup projection: the legacy `opsx-*` generation is ambiguity-skipped as a pattern and
retired through `legacyCommandWorkflows` per-artifact, while the `openspec-*` wildcard enumerates
matches as evidence per the registry's inherited wildcard-projection convention (upstream's own
cleanup is an exact allowlist; a user file matching the wildcard is still collected as evidence —
a documented projection divergence, and OpenSpecUI executes no deletion itself), and `.kilo/command/`
never appears in any cleanup pattern or runtime result

#### Scenario: Pinned executable generates the new path

- **GIVEN** the pinned `openspec-cli-113` fixture (1.13.2) initializing the `kilocode` tool in a fixture
repository
- **WHEN** command generation runs
- **THEN** files SHALL be generated under `.kilo/command/opsx-<id>.md`

### Requirement: Artifact Glob Recognition Parity

The local `isGlobPattern` mirror SHALL recognize the same glob syntax the pinned CLI's artifact-graph
recognizes: the original wildcard characters (`*`, `?`, `[`), brace expansions containing `,` or `..`,
and extglob groups, after POSIX separator normalization. The mirror exists solely to keep
dependency-watch granularity aligned (directory-tree watch for glob outputs, single-file watch for
literal outputs); it SHALL NOT fork the upstream semantics. This parity is a watcher-granularity fact
only: the tracked-task file matcher (`opsxPathMatchesPattern`) stays wildcard-class, and OpenSpecUI
SHALL document brace/extglob task tracking as a boundary rather than a silent divergence.

#### Scenario: Brace and extglob outputs are watched as globs

- **GIVEN** a schema artifact output path `docs/{api,cli}.md` or `!(a|b).md`
- **WHEN** artifact output dependencies are touched for reactive watching
- **THEN** the path SHALL be recognized as a glob pattern and watched at its directory granularity
- **AND** literal paths without wildcard, brace-expansion, or extglob syntax SHALL keep single-file
watching
34 changes: 34 additions & 0 deletions openspec/specs/opsx-workflow-ui/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -665,3 +665,37 @@ and row visibility SHALL NOT become CLI-gated.
- **WHEN** the user inspects the warning region
- **THEN** no change-detail route entry for `area` SHALL exist
- **AND** OpenSpecUI SHALL NOT attempt to read, write, or repair the nested directories

### Requirement: Apply Tracking Evidence Surface

The Change Detail Apply status region SHALL surface the OpenSpec 1.13.2 Apply task-tracking evidence on
the direct plane: when `unavailableTrackingFiles` is non-empty, the region SHALL mount and render one
amber evidence line per entry with the file path and the upstream reason verbatim; when
`taskTrackingConfigured` is `false`, the region SHALL state that the schema tracks no tasks so empty
`tasks` are not missing evidence. Absent members SHALL render nothing (no fabricated `0/0` semantics, no
"tracking unavailable" claim for pre-1.13.2 CLIs). The evidence SHALL NOT redefine the Apply state,
progress, or unlock presentation owned by the CLI payload.

#### Scenario: Unreadable tracking files render as direct evidence

- **GIVEN** a Change Detail whose apply instructions carry
`unavailableTrackingFiles: [{path: "/abs/x/tasks.md", reason: "EACCES: permission denied"}]`
- **WHEN** the detail renders
- **THEN** the Apply status region SHALL be mounted showing the path and the reason verbatim in an amber
evidence treatment beside the existing warnings/build-order evidence
- **AND** the Apply state chip SHALL still reflect the payload's own `state`

#### Scenario: No-tracking schemas are not missing evidence

- **GIVEN** a Change Detail whose apply instructions carry `taskTrackingConfigured: false` and empty
`tasks`
- **WHEN** the detail renders
- **THEN** the status region SHALL state that the schema tracks no tasks
- **AND** SHALL NOT present the empty task list as blocked or incomplete work

#### Scenario: Absent members render nothing extra

- **GIVEN** apply instructions decoded from a 1.13.0/1.13.1 payload (neither member present)
- **WHEN** the detail renders
- **THEN** the status region SHALL be exactly what the member-less payload implies today (regression
guard)
Loading