@coreplane/switchboard 1.246.0 → 1.247.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/config/config.example.yaml +1 -1
- package/dist/assets/deploy/cloudflare-memory/worker.ts +14 -4
- package/dist/assets/deploy/cloudflare-resident/worker.ts +1 -1
- package/dist/assets/package-lock.json +3 -3
- package/dist/assets/package.json +5 -3
- package/dist/assets/project.json +10 -2
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/agents/registry.ts +1 -1
- package/dist/assets/src/core/budgets.ts +19 -7
- package/dist/assets/src/core/runEvents.ts +5 -1
- package/dist/assets/src/core/ship/contract.ts +7 -0
- package/dist/assets/src/core/ship/coordinator.ts +1 -1
- package/dist/assets/src/core/trace/attrs.ts +9 -0
- package/dist/assets/web/dist/.vite/manifest.json +474 -485
- package/dist/assets/web/dist/assets/AppShell-DAtHiuI6.js +1 -0
- package/dist/assets/web/dist/assets/CostsPage-BoKzYa4B.js +2 -0
- package/dist/assets/web/dist/assets/DeliveryPage-NP4g6bQd.js +1 -0
- package/dist/assets/web/dist/assets/HomePage-DYxC0izY.js +2 -0
- package/dist/assets/web/dist/assets/InputMenu-C6aPpe30.js +1 -0
- package/dist/assets/web/dist/assets/NotFoundPage-DtE-GgTk.js +1 -0
- package/dist/assets/web/dist/assets/PendingTurnRow-BuRre8it.js +1 -0
- package/dist/assets/web/dist/assets/ResidentDetailPage-DLIpWYOc.js +1 -0
- package/dist/assets/web/dist/assets/ResidentsIndexPage-6LipuDjR.js +1 -0
- package/dist/assets/web/dist/assets/RunFoldRow-V-iSy64e.js +1 -0
- package/dist/assets/web/dist/assets/RunRoutePage-DUalB1u2.js +9 -0
- package/dist/assets/web/dist/assets/RunsIndexPage-B9Ba1KdD.js +1 -0
- package/dist/assets/web/dist/assets/RunsTabs-YSbUu5py.js +1 -0
- package/dist/assets/web/dist/assets/ScheduledPage-KdjLtD_7.js +1 -0
- package/dist/assets/web/dist/assets/SettingSelect-BIzAsLk1.js +1 -0
- package/dist/assets/web/dist/assets/SettingsPage-IT5l_NaL.js +1 -0
- package/dist/assets/web/dist/assets/StatusDot-DBHAl4Il.js +1 -0
- package/dist/assets/web/dist/assets/Tooltip-_LEjptLV.js +1 -0
- package/dist/assets/web/dist/assets/UnitRoutePage-DPBsvGPR.js +1 -0
- package/dist/assets/web/dist/assets/{angular-html-D_3slZqf.js → angular-html-BjeQZdCq.js} +1 -1
- package/dist/assets/web/dist/assets/{angular-ts-D1Fv2cpN.js → angular-ts-ZGdORrL2.js} +1 -1
- package/dist/assets/web/dist/assets/{apl-60Nm_trN.js → apl-DhvV_X93.js} +1 -1
- package/dist/assets/web/dist/assets/{astro-CvyaM3Q9.js → astro-DiRSE4Ug.js} +1 -1
- package/dist/assets/web/dist/assets/{blade-yan3VBls.js → blade-D8Fr5Wvq.js} +1 -1
- package/dist/assets/web/dist/assets/{seed-BhxEVasY.js → browser-B6T5hjfR.js} +1 -1
- package/dist/assets/web/dist/assets/{c-Ddgepap2.js → c-BwbC64D4.js} +1 -1
- package/dist/assets/web/dist/assets/{chapel-CgNY6dxC.js → chapel-DgmqRK97.js} +1 -1
- package/dist/assets/web/dist/assets/{cobol-C7q82cdP.js → cobol-DJod2RNK.js} +1 -1
- package/dist/assets/web/dist/assets/{coffee-DgRMF_ni.js → coffee-D1Y2CgBY.js} +1 -1
- package/dist/assets/web/dist/assets/{cpp-B8Lf-aeo.js → cpp-CsO97YOM.js} +1 -1
- package/dist/assets/web/dist/assets/{crystal-CkA_dhEO.js → crystal-CJ7m2tOc.js} +1 -1
- package/dist/assets/web/dist/assets/{css-Cyu-C_oA.js → css-B2M-NKoj.js} +1 -1
- package/dist/assets/web/dist/assets/{dist-DS-gMjLZ.js → dist-BcYPGOBL.js} +2 -2
- package/dist/assets/web/dist/assets/durationTone-U_rOqo6r.js +1 -0
- package/dist/assets/web/dist/assets/{edge-BxV3rKNI.js → edge-CFVW-m9B.js} +1 -1
- package/dist/assets/web/dist/assets/{elixir-pNSEK39d.js → elixir-B2mtRgCr.js} +1 -1
- package/dist/assets/web/dist/assets/{elm-zgwWE33W.js → elm-2teVAwCi.js} +1 -1
- package/dist/assets/web/dist/assets/{erb-yzcYAHp_.js → erb-LAbeNqen.js} +1 -1
- package/dist/assets/web/dist/assets/eventSource-Bj_dZf6M.js +1 -0
- package/dist/assets/web/dist/assets/{git-rebase-Dg7Ous1-.js → git-rebase-DnhzH_sp.js} +1 -1
- package/dist/assets/web/dist/assets/{glimmer-js-CbZEwX27.js → glimmer-js-DPKjXf1-.js} +1 -1
- package/dist/assets/web/dist/assets/{glimmer-ts-D3NIqALy.js → glimmer-ts-CABXnt5z.js} +1 -1
- package/dist/assets/web/dist/assets/{glsl-y4-3WrI2.js → glsl-Dz4-3-gJ.js} +1 -1
- package/dist/assets/web/dist/assets/{graphql-D5d0al7K.js → graphql-ByWUD1DL.js} +1 -1
- package/dist/assets/web/dist/assets/{hack-D8fD6kEl.js → hack-CdmOK2K-.js} +1 -1
- package/dist/assets/web/dist/assets/{haml-BWeFFc-V.js → haml-DzegMpd2.js} +1 -1
- package/dist/assets/web/dist/assets/{handlebars-gIm5FeE_.js → handlebars-B5NeiP0e.js} +1 -1
- package/dist/assets/web/dist/assets/{html-fXJTVLSM.js → html-Zg_NHLv9.js} +1 -1
- package/dist/assets/web/dist/assets/{html-derivative-B3ySSBrQ.js → html-derivative-DZf9JNzh.js} +1 -1
- package/dist/assets/web/dist/assets/{http-DrJfQUmw.js → http-CVFrQZeN.js} +1 -1
- package/dist/assets/web/dist/assets/{hurl-Bvbnsf55.js → hurl-L5brWAJe.js} +1 -1
- package/dist/assets/web/dist/assets/{java-CUSpb-i-.js → java-hFphyZ4R.js} +1 -1
- package/dist/assets/web/dist/assets/{javascript-BWRH5fbY.js → javascript-CAJO1WKX.js} +1 -1
- package/dist/assets/web/dist/assets/{jinja-D3Ymci8y.js → jinja-N4A4srXI.js} +1 -1
- package/dist/assets/web/dist/assets/{jison-Gt9SO7ZC.js → jison-D3BZa_iU.js} +1 -1
- package/dist/assets/web/dist/assets/{json-Cfcblhgn.js → json-DxD1Qh8W.js} +1 -1
- package/dist/assets/web/dist/assets/{jsx-C0366fFM.js → jsx-CHhag69S.js} +1 -1
- package/dist/assets/web/dist/assets/{julia-CyBOTbxS.js → julia-CrhkZ6Tt.js} +1 -1
- package/dist/assets/web/dist/assets/{just-FPXZcIOd.js → just-D0LFOuhq.js} +1 -1
- package/dist/assets/web/dist/assets/{latex-Bd-c88v0.js → latex-BHAlwCXK.js} +1 -1
- package/dist/assets/web/dist/assets/{liquid-5tu9Hc0k.js → liquid-CkaLfCWh.js} +1 -1
- package/dist/assets/web/dist/assets/{lua-BZ5fdPP8.js → lua-B1h4aAzP.js} +1 -1
- package/dist/assets/web/dist/assets/main-DUfSE0dj.js +28 -0
- package/dist/assets/web/dist/assets/main-zbP_dTjR.css +1 -0
- package/dist/assets/web/dist/assets/{marko-C_mmj4p0.js → marko-D6CG4hvX.js} +1 -1
- package/dist/assets/web/dist/assets/{mdc-CtaNqWjY.js → mdc-CVQzimAU.js} +1 -1
- package/dist/assets/web/dist/assets/{nginx-Ddm5Mb8J.js → nginx-h-9Ir54h.js} +1 -1
- package/dist/assets/web/dist/assets/{nim-COhfroYB.js → nim-DHVI30sp.js} +1 -1
- package/dist/assets/web/dist/assets/{org-CCHFgmTb.js → org-AasAXfMF.js} +1 -1
- package/dist/assets/web/dist/assets/{perl-CXzOE-Z-.js → perl-BVi5aTEy.js} +1 -1
- package/dist/assets/web/dist/assets/{php-1V6jAIhU.js → php-qOkCeUKr.js} +1 -1
- package/dist/assets/web/dist/assets/{pug-uS37efts.js → pug-8TnUGvEX.js} +1 -1
- package/dist/assets/web/dist/assets/{qml-Bj1A0Ben.js → qml-CpJbhoxn.js} +1 -1
- package/dist/assets/web/dist/assets/{r-CMbKbLsS.js → r-JkUNcAJW.js} +1 -1
- package/dist/assets/web/dist/assets/{razor-DVRq_Ndk.js → razor-CtU4ws5a.js} +1 -1
- package/dist/assets/web/dist/assets/{regexp-AbaOr4oB.js → regexp-J2zA6ceN.js} +1 -1
- package/dist/assets/web/dist/assets/{rst-Dq_QWgOF.js → rst-CMCvf-yZ.js} +1 -1
- package/dist/assets/web/dist/assets/{ruby-CVSsAj7T.js → ruby-ChLBY_iR.js} +1 -1
- package/dist/assets/web/dist/assets/{sas-C-dGfxUi.js → sas-cwn4x2VY.js} +1 -1
- package/dist/assets/web/dist/assets/{scss-DxALxYPA.js → scss-jSrJlzLI.js} +1 -1
- package/dist/assets/web/dist/assets/{shellscript--qXcvQ5L.js → shellscript-D5nAd0gs.js} +1 -1
- package/dist/assets/web/dist/assets/{shellsession-DeqnW8Ux.js → shellsession-BZY4-Tdh.js} +1 -1
- package/dist/assets/web/dist/assets/{soy-DreoUIMt.js → soy-COppPOKr.js} +1 -1
- package/dist/assets/web/dist/assets/{sql-o3i2VTG6.js → sql-Blc_6dOA.js} +1 -1
- package/dist/assets/web/dist/assets/{sseReplay-qF-gpbAY.js → sseReplay-DXC7kGbN.js} +3 -3
- package/dist/assets/web/dist/assets/{stata-CGAT41H7.js → stata-DRv3OY-h.js} +1 -1
- package/dist/assets/web/dist/assets/{surrealql-CBU0QuGV.js → surrealql-qMv_eeJ6.js} +1 -1
- package/dist/assets/web/dist/assets/{svelte-CfHaLZiG.js → svelte-d1Edb6Rz.js} +1 -1
- package/dist/assets/web/dist/assets/{templ-D02MUcma.js → templ-CUMSIOXG.js} +1 -1
- package/dist/assets/web/dist/assets/{tex-DjprHYXl.js → tex-BGZQA-Ei.js} +1 -1
- package/dist/assets/web/dist/assets/{ts-tags-DftDOzP-.js → ts-tags-Z9ulxVsq.js} +1 -1
- package/dist/assets/web/dist/assets/{tsx-BOdvPohJ.js → tsx-oI4bI3Vf.js} +1 -1
- package/dist/assets/web/dist/assets/{twig-B_yLS56B.js → twig-D_RXwBIX.js} +1 -1
- package/dist/assets/web/dist/assets/{typescript-CdPCa4nU.js → typescript-BgqQDYoN.js} +1 -1
- package/dist/assets/web/dist/assets/{typst-C1oIFsUl.js → typst-5MW-KRDd.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-CcszJEX8.js → vue-CZhHHsPm.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-html-DcpxPcuT.js → vue-html-DlYy2d8v.js} +1 -1
- package/dist/assets/web/dist/assets/{vue-vine-D26bIKGj.js → vue-vine-CJDnx-qn.js} +1 -1
- package/dist/assets/web/dist/assets/wallClock-DmaC1sKA.js +1 -0
- package/dist/assets/web/dist/assets/{xml-D8zl6W5P.js → xml-BRBDk65Q.js} +1 -1
- package/dist/assets/web/dist/assets/{xsl-D86Bii28.js → xsl-BlCykPxo.js} +1 -1
- package/dist/assets/web/dist/assets/{yaml-g6Px4KFU.js → yaml-BqW48szf.js} +1 -1
- package/dist/cli.js +1120 -672
- package/package.json +1 -1
- package/dist/assets/web/dist/assets/AppShell-B4EUiSwP.js +0 -1
- package/dist/assets/web/dist/assets/CostsPage-D8VjAtuH.js +0 -2
- package/dist/assets/web/dist/assets/DeliveryPage-DpQi5XUI.js +0 -1
- package/dist/assets/web/dist/assets/HomePage-CvKuIGqg.js +0 -2
- package/dist/assets/web/dist/assets/InputMenu-DmqAxkn4.js +0 -1
- package/dist/assets/web/dist/assets/NotFoundPage-DDogyiXA.js +0 -1
- package/dist/assets/web/dist/assets/PendingTurnRow-BoSLlR6j.js +0 -1
- package/dist/assets/web/dist/assets/ResidentDetailPage-CiBdbzkE.js +0 -1
- package/dist/assets/web/dist/assets/ResidentsIndexPage-DgtHtd9K.js +0 -1
- package/dist/assets/web/dist/assets/RunFoldRow-IF4xbz-3.js +0 -1
- package/dist/assets/web/dist/assets/RunRoutePage-DHYa7rHK.js +0 -9
- package/dist/assets/web/dist/assets/RunsIndexPage-aWhNTv8r.js +0 -1
- package/dist/assets/web/dist/assets/RunsTabs-CY_tdGTU.js +0 -1
- package/dist/assets/web/dist/assets/ScheduledPage-gPEBZjcx.js +0 -1
- package/dist/assets/web/dist/assets/SettingSelect-VDanrTZi.js +0 -1
- package/dist/assets/web/dist/assets/SettingsPage-CFoltSRD.js +0 -1
- package/dist/assets/web/dist/assets/StatusDot-DA3eTVrT.js +0 -1
- package/dist/assets/web/dist/assets/Tooltip-BgbCkM12.js +0 -1
- package/dist/assets/web/dist/assets/UnitRoutePage-DibegaJJ.js +0 -1
- package/dist/assets/web/dist/assets/durationTone-l6aVrHb8.js +0 -1
- package/dist/assets/web/dist/assets/eventSource-Ce94ho6M.js +0 -1
- package/dist/assets/web/dist/assets/favicon-D1hkyC5j.js +0 -1
- package/dist/assets/web/dist/assets/main-B4A6x82d.js +0 -28
- package/dist/assets/web/dist/assets/main-CpkwzHX6.css +0 -1
- package/dist/assets/web/dist/assets/residentsModel-By1fThvk.js +0 -1
- package/dist/assets/web/dist/assets/wallClock-DPTuP2FD.js +0 -1
|
@@ -347,7 +347,7 @@ workspaceDir: ./workspaces
|
|
|
347
347
|
# `ship` fails the load by name.
|
|
348
348
|
# ship:
|
|
349
349
|
# maxRounds: 3 # review rounds per unit
|
|
350
|
-
# maxMinutes:
|
|
350
|
+
# maxMinutes: 240 # the ship preset's wall-clock budget in minutes (the registry's default)
|
|
351
351
|
|
|
352
352
|
# Which harness each preset's runs are driven by, deployment-wide
|
|
353
353
|
# (docs/reference/specs/harness.md item 8): a mapping of preset to a harness's
|
|
@@ -641,8 +641,18 @@ interface ConfirmationRow extends ConfirmationInput {
|
|
|
641
641
|
}
|
|
642
642
|
/** Why a consume or a cancel refused: the row is gone (`used`), past its expiry (`expired`), or someone else's (`foreign`). */
|
|
643
643
|
type ConfirmationRefusal = "used" | "expired" | "foreign";
|
|
644
|
-
|
|
644
|
+
/** A refusal names the row where one still exists — `expired` (deleted here)
|
|
645
|
+
* and `foreign` (kept) — so the bot can record the click's refusal against
|
|
646
|
+
* the command that was bound (record 0054); `used` has no row to name. */
|
|
647
|
+
type ConfirmationOutcome = { row: ConfirmationRow } | { refused: ConfirmationRefusal; row?: ConfirmationRow };
|
|
645
648
|
type ConfirmationCancelOutcome = { ok: true } | { refused: Exclude<ConfirmationRefusal, "expired"> };
|
|
649
|
+
/** The consume log's word: a refusal may carry the row it names (expired,
|
|
650
|
+
* foreign), so the refusal is the discriminant, never the row's presence. The
|
|
651
|
+
* parameter is the declared union, where the narrowing holds; the stub's
|
|
652
|
+
* return type narrows to `never` across `in`. */
|
|
653
|
+
function consumeWord(outcome: ConfirmationOutcome): string {
|
|
654
|
+
return "refused" in outcome ? outcome.refused : "consumed";
|
|
655
|
+
}
|
|
646
656
|
|
|
647
657
|
function isJsonObject(v: unknown): v is Record<string, unknown> {
|
|
648
658
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
@@ -718,9 +728,9 @@ export class ConfigDO extends DurableObject<Env> {
|
|
|
718
728
|
if (!stored) return { refused: "used" };
|
|
719
729
|
if (stored.expiresAt <= now) {
|
|
720
730
|
this.sql.exec(`DELETE FROM confirmations WHERE id = ?`, id);
|
|
721
|
-
return { refused: "expired" };
|
|
731
|
+
return { refused: "expired", row: stored };
|
|
722
732
|
}
|
|
723
|
-
if (!actorIds.includes(stored.requester)) return { refused: "foreign" };
|
|
733
|
+
if (!actorIds.includes(stored.requester)) return { refused: "foreign", row: stored };
|
|
724
734
|
this.sql.exec(`DELETE FROM confirmations WHERE id = ?`, id);
|
|
725
735
|
return { row: stored };
|
|
726
736
|
});
|
|
@@ -1233,7 +1243,7 @@ async function handleConfig(pathname: string, body: unknown, env: Env): Promise<
|
|
|
1233
1243
|
const click = confirmationClickOf(b);
|
|
1234
1244
|
if (click instanceof Response) return click;
|
|
1235
1245
|
const outcome = await dO.consumeConfirmation(click.id, click.actorIds, systemClock());
|
|
1236
|
-
console.log(`[config/confirmations/consume] ${click.id} ${
|
|
1246
|
+
console.log(`[config/confirmations/consume] ${click.id} ${consumeWord(outcome)}`);
|
|
1237
1247
|
return json(outcome);
|
|
1238
1248
|
}
|
|
1239
1249
|
case "/config/confirmations/cancel": {
|
|
@@ -628,7 +628,7 @@ const ATTACH_MUTEX_WAIT_MS = 60_000;
|
|
|
628
628
|
* 20-minute ceiling (`BASH_TIMEOUT_MAX_MS`) — clamped server-side by
|
|
629
629
|
* `clampBashTimeout` in handleExec, never trusting the client's number. The
|
|
630
630
|
* heartbeat keeps every HTTP hop alive for the whole budget; the ceiling
|
|
631
|
-
* stays far inside the bot's
|
|
631
|
+
* stays far inside the bot's 90-min coding budget. Work beyond 20 minutes
|
|
632
632
|
* belongs in background jobs.
|
|
633
633
|
*
|
|
634
634
|
* /op runs (test/build) get the flat 20-minute ceiling — the deterministic op
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.247.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "switchboard",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.247.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"workspaces": [
|
|
12
12
|
"web",
|
|
@@ -20445,7 +20445,7 @@
|
|
|
20445
20445
|
},
|
|
20446
20446
|
"packages/switchboard": {
|
|
20447
20447
|
"name": "@coreplane/switchboard",
|
|
20448
|
-
"version": "1.
|
|
20448
|
+
"version": "1.247.0",
|
|
20449
20449
|
"license": "Apache-2.0",
|
|
20450
20450
|
"dependencies": {
|
|
20451
20451
|
"@earendil-works/pi-ai": "0.85.1",
|
package/dist/assets/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchboard",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.247.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -39,14 +39,16 @@
|
|
|
39
39
|
"cli": "tsx src/cli.ts",
|
|
40
40
|
"verify": "npm run verify:root && npm run verify --workspaces --if-present && npm run check:site",
|
|
41
41
|
"verify:root": "npm run check:consistency && npm run typecheck && npm run lint && npm run format:check && npm test && npm run check:dist",
|
|
42
|
-
"check:consistency": "npm run check:lockfile && npm run check:sandbox-pair && npm run skills:check && npm run licenses:check && npm run docs:check && npm run specs:check && npm run decisions:check && npm run hygiene:check && npm run check:project-facts && npm run agents:check && npm run clock:check && npm run screenshots:check",
|
|
42
|
+
"check:consistency": "npm run check:lockfile && npm run check:sandbox-pair && npm run skills:check && npm run licenses:check && npm run docs:check && npm run pr-title:check && npm run specs:check && npm run decisions:check && npm run hygiene:check && npm run check:project-facts && npm run agents:check && npm run clock:check && npm run screenshots:check",
|
|
43
43
|
"ci:gate": "node scripts/ci-gate.mjs",
|
|
44
|
-
"fix": "npm run docs:gen && npm run agents:gen && npm run clock:gen && npm run hygiene:gen && npm run deploy:gen && npm run skills:sync && npm run lint:fix && npm run format",
|
|
44
|
+
"fix": "npm run docs:gen && npm run pr-title:gen && npm run agents:gen && npm run clock:gen && npm run hygiene:gen && npm run deploy:gen && npm run skills:sync && npm run lint:fix && npm run format",
|
|
45
45
|
"deploy:gen": "npm run --silent cli -- deploy init",
|
|
46
46
|
"deploy:check": "npm run --silent cli -- deploy init --check",
|
|
47
47
|
"check:lockfile": "node scripts/check-lockfile.mjs",
|
|
48
48
|
"check:sandbox-pair": "node scripts/check-sandbox-pair.mjs",
|
|
49
49
|
"check:pr-title": "node scripts/check-pr-title.mjs",
|
|
50
|
+
"pr-title:gen": "node scripts/pr-title-vocabulary.mjs --write",
|
|
51
|
+
"pr-title:check": "node scripts/pr-title-vocabulary.mjs",
|
|
50
52
|
"check:project-facts": "node scripts/check-project-facts.mjs",
|
|
51
53
|
"agents:gen": "tsx scripts/agents-gen.ts",
|
|
52
54
|
"clock:gen": "tsx scripts/clock-allowlist.mts --write",
|
package/dist/assets/project.json
CHANGED
|
@@ -100,8 +100,16 @@
|
|
|
100
100
|
"when": "After bumping either half of a pair."
|
|
101
101
|
},
|
|
102
102
|
"check:pr-title": {
|
|
103
|
-
"does": "Judges one PR title as the changelog line
|
|
104
|
-
"when": "`-- \"feat(scope): …\"` before opening a PR; CI's `title` check
|
|
103
|
+
"does": "Judges one PR title as the changelog line: grammar, type, scope, the `!` migration note.",
|
|
104
|
+
"when": "`-- \"feat(scope): …\"` before opening a PR; CI's `title` check."
|
|
105
|
+
},
|
|
106
|
+
"pr-title:gen": {
|
|
107
|
+
"does": "Writes the title gate's types and scopes from the release config and the code map.",
|
|
108
|
+
"when": "Part of `fix`."
|
|
109
|
+
},
|
|
110
|
+
"pr-title:check": {
|
|
111
|
+
"does": "The committed title vocabulary equals its two sources.",
|
|
112
|
+
"when": "Part of `check:consistency`."
|
|
105
113
|
},
|
|
106
114
|
"check:dist": {
|
|
107
115
|
"does": "Builds, then proves the compiled entry points and the web bundle the image needs exist.",
|
package/dist/assets/source.json
CHANGED
|
@@ -143,7 +143,7 @@ export function statusCardRule(examples = '"Implement the fix", "Run the test su
|
|
|
143
143
|
);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
const PR_DESCRIPTION_TEMPLATE = `PR description — submit it with the submit_pr_description tool for EVERY PR (this is the default, not something to wait to be asked for). Switchboard renders the GitHub body from the object you submit, so never author PR-body markdown yourself. Before submitting, judge your title with the ${PR_TITLE_GUARD} gate — \`npm run check:pr-title -- "<title>"\` — and submit only a title it accepts; the same gate refuses the PR in CI. The body is a fixed-size MAP for the reader with everything for agents collapsed under it; every field is capped in visible characters (a link's URL is not counted) and the tool refuses an object over a cap naming the field and the count — cut and resubmit. Prose is unwrapped — no hard line breaks inside a paragraph. Always hyperlink the triggering issue/request. Never fabricate validation — state exactly what you ran and the real result. BEFORE authoring the pointers, load the \`pr-description\` skill with use_skill — it defines how to choose at most seven pointers, the mechanical anchor rules and what goes below the fold; follow it for every PR.
|
|
146
|
+
const PR_DESCRIPTION_TEMPLATE = `PR description — submit it with the submit_pr_description tool for EVERY PR (this is the default, not something to wait to be asked for). Switchboard renders the GitHub body from the object you submit, so never author PR-body markdown yourself. Before submitting, judge your title with the ${PR_TITLE_GUARD} gate — \`npm run check:pr-title -- "<title>"\` — and submit only a title it accepts; the same gate refuses the PR in CI, and on Switchboard's own repository the tool refuses the same titles with the gate's own sentence, so fix the title and resubmit rather than pushing on. The body is a fixed-size MAP for the reader with everything for agents collapsed under it; every field is capped in visible characters (a link's URL is not counted) and the tool refuses an object over a cap naming the field and the count — cut and resubmit. Prose is unwrapped — no hard line breaks inside a paragraph. Always hyperlink the triggering issue/request. Never fabricate validation — state exactly what you ran and the real result. BEFORE authoring the pointers, load the \`pr-description\` skill with use_skill — it defines how to choose at most seven pointers, the mechanical anchor rules and what goes below the fold; follow it for every PR.
|
|
147
147
|
EVERY PR includes one that already exists when you push — opened by a person, by dependabot, or by an earlier run. After EVERY push to such a PR: read its current title and body (\`github_issue_get\` with the PR number works for pull requests; \`gh pr view\` where gh exists), judge them against the change as it now stands at the pushed head, and submit the object that describes the PR as it is NOW — carry forward what the existing body says that is still true (a dependency bump's release notes belong in why), add what you changed, and anchor the pointers at the new head. Switchboard replaces the PR's title and body with your rendering. A description that describes an earlier state of its branch is a bug; "it is someone else's PR" is never a reason to leave it.
|
|
148
148
|
- **title** (≤72 characters in all): the changelog line — \`type(scope): what a reader can now do or expect\`, one change, one clause, present tense. The type and the scope spend the same budget as the description, so the description is short; the body carries the rest. The tool refuses a longer title naming the count, and so does the gate in CI.
|
|
149
149
|
- **TL;DR** (\`tldr\`, rendered first, ≤300): two sentences for a reader with zero context — what this PR does and why it matters.
|
|
@@ -68,12 +68,18 @@ export type Preset = LoopPreset | "ship";
|
|
|
68
68
|
|
|
69
69
|
/** What each preset asks for when nothing above it is tighter, in minutes. The
|
|
70
70
|
* pipeline's (`ship`) is the wall clock one segment of its loop runs under;
|
|
71
|
-
* a deployment's `ship.maxMinutes` replaces it, held to `fit` below.
|
|
71
|
+
* a deployment's `ship.maxMinutes` replaces it, held to `fit` below. Coding's
|
|
72
|
+
* is sized by the ledger's ship children, not its standalone runs: a child
|
|
73
|
+
* that pushes at minute 29 and then runs the repo's whole gate (seven to ten
|
|
74
|
+
* minutes on a resident) was cut at 45 one run in twelve, so the ask is
|
|
75
|
+
* double the 90th percentile (31.5) with the gate inside it. Ship's holds
|
|
76
|
+
* its own loop at the default rounds with a fix round at that ask, not at
|
|
77
|
+
* its floor (`fit` proves the floor case; the ask leaves room above it). */
|
|
72
78
|
export const ASKS: Readonly<Record<Preset, number>> = {
|
|
73
79
|
general: 5,
|
|
74
|
-
coding:
|
|
80
|
+
coding: 90,
|
|
75
81
|
review: 25,
|
|
76
|
-
ship:
|
|
82
|
+
ship: 240,
|
|
77
83
|
research: 8,
|
|
78
84
|
explore: 120,
|
|
79
85
|
conductor: 120,
|
|
@@ -87,10 +93,13 @@ export type RoundKind = "coding" | "review" | "fix" | "merge";
|
|
|
87
93
|
* falls under the floor is refused rather than dispatched: a two-minute
|
|
88
94
|
* review or fix costs an attach and a model turn and finishes nothing.
|
|
89
95
|
* Review's is the ledger's 90th percentile of completed reviews (5.1 min over
|
|
90
|
-
* 181); coding's
|
|
96
|
+
* 181); coding's is the least a fix round can run the repo's gate in — the
|
|
97
|
+
* gate alone takes seven to ten minutes on a resident, and a fix that cannot
|
|
98
|
+
* run it finishes nothing its contract asks; the merge wait's is a guess
|
|
99
|
+
* until the ledger says. */
|
|
91
100
|
export const PRESET_FLOORS: Readonly<Record<LoopPreset, number>> = {
|
|
92
101
|
general: 2,
|
|
93
|
-
coding:
|
|
102
|
+
coding: 15,
|
|
94
103
|
review: 5,
|
|
95
104
|
research: 3,
|
|
96
105
|
explore: 15,
|
|
@@ -387,6 +396,9 @@ export type GrantSource = "org" | "channel" | "user" | "run";
|
|
|
387
396
|
export const DEFAULT_GRANT: Grant = { renewals: 0 };
|
|
388
397
|
|
|
389
398
|
/** The most renewals one request may carry: thirteen segments of the ship
|
|
390
|
-
* preset's ask are
|
|
391
|
-
*
|
|
399
|
+
* preset's ask are two days. The cap bounds a COUNT a person types
|
|
400
|
+
* (`renewals:`) or a scope holds; it did not halve when the ask doubled,
|
|
401
|
+
* since every grant already configured is a count of segments and a day's
|
|
402
|
+
* hand-over is now `renewals: 5` — the longest problem a person hands over
|
|
403
|
+
* in one message before a plan should carry it. */
|
|
392
404
|
export const GRANT_RENEWALS_MAX = 12;
|
|
@@ -462,7 +462,7 @@ export type RouteInputValue = RouteInputLeafOrList | RouteInputObject3;
|
|
|
462
462
|
* `pasted` — the typed line that followed a hand-back in its thread, with the
|
|
463
463
|
* same receipt, ran. A routed read carries no outcome: it is not a decision
|
|
464
464
|
* about a state change. */
|
|
465
|
-
export type RouteOutcome = "hand_back" | "offered" | "confirmed" | "pasted";
|
|
465
|
+
export type RouteOutcome = "hand_back" | "offered" | "confirmed" | "pasted" | "refused";
|
|
466
466
|
|
|
467
467
|
export type RunEvent =
|
|
468
468
|
/** `callId` is the provider's tool_use id — the explicit pair key between a
|
|
@@ -864,6 +864,10 @@ export type RunEvent =
|
|
|
864
864
|
input?: { readonly [key: string]: RouteInputValue };
|
|
865
865
|
receipt?: string;
|
|
866
866
|
outcome?: RouteOutcome;
|
|
867
|
+
/** The refusal's code (src/core/refusal.ts) when `outcome` is `refused`
|
|
868
|
+
* (record 0054): a refusal after a command was bound is a run
|
|
869
|
+
* record, and the door report counts it by cause and code. */
|
|
870
|
+
refusalCode?: string;
|
|
867
871
|
handBackRunId?: string;
|
|
868
872
|
seq?: number;
|
|
869
873
|
at?: number;
|
|
@@ -129,6 +129,13 @@ export const CONTRACT_SECTION_HEADINGS = {
|
|
|
129
129
|
* repository's rules file (~15k characters) and a long unit both inside it. */
|
|
130
130
|
export const DEFAULT_CONTRACT_MAX_CHARS = 48_000;
|
|
131
131
|
|
|
132
|
+
/** The most of a plan a reader hands the parsers: ten times the tool clip
|
|
133
|
+
* (`MAX_FILE_CHARS`, `src/execution/githubApi.ts`), which a plan that grows by
|
|
134
|
+
* amendment passes — the program plan crossed 400k characters and the seed
|
|
135
|
+
* then saw its first 25 units alone. A plan past this bound is refused by
|
|
136
|
+
* name, never parsed short. */
|
|
137
|
+
export const PLAN_MAX_CHARS = 2_000_000;
|
|
138
|
+
|
|
132
139
|
const UNIT_HEADING = /^### (U\d+)\. (.+?)\s*$/;
|
|
133
140
|
const ANY_HEADING = /^#{2,3} /;
|
|
134
141
|
const BULLET = /^- \*\*([^*]+)\*\*:(?:\s?(.*))?$/;
|
|
@@ -754,7 +754,7 @@ export const WAIT_MARGIN_MS = SHIP_WAIT.marginMinutes * MIN;
|
|
|
754
754
|
* one chunk of the runner's time, not the child's whole budget. Five minutes
|
|
755
755
|
* is the machine's one cadence for asking the bot what it cannot be told (the
|
|
756
756
|
* margin and the merge poll are the same number), and it keeps a round to a
|
|
757
|
-
* few steps: a coding child's
|
|
757
|
+
* few steps: a coding child's 90 minutes are eighteen waits and eighteen reads. */
|
|
758
758
|
export const WAIT_CHUNK_MS = SHIP_WAIT.chunkMinutes * MIN;
|
|
759
759
|
/** The merge wait is a round of its own: its minutes are carved from the
|
|
760
760
|
* pipeline's remainder when the door is first asked (the merge wait's ask and
|
|
@@ -26,6 +26,11 @@ export interface AttrDomain {
|
|
|
26
26
|
requester: "message" | "relay-footer" | "thread-parent" | "bot";
|
|
27
27
|
// dispatch.* / run.* / post.*
|
|
28
28
|
outcome: string;
|
|
29
|
+
/** The refusal's code (src/core/refusal.ts) — on the `dispatch.refuse` span
|
|
30
|
+
* and the request's root, so refusals are countable from the trace alone. */
|
|
31
|
+
refusal: string;
|
|
32
|
+
/** The refusal's cause, from the one code→cause table in src/core/refusal.ts. */
|
|
33
|
+
cause: "request" | "policy" | "system";
|
|
29
34
|
count: number;
|
|
30
35
|
backend: Backend;
|
|
31
36
|
// run.command
|
|
@@ -114,6 +119,8 @@ export type SpanAttrs = { readonly [K in SpanAttrKey]?: AttrDomain[K] };
|
|
|
114
119
|
const IDENTIFIER_KEYS: ReadonlySet<SpanAttrKey> = new Set<SpanAttrKey>([
|
|
115
120
|
"runId",
|
|
116
121
|
"outcome",
|
|
122
|
+
"refusal",
|
|
123
|
+
"cause",
|
|
117
124
|
"command",
|
|
118
125
|
"route",
|
|
119
126
|
"host",
|
|
@@ -163,6 +170,8 @@ const ATTR_TYPE: Record<SpanAttrKey, "string" | "number" | "boolean"> = {
|
|
|
163
170
|
dedupe: "string",
|
|
164
171
|
requester: "string",
|
|
165
172
|
outcome: "string",
|
|
173
|
+
refusal: "string",
|
|
174
|
+
cause: "string",
|
|
166
175
|
count: "number",
|
|
167
176
|
backend: "string",
|
|
168
177
|
command: "string",
|