Skip to content

docs(openspec): chain-restructuring proposal (reject complex one-liners with guidance) - #17

Open
preved911 wants to merge 5 commits into
mainfrom
openspec/chain-restructuring
Open

docs(openspec): chain-restructuring proposal (reject complex one-liners with guidance)#17
preved911 wants to merge 5 commits into
mainfrom
openspec/chain-restructuring

Conversation

@preved911

@preved911 preved911 commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

OpenSpec change proposal for chain-restructuring — deterministic steering: the plugin rejects not-allowed complex one-liners with an actionable error, so the agent re-issues them as separate commands or a multi-line script (one command per line), each checked individually. Allowed chains stay allowed — restructuring targets exactly the commands a human must review. Proposal only; implementation follows after review.

Why

Not-allowed multi-step commands surface to the human as an unreadable one-liner in the permission dialog, and the agent has no incentive to write readable commands. AGENTS.md instructions are soft (probabilistic, no verification loop).

Verified mechanism (from opencode API research)

  • permission.ask output carries only { status } — no reason field; per issue [FEATURE]: Wire the permission.ask plugin hook anomalyco/opencode#19469 the hook isn't even triggered by the engine in current source. Unusable for steering.
  • tool.execute.before + throw works: thrown errors become tool results with resultType: "error" and the error text reaches the model (official docs pattern). The model retries in compliant form — a closed deterministic loop.

Proposed config — separate plugin file

opencode-bash-guard.jsonc in the opencode config dirs (global ~/.config/opencode/, project .opencode/), JSONC with comments, deep-merged project over global. Permission actions stay in opencode.json; plugin behavior tuning lives here.

{
  // Reject complex one-liners and ask the agent to restructure them
  "restructure": {
    "enabled": false,     // default false — zero behavior change
    "max_segments": 3,    // max commands in a single-line chain
    "max_depth": 2        // max $()/backtick/meta-command nesting
  }
}

Key design decisions

  1. Scope: ask-resolving chains only — allowed = allowed (pass untouched); deny = forbidden regardless of format (unchanged); parse errors = fail-closed deny (unchanged). Under the "*": "ask" prerequisite, "not allowed" ⇔ ask in practice
  2. One-liner targeting: segment limit applies to single-line commands only; multi-line scripts (the compliant form) are exempt from the segment limit but still depth-checked — a compliant re-issue always exists, so the retry loop cannot deadlock
  3. Metrics: segment count (existing parseChain) + max substitution nesting depth (new — catches echo $(echo $(...)) obfuscation)
  4. Reject with guidance: error message includes actual counts + both compliant forms; nothing executes, no dialog
  5. No bypass: multi-line re-issues parse per line (newlines are already segment separators), separate calls are single segments — everything still permission-checked
  6. README correction: removes the stale "multi-segment → ask (defense-in-depth)" claim that contradicts implementation/spec
  7. AGENTS.md snippet documented as complementary soft layer (reduces rejection frequency; plugin guarantees enforcement)

Artifacts

  • proposal.md — what & why
  • design.md — 8 decisions + risks (review decision recorded: restructure applies only to not-allowed commands)
  • specs/chain-restructuring/spec.md — 6 requirements, 26 scenarios
  • tasks.md — 6 sections, 29 tasks (incl. new config-loader module + jsonc-parser dep)

Out of scope (flagged)

permission.ask may never fire in current opencode (anomalyco/opencode#19469) — the deny path of this plugin may not hard-block. Needs separate verification + possible fix change.

Next steps

  • Review proposal
  • Run /opsx-apply to implement

Ultraworked with Sisyphus

preved911 and others added 3 commits September 3, 2026 14:14
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

👀 AI Code Review

Something went wrong: <urlopen error [Errno -2] Name or service not known>


Powered by GPT-4o via GitHub Models

preved911 and others added 2 commits September 4, 2026 14:30
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

👀 AI Code Review

Something went wrong: <urlopen error [Errno -2] Name or service not known>


Powered by GPT-4o via GitHub Models

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant