From ec9dd6e90c1771e08186231a1a495eb3a5cf1964 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 9 Jul 2026 07:34:16 +0100 Subject: [PATCH] feat(bug-filing-mcp): new cartridge wrapping the real feedback-o-tron engine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a first-class JS-worker cartridge that packages the real bug-filing engine for the autonomous bug-reporting pipeline. Its submit_feedback tool forwards to the engine's HTTP intake (POST 127.0.0.1:7722/api/v1/submit_feedback, companion feedback-o-tron PR), so the boj gateway can reach the engine via POST /cartridge/bug-filing-mcp/invoke. Implements owner decision D0 = new wrapping cartridge: the unrelated feedback-mcp sentiment counter is left untouched; this is a new, distinctly named cartridge for the real engine. Manifest validates against schemas/cartridge-v1.json; no FFI (.so) claims — pure mod.js dispatch. Closes: hyperpolymath/boj-server#279 Refs: hyperpolymath/boj-server#274 Co-Authored-By: Claude Opus 4.8 --- .../development/bug-filing-mcp/README.adoc | 65 +++++++++++++++++ .../development/bug-filing-mcp/cartridge.json | 69 +++++++++++++++++++ .../domains/development/bug-filing-mcp/mod.js | 53 ++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 cartridges/domains/development/bug-filing-mcp/README.adoc create mode 100644 cartridges/domains/development/bug-filing-mcp/cartridge.json create mode 100644 cartridges/domains/development/bug-filing-mcp/mod.js diff --git a/cartridges/domains/development/bug-filing-mcp/README.adoc b/cartridges/domains/development/bug-filing-mcp/README.adoc new file mode 100644 index 0000000..9953855 --- /dev/null +++ b/cartridges/domains/development/bug-filing-mcp/README.adoc @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) += bug-filing-mcp + +Autonomous bug-report filing cartridge. It is the boj-side packaging of the +real *feedback-o-tron* engine for the autonomous bug-reporting pipeline +(see `feedback-o-tron/docs/AUTONOMOUS-BUG-PIPELINE.adoc`). + +[IMPORTANT] +==== +*This is not `feedback-mcp`.* `feedback-mcp` is an unrelated in-memory *sentiment +counter*. Per owner decision *D0 = new wrapping cartridge*, that cartridge is left +untouched and this *new* cartridge wraps the real bug-filing engine. The two only +share the `127.0.0.1:7722` placeholder port; run one backend or the other. +==== + +== What it does + +Exposes a single tool, `submit_feedback`, that files a bug report / feedback / +proposal to one or more forges (GitHub, GitLab, Bitbucket, Codeberg, Bugzilla, +email) through the feedback-o-tron engine — with deduplication against existing +issues and audit logging handled engine-side. + +== How it wires + +[source,text] +---- +boj gateway :7700 + POST /cartridge/bug-filing-mcp/invoke {tool:"submit_feedback", arguments:{title,body,repo}} + -> bug-filing-mcp/mod.js (Deno JS worker) + -> POST http://127.0.0.1:7722/api/v1/submit_feedback + -> feedback-o-tron Submitter -> gh / glab / Bugzilla REST / ... +---- + +The cartridge is a thin HTTP client; all submission logic (dedup, audit, rate +limiting, dry-run) lives in the engine, reached over its localhost HTTP intake. + +== Prerequisites + +Run the feedback-o-tron engine with its HTTP intake enabled: + +[source,sh] +---- +FEEDBACK_A_TRON_HTTP=1 feedback-a-tron # listens on 127.0.0.1:7722 +# override: FEEDBACK_A_TRON_HTTP_PORT, FEEDBACK_A_TRON_HTTP_BIND +---- + +Point the cartridge elsewhere with `BUG_FILING_BACKEND_URL` if needed. + +== Tool: `submit_feedback` + +[cols="1,1,3",options="header"] +|=== +| Field | Required | Meaning +| `title` | yes | Issue title +| `body` | yes | Issue body (markdown) +| `repo` | yes | Target repo, `owner/repo` +| `platforms` | no | Subset of `github,gitlab,bitbucket,codeberg,bugzilla,email` (default `github`) +| `labels` | no | Labels to apply (platform-dependent) +| `dry_run` | no | Preview without filing +| `skip_dedupe` | no | Skip duplicate checking +|=== + +If the backend is not running, the cartridge returns a `503` with a hint to +start the engine with `FEEDBACK_A_TRON_HTTP=1`. diff --git a/cartridges/domains/development/bug-filing-mcp/cartridge.json b/cartridges/domains/development/bug-filing-mcp/cartridge.json new file mode 100644 index 0000000..6c86d61 --- /dev/null +++ b/cartridges/domains/development/bug-filing-mcp/cartridge.json @@ -0,0 +1,69 @@ +{ + "$schema": "https://hyperpolymath.dev/standards/cartridges/cartridge-v1.json", + "spdx": "MPL-2.0", + "copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)", + "name": "bug-filing-mcp", + "version": "0.1.0", + "description": "Autonomous bug-report filing cartridge -- wraps the real feedback-o-tron engine (multi-forge issue submission with deduplication and audit logging) via its localhost HTTP intake. This is the boj-side packaging of the engine for the autonomous bug-reporting pipeline (feedback-o-tron/docs/AUTONOMOUS-BUG-PIPELINE.adoc, D0 = new wrapping cartridge). NOT the same as feedback-mcp, which is an unrelated in-memory sentiment counter.", + "domain": "development", + "category": "domain", + "tier": "Ayo", + "protocols": [ + "MCP", + "REST" + ], + "auth": { + "method": "none", + "env_var": null, + "credential_source": null + }, + "api": { + "base_url": "http://127.0.0.1:7722", + "content_type": "application/json" + }, + "tools": [ + { + "name": "submit_feedback", + "description": "File a bug report / feedback / proposal to one or more forges (GitHub, GitLab, Bitbucket, Codeberg, Bugzilla, email) via the feedback-o-tron engine. Includes deduplication against existing issues and audit logging. Use dry_run to preview without filing.", + "inputSchema": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "Issue/feedback title" + }, + "body": { + "type": "string", + "description": "Issue/feedback body (markdown supported)" + }, + "repo": { + "type": "string", + "description": "Target repository (owner/repo format)" + }, + "platforms": { + "type": "array", + "items": { + "type": "string", + "enum": ["github", "gitlab", "bitbucket", "codeberg", "bugzilla", "email"] + }, + "description": "Platforms to submit to (default: github)" + }, + "labels": { + "type": "array", + "items": { "type": "string" }, + "description": "Labels to apply (platform-dependent)" + }, + "dry_run": { + "type": "boolean", + "description": "If true, show what would be submitted without actually submitting" + }, + "skip_dedupe": { + "type": "boolean", + "description": "If true, skip duplicate checking" + } + }, + "required": ["title", "body", "repo"] + } + } + ] +} diff --git a/cartridges/domains/development/bug-filing-mcp/mod.js b/cartridges/domains/development/bug-filing-mcp/mod.js new file mode 100644 index 0000000..c8f0b7b --- /dev/null +++ b/cartridges/domains/development/bug-filing-mcp/mod.js @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +// +// bug-filing-mcp/mod.js — autonomous bug-report filing. +// +// Wraps the real feedback-o-tron engine via its localhost HTTP intake +// (POST /api/v1/submit_feedback on http://127.0.0.1:7722; run the engine with +// FEEDBACK_A_TRON_HTTP=1). Override the backend with BUG_FILING_BACKEND_URL. +// +// This is the boj-side packaging of the engine for the autonomous bug-reporting +// pipeline (feedback-o-tron/docs/AUTONOMOUS-BUG-PIPELINE.adoc, contract C4 dispatch +// under D0 = new wrapping cartridge). It is NOT feedback-mcp (an unrelated +// in-memory sentiment counter that happens to share the 7722 placeholder port). + +const BASE_URL = Deno.env.get("BUG_FILING_BACKEND_URL") ?? "http://127.0.0.1:7722"; +const TIMEOUT_MS = 30_000; + +async function post(path, payload) { + const ctrl = new AbortController(); + const t = setTimeout(() => ctrl.abort(), TIMEOUT_MS); + try { + const r = await fetch(`${BASE_URL}${path}`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload ?? {}), + signal: ctrl.signal, + }); + const data = await r.json().catch(() => ({ error: "non-JSON response from bug-filing backend" })); + return { status: r.status, data }; + } catch (e) { + if (e.name === "AbortError") { + return { status: 504, data: { error: "bug-filing backend (feedback-o-tron) timed out" } }; + } + return { + status: 503, + data: { + error: `bug-filing backend unavailable: ${e.message}. ` + + `Start feedback-o-tron with FEEDBACK_A_TRON_HTTP=1 (listening on ${BASE_URL}).`, + }, + }; + } finally { + clearTimeout(t); + } +} + +export async function handleTool(toolName, args) { + switch (toolName) { + case "submit_feedback": + return post("/api/v1/submit_feedback", args ?? {}); + default: + return { status: 404, data: { error: `Unknown tool: ${toolName}` } }; + } +}