@webpieces/rules-config 0.4.469 → 0.4.470
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/package.json +1 -1
- package/src/checklist-config.d.ts +3 -1
- package/src/checklist-config.js +13 -2
- package/src/checklist-config.js.map +1 -1
- package/src/checklist-docs-validator.d.ts +9 -0
- package/src/checklist-docs-validator.js +45 -0
- package/src/checklist-docs-validator.js.map +1 -0
- package/src/gate-token.d.ts +24 -0
- package/src/gate-token.js +78 -0
- package/src/gate-token.js.map +1 -0
- package/src/index.d.ts +5 -2
- package/src/index.js +27 -4
- package/src/index.js.map +1 -1
- package/src/pr-gate-config.d.ts +14 -1
- package/src/pr-gate-config.js +18 -2
- package/src/pr-gate-config.js.map +1 -1
- package/src/review-json.d.ts +27 -2
- package/src/review-json.js +147 -31
- package/src/review-json.js.map +1 -1
- package/src/subagent-provenance.d.ts +39 -0
- package/src/subagent-provenance.js +173 -0
- package/src/subagent-provenance.js.map +1 -0
- package/src/validate-config.d.ts +1 -0
- package/src/validate-config.js +12 -0
- package/src/validate-config.js.map +1 -1
- package/templates/webpieces-pr-gate.yml +40 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/rules-config",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.470",
|
|
4
4
|
"description": "Shared webpieces.config.json loader. Single source of truth for validation rule configuration consumed by @webpieces/ai-hook-rules, @webpieces/code-rules, and @webpieces/nx-webpieces-rules.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -10,7 +10,8 @@ export declare class ChecklistDefinition {
|
|
|
10
10
|
severity: string;
|
|
11
11
|
blockMessage: string;
|
|
12
12
|
disabled: boolean;
|
|
13
|
-
|
|
13
|
+
subagent: string;
|
|
14
|
+
constructor(id: string, title: string, patterns: string[], contentPatterns: string[], docs: string[], severity: string, blockMessage: string, disabled?: boolean, subagent?: string);
|
|
14
15
|
}
|
|
15
16
|
export interface RawChecklist {
|
|
16
17
|
id?: string;
|
|
@@ -21,5 +22,6 @@ export interface RawChecklist {
|
|
|
21
22
|
severity?: string;
|
|
22
23
|
blockMessage?: string;
|
|
23
24
|
disabled?: boolean;
|
|
25
|
+
subagent?: string;
|
|
24
26
|
}
|
|
25
27
|
export declare function toChecklist(raw: RawChecklist): ChecklistDefinition;
|
package/src/checklist-config.js
CHANGED
|
@@ -27,8 +27,18 @@ class ChecklistDefinition {
|
|
|
27
27
|
severity; // 'BLOCK' | 'WARN'
|
|
28
28
|
blockMessage; // consumer-owned wording shown when it blocks
|
|
29
29
|
disabled; // example/inactive checklist kept in the file (JSON has no comments)
|
|
30
|
+
// Expected agentType (e.g. "morpheus-reviewer") that must have run on this branch for the checklist
|
|
31
|
+
// to be considered independently reviewed. When set, wp-finish-upsert-pr reads the Claude Code
|
|
32
|
+
// harness's own subagent artifacts (agent-*.meta.json agentType + spawnDepth, sibling jsonl
|
|
33
|
+
// isSidechain/gitBranch) to VERIFY such a subagent actually ran — provenance is READ from harness
|
|
34
|
+
// artifacts, never asserted in review.json. '' = no provenance requirement.
|
|
35
|
+
//
|
|
36
|
+
// NOT tamper-proof: a determined agent can hand-write a fake agent-*.meta.json. This raises the bar
|
|
37
|
+
// from "trust the model's word" to "deliberate, auditable forgery"; it is not cryptographic proof.
|
|
38
|
+
// Absent CLAUDE_CODE_SESSION_ID (plain terminal / CI) the check warns + skips rather than failing.
|
|
39
|
+
subagent;
|
|
30
40
|
// eslint-disable-next-line @typescript-eslint/max-params
|
|
31
|
-
constructor(id, title, patterns, contentPatterns, docs, severity, blockMessage, disabled = false) {
|
|
41
|
+
constructor(id, title, patterns, contentPatterns, docs, severity, blockMessage, disabled = false, subagent = '') {
|
|
32
42
|
this.id = id;
|
|
33
43
|
this.title = title;
|
|
34
44
|
this.patterns = patterns;
|
|
@@ -37,12 +47,13 @@ class ChecklistDefinition {
|
|
|
37
47
|
this.severity = severity;
|
|
38
48
|
this.blockMessage = blockMessage;
|
|
39
49
|
this.disabled = disabled;
|
|
50
|
+
this.subagent = subagent;
|
|
40
51
|
}
|
|
41
52
|
}
|
|
42
53
|
exports.ChecklistDefinition = ChecklistDefinition;
|
|
43
54
|
// Mirror of pr-gate-config's toGate: build a ChecklistDefinition from an omitting-friendly raw entry.
|
|
44
55
|
// webpieces-disable no-function-outside-class -- pure config transform beside its data class, mirrors toGate
|
|
45
56
|
function toChecklist(raw) {
|
|
46
|
-
return new ChecklistDefinition(raw.id ?? '', raw.title ?? '', raw.patterns ?? [], raw.contentPatterns ?? [], raw.docs ?? [], raw.severity ?? exports.CHECKLIST_WARN, raw.blockMessage ?? '', raw.disabled ?? false);
|
|
57
|
+
return new ChecklistDefinition(raw.id ?? '', raw.title ?? '', raw.patterns ?? [], raw.contentPatterns ?? [], raw.docs ?? [], raw.severity ?? exports.CHECKLIST_WARN, raw.blockMessage ?? '', raw.disabled ?? false, raw.subagent ?? '');
|
|
47
58
|
}
|
|
48
59
|
//# sourceMappingURL=checklist-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checklist-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/checklist-config.ts"],"names":[],"mappings":";AAAA,mGAAmG;AACnG,sGAAsG;AACtG,uGAAuG;AACvG,iGAAiG;AACjG,EAAE;AACF,uGAAuG;AACvG,uGAAuG;AACvG,kFAAkF;AAClF,EAAE;AACF,wGAAwG;AACxG,0FAA0F;;;
|
|
1
|
+
{"version":3,"file":"checklist-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/checklist-config.ts"],"names":[],"mappings":";AAAA,mGAAmG;AACnG,sGAAsG;AACtG,uGAAuG;AACvG,iGAAiG;AACjG,EAAE;AACF,uGAAuG;AACvG,uGAAuG;AACvG,kFAAkF;AAClF,EAAE;AACF,wGAAwG;AACxG,0FAA0F;;;AAmE1F,kCAYC;AA7EY,QAAA,eAAe,GAAG,OAAO,CAAC;AAC1B,QAAA,cAAc,GAAG,MAAM,CAAC;AACrC,oGAAoG;AACpG,6FAA6F;AAChF,QAAA,oBAAoB,GAAG,CAAC,uBAAe,EAAE,sBAAc,CAAC,CAAC;AAEtE,MAAa,mBAAmB;IAC5B,EAAE,CAAS,CAAiB,sEAAsE;IAClG,KAAK,CAAS,CAAc,kBAAkB;IAC9C,QAAQ,CAAW,CAAS,+DAA+D;IAC3F,eAAe,CAAW,CAAE,wEAAwE;IACpG,IAAI,CAAW,CAAa,iEAAiE;IAC7F,QAAQ,CAAS,CAAW,mBAAmB;IAC/C,YAAY,CAAS,CAAO,8CAA8C;IAC1E,QAAQ,CAAU,CAAU,qEAAqE;IACjG,oGAAoG;IACpG,+FAA+F;IAC/F,4FAA4F;IAC5F,kGAAkG;IAClG,4EAA4E;IAC5E,EAAE;IACF,oGAAoG;IACpG,mGAAmG;IACnG,mGAAmG;IACnG,QAAQ,CAAS;IAEjB,yDAAyD;IACzD,YACI,EAAU,EACV,KAAa,EACb,QAAkB,EAClB,eAAyB,EACzB,IAAc,EACd,QAAgB,EAChB,YAAoB,EACpB,QAAQ,GAAG,KAAK,EAChB,QAAQ,GAAG,EAAE;QAEb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ;AA1CD,kDA0CC;AAeD,sGAAsG;AACtG,6GAA6G;AAC7G,SAAgB,WAAW,CAAC,GAAiB;IACzC,OAAO,IAAI,mBAAmB,CAC1B,GAAG,CAAC,EAAE,IAAI,EAAE,EACZ,GAAG,CAAC,KAAK,IAAI,EAAE,EACf,GAAG,CAAC,QAAQ,IAAI,EAAE,EAClB,GAAG,CAAC,eAAe,IAAI,EAAE,EACzB,GAAG,CAAC,IAAI,IAAI,EAAE,EACd,GAAG,CAAC,QAAQ,IAAI,sBAAc,EAC9B,GAAG,CAAC,YAAY,IAAI,EAAE,EACtB,GAAG,CAAC,QAAQ,IAAI,KAAK,EACrB,GAAG,CAAC,QAAQ,IAAI,EAAE,CACrB,CAAC;AACN,CAAC","sourcesContent":["// A company review checklist: a diff-triggered extension point that lets a CONSUMER inject its own\n// PR-time review process into the webpieces gated flow WITHOUT forking the tooling. When the branch's\n// diff touches paths/content the consumer cares about, the AI is made to read the named docs before it\n// writes review.json, and a BLOCK checklist refuses to open the PR until the AI acknowledges it.\n//\n// This is deliberately NOT an authorization mechanism (acknowledged: true is written by the AI). It is\n// a SURFACING + AUDIT extension point — the wording, the docs, and the trigger are all consumer-owned;\n// webpieces owns only the mechanism. Data-only (per CLAUDE.md, classes for data).\n//\n// Lives in rules-config (not pr-gate) because both the config layer AND review.json validation need the\n// severity vocabulary, and rules-config is the package every consumer already depends on.\n\nexport const CHECKLIST_BLOCK = 'BLOCK';\nexport const CHECKLIST_WARN = 'WARN';\n// BLOCK — an unacknowledged one throws before the PR is opened (same guarantee buildCommand gives).\n// WARN — never validated; absence just renders a yellow dashboard row (a nudge, not a gate).\nexport const CHECKLIST_SEVERITIES = [CHECKLIST_BLOCK, CHECKLIST_WARN];\n\nexport class ChecklistDefinition {\n id: string; // stable key echoed in review.json + the dashboard, e.g. \"migrations\"\n title: string; // dashboard label\n patterns: string[]; // path globs (isPathExcluded semantics); [] = any changed file\n contentPatterns: string[]; // regexes matched against ADDED diff lines only; [] = path-only trigger\n docs: string[]; // repo-relative docs the AI MUST read before writing review.json\n severity: string; // 'BLOCK' | 'WARN'\n blockMessage: string; // consumer-owned wording shown when it blocks\n disabled: boolean; // example/inactive checklist kept in the file (JSON has no comments)\n // Expected agentType (e.g. \"morpheus-reviewer\") that must have run on this branch for the checklist\n // to be considered independently reviewed. When set, wp-finish-upsert-pr reads the Claude Code\n // harness's own subagent artifacts (agent-*.meta.json agentType + spawnDepth, sibling jsonl\n // isSidechain/gitBranch) to VERIFY such a subagent actually ran — provenance is READ from harness\n // artifacts, never asserted in review.json. '' = no provenance requirement.\n //\n // NOT tamper-proof: a determined agent can hand-write a fake agent-*.meta.json. This raises the bar\n // from \"trust the model's word\" to \"deliberate, auditable forgery\"; it is not cryptographic proof.\n // Absent CLAUDE_CODE_SESSION_ID (plain terminal / CI) the check warns + skips rather than failing.\n subagent: string;\n\n // eslint-disable-next-line @typescript-eslint/max-params\n constructor(\n id: string,\n title: string,\n patterns: string[],\n contentPatterns: string[],\n docs: string[],\n severity: string,\n blockMessage: string,\n disabled = false,\n subagent = '',\n ) {\n this.id = id;\n this.title = title;\n this.patterns = patterns;\n this.contentPatterns = contentPatterns;\n this.docs = docs;\n this.severity = severity;\n this.blockMessage = blockMessage;\n this.disabled = disabled;\n this.subagent = subagent;\n }\n}\n\n// One checklist entry straight from consumer JSON, before it is validated + narrowed into a class.\nexport interface RawChecklist {\n id?: string;\n title?: string;\n patterns?: string[];\n contentPatterns?: string[];\n docs?: string[];\n severity?: string;\n blockMessage?: string;\n disabled?: boolean;\n subagent?: string;\n}\n\n// Mirror of pr-gate-config's toGate: build a ChecklistDefinition from an omitting-friendly raw entry.\n// webpieces-disable no-function-outside-class -- pure config transform beside its data class, mirrors toGate\nexport function toChecklist(raw: RawChecklist): ChecklistDefinition {\n return new ChecklistDefinition(\n raw.id ?? '',\n raw.title ?? '',\n raw.patterns ?? [],\n raw.contentPatterns ?? [],\n raw.docs ?? [],\n raw.severity ?? CHECKLIST_WARN,\n raw.blockMessage ?? '',\n raw.disabled ?? false,\n raw.subagent ?? '',\n );\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate ONLY the pr-gate `checklists[]` block, in isolation — docs paths exist, contentPatterns
|
|
3
|
+
* compile, ids are unique, blockMessage present on BLOCK entries. This is the same logic
|
|
4
|
+
* loadAndValidate runs (validateChecklists), but callable directly so a missing/typo'd `docs:` path
|
|
5
|
+
* fails as its OWN `validate-checklist-docs` check (with a clear owner) instead of surfacing as an
|
|
6
|
+
* unrelated validator's banner because it rode along inside loadAndValidate. Returns human-readable
|
|
7
|
+
* errors; never throws.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateChecklistDocs(cwd: string): string[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateChecklistDocs = validateChecklistDocs;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
|
+
const config_file_1 = require("./config-file");
|
|
8
|
+
const validate_config_1 = require("./validate-config");
|
|
9
|
+
const to_error_1 = require("./to-error");
|
|
10
|
+
/**
|
|
11
|
+
* Validate ONLY the pr-gate `checklists[]` block, in isolation — docs paths exist, contentPatterns
|
|
12
|
+
* compile, ids are unique, blockMessage present on BLOCK entries. This is the same logic
|
|
13
|
+
* loadAndValidate runs (validateChecklists), but callable directly so a missing/typo'd `docs:` path
|
|
14
|
+
* fails as its OWN `validate-checklist-docs` check (with a clear owner) instead of surfacing as an
|
|
15
|
+
* unrelated validator's banner because it rode along inside loadAndValidate. Returns human-readable
|
|
16
|
+
* errors; never throws.
|
|
17
|
+
*/
|
|
18
|
+
// webpieces-disable no-function-outside-class -- module-level config validator, matches validate-config.ts
|
|
19
|
+
function validateChecklistDocs(cwd) {
|
|
20
|
+
const configPath = (0, config_file_1.findConfigFile)(cwd);
|
|
21
|
+
if (!configPath)
|
|
22
|
+
return [];
|
|
23
|
+
// webpieces-disable no-any-unknown -- parsed config JSON is opaque until narrowed below
|
|
24
|
+
let raw;
|
|
25
|
+
// webpieces-disable no-unmanaged-exceptions -- chokepoint: a malformed config surfaces as one readable error
|
|
26
|
+
// eslint-disable-next-line @webpieces/no-unmanaged-exceptions
|
|
27
|
+
try {
|
|
28
|
+
// webpieces-disable no-any-unknown -- parsed config JSON is opaque until narrowed below
|
|
29
|
+
raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
const error = (0, to_error_1.toError)(err);
|
|
33
|
+
return [`[pr-gate] ${path.basename(configPath)} is not valid JSON: ${error.message}`];
|
|
34
|
+
}
|
|
35
|
+
const repoRoot = path.dirname(configPath);
|
|
36
|
+
// Checklists live under commands["pr-gate"].checklists (current) or the legacy top-level pr-gate.
|
|
37
|
+
// webpieces-disable no-any-unknown -- narrowing the opaque command section
|
|
38
|
+
const commands = raw['commands'];
|
|
39
|
+
// webpieces-disable no-any-unknown -- narrowing the opaque pr-gate section
|
|
40
|
+
const prGate = (commands?.['pr-gate'] ?? raw['pr-gate']);
|
|
41
|
+
if (!prGate || !('checklists' in prGate))
|
|
42
|
+
return [];
|
|
43
|
+
return (0, validate_config_1.validateChecklists)(prGate['checklists'], repoRoot);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=checklist-docs-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checklist-docs-validator.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/checklist-docs-validator.ts"],"names":[],"mappings":";;AAeA,sDAsBC;;AArCD,+CAAyB;AACzB,mDAA6B;AAC7B,+CAA+C;AAC/C,uDAAuD;AACvD,yCAAqC;AAErC;;;;;;;GAOG;AACH,2GAA2G;AAC3G,SAAgB,qBAAqB,CAAC,GAAW;IAC7C,MAAM,UAAU,GAAG,IAAA,4BAAc,EAAC,GAAG,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IAC3B,wFAAwF;IACxF,IAAI,GAA4B,CAAC;IACjC,6GAA6G;IAC7G,8DAA8D;IAC9D,IAAI,CAAC;QACD,wFAAwF;QACxF,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAA4B,CAAC;IACrF,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC;QAC3B,OAAO,CAAC,aAAa,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,uBAAuB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1C,kGAAkG;IAClG,2EAA2E;IAC3E,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAwC,CAAC;IACxE,2EAA2E;IAC3E,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAwC,CAAC;IAChG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,YAAY,IAAI,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACpD,OAAO,IAAA,oCAAkB,EAAC,MAAM,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { findConfigFile } from './config-file';\nimport { validateChecklists } from './validate-config';\nimport { toError } from './to-error';\n\n/**\n * Validate ONLY the pr-gate `checklists[]` block, in isolation — docs paths exist, contentPatterns\n * compile, ids are unique, blockMessage present on BLOCK entries. This is the same logic\n * loadAndValidate runs (validateChecklists), but callable directly so a missing/typo'd `docs:` path\n * fails as its OWN `validate-checklist-docs` check (with a clear owner) instead of surfacing as an\n * unrelated validator's banner because it rode along inside loadAndValidate. Returns human-readable\n * errors; never throws.\n */\n// webpieces-disable no-function-outside-class -- module-level config validator, matches validate-config.ts\nexport function validateChecklistDocs(cwd: string): string[] {\n const configPath = findConfigFile(cwd);\n if (!configPath) return [];\n // webpieces-disable no-any-unknown -- parsed config JSON is opaque until narrowed below\n let raw: Record<string, unknown>;\n // webpieces-disable no-unmanaged-exceptions -- chokepoint: a malformed config surfaces as one readable error\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n // webpieces-disable no-any-unknown -- parsed config JSON is opaque until narrowed below\n raw = JSON.parse(fs.readFileSync(configPath, 'utf8')) as Record<string, unknown>;\n } catch (err: unknown) {\n const error = toError(err);\n return [`[pr-gate] ${path.basename(configPath)} is not valid JSON: ${error.message}`];\n }\n const repoRoot = path.dirname(configPath);\n // Checklists live under commands[\"pr-gate\"].checklists (current) or the legacy top-level pr-gate.\n // webpieces-disable no-any-unknown -- narrowing the opaque command section\n const commands = raw['commands'] as Record<string, unknown> | undefined;\n // webpieces-disable no-any-unknown -- narrowing the opaque pr-gate section\n const prGate = (commands?.['pr-gate'] ?? raw['pr-gate']) as Record<string, unknown> | undefined;\n if (!prGate || !('checklists' in prGate)) return [];\n return validateChecklists(prGate['checklists'], repoRoot);\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mints + verifies the server-verifiable PR gate token.
|
|
3
|
+
*
|
|
4
|
+
* `token = HMAC-SHA256(gateSalt, HEAD_sha)`. `wp-finish-upsert-pr` writes it into the PR body (and
|
|
5
|
+
* refuses to mint it unless every BLOCK checklist passed), so a valid token IS proof the local gate ran
|
|
6
|
+
* and passed on that exact commit. `wp-check-pr` in CI recomputes `HMAC(gateSalt, pr.head.sha)` from the
|
|
7
|
+
* committed salt and compares — a PR opened outside the gated flow (unhooked teammate, web UI) carries
|
|
8
|
+
* no valid token for its head sha and fails.
|
|
9
|
+
*
|
|
10
|
+
* Bound to the HEAD sha (not the title/diff) so every push needs a fresh mint: hooked devs re-run finish
|
|
11
|
+
* on every push anyway (manual push is locally blocked), an unhooked bypasser's raw push does not.
|
|
12
|
+
*
|
|
13
|
+
* `@injectable(bindingScopeValues.Singleton)` so it is drawn in the DI design and injected by type.
|
|
14
|
+
*/
|
|
15
|
+
export declare class GateTokenService {
|
|
16
|
+
computeGateToken(gateSalt: string, headSha: string): string;
|
|
17
|
+
gateTokenMarker(gateSalt: string, headSha: string): string;
|
|
18
|
+
extractGateToken(prBody: string): string;
|
|
19
|
+
verifyGateToken(prBody: string, gateSalt: string, headSha: string): boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function computeGateToken(gateSalt: string, headSha: string): string;
|
|
22
|
+
export declare function gateTokenMarker(gateSalt: string, headSha: string): string;
|
|
23
|
+
export declare function extractGateToken(prBody: string): string;
|
|
24
|
+
export declare function verifyGateToken(prBody: string, gateSalt: string, headSha: string): boolean;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GateTokenService = void 0;
|
|
4
|
+
exports.computeGateToken = computeGateToken;
|
|
5
|
+
exports.gateTokenMarker = gateTokenMarker;
|
|
6
|
+
exports.extractGateToken = extractGateToken;
|
|
7
|
+
exports.verifyGateToken = verifyGateToken;
|
|
8
|
+
const tslib_1 = require("tslib");
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
const inversify_1 = require("inversify");
|
|
11
|
+
// The hidden PR-body marker that carries the gate token. An HTML comment so it does NOT render in the
|
|
12
|
+
// PR description a human reads, but survives round-tripping through `gh pr view --json body`. Versioned
|
|
13
|
+
// so the format can evolve without silently validating an old shape.
|
|
14
|
+
const MARKER_RE = /<!--\s*webpieces-pr-gate\s+v1\s+token=([0-9a-f]{64})\s*-->/;
|
|
15
|
+
/**
|
|
16
|
+
* Mints + verifies the server-verifiable PR gate token.
|
|
17
|
+
*
|
|
18
|
+
* `token = HMAC-SHA256(gateSalt, HEAD_sha)`. `wp-finish-upsert-pr` writes it into the PR body (and
|
|
19
|
+
* refuses to mint it unless every BLOCK checklist passed), so a valid token IS proof the local gate ran
|
|
20
|
+
* and passed on that exact commit. `wp-check-pr` in CI recomputes `HMAC(gateSalt, pr.head.sha)` from the
|
|
21
|
+
* committed salt and compares — a PR opened outside the gated flow (unhooked teammate, web UI) carries
|
|
22
|
+
* no valid token for its head sha and fails.
|
|
23
|
+
*
|
|
24
|
+
* Bound to the HEAD sha (not the title/diff) so every push needs a fresh mint: hooked devs re-run finish
|
|
25
|
+
* on every push anyway (manual push is locally blocked), an unhooked bypasser's raw push does not.
|
|
26
|
+
*
|
|
27
|
+
* `@injectable(bindingScopeValues.Singleton)` so it is drawn in the DI design and injected by type.
|
|
28
|
+
*/
|
|
29
|
+
let GateTokenService = class GateTokenService {
|
|
30
|
+
// The raw HMAC hex for (salt, sha). Empty salt ⇒ '' (caller treats '' as "no token / disabled").
|
|
31
|
+
computeGateToken(gateSalt, headSha) {
|
|
32
|
+
if (gateSalt.trim() === '' || headSha.trim() === '')
|
|
33
|
+
return '';
|
|
34
|
+
return (0, crypto_1.createHmac)('sha256', gateSalt).update(headSha).digest('hex');
|
|
35
|
+
}
|
|
36
|
+
// The hidden HTML-comment marker to append to a PR body. '' when there is no token to embed, so a
|
|
37
|
+
// repo with no gateSalt gets a byte-identical PR body to before this feature existed.
|
|
38
|
+
gateTokenMarker(gateSalt, headSha) {
|
|
39
|
+
const token = this.computeGateToken(gateSalt, headSha);
|
|
40
|
+
return token === '' ? '' : `<!-- webpieces-pr-gate v1 token=${token} -->`;
|
|
41
|
+
}
|
|
42
|
+
// Pull the token hex out of a PR body (whatever else the body contains), or '' when absent.
|
|
43
|
+
extractGateToken(prBody) {
|
|
44
|
+
const m = MARKER_RE.exec(prBody);
|
|
45
|
+
return m ? m[1] : '';
|
|
46
|
+
}
|
|
47
|
+
// True when `prBody` carries a token that matches HMAC(gateSalt, headSha). Constant-ish comparison is
|
|
48
|
+
// unnecessary here — the salt is committed/obscurity-grade, so timing side channels add no security.
|
|
49
|
+
verifyGateToken(prBody, gateSalt, headSha) {
|
|
50
|
+
const expected = this.computeGateToken(gateSalt, headSha);
|
|
51
|
+
if (expected === '')
|
|
52
|
+
return false;
|
|
53
|
+
return this.extractGateToken(prBody) === expected;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
exports.GateTokenService = GateTokenService;
|
|
57
|
+
exports.GateTokenService = GateTokenService = tslib_1.__decorate([
|
|
58
|
+
(0, inversify_1.injectable)(inversify_1.bindingScopeValues.Singleton)
|
|
59
|
+
], GateTokenService);
|
|
60
|
+
// Temporary migration delegators to GateTokenService — removed once every consumer injects it.
|
|
61
|
+
const gateTokenSvc = new GateTokenService();
|
|
62
|
+
// webpieces-disable no-function-outside-class -- temporary back-compat delegator to GateTokenService
|
|
63
|
+
function computeGateToken(gateSalt, headSha) {
|
|
64
|
+
return gateTokenSvc.computeGateToken(gateSalt, headSha);
|
|
65
|
+
}
|
|
66
|
+
// webpieces-disable no-function-outside-class -- temporary back-compat delegator to GateTokenService
|
|
67
|
+
function gateTokenMarker(gateSalt, headSha) {
|
|
68
|
+
return gateTokenSvc.gateTokenMarker(gateSalt, headSha);
|
|
69
|
+
}
|
|
70
|
+
// webpieces-disable no-function-outside-class -- temporary back-compat delegator to GateTokenService
|
|
71
|
+
function extractGateToken(prBody) {
|
|
72
|
+
return gateTokenSvc.extractGateToken(prBody);
|
|
73
|
+
}
|
|
74
|
+
// webpieces-disable no-function-outside-class -- temporary back-compat delegator to GateTokenService
|
|
75
|
+
function verifyGateToken(prBody, gateSalt, headSha) {
|
|
76
|
+
return gateTokenSvc.verifyGateToken(prBody, gateSalt, headSha);
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=gate-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-token.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/gate-token.ts"],"names":[],"mappings":";;;AAwDA,4CAEC;AAGD,0CAEC;AAGD,4CAEC;AAGD,0CAEC;;AAzED,mCAAoC;AACpC,yCAA2D;AAE3D,sGAAsG;AACtG,wGAAwG;AACxG,qEAAqE;AACrE,MAAM,SAAS,GAAG,4DAA4D,CAAC;AAE/E;;;;;;;;;;;;;GAaG;AAEI,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IACzB,iGAAiG;IACjG,gBAAgB,CAAC,QAAgB,EAAE,OAAe;QAC9C,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC;QAC/D,OAAO,IAAA,mBAAU,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC;IAED,kGAAkG;IAClG,sFAAsF;IACtF,eAAe,CAAC,QAAgB,EAAE,OAAe;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mCAAmC,KAAK,MAAM,CAAC;IAC9E,CAAC;IAED,4FAA4F;IAC5F,gBAAgB,CAAC,MAAc;QAC3B,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzB,CAAC;IAED,sGAAsG;IACtG,qGAAqG;IACrG,eAAe,CAAC,MAAc,EAAE,QAAgB,EAAE,OAAe;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,QAAQ,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;QAClC,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC;IACtD,CAAC;CACJ,CAAA;AA3BY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,sBAAU,EAAC,8BAAkB,CAAC,SAAS,CAAC;GAC5B,gBAAgB,CA2B5B;AAED,+FAA+F;AAC/F,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;AAE5C,qGAAqG;AACrG,SAAgB,gBAAgB,CAAC,QAAgB,EAAE,OAAe;IAC9D,OAAO,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED,qGAAqG;AACrG,SAAgB,eAAe,CAAC,QAAgB,EAAE,OAAe;IAC7D,OAAO,YAAY,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,qGAAqG;AACrG,SAAgB,gBAAgB,CAAC,MAAc;IAC3C,OAAO,YAAY,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC;AAED,qGAAqG;AACrG,SAAgB,eAAe,CAAC,MAAc,EAAE,QAAgB,EAAE,OAAe;IAC7E,OAAO,YAAY,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC","sourcesContent":["import { createHmac } from 'crypto';\nimport { injectable, bindingScopeValues } from 'inversify';\n\n// The hidden PR-body marker that carries the gate token. An HTML comment so it does NOT render in the\n// PR description a human reads, but survives round-tripping through `gh pr view --json body`. Versioned\n// so the format can evolve without silently validating an old shape.\nconst MARKER_RE = /<!--\\s*webpieces-pr-gate\\s+v1\\s+token=([0-9a-f]{64})\\s*-->/;\n\n/**\n * Mints + verifies the server-verifiable PR gate token.\n *\n * `token = HMAC-SHA256(gateSalt, HEAD_sha)`. `wp-finish-upsert-pr` writes it into the PR body (and\n * refuses to mint it unless every BLOCK checklist passed), so a valid token IS proof the local gate ran\n * and passed on that exact commit. `wp-check-pr` in CI recomputes `HMAC(gateSalt, pr.head.sha)` from the\n * committed salt and compares — a PR opened outside the gated flow (unhooked teammate, web UI) carries\n * no valid token for its head sha and fails.\n *\n * Bound to the HEAD sha (not the title/diff) so every push needs a fresh mint: hooked devs re-run finish\n * on every push anyway (manual push is locally blocked), an unhooked bypasser's raw push does not.\n *\n * `@injectable(bindingScopeValues.Singleton)` so it is drawn in the DI design and injected by type.\n */\n@injectable(bindingScopeValues.Singleton)\nexport class GateTokenService {\n // The raw HMAC hex for (salt, sha). Empty salt ⇒ '' (caller treats '' as \"no token / disabled\").\n computeGateToken(gateSalt: string, headSha: string): string {\n if (gateSalt.trim() === '' || headSha.trim() === '') return '';\n return createHmac('sha256', gateSalt).update(headSha).digest('hex');\n }\n\n // The hidden HTML-comment marker to append to a PR body. '' when there is no token to embed, so a\n // repo with no gateSalt gets a byte-identical PR body to before this feature existed.\n gateTokenMarker(gateSalt: string, headSha: string): string {\n const token = this.computeGateToken(gateSalt, headSha);\n return token === '' ? '' : `<!-- webpieces-pr-gate v1 token=${token} -->`;\n }\n\n // Pull the token hex out of a PR body (whatever else the body contains), or '' when absent.\n extractGateToken(prBody: string): string {\n const m = MARKER_RE.exec(prBody);\n return m ? m[1] : '';\n }\n\n // True when `prBody` carries a token that matches HMAC(gateSalt, headSha). Constant-ish comparison is\n // unnecessary here — the salt is committed/obscurity-grade, so timing side channels add no security.\n verifyGateToken(prBody: string, gateSalt: string, headSha: string): boolean {\n const expected = this.computeGateToken(gateSalt, headSha);\n if (expected === '') return false;\n return this.extractGateToken(prBody) === expected;\n }\n}\n\n// Temporary migration delegators to GateTokenService — removed once every consumer injects it.\nconst gateTokenSvc = new GateTokenService();\n\n// webpieces-disable no-function-outside-class -- temporary back-compat delegator to GateTokenService\nexport function computeGateToken(gateSalt: string, headSha: string): string {\n return gateTokenSvc.computeGateToken(gateSalt, headSha);\n}\n\n// webpieces-disable no-function-outside-class -- temporary back-compat delegator to GateTokenService\nexport function gateTokenMarker(gateSalt: string, headSha: string): string {\n return gateTokenSvc.gateTokenMarker(gateSalt, headSha);\n}\n\n// webpieces-disable no-function-outside-class -- temporary back-compat delegator to GateTokenService\nexport function extractGateToken(prBody: string): string {\n return gateTokenSvc.extractGateToken(prBody);\n}\n\n// webpieces-disable no-function-outside-class -- temporary back-compat delegator to GateTokenService\nexport function verifyGateToken(prBody: string, gateSalt: string, headSha: string): boolean {\n return gateTokenSvc.verifyGateToken(prBody, gateSalt, headSha);\n}\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -14,7 +14,8 @@ export { ExcludePaths } from './exclude-hook-paths';
|
|
|
14
14
|
export { isPathExcluded } from './exclude-paths';
|
|
15
15
|
export { defaultRules, defaultRulesDir } from './default-rules';
|
|
16
16
|
export { loadTemplate, writeTemplateIfMissing, writeTemplate, TemplateWriter } from './load-template';
|
|
17
|
-
export { validateWebpiecesConfig, validatePrGateSection, validateSectionPlacement, validateCommandsSection, validateExcludePaths, validateMatchRulesSection, allRuleNames } from './validate-config';
|
|
17
|
+
export { validateWebpiecesConfig, validatePrGateSection, validateChecklists, validateSectionPlacement, validateCommandsSection, validateExcludePaths, validateMatchRulesSection, allRuleNames } from './validate-config';
|
|
18
|
+
export { validateChecklistDocs } from './checklist-docs-validator';
|
|
18
19
|
export { MatchRuleConfig, MatchRuleViolation, findMatchRuleViolations, isMatchRuleAllowedPath, compileMatchRulePatterns, renderMatchRuleMessage, DEFAULT_MATCH_RULES, } from './match-rules-config';
|
|
19
20
|
export type { ConfigSection } from './sections';
|
|
20
21
|
export { HOOK_GUARD_NAMES, isHookGuard, sectionForRule } from './sections';
|
|
@@ -35,7 +36,9 @@ export type { MethodLimitMode, FileLimitMode, ReturnTypeMode, InlineTypeMode, Mo
|
|
|
35
36
|
export { GateDefinition, PrGateConfig, defaultGates, defaultPrGateConfig, buildPrGateConfig, MERGE_MODE_AUTO, MERGE_MODE_NONE, MERGE_MODES, } from './pr-gate-config';
|
|
36
37
|
export { ChecklistDefinition, toChecklist, CHECKLIST_BLOCK, CHECKLIST_WARN, CHECKLIST_SEVERITIES, } from './checklist-config';
|
|
37
38
|
export type { RawChecklist } from './checklist-config';
|
|
38
|
-
export {
|
|
39
|
+
export { GateTokenService, computeGateToken, gateTokenMarker, extractGateToken, verifyGateToken, } from './gate-token';
|
|
40
|
+
export { SubagentProvenanceService, ProvenanceResult, PROVENANCE_OK, PROVENANCE_MISSING, PROVENANCE_SKIPPED, } from './subagent-provenance';
|
|
41
|
+
export { ReviewJson, ChecklistAck, ChecklistResult, ChecklistVerdict, CK_PASS, CK_OVERRIDDEN, CK_FAIL, CK_MISSING, CK_ACKED, RequiredChecklist, ReviewJsonService, loadReviewJson, prDirFor, reviewJsonPath, reviewJsonSchemaHint, } from './review-json';
|
|
39
42
|
export { MainSyncStatus, MainSyncLock, MainSyncStatusService, DEFAULT_HANG_TIMEOUT_MINUTES, mainSyncStatusPath, mainSyncLockPath, readMainSyncStatus, writeMainSyncStatus, readMainSyncLock, writeMainSyncLock, isLockStale, isRefreshInProgress, inProcessLock, finishedLock, computeMainSyncStatus, stampCleanMainSyncStatus, squashRecoverySteps, } from './main-sync-status';
|
|
40
43
|
export { MergedBranch, DeletableBranch, DeletableWorktree, MergedBranchesCache, MergedBranchesService, } from './merged-branches';
|
|
41
44
|
export { Worktree, WorktreeService, } from './worktrees';
|
package/src/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
3
|
+
exports.FieldDef = exports.sectionForRule = exports.isHookGuard = exports.HOOK_GUARD_NAMES = exports.DEFAULT_MATCH_RULES = exports.renderMatchRuleMessage = exports.compileMatchRulePatterns = exports.isMatchRuleAllowedPath = exports.findMatchRuleViolations = exports.MatchRuleViolation = exports.MatchRuleConfig = exports.validateChecklistDocs = exports.allRuleNames = exports.validateMatchRulesSection = exports.validateExcludePaths = exports.validateCommandsSection = exports.validateSectionPlacement = exports.validateChecklists = exports.validatePrGateSection = exports.validateWebpiecesConfig = exports.TemplateWriter = exports.writeTemplate = exports.writeTemplateIfMissing = exports.loadTemplate = exports.defaultRulesDir = exports.defaultRules = exports.isPathExcluded = exports.ExcludePaths = exports.DESIGN_METADATA_KEYS = exports.isDocumentDesign = exports.DocumentDesign = exports.RulesConfigDesign = exports.INSTRUCT_AI_DIR = exports.RepoRootFinder = exports.ConfigFile = exports.CONFIG_FILENAME = exports.findConfigFile = exports.ConfigLoader = exports.LoadedConfig = exports.loadAndValidate = exports.toError = exports.runMain = exports.CliArgs = exports.CliArgsCheck = exports.CliUsage = exports.CliExitError = exports.RuleFailError = exports.InformAiError = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
|
|
4
|
+
exports.PrCreationOrPushGuardConfig = exports.BranchCreationGuardConfig = exports.RoleTagConfig = exports.FrameworkTagConfig = exports.InjectAnnotationNotNeededForConcreteClassConfig = exports.NoFunctionOutsideClassConfig = exports.NoProcessExitOutsideMainConfig = exports.NoCustomCssConfig = exports.NoSymbolDiTokensConfig = exports.AngularNoDirectApiInResolverConfig = exports.ThrowCauseRequiredConfig = exports.CatchErrorPatternConfig = exports.NoUnmanagedExceptionsConfig = exports.NoDestructureConfig = exports.PrismaConverterConfig = exports.PrismaValidateDtosConfig = exports.NoImplicitAnyConfig = exports.NoAnyUnknownConfig = exports.NoInlineTypeLiteralsConfig = exports.RequireReturnTypeConfig = exports.MaxFileLinesConfig = exports.MaxMethodLinesConfig = exports.WP_FINISH_UPSERT_PR = exports.WP_START_UPSERT_PR = exports.WP_FINISH_UPDATE = exports.WP_START_UPDATE = exports.SyncFlowGuidance = exports.WebpiecesRulesConfig = exports.MERGE_EXPLANATION_FILE = exports.MERGE_IN_PROGRESS_FILE = exports.PR_REVIEW_DIR = exports.MERGE_INFO_DIR = exports.WEBPIECES_TMP_DIR = exports.hasDisable = exports.RULE_NAMES = exports.WEBPIECES_DISABLE = exports.AbstractRule = exports.ChangedFilesOptions = exports.DiffRange = exports.DiffScope = exports.isNewOrModified = exports.hasChangesInRange = exports.findNewMethodSignaturesInDiff = exports.getChangedLineNumbers = exports.getFileDiff = exports.getChangedFiles = exports.resolveBase = exports.detectBase = exports.getCurrentBranch = exports.shouldSkipRule = void 0;
|
|
5
|
+
exports.extractGateToken = exports.gateTokenMarker = exports.computeGateToken = exports.GateTokenService = exports.CHECKLIST_SEVERITIES = exports.CHECKLIST_WARN = exports.CHECKLIST_BLOCK = exports.toChecklist = exports.ChecklistDefinition = exports.MERGE_MODES = exports.MERGE_MODE_NONE = exports.MERGE_MODE_AUTO = exports.buildPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.CLIENT_CREATION_SEVERITIES = exports.NoClientCreationOutsideServerOrClientConfig = exports.VALIDATE_TS_MODES = exports.STRUCTURAL_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.PROJECT_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = exports.BaseRuleConfig = exports.ValidateEslintSyncConfig = exports.ValidateVersionsLockedConfig = exports.ValidatePackageJsonConfig = exports.ValidateNoArchitectureCyclesConfig = exports.ValidateArchitectureUnchangedConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.DiGraphConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.MergedBranchBashGuardConfig = exports.ReadStaleGuardConfig = exports.FeatureBranchGuardConfig = exports.RedirectHowToMergeMainConfig = exports.PrMergeGuardConfig = exports.MergeInProgressGuardConfig = void 0;
|
|
6
|
+
exports.BranchMutationLog = exports.BranchMutationEvent = exports.BranchReaper = exports.ReapResult = exports.ReapedBranch = exports.WorktreeService = exports.Worktree = exports.MergedBranchesService = exports.MergedBranchesCache = exports.DeletableWorktree = exports.DeletableBranch = exports.MergedBranch = exports.squashRecoverySteps = exports.stampCleanMainSyncStatus = exports.computeMainSyncStatus = exports.finishedLock = exports.inProcessLock = exports.isRefreshInProgress = exports.isLockStale = exports.writeMainSyncLock = exports.readMainSyncLock = exports.writeMainSyncStatus = exports.readMainSyncStatus = exports.mainSyncLockPath = exports.mainSyncStatusPath = exports.DEFAULT_HANG_TIMEOUT_MINUTES = exports.MainSyncStatusService = exports.MainSyncLock = exports.MainSyncStatus = exports.reviewJsonSchemaHint = exports.reviewJsonPath = exports.prDirFor = exports.loadReviewJson = exports.ReviewJsonService = exports.RequiredChecklist = exports.CK_ACKED = exports.CK_MISSING = exports.CK_FAIL = exports.CK_OVERRIDDEN = exports.CK_PASS = exports.ChecklistVerdict = exports.ChecklistResult = exports.ChecklistAck = exports.ReviewJson = exports.PROVENANCE_SKIPPED = exports.PROVENANCE_MISSING = exports.PROVENANCE_OK = exports.ProvenanceResult = exports.SubagentProvenanceService = exports.verifyGateToken = void 0;
|
|
7
|
+
exports.DEFAULT_MERGE_COMPLETE_COMMAND = exports.DEFAULT_UPSERT_PR_COMMAND = exports.buildCommandsConfig = exports.CommandsConfig = exports.logBranchMutation = exports.branchMutationLogPath = void 0;
|
|
7
8
|
var types_1 = require("./types");
|
|
8
9
|
Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return types_1.ResolvedConfig; } });
|
|
9
10
|
Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return types_1.ResolvedRuleConfig; } });
|
|
@@ -53,11 +54,14 @@ Object.defineProperty(exports, "TemplateWriter", { enumerable: true, get: functi
|
|
|
53
54
|
var validate_config_1 = require("./validate-config");
|
|
54
55
|
Object.defineProperty(exports, "validateWebpiecesConfig", { enumerable: true, get: function () { return validate_config_1.validateWebpiecesConfig; } });
|
|
55
56
|
Object.defineProperty(exports, "validatePrGateSection", { enumerable: true, get: function () { return validate_config_1.validatePrGateSection; } });
|
|
57
|
+
Object.defineProperty(exports, "validateChecklists", { enumerable: true, get: function () { return validate_config_1.validateChecklists; } });
|
|
56
58
|
Object.defineProperty(exports, "validateSectionPlacement", { enumerable: true, get: function () { return validate_config_1.validateSectionPlacement; } });
|
|
57
59
|
Object.defineProperty(exports, "validateCommandsSection", { enumerable: true, get: function () { return validate_config_1.validateCommandsSection; } });
|
|
58
60
|
Object.defineProperty(exports, "validateExcludePaths", { enumerable: true, get: function () { return validate_config_1.validateExcludePaths; } });
|
|
59
61
|
Object.defineProperty(exports, "validateMatchRulesSection", { enumerable: true, get: function () { return validate_config_1.validateMatchRulesSection; } });
|
|
60
62
|
Object.defineProperty(exports, "allRuleNames", { enumerable: true, get: function () { return validate_config_1.allRuleNames; } });
|
|
63
|
+
var checklist_docs_validator_1 = require("./checklist-docs-validator");
|
|
64
|
+
Object.defineProperty(exports, "validateChecklistDocs", { enumerable: true, get: function () { return checklist_docs_validator_1.validateChecklistDocs; } });
|
|
61
65
|
var match_rules_config_1 = require("./match-rules-config");
|
|
62
66
|
Object.defineProperty(exports, "MatchRuleConfig", { enumerable: true, get: function () { return match_rules_config_1.MatchRuleConfig; } });
|
|
63
67
|
Object.defineProperty(exports, "MatchRuleViolation", { enumerable: true, get: function () { return match_rules_config_1.MatchRuleViolation; } });
|
|
@@ -180,9 +184,28 @@ Object.defineProperty(exports, "toChecklist", { enumerable: true, get: function
|
|
|
180
184
|
Object.defineProperty(exports, "CHECKLIST_BLOCK", { enumerable: true, get: function () { return checklist_config_1.CHECKLIST_BLOCK; } });
|
|
181
185
|
Object.defineProperty(exports, "CHECKLIST_WARN", { enumerable: true, get: function () { return checklist_config_1.CHECKLIST_WARN; } });
|
|
182
186
|
Object.defineProperty(exports, "CHECKLIST_SEVERITIES", { enumerable: true, get: function () { return checklist_config_1.CHECKLIST_SEVERITIES; } });
|
|
187
|
+
var gate_token_1 = require("./gate-token");
|
|
188
|
+
Object.defineProperty(exports, "GateTokenService", { enumerable: true, get: function () { return gate_token_1.GateTokenService; } });
|
|
189
|
+
Object.defineProperty(exports, "computeGateToken", { enumerable: true, get: function () { return gate_token_1.computeGateToken; } });
|
|
190
|
+
Object.defineProperty(exports, "gateTokenMarker", { enumerable: true, get: function () { return gate_token_1.gateTokenMarker; } });
|
|
191
|
+
Object.defineProperty(exports, "extractGateToken", { enumerable: true, get: function () { return gate_token_1.extractGateToken; } });
|
|
192
|
+
Object.defineProperty(exports, "verifyGateToken", { enumerable: true, get: function () { return gate_token_1.verifyGateToken; } });
|
|
193
|
+
var subagent_provenance_1 = require("./subagent-provenance");
|
|
194
|
+
Object.defineProperty(exports, "SubagentProvenanceService", { enumerable: true, get: function () { return subagent_provenance_1.SubagentProvenanceService; } });
|
|
195
|
+
Object.defineProperty(exports, "ProvenanceResult", { enumerable: true, get: function () { return subagent_provenance_1.ProvenanceResult; } });
|
|
196
|
+
Object.defineProperty(exports, "PROVENANCE_OK", { enumerable: true, get: function () { return subagent_provenance_1.PROVENANCE_OK; } });
|
|
197
|
+
Object.defineProperty(exports, "PROVENANCE_MISSING", { enumerable: true, get: function () { return subagent_provenance_1.PROVENANCE_MISSING; } });
|
|
198
|
+
Object.defineProperty(exports, "PROVENANCE_SKIPPED", { enumerable: true, get: function () { return subagent_provenance_1.PROVENANCE_SKIPPED; } });
|
|
183
199
|
var review_json_1 = require("./review-json");
|
|
184
200
|
Object.defineProperty(exports, "ReviewJson", { enumerable: true, get: function () { return review_json_1.ReviewJson; } });
|
|
185
201
|
Object.defineProperty(exports, "ChecklistAck", { enumerable: true, get: function () { return review_json_1.ChecklistAck; } });
|
|
202
|
+
Object.defineProperty(exports, "ChecklistResult", { enumerable: true, get: function () { return review_json_1.ChecklistResult; } });
|
|
203
|
+
Object.defineProperty(exports, "ChecklistVerdict", { enumerable: true, get: function () { return review_json_1.ChecklistVerdict; } });
|
|
204
|
+
Object.defineProperty(exports, "CK_PASS", { enumerable: true, get: function () { return review_json_1.CK_PASS; } });
|
|
205
|
+
Object.defineProperty(exports, "CK_OVERRIDDEN", { enumerable: true, get: function () { return review_json_1.CK_OVERRIDDEN; } });
|
|
206
|
+
Object.defineProperty(exports, "CK_FAIL", { enumerable: true, get: function () { return review_json_1.CK_FAIL; } });
|
|
207
|
+
Object.defineProperty(exports, "CK_MISSING", { enumerable: true, get: function () { return review_json_1.CK_MISSING; } });
|
|
208
|
+
Object.defineProperty(exports, "CK_ACKED", { enumerable: true, get: function () { return review_json_1.CK_ACKED; } });
|
|
186
209
|
Object.defineProperty(exports, "RequiredChecklist", { enumerable: true, get: function () { return review_json_1.RequiredChecklist; } });
|
|
187
210
|
Object.defineProperty(exports, "ReviewJsonService", { enumerable: true, get: function () { return review_json_1.ReviewJsonService; } });
|
|
188
211
|
Object.defineProperty(exports, "loadReviewJson", { enumerable: true, get: function () { return review_json_1.loadReviewJson; } });
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { RuleFailError } from './rule-fail-error';\nexport { CliExitError } from './cli-exit-error';\nexport { CliUsage, CliArgsCheck, CliArgs } from './cli-args';\nexport { runMain } from './run-main';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig, ConfigLoader } from './load-config';\nexport { findConfigFile, CONFIG_FILENAME, ConfigFile } from './config-file';\nexport { RepoRootFinder, INSTRUCT_AI_DIR } from './repo-root';\nexport { RulesConfigDesign } from './rules-config-design';\nexport { DocumentDesign, isDocumentDesign, DESIGN_METADATA_KEYS } from './di';\nexport { ExcludePaths } from './exclude-hook-paths';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate, TemplateWriter } from './load-template';\nexport { validateWebpiecesConfig, validatePrGateSection, validateSectionPlacement, validateCommandsSection, validateExcludePaths, validateMatchRulesSection, allRuleNames } from './validate-config';\nexport {\n MatchRuleConfig,\n MatchRuleViolation,\n findMatchRuleViolations,\n isMatchRuleAllowedPath,\n compileMatchRulePatterns,\n renderMatchRuleMessage,\n DEFAULT_MATCH_RULES,\n} from './match-rules-config';\nexport type { ConfigSection } from './sections';\nexport { HOOK_GUARD_NAMES, isHookGuard, sectionForRule } from './sections';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport type { SkipRuleResult } from './skip-rule';\nexport {\n detectBase,\n resolveBase,\n getChangedFiles,\n getFileDiff,\n getChangedLineNumbers,\n findNewMethodSignaturesInDiff,\n hasChangesInRange,\n isNewOrModified,\n DiffScope,\n DiffRange,\n ChangedFilesOptions,\n} from './diff-scope';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_INFO_DIR,\n PR_REVIEW_DIR,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n SyncFlowGuidance,\n WP_START_UPDATE,\n WP_FINISH_UPDATE,\n WP_START_UPSERT_PR,\n WP_FINISH_UPSERT_PR,\n} from './sync-flow-guidance';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoCustomCssConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n BranchCreationGuardConfig,\n PrCreationOrPushGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeGuardConfig,\n RedirectHowToMergeMainConfig,\n FeatureBranchGuardConfig,\n ReadStaleGuardConfig,\n MergedBranchBashGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n ValidateArchitectureUnchangedConfig,\n ValidateNoArchitectureCyclesConfig,\n ValidatePackageJsonConfig,\n ValidateVersionsLockedConfig,\n ValidateEslintSyncConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PROJECT_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n STRUCTURAL_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport {\n NoClientCreationOutsideServerOrClientConfig,\n CLIENT_CREATION_SEVERITIES,\n} from './no-client-creation-config';\nexport type { ClientCreationSeverity } from './no-client-creation-config';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n ProjectMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n StructuralMode,\n ValidateTsMode,\n} from './rule-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n defaultGates,\n defaultPrGateConfig,\n buildPrGateConfig,\n MERGE_MODE_AUTO,\n MERGE_MODE_NONE,\n MERGE_MODES,\n} from './pr-gate-config';\nexport {\n ChecklistDefinition,\n toChecklist,\n CHECKLIST_BLOCK,\n CHECKLIST_WARN,\n CHECKLIST_SEVERITIES,\n} from './checklist-config';\nexport type { RawChecklist } from './checklist-config';\nexport {\n ReviewJson,\n ChecklistAck,\n RequiredChecklist,\n ReviewJsonService,\n loadReviewJson,\n prDirFor,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\nexport {\n MainSyncStatus,\n MainSyncLock,\n MainSyncStatusService,\n DEFAULT_HANG_TIMEOUT_MINUTES,\n mainSyncStatusPath,\n mainSyncLockPath,\n readMainSyncStatus,\n writeMainSyncStatus,\n readMainSyncLock,\n writeMainSyncLock,\n isLockStale,\n isRefreshInProgress,\n inProcessLock,\n finishedLock,\n computeMainSyncStatus,\n stampCleanMainSyncStatus,\n squashRecoverySteps,\n} from './main-sync-status';\nexport {\n MergedBranch,\n DeletableBranch,\n DeletableWorktree,\n MergedBranchesCache,\n MergedBranchesService,\n} from './merged-branches';\nexport {\n Worktree,\n WorktreeService,\n} from './worktrees';\nexport {\n ReapedBranch,\n ReapResult,\n BranchReaper,\n} from './branch-reaper';\nexport type { MutationVerb, MutationPhase } from './branch-mutation-log';\nexport {\n BranchMutationEvent,\n BranchMutationLog,\n branchMutationLogPath,\n logBranchMutation,\n} from './branch-mutation-log';\nexport {\n CommandsConfig,\n buildCommandsConfig,\n DEFAULT_UPSERT_PR_COMMAND,\n DEFAULT_MERGE_COMPLETE_COMMAND,\n} from './commands-config';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { RuleFailError } from './rule-fail-error';\nexport { CliExitError } from './cli-exit-error';\nexport { CliUsage, CliArgsCheck, CliArgs } from './cli-args';\nexport { runMain } from './run-main';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig, ConfigLoader } from './load-config';\nexport { findConfigFile, CONFIG_FILENAME, ConfigFile } from './config-file';\nexport { RepoRootFinder, INSTRUCT_AI_DIR } from './repo-root';\nexport { RulesConfigDesign } from './rules-config-design';\nexport { DocumentDesign, isDocumentDesign, DESIGN_METADATA_KEYS } from './di';\nexport { ExcludePaths } from './exclude-hook-paths';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate, TemplateWriter } from './load-template';\nexport { validateWebpiecesConfig, validatePrGateSection, validateChecklists, validateSectionPlacement, validateCommandsSection, validateExcludePaths, validateMatchRulesSection, allRuleNames } from './validate-config';\nexport { validateChecklistDocs } from './checklist-docs-validator';\nexport {\n MatchRuleConfig,\n MatchRuleViolation,\n findMatchRuleViolations,\n isMatchRuleAllowedPath,\n compileMatchRulePatterns,\n renderMatchRuleMessage,\n DEFAULT_MATCH_RULES,\n} from './match-rules-config';\nexport type { ConfigSection } from './sections';\nexport { HOOK_GUARD_NAMES, isHookGuard, sectionForRule } from './sections';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport type { SkipRuleResult } from './skip-rule';\nexport {\n detectBase,\n resolveBase,\n getChangedFiles,\n getFileDiff,\n getChangedLineNumbers,\n findNewMethodSignaturesInDiff,\n hasChangesInRange,\n isNewOrModified,\n DiffScope,\n DiffRange,\n ChangedFilesOptions,\n} from './diff-scope';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_INFO_DIR,\n PR_REVIEW_DIR,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n SyncFlowGuidance,\n WP_START_UPDATE,\n WP_FINISH_UPDATE,\n WP_START_UPSERT_PR,\n WP_FINISH_UPSERT_PR,\n} from './sync-flow-guidance';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoCustomCssConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n BranchCreationGuardConfig,\n PrCreationOrPushGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeGuardConfig,\n RedirectHowToMergeMainConfig,\n FeatureBranchGuardConfig,\n ReadStaleGuardConfig,\n MergedBranchBashGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n ValidateArchitectureUnchangedConfig,\n ValidateNoArchitectureCyclesConfig,\n ValidatePackageJsonConfig,\n ValidateVersionsLockedConfig,\n ValidateEslintSyncConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PROJECT_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n STRUCTURAL_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport {\n NoClientCreationOutsideServerOrClientConfig,\n CLIENT_CREATION_SEVERITIES,\n} from './no-client-creation-config';\nexport type { ClientCreationSeverity } from './no-client-creation-config';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n ProjectMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n StructuralMode,\n ValidateTsMode,\n} from './rule-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n defaultGates,\n defaultPrGateConfig,\n buildPrGateConfig,\n MERGE_MODE_AUTO,\n MERGE_MODE_NONE,\n MERGE_MODES,\n} from './pr-gate-config';\nexport {\n ChecklistDefinition,\n toChecklist,\n CHECKLIST_BLOCK,\n CHECKLIST_WARN,\n CHECKLIST_SEVERITIES,\n} from './checklist-config';\nexport type { RawChecklist } from './checklist-config';\nexport {\n GateTokenService,\n computeGateToken,\n gateTokenMarker,\n extractGateToken,\n verifyGateToken,\n} from './gate-token';\nexport {\n SubagentProvenanceService,\n ProvenanceResult,\n PROVENANCE_OK,\n PROVENANCE_MISSING,\n PROVENANCE_SKIPPED,\n} from './subagent-provenance';\nexport {\n ReviewJson,\n ChecklistAck,\n ChecklistResult,\n ChecklistVerdict,\n CK_PASS,\n CK_OVERRIDDEN,\n CK_FAIL,\n CK_MISSING,\n CK_ACKED,\n RequiredChecklist,\n ReviewJsonService,\n loadReviewJson,\n prDirFor,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\nexport {\n MainSyncStatus,\n MainSyncLock,\n MainSyncStatusService,\n DEFAULT_HANG_TIMEOUT_MINUTES,\n mainSyncStatusPath,\n mainSyncLockPath,\n readMainSyncStatus,\n writeMainSyncStatus,\n readMainSyncLock,\n writeMainSyncLock,\n isLockStale,\n isRefreshInProgress,\n inProcessLock,\n finishedLock,\n computeMainSyncStatus,\n stampCleanMainSyncStatus,\n squashRecoverySteps,\n} from './main-sync-status';\nexport {\n MergedBranch,\n DeletableBranch,\n DeletableWorktree,\n MergedBranchesCache,\n MergedBranchesService,\n} from './merged-branches';\nexport {\n Worktree,\n WorktreeService,\n} from './worktrees';\nexport {\n ReapedBranch,\n ReapResult,\n BranchReaper,\n} from './branch-reaper';\nexport type { MutationVerb, MutationPhase } from './branch-mutation-log';\nexport {\n BranchMutationEvent,\n BranchMutationLog,\n branchMutationLogPath,\n logBranchMutation,\n} from './branch-mutation-log';\nexport {\n CommandsConfig,\n buildCommandsConfig,\n DEFAULT_UPSERT_PR_COMMAND,\n DEFAULT_MERGE_COMPLETE_COMMAND,\n} from './commands-config';\n"]}
|
package/src/pr-gate-config.d.ts
CHANGED
|
@@ -29,7 +29,20 @@ export declare class PrGateConfig {
|
|
|
29
29
|
*/
|
|
30
30
|
mergeMode: string;
|
|
31
31
|
checklists: ChecklistDefinition[];
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Shared secret used to mint the server-verifiable gate token. `wp-finish-upsert-pr` writes
|
|
34
|
+
* `HMAC(gateSalt, HEAD_sha)` as a hidden marker into the PR body (and REFUSES to mint it unless
|
|
35
|
+
* every BLOCK checklist passed), so a valid token IS proof the local gate ran and passed. A CI
|
|
36
|
+
* check (`wp-check-pr` + the scaffolded workflow) recomputes it from the PR head sha and this salt.
|
|
37
|
+
*
|
|
38
|
+
* Optional, defaults to '' — empty means "no token minted, no CI enforcement" (byte-identical to
|
|
39
|
+
* before this field existed). This is COMMITTED, obscurity-grade: it stops unhooked teammates who
|
|
40
|
+
* push + open a PR in the web UI, but is readable in-repo and therefore forgeable by a determined
|
|
41
|
+
* reader. It is deliberately NOT cryptographically sound; nothing local can stop a filesystem-reading
|
|
42
|
+
* agent. See RESPONSE-pr-gate-ci-enforcement / the design memo for the full tradeoff.
|
|
43
|
+
*/
|
|
44
|
+
gateSalt: string;
|
|
45
|
+
constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string, checklists?: ChecklistDefinition[], gateSalt?: string);
|
|
33
46
|
}
|
|
34
47
|
export declare function defaultGates(): GateDefinition[];
|
|
35
48
|
export declare function defaultPrGateConfig(): PrGateConfig;
|
package/src/pr-gate-config.js
CHANGED
|
@@ -58,13 +58,27 @@ class PrGateConfig {
|
|
|
58
58
|
// Diff-triggered company review checklists (the extension point). Defaults to [] — an absent
|
|
59
59
|
// `checklists` key produces byte-identical behavior to before this field existed.
|
|
60
60
|
checklists;
|
|
61
|
+
/**
|
|
62
|
+
* Shared secret used to mint the server-verifiable gate token. `wp-finish-upsert-pr` writes
|
|
63
|
+
* `HMAC(gateSalt, HEAD_sha)` as a hidden marker into the PR body (and REFUSES to mint it unless
|
|
64
|
+
* every BLOCK checklist passed), so a valid token IS proof the local gate ran and passed. A CI
|
|
65
|
+
* check (`wp-check-pr` + the scaffolded workflow) recomputes it from the PR head sha and this salt.
|
|
66
|
+
*
|
|
67
|
+
* Optional, defaults to '' — empty means "no token minted, no CI enforcement" (byte-identical to
|
|
68
|
+
* before this field existed). This is COMMITTED, obscurity-grade: it stops unhooked teammates who
|
|
69
|
+
* push + open a PR in the web UI, but is readable in-repo and therefore forgeable by a determined
|
|
70
|
+
* reader. It is deliberately NOT cryptographically sound; nothing local can stop a filesystem-reading
|
|
71
|
+
* agent. See RESPONSE-pr-gate-ci-enforcement / the design memo for the full tradeoff.
|
|
72
|
+
*/
|
|
73
|
+
gateSalt;
|
|
61
74
|
// eslint-disable-next-line @typescript-eslint/max-params
|
|
62
|
-
constructor(mode, buildCommand, gates, mergeMode, checklists = []) {
|
|
75
|
+
constructor(mode, buildCommand, gates, mergeMode, checklists = [], gateSalt = '') {
|
|
63
76
|
this.mode = mode;
|
|
64
77
|
this.buildCommand = buildCommand;
|
|
65
78
|
this.gates = gates;
|
|
66
79
|
this.mergeMode = mergeMode;
|
|
67
80
|
this.checklists = checklists;
|
|
81
|
+
this.gateSalt = gateSalt;
|
|
68
82
|
}
|
|
69
83
|
}
|
|
70
84
|
exports.PrGateConfig = PrGateConfig;
|
|
@@ -105,6 +119,8 @@ function buildPrGateConfig(section) {
|
|
|
105
119
|
const mergeMode = raw.mergeMode ?? defaults.mergeMode;
|
|
106
120
|
// Optional extension point — omitted ⇒ [] ⇒ no checklists computed anywhere downstream.
|
|
107
121
|
const checklists = raw.checklists !== undefined ? raw.checklists.map(checklist_config_1.toChecklist) : defaults.checklists;
|
|
108
|
-
|
|
122
|
+
// Optional — omitted ⇒ '' ⇒ no gate token minted and CI enforcement is a no-op (back-compat).
|
|
123
|
+
const gateSalt = raw.gateSalt ?? defaults.gateSalt;
|
|
124
|
+
return new PrGateConfig(mode, buildCommand, gates, mergeMode, checklists, gateSalt);
|
|
109
125
|
}
|
|
110
126
|
//# sourceMappingURL=pr-gate-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr-gate-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/pr-gate-config.ts"],"names":[],"mappings":"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","sourcesContent":["// PrGateConfig is the \"special section\" for the pr-gate dashboard. It does NOT live in the\n// validated `rules` map (the FieldDef schema can't express nested object arrays), but as a\n// top-level `pr-gate` key in webpieces.config.json. It is built and validated by\n// loadAndValidate (load-config.ts); this module holds only the data classes + defaults + toGate.\n\nimport { ChecklistDefinition, RawChecklist, toChecklist } from './checklist-config';\n\nexport class GateDefinition {\n name: string;\n patterns: string[];\n // The warning color shown on the dashboard WHEN this gate's patterns match a changed file. Green\n // is implicit (shown when nothing matched), so it is never configured. warningColor is purely\n // visual — even 'red' never fails/blocks the PR (only the build gate can). 'yellow' = caution,\n // 'red' = louder \"look here\" flag (e.g. DB schema / migration changes). REQUIRED on every gate.\n warningColor: string; // 'yellow' | 'red'\n // Example/inactive gate: parsed and kept in the file (JSON has no comments) but skipped at\n // compute/render time. Other projects flip this to false and tune patterns/warningColor.\n disabled: boolean;\n\n constructor(name: string, patterns: string[], warningColor: string, disabled = false) {\n this.name = name;\n this.patterns = patterns;\n this.warningColor = warningColor;\n this.disabled = disabled;\n }\n}\n\n// How wp-finish-upsert-pr should try to LAND the PR once it has posted it. GitHub's auto-merge queue\n// is a REPO-level setting (`allow_auto_merge`) that many orgs turn OFF as a policy control, and it\n// CANNOT be forced from the client: `gh pr merge --auto` calls the enablePullRequestAutoMerge GraphQL\n// mutation, which hard-errors with \"Auto merge is not allowed for this repository\" when the repo says\n// no. So the only lever a config knob has is WHICH PATHS WE ATTEMPT — never whether the queue exists.\nexport const MERGE_MODE_AUTO = 'AUTO';\nexport const MERGE_MODE_NONE = 'NONE';\nexport const MERGE_MODES = [MERGE_MODE_AUTO, MERGE_MODE_NONE];\n\nexport class PrGateConfig {\n mode: string;\n buildCommand: string;\n gates: GateDefinition[];\n /**\n * REQUIRED — every repo must state its policy; there is deliberately no default, because the two\n * answers are a real policy decision and guessing it either merges when a team did not want that,\n * or silently stops landing PRs on a team that relied on it.\n *\n * AUTO — wp-finish-upsert-pr LANDS the PR: squash-merge it right away when it is mergeable, else\n * enable GitHub auto-merge so it lands when the checks pass. Both carry an explicit --subject /\n * --body-file, which is the ONLY way main's history gets the PR title plus the compact\n * risk/flags body — no repo setting can produce that. Requires allow_auto_merge on the repo.\n * NONE — wp-finish-upsert-pr only opens/updates the PR and stops; a human merges. NOTE the cost:\n * a UI merge cannot use the compact body, so main's commit falls back to the repo's\n * squash_merge_commit_title/message settings. Set squash_merge_commit_title=PR_TITLE there, or\n * commits land as the internal \"Squash merge of <branch>\" subject.\n */\n mergeMode: string;\n // Diff-triggered company review checklists (the extension point). Defaults to [] — an absent\n // `checklists` key produces byte-identical behavior to before this field existed.\n checklists: ChecklistDefinition[];\n\n // eslint-disable-next-line @typescript-eslint/max-params\n constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string, checklists: ChecklistDefinition[] = []) {\n this.mode = mode;\n this.buildCommand = buildCommand;\n this.gates = gates;\n this.mergeMode = mergeMode;\n this.checklists = checklists;\n }\n}\n\n// Default infra gates — path-pattern based, tuned for this monorepo. Clients override the\n// whole list via the `pr-gate.gates` array in webpieces.config.json.\nexport function defaultGates(): GateDefinition[] {\n return [\n new GateDefinition('API Changed', ['libraries/apis/**', '**/*Api.ts'], 'yellow'),\n new GateDefinition('Config Files Changed', ['**/package.json', '**/tsconfig*.json', 'nx.json', '**/*.config.*'], 'yellow'),\n new GateDefinition('Dependency Graph Changed', ['architecture/dependencies.json'], 'yellow'),\n new GateDefinition('Claude / Rules Changed', ['**/CLAUDE.md', '**/claude.*.md', '.claude/**', 'webpieces.config.json'], 'yellow'),\n ];\n}\n\nexport function defaultPrGateConfig(): PrGateConfig {\n // No default checklists — the extension point is opt-in; the default monorepo ships none.\n return new PrGateConfig('ON', '', defaultGates(), MERGE_MODE_AUTO, []);\n}\n\ninterface RawGate {\n name?: string;\n patterns?: string[];\n warningColor?: string;\n disabled?: boolean;\n}\n\ninterface RawPrGateSection {\n mode?: string;\n buildCommand?: string;\n gates?: RawGate[];\n mergeMode?: string;\n checklists?: RawChecklist[];\n}\n\nfunction toGate(raw: RawGate): GateDefinition {\n return new GateDefinition(raw.name ?? '', raw.patterns ?? [], raw.warningColor ?? 'yellow', raw.disabled ?? false);\n}\n\n/**\n * Build a PrGateConfig from the already-parsed top-level `pr-gate` section, falling back to defaults\n * for any field the consumer omits. Pure transform — the file read + structural validation happen in\n * loadAndValidate (load-config.ts) so every consumer goes through one validated path. Pass undefined\n * (no `pr-gate` key / no config file) to get full defaults.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed here\nexport function buildPrGateConfig(section: unknown): PrGateConfig {\n const defaults = defaultPrGateConfig();\n if (section === undefined || section === null || typeof section !== 'object') return defaults;\n\n const raw = section as RawPrGateSection;\n const mode = raw.mode ?? defaults.mode;\n const buildCommand = raw.buildCommand ?? defaults.buildCommand;\n const gates = raw.gates !== undefined ? raw.gates.map(toGate) : defaults.gates;\n // REQUIRED — validatePrGateSection rejects an omitted/unknown value, so this fallback only ever\n // applies to the no-config-file path that defaultPrGateConfig() serves.\n const mergeMode = raw.mergeMode ?? defaults.mergeMode;\n // Optional extension point — omitted ⇒ [] ⇒ no checklists computed anywhere downstream.\n const checklists = raw.checklists !== undefined ? raw.checklists.map(toChecklist) : defaults.checklists;\n return new PrGateConfig(mode, buildCommand, gates, mergeMode, checklists);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pr-gate-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/pr-gate-config.ts"],"names":[],"mappings":"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","sourcesContent":["// PrGateConfig is the \"special section\" for the pr-gate dashboard. It does NOT live in the\n// validated `rules` map (the FieldDef schema can't express nested object arrays), but as a\n// top-level `pr-gate` key in webpieces.config.json. It is built and validated by\n// loadAndValidate (load-config.ts); this module holds only the data classes + defaults + toGate.\n\nimport { ChecklistDefinition, RawChecklist, toChecklist } from './checklist-config';\n\nexport class GateDefinition {\n name: string;\n patterns: string[];\n // The warning color shown on the dashboard WHEN this gate's patterns match a changed file. Green\n // is implicit (shown when nothing matched), so it is never configured. warningColor is purely\n // visual — even 'red' never fails/blocks the PR (only the build gate can). 'yellow' = caution,\n // 'red' = louder \"look here\" flag (e.g. DB schema / migration changes). REQUIRED on every gate.\n warningColor: string; // 'yellow' | 'red'\n // Example/inactive gate: parsed and kept in the file (JSON has no comments) but skipped at\n // compute/render time. Other projects flip this to false and tune patterns/warningColor.\n disabled: boolean;\n\n constructor(name: string, patterns: string[], warningColor: string, disabled = false) {\n this.name = name;\n this.patterns = patterns;\n this.warningColor = warningColor;\n this.disabled = disabled;\n }\n}\n\n// How wp-finish-upsert-pr should try to LAND the PR once it has posted it. GitHub's auto-merge queue\n// is a REPO-level setting (`allow_auto_merge`) that many orgs turn OFF as a policy control, and it\n// CANNOT be forced from the client: `gh pr merge --auto` calls the enablePullRequestAutoMerge GraphQL\n// mutation, which hard-errors with \"Auto merge is not allowed for this repository\" when the repo says\n// no. So the only lever a config knob has is WHICH PATHS WE ATTEMPT — never whether the queue exists.\nexport const MERGE_MODE_AUTO = 'AUTO';\nexport const MERGE_MODE_NONE = 'NONE';\nexport const MERGE_MODES = [MERGE_MODE_AUTO, MERGE_MODE_NONE];\n\nexport class PrGateConfig {\n mode: string;\n buildCommand: string;\n gates: GateDefinition[];\n /**\n * REQUIRED — every repo must state its policy; there is deliberately no default, because the two\n * answers are a real policy decision and guessing it either merges when a team did not want that,\n * or silently stops landing PRs on a team that relied on it.\n *\n * AUTO — wp-finish-upsert-pr LANDS the PR: squash-merge it right away when it is mergeable, else\n * enable GitHub auto-merge so it lands when the checks pass. Both carry an explicit --subject /\n * --body-file, which is the ONLY way main's history gets the PR title plus the compact\n * risk/flags body — no repo setting can produce that. Requires allow_auto_merge on the repo.\n * NONE — wp-finish-upsert-pr only opens/updates the PR and stops; a human merges. NOTE the cost:\n * a UI merge cannot use the compact body, so main's commit falls back to the repo's\n * squash_merge_commit_title/message settings. Set squash_merge_commit_title=PR_TITLE there, or\n * commits land as the internal \"Squash merge of <branch>\" subject.\n */\n mergeMode: string;\n // Diff-triggered company review checklists (the extension point). Defaults to [] — an absent\n // `checklists` key produces byte-identical behavior to before this field existed.\n checklists: ChecklistDefinition[];\n /**\n * Shared secret used to mint the server-verifiable gate token. `wp-finish-upsert-pr` writes\n * `HMAC(gateSalt, HEAD_sha)` as a hidden marker into the PR body (and REFUSES to mint it unless\n * every BLOCK checklist passed), so a valid token IS proof the local gate ran and passed. A CI\n * check (`wp-check-pr` + the scaffolded workflow) recomputes it from the PR head sha and this salt.\n *\n * Optional, defaults to '' — empty means \"no token minted, no CI enforcement\" (byte-identical to\n * before this field existed). This is COMMITTED, obscurity-grade: it stops unhooked teammates who\n * push + open a PR in the web UI, but is readable in-repo and therefore forgeable by a determined\n * reader. It is deliberately NOT cryptographically sound; nothing local can stop a filesystem-reading\n * agent. See RESPONSE-pr-gate-ci-enforcement / the design memo for the full tradeoff.\n */\n gateSalt: string;\n\n // eslint-disable-next-line @typescript-eslint/max-params\n constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string, checklists: ChecklistDefinition[] = [], gateSalt = '') {\n this.mode = mode;\n this.buildCommand = buildCommand;\n this.gates = gates;\n this.mergeMode = mergeMode;\n this.checklists = checklists;\n this.gateSalt = gateSalt;\n }\n}\n\n// Default infra gates — path-pattern based, tuned for this monorepo. Clients override the\n// whole list via the `pr-gate.gates` array in webpieces.config.json.\nexport function defaultGates(): GateDefinition[] {\n return [\n new GateDefinition('API Changed', ['libraries/apis/**', '**/*Api.ts'], 'yellow'),\n new GateDefinition('Config Files Changed', ['**/package.json', '**/tsconfig*.json', 'nx.json', '**/*.config.*'], 'yellow'),\n new GateDefinition('Dependency Graph Changed', ['architecture/dependencies.json'], 'yellow'),\n new GateDefinition('Claude / Rules Changed', ['**/CLAUDE.md', '**/claude.*.md', '.claude/**', 'webpieces.config.json'], 'yellow'),\n ];\n}\n\nexport function defaultPrGateConfig(): PrGateConfig {\n // No default checklists — the extension point is opt-in; the default monorepo ships none.\n return new PrGateConfig('ON', '', defaultGates(), MERGE_MODE_AUTO, []);\n}\n\ninterface RawGate {\n name?: string;\n patterns?: string[];\n warningColor?: string;\n disabled?: boolean;\n}\n\ninterface RawPrGateSection {\n mode?: string;\n buildCommand?: string;\n gates?: RawGate[];\n mergeMode?: string;\n checklists?: RawChecklist[];\n gateSalt?: string;\n}\n\nfunction toGate(raw: RawGate): GateDefinition {\n return new GateDefinition(raw.name ?? '', raw.patterns ?? [], raw.warningColor ?? 'yellow', raw.disabled ?? false);\n}\n\n/**\n * Build a PrGateConfig from the already-parsed top-level `pr-gate` section, falling back to defaults\n * for any field the consumer omits. Pure transform — the file read + structural validation happen in\n * loadAndValidate (load-config.ts) so every consumer goes through one validated path. Pass undefined\n * (no `pr-gate` key / no config file) to get full defaults.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed here\nexport function buildPrGateConfig(section: unknown): PrGateConfig {\n const defaults = defaultPrGateConfig();\n if (section === undefined || section === null || typeof section !== 'object') return defaults;\n\n const raw = section as RawPrGateSection;\n const mode = raw.mode ?? defaults.mode;\n const buildCommand = raw.buildCommand ?? defaults.buildCommand;\n const gates = raw.gates !== undefined ? raw.gates.map(toGate) : defaults.gates;\n // REQUIRED — validatePrGateSection rejects an omitted/unknown value, so this fallback only ever\n // applies to the no-config-file path that defaultPrGateConfig() serves.\n const mergeMode = raw.mergeMode ?? defaults.mergeMode;\n // Optional extension point — omitted ⇒ [] ⇒ no checklists computed anywhere downstream.\n const checklists = raw.checklists !== undefined ? raw.checklists.map(toChecklist) : defaults.checklists;\n // Optional — omitted ⇒ '' ⇒ no gate token minted and CI enforcement is a no-op (back-compat).\n const gateSalt = raw.gateSalt ?? defaults.gateSalt;\n return new PrGateConfig(mode, buildCommand, gates, mergeMode, checklists, gateSalt);\n}\n"]}
|