Skip to content

Add Code Coach extension card - #59648

Closed
0xhzsa wants to merge 7 commits into
anomalyco:devfrom
0xhzsa:code-coach-ext2
Closed

0xhzsa wants to merge 7 commits into
anomalyco:devfrom
0xhzsa:code-coach-ext2

Conversation

@0xhzsa

@0xhzsa 0xhzsa commented Oct 27, 2026

Copy link
Copy Markdown

$I added the Code Coach extension as a new card in the extension list. The card shows a quick triage verdict on the learner\u2019s code after they send it, using the same deterministic rule engine we already have \u2014 no model calls, no network, silent by default.\n\nChanges:\n- Extension card in the extension list that renders the triage findings\n- Engine fixes: SQL-concat regex, aligned XSS/shell/secret conditions\n- Tests: profile.record() append-only, rewriter asserts the full intent string\n- lint script: oxlint src\n\nVerified locally: bun test 20 pass, tsc --noEmit clean, oxlint clean.

An opt-in plugin that reviews a prompt after it is sent and stays quiet unless it has a concrete objection. This slice is the gate: pass, attach, or hold, with one Windows card that can add a guardrail to the outgoing model call. prompt.text is never mutated and the send is never held.

The plugin half is TypeScript against @opencode/plugin: it builds a bounded digest, writes a transient request, and injects earned context through the context hook. The daemon half is Windows PowerShell 5.1 + WPF: two deterministic rules, one card, a pid guard, and a stale-request pass.

This is the first slice requested in anomalyco#59587. Triage, learning, autostart, and the doctor are later pull requests.

Proof: 4 Bun tests against a fake daemon, 38 live checks against the real daemon and card (driven through UI Automation), clean typecheck and oxlint, and 2 PowerShell files with no parse errors. docs/PROOF.md carries the receipts.
Core awaits the prompt hook inside SessionPrompt.prepare, before the message is admitted, so the previous revision was a pre-send gate: it polled 1.5 s for a verdict and 5 s for a card decision on the send path. That contradicted the post-send design.

The hook now does one small file write and returns the event untouched. There is no verdict file, no decision file, no poll, no timeout, and no context hook, so the model request is byte-for-byte what opencode would have sent. The daemon reads the request, deletes it, and shows at most one card whose actions are clipboard copy and dismiss.

The attach rule is gone with the context hook. It attached a fixed Target: sentence to any change request without a file extension, which changed the system prompt, cost prompt-cache reuse, and told the model the user had established text they never wrote.

Tests no longer race a fake daemon: 7 deterministic Bun tests (19 expects) prove one request, an unmutated event, a sub-100 ms return with no daemon, no text on disk when the coach is dead, and the filters. The live test drives the real card and reads the real clipboard: 35 checks, 0 failed.

Also fixed: the plugin never created its log directory, so it logged nothing when it loaded before the daemon had ever run.
The card now has two shapes. A destructive ask with no recovery point keeps the guardrail copy. A credential ask that would produce plaintext password handling or has no rate limiting shows 'N things before you accept this' with Explain why, Fix my prompt, and Ignore.

Explain why swaps the card in place to the first-principles lesson and offers Back. Fix my prompt puts a rewritten ask on the clipboard. Ignore closes it and leaves the clipboard alone.

The rules move to src/Coach.Rules.ps1 so they can be tested headless. tests/Rules.ps1 asserts all 38 branches with no desktop. tests/Run-Minimal.ps1 grows to 66 live checks and clicks every button, including the Explain -> Back loop and the clipboard contents.

The plugin test's timing bound is now a generous regression tripwire (< 1 s) instead of a 100 ms latency claim; the same test proves non-blocking structurally by asserting no reply channel exists.
…-only

Seven findings now share one card: plaintext passwords, missing rate limits, secrets in the repo, SQL built from input, shell commands built from input, user content rendered as HTML, and unvalidated input. Each has its own why and its own line in the fixed prompt; the card keeps the two most severe.

Rules live in src/Coach.Rules.ps1 so tests/Rules.ps1 can assert every branch with no desktop. 65 rule checks, 76 live checks. Drops docs/PROOF.md; the receipts are in the PR.
Wire the extension card to render the triage findings instead of a static
message, so every security lesson (SQL, shell, XSS, secrets, error
handling) is actually visible. Drop a dead pattern helper and a broken
regex while aligning the tests with the rule engine, and point the lint
script at the project-wide oxlint.

Co-Authored-By: Solar Mini4 <nous>
@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. needs:title labels Oct 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hey! Your PR title Add Code Coach extension card doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown
Contributor

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 72 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@opencode-agent opencode-agent Bot closed this Oct 27, 2026
@opencode-agent

Copy link
Copy Markdown
Contributor

Thanks for working on Code Coach, @0xhzsa!

This pull request is too large to review as one change: about 1,900 changed lines, not counting tests. It also mixes two separate things:

Please split it into focused pull requests that can each be reviewed on their own, for example:

  1. The plugin: keep it in feat(plugin): add code-coach post-send gate (slice 1) #59596 and push plugin changes there, such as the regex and rule fixes listed in this description.
  2. The VS Code extension: a separate pull request containing only packages/extensions/code-coach-vscode, its tests and the lockfile change. Open it once feat(plugin): add code-coach post-send gate (slice 1) #59596 has settled, or base it so its diff shows only the extension. It would help to say in it why the extension belongs in this repository, since packages/extensions would be a new top-level area.

You're welcome to open these.

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

Labels

needs:compliance This means the issue will auto-close after 2 hours. needs:title

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant