From 2dc1a26b39755bc3f663df899d9730e416d6d2d9 Mon Sep 17 00:00:00 2001 From: m-aebrer Date: Mon, 10 Aug 2026 08:34:22 -0400 Subject: [PATCH 1/4] chore: open PR for issue 438 From 80d416441103c315349cac33340c97c9cbf7dcbb Mon Sep 17 00:00:00 2001 From: m-aebrer Date: Mon, 10 Aug 2026 08:39:43 -0400 Subject: [PATCH 2/4] Add posting guardrails to mach6-issue skill --- .../coding-agent/skills/mach6-issue/SKILL.md | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/coding-agent/skills/mach6-issue/SKILL.md b/packages/coding-agent/skills/mach6-issue/SKILL.md index b554de8e..350de810 100644 --- a/packages/coding-agent/skills/mach6-issue/SKILL.md +++ b/packages/coding-agent/skills/mach6-issue/SKILL.md @@ -111,7 +111,9 @@ If templates exist, read them and select the most appropriate one. If codebase context is needed, use Explore subagents only for bounded evidence such as locating named behavior, files, tests, call sites, or exact snippets. The primary agent must interpret that evidence and own the issue's requirements, proposed behavior, scope, and technical conclusions. -### Step 2: Draft the issue +### Step 2: Draft and approve the issue + +An initial request to "create," "post," or "open" an issue is a request to draft it, **not approval to post it**. Never create an issue in the same turn as that initial request, regardless of how imperative or complete it is. Create a structured issue with: - **Title**: Clear, concise, action-oriented (under 80 chars, imperative form) @@ -123,16 +125,32 @@ Create a structured issue with: - **Technical Notes**: Implementation hints, relevant files, architectural considerations - **Labels**: Suggest appropriate labels based on the issue type -Present the draft to the user for approval. +Determine the candidate target repository as an exact `owner/repo`; do not rely on ambient `gh` context when posting. Use `ask_user` to present one Markdown-formatted approval question containing all of the following without summarizing or truncating them: +- The exact target `owner/repo` +- The complete issue title +- The complete Markdown issue body + +The question must offer exactly these three options and allow free-text discussion: +- **Approve** +- **Deny/Discuss** +- **Detailed Explanation with minimal jargon of each acceptance criteria** + +Only an explicit selection of **Approve** authorizes posting. Free text, a skipped or unanswered question, cancellation, **Deny/Discuss**, or the explanation option are not approval and must never fall through to issue creation. + +If the user selects **Deny/Discuss**, discuss or revise the draft without posting. If the user requests the detailed explanation, explain every acceptance criterion with minimal jargon without posting. After either path, present the complete draft and target through this approval gate again before posting. Any change to the title, body, or target repository invalidates prior approval and requires a fresh approval. + +Stop and wait for the distinct `ask_user` response before continuing to Step 3. The non-interactive `gh` rule applies only to CLI execution; it does not replace this human approval gate. ### Step 3: Create the issue +Proceed only after the approval gate in Step 2 returned **Approve** for the exact title, body, and target used below. + ```bash GH_BODY="$(mktemp /tmp/gh-body.$$.XXXXXXXX)" cat > "$GH_BODY" << 'MACH6_EOF' MACH6_EOF -gh issue create --title "" --body-file "$GH_BODY" [--label "<labels>"] +gh issue create --repo "<owner/repo>" --title "<title>" --body-file "$GH_BODY" [--label "<labels>"] ``` Report the issue number and URL. Suggest next step: `/skill:mach6-plan <number>` From bafcb874e70db1123336c782f7cbd06754ea3c00 Mon Sep 17 00:00:00 2001 From: m-aebrer <andrew.brereton@milliporesigma.com> Date: Mon, 10 Aug 2026 09:08:31 -0400 Subject: [PATCH 3/4] Fix CREATE-mode review findings --- packages/ai/test/context-overflow.test.ts | 4 ++-- packages/ai/test/total-tokens.test.ts | 4 ++-- .../coding-agent/skills/mach6-issue/SKILL.md | 10 ++++++--- packages/coding-agent/test/skills.test.ts | 21 +++++++++++++++++++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/packages/ai/test/context-overflow.test.ts b/packages/ai/test/context-overflow.test.ts index fe025d57..f2639fa7 100644 --- a/packages/ai/test/context-overflow.test.ts +++ b/packages/ai/test/context-overflow.test.ts @@ -202,8 +202,8 @@ describe("Context overflow error handling", () => { // ============================================================================= describe.skipIf(process.env.DREB_SKIP_LIVE_API === "1" || !process.env.GEMINI_API_KEY)("Google", () => { - it("gemini-2.0-flash - should detect overflow via isContextOverflow", async () => { - const model = getModel("google", "gemini-2.0-flash"); + it("gemini-2.5-flash - should detect overflow via isContextOverflow", async () => { + const model = getModel("google", "gemini-2.5-flash"); const result = await testContextOverflow(model, process.env.GEMINI_API_KEY!); logResult(result); diff --git a/packages/ai/test/total-tokens.test.ts b/packages/ai/test/total-tokens.test.ts index c041cfe4..d96f8121 100644 --- a/packages/ai/test/total-tokens.test.ts +++ b/packages/ai/test/total-tokens.test.ts @@ -203,10 +203,10 @@ describe("totalTokens field", () => { describe.skipIf(process.env.DREB_SKIP_LIVE_API === "1" || !process.env.GEMINI_API_KEY)("Google", () => { it( - "gemini-2.0-flash - should return totalTokens equal to sum of components", + "gemini-2.5-flash - should return totalTokens equal to sum of components", { retry: 3, timeout: 60000 }, async () => { - const llm = getModel("google", "gemini-2.0-flash"); + const llm = getModel("google", "gemini-2.5-flash"); console.log(`\nGoogle / ${llm.id}:`); const { first, second } = await testTotalTokensWithCache(llm); diff --git a/packages/coding-agent/skills/mach6-issue/SKILL.md b/packages/coding-agent/skills/mach6-issue/SKILL.md index 350de810..36730f57 100644 --- a/packages/coding-agent/skills/mach6-issue/SKILL.md +++ b/packages/coding-agent/skills/mach6-issue/SKILL.md @@ -117,6 +117,7 @@ An initial request to "create," "post," or "open" an issue is a request to draft Create a structured issue with: - **Title**: Clear, concise, action-oriented (under 80 chars, imperative form) +- **Original Request**: A clearly identified block quote containing the user's original request/input verbatim; do not paraphrase, correct, or omit any part of it - **Summary**: 2-3 sentences describing the problem or feature - **Current Behavior** (for bugs/improvements): What happens now - **Proposed Behavior**: What should happen @@ -125,10 +126,13 @@ Create a structured issue with: - **Technical Notes**: Implementation hints, relevant files, architectural considerations - **Labels**: Suggest appropriate labels based on the issue type +Keep the issue limited to what the user explicitly requested. Before adding any acceptance criterion that the user did not explicitly ask for, present the proposed criterion separately with `ask_user` and obtain explicit confirmation that it is valid scope. Do not include an unrequested criterion without that confirmation, and do not treat approval of the completed issue draft as retroactive scope confirmation. + Determine the candidate target repository as an exact `owner/repo`; do not rely on ambient `gh` context when posting. Use `ask_user` to present one Markdown-formatted approval question containing all of the following without summarizing or truncating them: - The exact target `owner/repo` - The complete issue title -- The complete Markdown issue body +- The complete Markdown issue body, including the verbatim **Original Request** block quote +- The complete proposed label list, or an explicit statement that no labels are proposed The question must offer exactly these three options and allow free-text discussion: - **Approve** @@ -137,13 +141,13 @@ The question must offer exactly these three options and allow free-text discussi Only an explicit selection of **Approve** authorizes posting. Free text, a skipped or unanswered question, cancellation, **Deny/Discuss**, or the explanation option are not approval and must never fall through to issue creation. -If the user selects **Deny/Discuss**, discuss or revise the draft without posting. If the user requests the detailed explanation, explain every acceptance criterion with minimal jargon without posting. After either path, present the complete draft and target through this approval gate again before posting. Any change to the title, body, or target repository invalidates prior approval and requires a fresh approval. +If the user selects **Deny/Discuss**, discuss or revise the draft without posting. If the user requests the detailed explanation, explain every acceptance criterion with minimal jargon without posting. After either path, present the complete draft, target, and proposed labels through this approval gate again before posting. Any change to the title, body, target repository, or proposed labels invalidates prior approval and requires a fresh approval. Stop and wait for the distinct `ask_user` response before continuing to Step 3. The non-interactive `gh` rule applies only to CLI execution; it does not replace this human approval gate. ### Step 3: Create the issue -Proceed only after the approval gate in Step 2 returned **Approve** for the exact title, body, and target used below. +Proceed only after the approval gate in Step 2 returned **Approve** for the exact title, body, target, and proposed labels used below. ```bash GH_BODY="$(mktemp /tmp/gh-body.$$.XXXXXXXX)" diff --git a/packages/coding-agent/test/skills.test.ts b/packages/coding-agent/test/skills.test.ts index 0ec3eee3..07280fb2 100644 --- a/packages/coding-agent/test/skills.test.ts +++ b/packages/coding-agent/test/skills.test.ts @@ -539,6 +539,27 @@ describe("skills", () => { } }); + it("mach6-issue should preserve CREATE-mode scope and posting guardrails", () => { + const body = readBuiltInSkill("mach6-issue"); + expect(body).toContain("Never create an issue in the same turn as that initial request"); + expect(body).toContain("user's original request/input verbatim"); + expect(body).toContain("do not paraphrase, correct, or omit any part of it"); + expect(body).toContain("Before adding any acceptance criterion that the user did not explicitly ask for"); + expect(body).toContain("do not treat approval of the completed issue draft as retroactive scope confirmation"); + expect(body).toContain("The exact target `owner/repo`"); + expect(body).toContain("The complete issue title"); + expect(body).toContain("including the verbatim **Original Request** block quote"); + expect(body).toContain( + "The complete proposed label list, or an explicit statement that no labels are proposed", + ); + expect(body).toContain("- **Approve**"); + expect(body).toContain("- **Deny/Discuss**"); + expect(body).toContain("- **Detailed Explanation with minimal jargon of each acceptance criteria**"); + expect(body).toContain("Free text, a skipped or unanswered question, cancellation"); + expect(body).toContain("title, body, target repository, or proposed labels invalidates prior approval"); + expect(body).toContain('gh issue create --repo "<owner/repo>"'); + }); + it("mach6 CI workflows use watch_github_ci instead of polling or wait", () => { for (const name of ["mach6-implement", "mach6-publish"]) { const body = readBuiltInSkill(name); From 05cddac86e345bc354f1ae9e18b6010e7af3ef53 Mon Sep 17 00:00:00 2001 From: m-aebrer <andrew.brereton@milliporesigma.com> Date: Mon, 10 Aug 2026 09:25:44 -0400 Subject: [PATCH 4/4] chore: bump version to 2.55.1 --- package-lock.json | 18 +++++++++--------- package.json | 2 +- packages/agent/package.json | 2 +- packages/ai/package.json | 2 +- packages/coding-agent/package.json | 2 +- packages/dashboard/package.json | 2 +- .../semantic-search/.claude-plugin/plugin.json | 2 +- packages/semantic-search/package.json | 2 +- packages/telegram/package.json | 2 +- packages/tui/package.json | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 70b99eed..16d0bbd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dreb", - "version": "2.55.0", + "version": "2.55.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dreb", - "version": "2.55.0", + "version": "2.55.1", "workspaces": [ "packages/*", "packages/coding-agent/examples/extensions/with-deps", @@ -10955,7 +10955,7 @@ }, "packages/agent": { "name": "@dreb/agent-core", - "version": "2.55.0", + "version": "2.55.1", "license": "MIT", "dependencies": { "@dreb/ai": "*" @@ -10984,7 +10984,7 @@ }, "packages/ai": { "name": "@dreb/ai", - "version": "2.55.0", + "version": "2.55.1", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.73.0", @@ -11040,7 +11040,7 @@ }, "packages/coding-agent": { "name": "@dreb/coding-agent", - "version": "2.55.0", + "version": "2.55.1", "license": "MIT", "dependencies": { "@dreb/agent-core": "*", @@ -11169,7 +11169,7 @@ }, "packages/dashboard": { "name": "@dreb/dashboard", - "version": "2.55.0", + "version": "2.55.1", "license": "MIT", "dependencies": { "@dreb/coding-agent": "*", @@ -11401,7 +11401,7 @@ }, "packages/semantic-search": { "name": "@dreb/semantic-search", - "version": "2.55.0", + "version": "2.55.1", "license": "MIT", "dependencies": { "@huggingface/transformers": "^4.0.1", @@ -11450,7 +11450,7 @@ }, "packages/telegram": { "name": "@dreb/telegram", - "version": "2.55.0", + "version": "2.55.1", "license": "MIT", "dependencies": { "@dreb/coding-agent": "*", @@ -11483,7 +11483,7 @@ }, "packages/tui": { "name": "@dreb/tui", - "version": "2.55.0", + "version": "2.55.1", "license": "MIT", "dependencies": { "@types/mime-types": "^2.1.4", diff --git a/package.json b/package.json index fbe06169..e87cd7f0 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "node": "22.x" }, "packageManager": "npm@11.5.1", - "version": "2.55.0", + "version": "2.55.1", "dependencies": { "@dreb/coding-agent": "*", "@mariozechner/jiti": "^2.6.5", diff --git a/packages/agent/package.json b/packages/agent/package.json index bd409623..881069a1 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -1,6 +1,6 @@ { "name": "@dreb/agent-core", - "version": "2.55.0", + "version": "2.55.1", "description": "General-purpose agent with transport abstraction, state management, and attachment support", "type": "module", "main": "./dist/index.js", diff --git a/packages/ai/package.json b/packages/ai/package.json index a8d456ba..b8bd28e4 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@dreb/ai", - "version": "2.55.0", + "version": "2.55.1", "description": "Unified LLM API with automatic model discovery and provider configuration", "type": "module", "main": "./dist/index.js", diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json index d53f534d..ac944418 100644 --- a/packages/coding-agent/package.json +++ b/packages/coding-agent/package.json @@ -1,6 +1,6 @@ { "name": "@dreb/coding-agent", - "version": "2.55.0", + "version": "2.55.1", "description": "Coding agent CLI with read, bash, edit, write tools and session management", "type": "module", "drebConfig": { diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json index cca6866a..9f5c9e72 100644 --- a/packages/dashboard/package.json +++ b/packages/dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@dreb/dashboard", - "version": "2.55.0", + "version": "2.55.1", "description": "Web dashboard for dreb — fleet overview, chat parity, subagent observability", "license": "MIT", "type": "module", diff --git a/packages/semantic-search/.claude-plugin/plugin.json b/packages/semantic-search/.claude-plugin/plugin.json index ad95e75f..6edfdc89 100644 --- a/packages/semantic-search/.claude-plugin/plugin.json +++ b/packages/semantic-search/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "semantic-search", "description": "Semantic codebase search — natural language queries over code and docs using embeddings, tree-sitter parsing, and POEM multi-signal ranking", - "version": "2.55.0", + "version": "2.55.1", "author": { "name": "Drew Brereton" }, diff --git a/packages/semantic-search/package.json b/packages/semantic-search/package.json index 1907b859..1c9e698a 100644 --- a/packages/semantic-search/package.json +++ b/packages/semantic-search/package.json @@ -1,6 +1,6 @@ { "name": "@dreb/semantic-search", - "version": "2.55.0", + "version": "2.55.1", "description": "Semantic codebase search engine with embedding-based ranking and MCP server", "publishConfig": { "access": "public" diff --git a/packages/telegram/package.json b/packages/telegram/package.json index da2daecc..6f1171c5 100644 --- a/packages/telegram/package.json +++ b/packages/telegram/package.json @@ -1,6 +1,6 @@ { "name": "@dreb/telegram", - "version": "2.55.0", + "version": "2.55.1", "description": "Telegram bot frontend for dreb coding agent", "license": "MIT", "type": "module", diff --git a/packages/tui/package.json b/packages/tui/package.json index a014415d..659510e0 100644 --- a/packages/tui/package.json +++ b/packages/tui/package.json @@ -1,6 +1,6 @@ { "name": "@dreb/tui", - "version": "2.55.0", + "version": "2.55.1", "description": "Terminal User Interface library with differential rendering for efficient text-based applications", "type": "module", "main": "dist/index.js",