@webpieces/rules-config 0.4.670 → 0.4.671
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/default-rules.js +5 -6
- package/src/default-rules.js.map +1 -1
- package/src/home-config.d.ts +27 -44
- package/src/home-config.js +46 -57
- package/src/home-config.js.map +1 -1
- package/src/index.d.ts +1 -1
- package/src/index.js +7 -8
- package/src/index.js.map +1 -1
- package/src/retired-config-keys.js +4 -4
- package/src/retired-config-keys.js.map +1 -1
- package/src/rule-configs.js +3 -2
- package/src/rule-configs.js.map +1 -1
- package/src/sections.d.ts +3 -2
- package/src/sections.js +3 -2
- package/src/sections.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/rules-config",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.671",
|
|
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",
|
package/src/default-rules.js
CHANGED
|
@@ -76,12 +76,11 @@ exports.defaultRules = {
|
|
|
76
76
|
},
|
|
77
77
|
'pr-lifecycle-guard': { mode: 'ON' },
|
|
78
78
|
// NOTE: `whole-repo-build-guard` is deliberately ABSENT from this table, and from RULE_SCHEMAS and
|
|
79
|
-
// HOOK_GUARD_NAMES with it. It is
|
|
80
|
-
//
|
|
81
|
-
// make it a rule every consumer must CONFIGURE
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
// RETIRED_CONFIG_KEYS.
|
|
79
|
+
// HOOK_GUARD_NAMES with it. It is EXPERIMENTAL and OFF by default; the ONLY thing that turns it on
|
|
80
|
+
// is `experimental.whole-repo-build-guard: true` in the optional machine-local
|
|
81
|
+
// ~/.webpieces/config.json. Adding it back here would make it a rule every consumer must CONFIGURE
|
|
82
|
+
// — which is fault Y, i.e. every Bash call blocked on upgrade, which is exactly what it did the
|
|
83
|
+
// first time. See RETIRED_CONFIG_KEYS.
|
|
85
84
|
//
|
|
86
85
|
// branch-state-guard ships ON, INCLUDING its Read-blocking half.
|
|
87
86
|
//
|
package/src/default-rules.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-rules.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/default-rules.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAC3D,4EAA4E;AAC5E,kEAAkE;AAClE,0EAA0E;AAC1E,MAAM,qBAAqB,GAAsB;IAC7C,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IACrC,WAAW,EAAE,mBAAmB;CACnC,CAAC;AAEF,2EAA2E;AAC3E,6EAA6E;AAC7E,sFAAsF;AACtF,iFAAiF;AACpE,QAAA,YAAY,GAA4C;IACjE,gBAAgB,EAAE,EAAE;IACpB,iBAAiB,EAAE,EAAE;IACrB,gBAAgB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;IAChC,kBAAkB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IACjC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,gBAAgB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;IACzC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,uBAAuB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACnD,sBAAsB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,aAAa,EAAE,EAAE,EAAE;IACrE,sBAAsB,EAAE,EAAE;IAC1B,kBAAkB,EAAE,EAAE;IACtB,mCAAmC,EAAE,EAAE;IACvC,qBAAqB,EAAE,EAAE;IACzB,sFAAsF;IACtF,6FAA6F;IAC7F,6CAA6C;IAC7C,6CAA6C,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;IAC9D,eAAe,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;IACnC,8BAA8B,EAAE,EAAE;IAClC,iDAAiD,EAAE,EAAE;IACrD,eAAe,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;IAC9G,UAAU,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE;IACpH,WAAW,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACvC,UAAU,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACtC,2BAA2B,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACvD,oBAAoB,EAAE;QAClB,IAAI,EAAE,wBAAwB;QAC9B,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,YAAY,EAAE,CAAC,GAAG,qBAAqB,CAAC;KAC3C;IACD,aAAa,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;IAC9B,iGAAiG;IACjG,kGAAkG;IAClG,0EAA0E;IAC1E,yFAAyF;IACzF,oFAAoF;IACpF,iCAAiC,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAC7D,iCAAiC,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAC7D,sBAAsB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAClD,0BAA0B,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACtD,sBAAsB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAClD,wFAAwF;IACxF,EAAE;IACF,mGAAmG;IACnG,iGAAiG;IACjG,mGAAmG;IACnG,kGAAkG;IAClG,8FAA8F;IAC9F,gGAAgG;IAChG,iGAAiG;IACjG,6FAA6F;IAC7F,EAAE;IACF,2EAA2E;IAC3E,uBAAuB,EAAE;QACrB,IAAI,EAAE,IAAI;QACV,eAAe,EAAE,sCAAsC;QACvD,sBAAsB,EAAE,IAAI;KAC/B;IACD,oBAAoB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACpC,mGAAmG;IACnG,
|
|
1
|
+
{"version":3,"file":"default-rules.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/default-rules.ts"],"names":[],"mappings":"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","sourcesContent":["// Default holistic exclude list for the validate-ts-in-src\n// rules. Bare names match a directory segment at any depth; globs match the\n// workspace-relative path. `**/*.d.ts` (ambient declarations) and\n// `**/jest.config.ts` legitimately live outside src/ and are exempt here.\nconst DEFAULT_EXCLUDE_PATHS: readonly string[] = [\n 'node_modules', 'dist', '.nx', '.git',\n '**/*.d.ts', '**/jest.config.ts',\n];\n\n// On/off is driven by `mode` (\"OFF\" disables; an absent mode leaves a rule\n// on). Code-rules entries omit `mode` so each executor keeps its own default\n// scope; structural rules declare `mode: 'RUN_EVERY_TIME'`, bash guards `mode: 'ON'`.\n// webpieces-disable no-any-unknown -- rule options are opaque at framework level\nexport const defaultRules: Record<string, Record<string, unknown>> = {\n 'no-any-unknown': {},\n 'no-implicit-any': {},\n 'max-file-lines': { limit: 900 },\n 'max-method-lines': { limit: 80 },\n 'require-return-type': {},\n 'no-inline-type-literals': {},\n 'no-destructure': { allowTopLevel: true },\n 'catch-error-pattern': {},\n 'no-unmanaged-exceptions': {},\n 'no-file-import-cycles': { mode: 'RUN_EVERY_TIME' },\n 'runtime-architecture': { mode: 'RUN_EVERY_TIME', allowedCycles: [] },\n 'prisma-validate-dtos': {},\n 'prisma-converter': {},\n 'angular-no-direct-api-in-resolver': {},\n 'no-symbol-di-tokens': {},\n // Ships OFF: a repo opts in per webpieces.config.json once it is ready to migrate any\n // client-in-a-lib sites (severity defaults to \"warn\" so even when enabled it reports without\n // failing until a repo flips it to \"error\").\n 'no-client-creation-outside-server-or-client': { mode: 'OFF' },\n 'no-custom-css': { allowGlobs: [] },\n 'no-process-exit-outside-main': {},\n 'inject-annotation-not-needed-for-concrete-class': {},\n 'framework-tag': { mode: 'MODIFIED_PROJECTS', knownTypes: ['browser', 'react', 'angular', 'node', 'express'] },\n 'role-tag': { mode: 'MODIFIED_PROJECTS', knownTypes: ['server', 'app', 'designed-lib', 'lib', 'client', 'api-lib'] },\n 'nx-wiring': { mode: 'RUN_EVERY_TIME' },\n 'di-graph': { mode: 'RUN_EVERY_TIME' },\n 'missing-design-annotation': { mode: 'RUN_EVERY_TIME' },\n 'validate-ts-in-src': {\n mode: 'NEW_AND_MODIFIED_FILES',\n allowedRootFiles: ['jest.setup.ts'],\n excludePaths: [...DEFAULT_EXCLUDE_PATHS],\n },\n 'no-js-files': { mode: 'OFF' },\n // The five Nx infrastructure validators. They enforced unconditionally before they were wired to\n // config, so RUN_EVERY_TIME is the only default that keeps existing repos behaving identically on\n // upgrade. Set \"mode\": \"OFF\" to disable one; the two graph-baseline rules\n // (validate-architecture-unchanged / validate-no-architecture-cycles) additionally honor\n // turnOffRuleUntilEpoch — the other three are all-or-nothing (see rule-configs.ts).\n 'validate-architecture-unchanged': { mode: 'RUN_EVERY_TIME' },\n 'validate-no-architecture-cycles': { mode: 'RUN_EVERY_TIME' },\n 'validate-packagejson': { mode: 'RUN_EVERY_TIME' },\n 'validate-versions-locked': { mode: 'RUN_EVERY_TIME' },\n 'validate-eslint-sync': { mode: 'RUN_EVERY_TIME' },\n // autoReapMergedBranches ships TRUE, and it is also what a fresh config is seeded with.\n //\n // It shipped FALSE on the reasoning that an upgrade must never delete branches unattended before a\n // human opts in. In practice that produced the opposite of safety: nobody opts in, dead branches\n // pile up, and the pile is what makes a real branch hard to find. The reap is also NOT destructive\n // in the way the old comment implied — BranchReaper deletes only provably-dead branches (a merged\n // PR, a squash-merge backup of one, or no commits of their own), spares everything else for a\n // human, and logs each deletion to .webpieces/logs/branch-mutations.log with the pre-delete SHA\n // and a ready-made `recover=` command. So the worst case is one paste to undo, which a human can\n // resolve; the previous default's worst case was unbounded accumulation nobody ever cleaned.\n //\n // Set it false to keep reaping manual; `pnpm wp-cleanup` works either way.\n 'branch-creation-guard': {\n mode: 'ON',\n subBranchNaming: 'feature/<ticket>/<short-description>',\n autoReapMergedBranches: true,\n },\n 'pr-lifecycle-guard': { mode: 'ON' },\n // NOTE: `whole-repo-build-guard` is deliberately ABSENT from this table, and from RULE_SCHEMAS and\n // HOOK_GUARD_NAMES with it. It is EXPERIMENTAL and OFF by default; the ONLY thing that turns it on\n // is `experimental.whole-repo-build-guard: true` in the optional machine-local\n // ~/.webpieces/config.json. Adding it back here would make it a rule every consumer must CONFIGURE\n // — which is fault Y, i.e. every Bash call blocked on upgrade, which is exactly what it did the\n // first time. See RETIRED_CONFIG_KEYS.\n //\n // branch-state-guard ships ON, INCLUDING its Read-blocking half.\n //\n // Its predecessor `read-stale-guard` shipped OFF as a \"phase 1\" staged rollout, on the reasoning\n // that Read is the highest-blast-radius tool there is and nobody should be armed before verifying\n // the fail-open paths against their own git layout. Phase 1 is over: this repo has run it ON in\n // production for releases, and the fail-open paths (branch undeterminable, cache absent, cache for\n // another branch, offline, dirty tree on main) are each covered by tests. Keeping it OFF now buys\n // nothing and costs the exact incident the guard exists for — a session spent reading a tree 18\n // commits behind while the log read \"handled\".\n //\n // Nothing is armed behind anyone's back either way: every built-in requires an explicit entry (the\n // config-sync check blocks until one exists), so a consumer states this mode themselves on upgrade.\n 'branch-state-guard': { mode: 'ON' },\n};\n\nexport const defaultRulesDir: readonly string[] = [];\n"]}
|
package/src/home-config.d.ts
CHANGED
|
@@ -70,12 +70,12 @@
|
|
|
70
70
|
* used to be a loud rejection; it is now a key nothing reads, so the flag keeps its default and nothing
|
|
71
71
|
* about the machine's behaviour reveals the mistake.
|
|
72
72
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* had to get fuzzier than the case-insensitive match it replaced: `gaurd` is a
|
|
78
|
-
* the class of typo an equality test cannot see.
|
|
73
|
+
* Every key here is an OPT-IN that defaults OFF, so a typo costs the author the feature they meant to
|
|
74
|
+
* switch on: misspell `whole-repo-build-guard` and the guard stays inert while they believe they armed
|
|
75
|
+
* it. That is the milder of the two failures — nothing they were doing stops working — but it is still
|
|
76
|
+
* invisible without a signal, which is why the warning below is not optional decoration, and why
|
|
77
|
+
* `nearestKnownKey` had to get fuzzier than the case-insensitive match it replaced: `gaurd` is a
|
|
78
|
+
* transposition, exactly the class of typo an equality test cannot see.
|
|
79
79
|
*
|
|
80
80
|
* That is mitigated, not eliminated, by making the ignore VISIBLE: every unknown key is printed once per
|
|
81
81
|
* load as a `[webpieces]` warning on stderr, and `nearestKnownKey` upgrades that line with a "did you
|
|
@@ -106,10 +106,16 @@
|
|
|
106
106
|
* default state. A repo-tracked config key cannot express that — an entry there is something every
|
|
107
107
|
* consumer must add, on a schedule set by whoever bumps the release.
|
|
108
108
|
*
|
|
109
|
-
* Note which half of that was the outage. It was the REQUIRED KEY
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
109
|
+
* Note which half of that was the outage. It was the REQUIRED KEY: the failure was at config LOAD,
|
|
110
|
+
* before any command was judged. That is why every key here stays OPTIONAL and why an absent file
|
|
111
|
+
* returns all-defaults silently.
|
|
112
|
+
*
|
|
113
|
+
* The DEFAULT is settled separately, by a standing policy this file does not get to re-litigate: EVERY
|
|
114
|
+
* `experimental.*` flag ships OFF and stays OFF for two years. `whole-repo-build-guard` is one of them,
|
|
115
|
+
* so it is OFF unless a machine writes `{"experimental": {"whole-repo-build-guard": true}}`. A flag that
|
|
116
|
+
* defaults ON is not an experiment — it is a shipped behaviour that skipped its soak period, and it
|
|
117
|
+
* changes what every agent on every machine can do the moment they upgrade. Low uptake of an opt-in
|
|
118
|
+
* experiment is information ABOUT the experiment; it is not a licence to force it on everybody.
|
|
113
119
|
*/
|
|
114
120
|
export declare const HOME_CONFIG_DIR = ".webpieces";
|
|
115
121
|
export declare const HOME_CONFIG_FILE = "config.json";
|
|
@@ -117,28 +123,6 @@ export declare const HOME_EXPERIMENTAL_SECTION = "experimental";
|
|
|
117
123
|
export declare const HOME_KEY_BUILD_GATE_LOG_CAPTURE = "buildGateLogCapture";
|
|
118
124
|
export declare const HOME_KEY_WHOLE_REPO_BUILD_GUARD = "whole-repo-build-guard";
|
|
119
125
|
export declare const HOME_KEY_ORPHAN_DIR_SWEEP = "orphan-dir-sweep";
|
|
120
|
-
/**
|
|
121
|
-
* `whole-repo-build-guard`'s value on a machine that does not name the key — including the machine with
|
|
122
|
-
* no such file at all, which is essentially every machine. It is TRUE: the guard is ON by default.
|
|
123
|
-
*
|
|
124
|
-
* ─── Why this one key defaults ON, and why that is not the outage this file warns about ─────────────
|
|
125
|
-
* The outage recorded below was a CONFIG-LOAD failure: the guard once required an entry under
|
|
126
|
-
* `hookGuards` in the repo-tracked `webpieces.config.json`, so every consumer who upgraded without
|
|
127
|
-
* adding it hit fault Y and had EVERY Bash call blocked, for a feature they had never asked for. The
|
|
128
|
-
* shape of that failure is "you must edit a file to get your shell back". Nothing here reproduces it:
|
|
129
|
-
* no file needs to exist, no key needs to be added, and the load path for an absent or silent file is
|
|
130
|
-
* unchanged. What changes is only what the guard DOES once loaded — it refuses a command that would
|
|
131
|
-
* build the whole monorepo, and hands back the scoped command in its place.
|
|
132
|
-
*
|
|
133
|
-
* That is the behaviour the guard was written for, and OFF-by-default is why it never delivered it: a
|
|
134
|
-
* guard nobody opts into never fires. The measured consequence is a sibling repo whose `ci:local`
|
|
135
|
-
* verify chain ran three whole-world passes on every inner loop for months, while the correct command
|
|
136
|
-
* sat unused in `commands.pr-gate.buildCommand`.
|
|
137
|
-
*
|
|
138
|
-
* The escape hatch stays, and it is one line: `{"experimental": {"whole-repo-build-guard": false}}`
|
|
139
|
-
* turns it off for a machine, with no repo config involved.
|
|
140
|
-
*/
|
|
141
|
-
export declare const WHOLE_REPO_BUILD_GUARD_DEFAULT = true;
|
|
142
126
|
/**
|
|
143
127
|
* The complete UNDERSTOOD shape. A key not on these lists is ignored with a warning rather than
|
|
144
128
|
* rejected (see the class docblock: this document is machine-global and older releases must survive
|
|
@@ -162,16 +146,15 @@ export declare class HomeConfig {
|
|
|
162
146
|
*/
|
|
163
147
|
buildGateLogCapture: boolean;
|
|
164
148
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* completely inert: no block, no log, no message.
|
|
149
|
+
* EXPERIMENTAL, and OFF unless this machine opts IN with an explicit `true`. When true,
|
|
150
|
+
* `whole-repo-build-guard` BLOCKS a Bash command that would build the WHOLE monorepo and hands back
|
|
151
|
+
* the repo's own scoped build command (`pnpm wp-build`). False — and absent, and no file at all —
|
|
152
|
+
* makes the guard completely inert: no block, no log, no message.
|
|
169
153
|
*
|
|
170
|
-
* This is the guard's ONLY switch, and it is an OPT-
|
|
154
|
+
* This is the guard's ONLY switch, and it is an OPT-IN. There is deliberately no
|
|
171
155
|
* webpieces.config.json entry for it (see RETIRED_CONFIG_KEYS): a guard that every consumer must
|
|
172
156
|
* ADD A KEY to avoid being blocked by is a guard that ships an outage on upgrade, which is exactly
|
|
173
|
-
* what happened.
|
|
174
|
-
* see WHOLE_REPO_BUILD_GUARD_DEFAULT for why that distinction is the whole argument.
|
|
157
|
+
* what happened once. Living here means the default state needs no file, no key and no edit.
|
|
175
158
|
*/
|
|
176
159
|
wholeRepoBuildGuard: boolean;
|
|
177
160
|
/**
|
|
@@ -256,12 +239,12 @@ export declare class HomeConfigService {
|
|
|
256
239
|
private parse;
|
|
257
240
|
private validate;
|
|
258
241
|
/**
|
|
259
|
-
* An absent key falls back to `whenAbsent`, which every caller states OUT LOUD
|
|
260
|
-
* "absent means false"
|
|
261
|
-
*
|
|
242
|
+
* An absent key falls back to `whenAbsent`, which every caller states OUT LOUD by passing
|
|
243
|
+
* `GUARD_OFF_WHEN_ABSENT` — an implicit "absent means false" buried in this method would put the
|
|
244
|
+
* default and the key that carries it in different places, free to drift apart.
|
|
262
245
|
*
|
|
263
|
-
* A PRESENT key of the wrong type is still an ERROR, and that is the line the unknown-key change
|
|
264
|
-
*
|
|
246
|
+
* A PRESENT key of the wrong type is still an ERROR, and that is the line neither the unknown-key change
|
|
247
|
+
* nor this one moved: `"whole-repo-build-guard": "yes"` is a file somebody wrote wrongly, not
|
|
265
248
|
* a file written for a different release. No release of webpieces has ever given this key a string
|
|
266
249
|
* meaning, so there is no forward-compatibility story to protect and nothing is gained by guessing —
|
|
267
250
|
* whereas guessing would turn a typed value into a silent fallback to the default, which is the very
|
package/src/home-config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HomeConfigService = exports.RETIRED_HOME_CONFIG_KEYS = exports.RetiredHomeConfigKey = exports.HomeConfig = exports.ALLOWED_EXPERIMENTAL = exports.ALLOWED_TOP_LEVEL = exports.
|
|
3
|
+
exports.HomeConfigService = exports.RETIRED_HOME_CONFIG_KEYS = exports.RetiredHomeConfigKey = exports.HomeConfig = exports.ALLOWED_EXPERIMENTAL = exports.ALLOWED_TOP_LEVEL = exports.HOME_KEY_ORPHAN_DIR_SWEEP = exports.HOME_KEY_WHOLE_REPO_BUILD_GUARD = exports.HOME_KEY_BUILD_GATE_LOG_CAPTURE = exports.HOME_EXPERIMENTAL_SECTION = exports.HOME_CONFIG_FILE = exports.HOME_CONFIG_DIR = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const fs = tslib_1.__importStar(require("fs"));
|
|
6
6
|
const os = tslib_1.__importStar(require("os"));
|
|
@@ -80,12 +80,12 @@ const to_error_1 = require("./to-error");
|
|
|
80
80
|
* used to be a loud rejection; it is now a key nothing reads, so the flag keeps its default and nothing
|
|
81
81
|
* about the machine's behaviour reveals the mistake.
|
|
82
82
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* had to get fuzzier than the case-insensitive match it replaced: `gaurd` is a
|
|
88
|
-
* the class of typo an equality test cannot see.
|
|
83
|
+
* Every key here is an OPT-IN that defaults OFF, so a typo costs the author the feature they meant to
|
|
84
|
+
* switch on: misspell `whole-repo-build-guard` and the guard stays inert while they believe they armed
|
|
85
|
+
* it. That is the milder of the two failures — nothing they were doing stops working — but it is still
|
|
86
|
+
* invisible without a signal, which is why the warning below is not optional decoration, and why
|
|
87
|
+
* `nearestKnownKey` had to get fuzzier than the case-insensitive match it replaced: `gaurd` is a
|
|
88
|
+
* transposition, exactly the class of typo an equality test cannot see.
|
|
89
89
|
*
|
|
90
90
|
* That is mitigated, not eliminated, by making the ignore VISIBLE: every unknown key is printed once per
|
|
91
91
|
* load as a `[webpieces]` warning on stderr, and `nearestKnownKey` upgrades that line with a "did you
|
|
@@ -116,10 +116,16 @@ const to_error_1 = require("./to-error");
|
|
|
116
116
|
* default state. A repo-tracked config key cannot express that — an entry there is something every
|
|
117
117
|
* consumer must add, on a schedule set by whoever bumps the release.
|
|
118
118
|
*
|
|
119
|
-
* Note which half of that was the outage. It was the REQUIRED KEY
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
119
|
+
* Note which half of that was the outage. It was the REQUIRED KEY: the failure was at config LOAD,
|
|
120
|
+
* before any command was judged. That is why every key here stays OPTIONAL and why an absent file
|
|
121
|
+
* returns all-defaults silently.
|
|
122
|
+
*
|
|
123
|
+
* The DEFAULT is settled separately, by a standing policy this file does not get to re-litigate: EVERY
|
|
124
|
+
* `experimental.*` flag ships OFF and stays OFF for two years. `whole-repo-build-guard` is one of them,
|
|
125
|
+
* so it is OFF unless a machine writes `{"experimental": {"whole-repo-build-guard": true}}`. A flag that
|
|
126
|
+
* defaults ON is not an experiment — it is a shipped behaviour that skipped its soak period, and it
|
|
127
|
+
* changes what every agent on every machine can do the moment they upgrade. Low uptake of an opt-in
|
|
128
|
+
* experiment is information ABOUT the experiment; it is not a licence to force it on everybody.
|
|
123
129
|
*/
|
|
124
130
|
exports.HOME_CONFIG_DIR = '.webpieces';
|
|
125
131
|
exports.HOME_CONFIG_FILE = 'config.json';
|
|
@@ -137,30 +143,17 @@ exports.HOME_KEY_WHOLE_REPO_BUILD_GUARD = 'whole-repo-build-guard';
|
|
|
137
143
|
// it switches, exactly as the guard key above is — one name, greppable from either end.
|
|
138
144
|
exports.HOME_KEY_ORPHAN_DIR_SWEEP = 'orphan-dir-sweep';
|
|
139
145
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* `
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* build the whole monorepo, and hands back the scoped command in its place.
|
|
151
|
-
*
|
|
152
|
-
* That is the behaviour the guard was written for, and OFF-by-default is why it never delivered it: a
|
|
153
|
-
* guard nobody opts into never fires. The measured consequence is a sibling repo whose `ci:local`
|
|
154
|
-
* verify chain ran three whole-world passes on every inner loop for months, while the correct command
|
|
155
|
-
* sat unused in `commands.pr-gate.buildCommand`.
|
|
156
|
-
*
|
|
157
|
-
* The escape hatch stays, and it is one line: `{"experimental": {"whole-repo-build-guard": false}}`
|
|
158
|
-
* turns it off for a machine, with no repo config involved.
|
|
146
|
+
* EVERY key's value when it is not named — including on the machine with no such file at all, which is
|
|
147
|
+
* essentially every machine. False, for all of them, with no exceptions and no per-key table.
|
|
148
|
+
*
|
|
149
|
+
* That uniformity is the policy, not a coincidence: every `experimental.*` flag ships OFF and stays OFF
|
|
150
|
+
* for two years, so "this machine never opted in" is byte-for-byte the behaviour of having no file. ON
|
|
151
|
+
* requires an explicit `true`; absent, and an explicit `false`, are the same state.
|
|
152
|
+
*
|
|
153
|
+
* Named rather than written as a bare `false` at each call site so the reason travels with the value —
|
|
154
|
+
* and there is deliberately exactly ONE such constant, because a second one would be a second place a
|
|
155
|
+
* default is stated, free to disagree with this one.
|
|
159
156
|
*/
|
|
160
|
-
exports.WHOLE_REPO_BUILD_GUARD_DEFAULT = true;
|
|
161
|
-
// Every OTHER key's value when it is not named. False — "this machine never opted in" — which for those
|
|
162
|
-
// keys is byte-for-byte the behaviour of having no file at all. Named rather than written as a bare
|
|
163
|
-
// `false` at each call site so the asymmetry with the constant above is visible where it is passed.
|
|
164
157
|
const GUARD_OFF_WHEN_ABSENT = false;
|
|
165
158
|
/**
|
|
166
159
|
* The complete UNDERSTOOD shape. A key not on these lists is ignored with a warning rather than
|
|
@@ -192,10 +185,8 @@ exports.ALLOWED_EXPERIMENTAL = [
|
|
|
192
185
|
* reasoning was sound for a single version and wrong for a shared file. It is optional now, along with
|
|
193
186
|
* every other key.
|
|
194
187
|
*
|
|
195
|
-
* Absent then reads as
|
|
196
|
-
* byte-for-byte the behaviour of having no file at all.
|
|
197
|
-
* and it defaults TRUE — it is no longer experimental — for the reason spelled out at
|
|
198
|
-
* WHOLE_REPO_BUILD_GUARD_DEFAULT.
|
|
188
|
+
* Absent then reads as the ONE declared default, `GUARD_OFF_WHEN_ABSENT`: false, for every key without
|
|
189
|
+
* exception, which is byte-for-byte the behaviour of having no file at all.
|
|
199
190
|
*
|
|
200
191
|
* The other half of cross-version safety — an OLD release IGNORING a key a NEW one added, rather than
|
|
201
192
|
* rejecting it — is solved by `warnUnknownKeys` below. The two halves are one invariant: for the set of
|
|
@@ -216,16 +207,15 @@ class HomeConfig {
|
|
|
216
207
|
*/
|
|
217
208
|
buildGateLogCapture;
|
|
218
209
|
/**
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* completely inert: no block, no log, no message.
|
|
210
|
+
* EXPERIMENTAL, and OFF unless this machine opts IN with an explicit `true`. When true,
|
|
211
|
+
* `whole-repo-build-guard` BLOCKS a Bash command that would build the WHOLE monorepo and hands back
|
|
212
|
+
* the repo's own scoped build command (`pnpm wp-build`). False — and absent, and no file at all —
|
|
213
|
+
* makes the guard completely inert: no block, no log, no message.
|
|
223
214
|
*
|
|
224
|
-
* This is the guard's ONLY switch, and it is an OPT-
|
|
215
|
+
* This is the guard's ONLY switch, and it is an OPT-IN. There is deliberately no
|
|
225
216
|
* webpieces.config.json entry for it (see RETIRED_CONFIG_KEYS): a guard that every consumer must
|
|
226
217
|
* ADD A KEY to avoid being blocked by is a guard that ships an outage on upgrade, which is exactly
|
|
227
|
-
* what happened.
|
|
228
|
-
* see WHOLE_REPO_BUILD_GUARD_DEFAULT for why that distinction is the whole argument.
|
|
218
|
+
* what happened once. Living here means the default state needs no file, no key and no edit.
|
|
229
219
|
*/
|
|
230
220
|
wholeRepoBuildGuard;
|
|
231
221
|
/**
|
|
@@ -314,13 +304,12 @@ let HomeConfigService = class HomeConfigService {
|
|
|
314
304
|
*/
|
|
315
305
|
load(homeDir = os.homedir()) {
|
|
316
306
|
const raw = this.readIfPresent(this.configPath(homeDir));
|
|
317
|
-
// THE ABSENT-FILE STATE, and the ONE place it is constructed. Every
|
|
318
|
-
//
|
|
319
|
-
//
|
|
320
|
-
//
|
|
321
|
-
// constructor — see the note there on why a defaulted parameter is a shim.
|
|
307
|
+
// THE ABSENT-FILE STATE, and the ONE place it is constructed. Every flag is off — the same value
|
|
308
|
+
// a present file that does not name the key gets, so "no file" and "file that ignores this key"
|
|
309
|
+
// can never disagree. Spelled out rather than defaulted in the constructor — see the note there
|
|
310
|
+
// on why a defaulted parameter is a shim.
|
|
322
311
|
if (raw === null) {
|
|
323
|
-
return new HomeConfig(GUARD_OFF_WHEN_ABSENT,
|
|
312
|
+
return new HomeConfig(GUARD_OFF_WHEN_ABSENT, GUARD_OFF_WHEN_ABSENT, GUARD_OFF_WHEN_ABSENT);
|
|
324
313
|
}
|
|
325
314
|
return this.validate(this.parse(raw, this.configPath(homeDir)), this.configPath(homeDir));
|
|
326
315
|
}
|
|
@@ -407,15 +396,15 @@ let HomeConfigService = class HomeConfigService {
|
|
|
407
396
|
// webpieces-disable no-any-unknown -- narrowed to a non-null, non-array object one line above
|
|
408
397
|
const experimental = (section ?? {});
|
|
409
398
|
this.warnUnknownKeys(Object.keys(experimental), exports.ALLOWED_EXPERIMENTAL, `${exports.HOME_EXPERIMENTAL_SECTION}.`);
|
|
410
|
-
return new HomeConfig(this.readOptionalBoolean(experimental, exports.HOME_KEY_BUILD_GATE_LOG_CAPTURE, file, GUARD_OFF_WHEN_ABSENT), this.readOptionalBoolean(experimental, exports.HOME_KEY_WHOLE_REPO_BUILD_GUARD, file,
|
|
399
|
+
return new HomeConfig(this.readOptionalBoolean(experimental, exports.HOME_KEY_BUILD_GATE_LOG_CAPTURE, file, GUARD_OFF_WHEN_ABSENT), this.readOptionalBoolean(experimental, exports.HOME_KEY_WHOLE_REPO_BUILD_GUARD, file, GUARD_OFF_WHEN_ABSENT), this.readOptionalBoolean(experimental, exports.HOME_KEY_ORPHAN_DIR_SWEEP, file, GUARD_OFF_WHEN_ABSENT));
|
|
411
400
|
}
|
|
412
401
|
/**
|
|
413
|
-
* An absent key falls back to `whenAbsent`, which every caller states OUT LOUD
|
|
414
|
-
* "absent means false"
|
|
415
|
-
*
|
|
402
|
+
* An absent key falls back to `whenAbsent`, which every caller states OUT LOUD by passing
|
|
403
|
+
* `GUARD_OFF_WHEN_ABSENT` — an implicit "absent means false" buried in this method would put the
|
|
404
|
+
* default and the key that carries it in different places, free to drift apart.
|
|
416
405
|
*
|
|
417
|
-
* A PRESENT key of the wrong type is still an ERROR, and that is the line the unknown-key change
|
|
418
|
-
*
|
|
406
|
+
* A PRESENT key of the wrong type is still an ERROR, and that is the line neither the unknown-key change
|
|
407
|
+
* nor this one moved: `"whole-repo-build-guard": "yes"` is a file somebody wrote wrongly, not
|
|
419
408
|
* a file written for a different release. No release of webpieces has ever given this key a string
|
|
420
409
|
* meaning, so there is no forward-compatibility story to protect and nothing is gained by guessing —
|
|
421
410
|
* whereas guessing would turn a typed value into a silent fallback to the default, which is the very
|