feat: the parallel-work rules reach every host; OpenCode/Kilo turn ends run hook stop - #259
Merged
Merged
Conversation
gitleaks hard-codes the default config for single-file sources: a repo .gitleaks.toml is only auto-found for directory scans, so repository allowlists silently stopped applying the moment a scan named a single file — which is exactly how the gate scans changed files. Pass --config when a repo .gitleaks.toml/.yml exists, for both the dir and the legacy detect invocations.
…ds run hook stop
AGENTS.md (the master every host reads or is copied from) gains the rules:
fan out when work decomposes into independent units — subagents where the
host has them, parallel sessions where it does not, ceiling is the unit not
the headcount; writers that touch the same files or feature are fenced in
their own git worktree on their own branch, read-only and file-disjoint
work shares the tree; convergence is one branch one writer through the
normal chain, gate and four passes on the merged result; subagents inherit
every rule. "Which command, right now" gains the initiative line: a trigger
is a situation, not a request — the matching command runs without being
told.
Every rule-file copy was regenerated (procoder agents; the drift guard keeps
them pinned), so the rules reach every host: the native tier reads AGENTS.md
by construction, the copy tier is gate-enforced.
OpenCode/Kilo turn end: the shared shim gets an event hook on
session.idle / session.compacted that runs procoder hook stop — the same
entry point Claude's Stop/PreCompact hooks and pi's agent_settled use.
Those hosts cannot refuse a turn, so the hook records: the handoff
survives and the unasked-decision reminder lands in the session log. The
asymmetry is documented in docs/portability.md ("What a turn end may stop").
The new portability test drives the plugin's event hook through node
against the fixture binary named procoder on PATH: exactly the two
turn-end events spawn hook stop with the session cwd, an unrelated event
spawns nothing, and a blocking verdict (exit 2) does not throw out of the
handler. Mutation-checked: removing the hook fails it.
There was a problem hiding this comment.
Pull request overview
This PR propagates Procoder governance text updates across host-specific rule copies, and extends the OpenCode/Kilo plugin shim so turn-end events run procoder hook stop (plus adds test/docs coverage). It also tightens gitleaks behavior so repository-scoped configuration continues to apply when scanning single files.
Changes:
- Add a “Parallel work” section and expand “Which command, right now” prose across AGENTS/rules/skill copies.
- Ensure gitleaks uses repo config (
.gitleaks.toml/.gitleaks.yml) for both directory and single-file scan shapes. - Add OpenCode/Kilo
session.idle/session.compactedhandling to runprocoder hook stop, with a new Go test and updated portability docs.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| skills/procoder/SKILL.md | Adds “Parallel work” guidance and expands “Which command” prose in the canonical skill doc. |
| internal/security/security.go | Ensures gitleaks repo config is applied even for single-file scans. |
| internal/portability/opencode_test.go | New test driving the OpenCode/Kilo plugin event hook to verify hook stop is invoked. |
| docs/portability.md | Documents OpenCode/Kilo turn-end behavior and adds “What a turn end may stop” section. |
| AGENTS.md | Propagates the same governance text updates to the repo’s main agent contract. |
| .windsurf/rules/procoder.md | Propagates governance text updates to Windsurf rules copy. |
| .roo/rules/procoder.md | Propagates governance text updates to Roo rules copy. |
| .qoder/rules/procoder.md | Propagates governance text updates to Qoder rules copy. |
| .opencode/plugins/procoder.mjs | Adds event hook to run procoder hook stop on session.idle / session.compacted. |
| .kiro/steering/procoder.md | Propagates governance text updates to Kiro steering copy. |
| .kilocode/rules/procoder.md | Propagates governance text updates to Kilocode rules copy. |
| .kilo/rules/procoder.md | Propagates governance text updates to Kilo rules copy. |
| .kilo/plugin/procoder.js | Mirrors the OpenCode plugin change (byte-identical shim) for Kilo. |
| .github/copilot-instructions.md | Propagates governance text updates to Copilot instructions copy. |
| .cursor/rules/procoder.mdc | Propagates governance text updates to Cursor rules copy. |
| .codex/AGENTS.md | Propagates governance text updates to Codex agent contract copy. |
| .clinerules/procoder.md | Propagates governance text updates to Cline rules copy. |
| .agents/rules/procoder.md | Propagates governance text updates to the .agents/ rules copy. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Windows refuses a bare absolute path as an ESM specifier ("On Windows,
absolute paths must be valid file:// URLs"), so the driver hands the
plugin path to node as an environment variable and lets node's own
pathToFileURL do the conversion. Same driver, both platforms.
The branch-protection state stayed BLOCKED with every required check green on the head commit, and re-running the suite did not clear it. A fresh head commit makes the protection rule evaluate a new check set.
Copilot review caught it: the binary a plugin spawns sits where the server process sits, and `hook stop` resolved its root from the process's working directory — so the handoff note could land in a different repository than the session it was serving. The payload's cwd is the host's working directory, and it now wins over the root the caller computed; the caller's root remains the fallback for a direct call with no payload. The dead rootFromPayload fallback is removed. The docs and the plugin comment stop overclaiming what the OpenCode/Kilo event hook records: the handoff, and only the handoff — the unasked- decision report needs the turn's last message, and an event payload does not carry it, so that check runs only where the host hands the message over (Claude's Stop, pi's agent_settled).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AGENTS.md (the master every host reads or is copied from) gains the rules:
git worktreeon their own branch; read-only and file-disjoint work shares the tree. Convergence is one branch, one writer, through the normal chain — the gate and the four passes on the merged result. Subagents inherit every rule.Every rule-file copy was regenerated (
procoder agents; the drift guard keeps them pinned), so the rules reach every host: the native tier (Claude, pi, OpenCode, Kilo, Codex) readsAGENTS.mdby construction; the 12-copy tier is gate-enforced.OpenCode/Kilo turn end: the shared shim gains an
eventhook onsession.idle/session.compactedthat runsprocoder hook stop— the same entry point Claude'sStop/PreCompacthooks and pi'sagent_settleduse. Those hosts cannot refuse a turn, so the hook records: the handoff survives and the unasked-decision reminder lands in the session log. Asymmetry documented indocs/portability.md("What a turn end may stop").New portability test drives the plugin's
eventhook through node against the fixture binary namedprocoderon PATH: exactly the two turn-end events spawnhook stopwith the session cwd, an unrelated event spawns nothing, and a blocking verdict (exit 2) does not throw out of the handler. Mutation-checked: removing the hook fails the test. Full suite green, gate clean.