diff --git a/openspec/changes/local-llm-acp-record-is-put-right/.openspec.yaml b/openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/.openspec.yaml similarity index 100% rename from openspec/changes/local-llm-acp-record-is-put-right/.openspec.yaml rename to openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/.openspec.yaml diff --git a/openspec/changes/local-llm-acp-record-is-put-right/design.md b/openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/design.md similarity index 100% rename from openspec/changes/local-llm-acp-record-is-put-right/design.md rename to openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/design.md diff --git a/openspec/changes/local-llm-acp-record-is-put-right/proposal.md b/openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/proposal.md similarity index 100% rename from openspec/changes/local-llm-acp-record-is-put-right/proposal.md rename to openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/proposal.md diff --git a/openspec/changes/local-llm-acp-record-is-put-right/specs/openspec-workbench/spec.md b/openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/specs/openspec-workbench/spec.md similarity index 100% rename from openspec/changes/local-llm-acp-record-is-put-right/specs/openspec-workbench/spec.md rename to openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/specs/openspec-workbench/spec.md diff --git a/openspec/changes/local-llm-acp-record-is-put-right/tasks.md b/openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/tasks.md similarity index 100% rename from openspec/changes/local-llm-acp-record-is-put-right/tasks.md rename to openspec/changes/archive/2026-10-02-local-llm-acp-record-is-put-right/tasks.md diff --git a/openspec/changes/local-llm-acp/.openspec.yaml b/openspec/changes/archive/2026-10-02-local-llm-acp/.openspec.yaml similarity index 100% rename from openspec/changes/local-llm-acp/.openspec.yaml rename to openspec/changes/archive/2026-10-02-local-llm-acp/.openspec.yaml diff --git a/openspec/changes/local-llm-acp/design.md b/openspec/changes/archive/2026-10-02-local-llm-acp/design.md similarity index 100% rename from openspec/changes/local-llm-acp/design.md rename to openspec/changes/archive/2026-10-02-local-llm-acp/design.md diff --git a/openspec/changes/local-llm-acp/proposal.md b/openspec/changes/archive/2026-10-02-local-llm-acp/proposal.md similarity index 100% rename from openspec/changes/local-llm-acp/proposal.md rename to openspec/changes/archive/2026-10-02-local-llm-acp/proposal.md diff --git a/openspec/changes/local-llm-acp/specs/execution-core/spec.md b/openspec/changes/archive/2026-10-02-local-llm-acp/specs/execution-core/spec.md similarity index 100% rename from openspec/changes/local-llm-acp/specs/execution-core/spec.md rename to openspec/changes/archive/2026-10-02-local-llm-acp/specs/execution-core/spec.md diff --git a/openspec/changes/local-llm-acp/tasks.md b/openspec/changes/archive/2026-10-02-local-llm-acp/tasks.md similarity index 100% rename from openspec/changes/local-llm-acp/tasks.md rename to openspec/changes/archive/2026-10-02-local-llm-acp/tasks.md diff --git a/openspec/specs/execution-core/spec.md b/openspec/specs/execution-core/spec.md index 346ef292..0f52a3c3 100644 --- a/openspec/specs/execution-core/spec.md +++ b/openspec/specs/execution-core/spec.md @@ -3007,9 +3007,24 @@ committed is a key published. The editor SHALL offer the base URL and the model as settings, and SHALL keep the key in its secret storage, set by a command. -Until this, the address and the model were fixed in code with no way to -change them, and no key could be sent: a user's server at -`http://192.168.137.33:8000/v1`, which wants one, could not be used. +In addition to the existing HTTP adapter, the system SHALL offer +`local-llm-acp`, which SHALL run a local ACP coding process through the +shared ACP session driver while using the same resolved base URL, model, +and optional API key. The API key SHALL remain out of files here as well. + +`local-llm-acp` SHALL expose a strict invocation contract for agent-loop +ceilings that can be passed to the ACP process: max iterations, max tool +calls, max run seconds, prompt/completion/total token ceilings, and +context ceilings (used/context window share/min free tokens). A value that +is not present SHALL be omitted rather than guessed. + +This adapter-level loop contract SHALL NOT replace harness chain/stage +controls (`timeout.maxRunSeconds`, `timeout.maxStageSeconds`, +`maxStageAttempts`, and `budget.maxContextShare`): those controls SHALL +continue to bound change-level and task/stage-level execution. + +Until this, local OpenAI-compatible usage could run only over direct HTTP, +with no ACP tool/permission flow and no ACP-native loop contract. #### Scenario: A server that wants a key @@ -3030,6 +3045,26 @@ change them, and no key could be sent: a user's server at - **THEN** the model is the editor's, and the base URL and the key are the environment's +#### Scenario: ACP local LLM reuses endpoint settings + +- **WHEN** `local-llm-acp` is selected and base URL/model/API key are + resolved from settings/environment +- **THEN** the adapter starts its ACP process with that same endpoint + identity and does not persist the key to files + +#### Scenario: ACP local loop limit contract is explicit + +- **WHEN** loop limits are configured for `local-llm-acp` +- **THEN** only the documented limit fields are passed to the ACP process, + and each absent field is omitted + +#### Scenario: Harness time and retries still bound change and task/stage runs + +- **WHEN** a chain runs with `timeout.maxRunSeconds`, + `timeout.maxStageSeconds`, or `maxStageAttempts` configured +- **THEN** those ceilings still govern change-level and task/stage-level + execution regardless of whether `local-llm` or `local-llm-acp` is selected + ### Requirement: The local model makes a change with nothing installed `local-llm-acp` SHALL be an Agent Client Protocol agent that runs inside diff --git a/openspec/specs/openspec-workbench/spec.md b/openspec/specs/openspec-workbench/spec.md index 748453eb..bb607d53 100644 --- a/openspec/specs/openspec-workbench/spec.md +++ b/openspec/specs/openspec-workbench/spec.md @@ -4,7 +4,9 @@ Define integrated OpenSpec workspace navigation, lifecycle control, native VS Code AI workflows, process visibility, and conflict-safe rollback. + ## Requirements + ### Requirement: Workbench exposes the complete OpenSpec workspace The system SHALL provide hierarchical navigation to configuration, active and @@ -239,6 +241,14 @@ Where an item can only be carried out by a person, it SHALL remain open until that person has carried it out, and SHALL NOT be inferred from related evidence. +Where an item is marked as requiring a person or as delegated to an +agent, the evidence closing it SHALL be written in the lines under the +item, which is where the rule that closes the item reads. An item whose +evidence is written only on its own checkbox line SHALL be treated as +recording nothing, because an item's own text already states what it +obliges and nothing distinguishes that text from evidence appended to +it. + #### Scenario: Work has shipped - **WHEN** a change's implementation is present in the default branch @@ -261,6 +271,13 @@ related evidence. - **THEN** the item stays open, rather than being closed on the observed part +#### Scenario: Evidence written on the checkbox line alone + +- **WHEN** a delegated or human-only item is ticked and its evidence is + written on the checkbox line, with nothing in the lines under it +- **THEN** the item counts as recording nothing, and the change owes it + and is not archived, until the evidence is written under the item + ### Requirement: A refused archive states the reason the tool gave Where archiving a change is refused, the reason SHALL be reported as the @@ -848,4 +865,3 @@ month later the line is all there is of it. is ticked - **THEN** its line names what the sweep did, on what, and when it was seen -