@hominis/fireforge 0.52.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/dist/build-info.json +4 -4
- package/dist/src/commands/bootstrap.js +2 -3
- package/dist/src/commands/build-prelock.d.ts +3 -3
- package/dist/src/commands/build-prelock.js +3 -3
- package/dist/src/commands/build.js +4 -0
- package/dist/src/commands/declarations-report.d.ts +9 -3
- package/dist/src/commands/declarations-report.js +18 -11
- package/dist/src/commands/discard.js +3 -3
- package/dist/src/commands/doctor-furnace-config-sync.js +4 -4
- package/dist/src/commands/doctor-furnace.js +5 -5
- package/dist/src/commands/export-adopt-check.d.ts +5 -6
- package/dist/src/commands/export-adopt-check.js +5 -6
- package/dist/src/commands/export-flow.js +6 -9
- package/dist/src/commands/export-staged-registration.d.ts +4 -4
- package/dist/src/commands/export-staged-registration.js +4 -4
- package/dist/src/commands/forward-import-remedy.d.ts +2 -3
- package/dist/src/commands/forward-import-remedy.js +2 -3
- package/dist/src/commands/furnace/create-dry-run.d.ts +2 -2
- package/dist/src/commands/furnace/deploy-fragment-includers.d.ts +2 -2
- package/dist/src/commands/furnace/deploy-fragment-includers.js +2 -2
- package/dist/src/commands/furnace/index.js +2 -2
- package/dist/src/commands/lint.js +4 -4
- package/dist/src/commands/patch/compact.js +1 -1
- package/dist/src/commands/patch/lint-ignore-from.d.ts +3 -4
- package/dist/src/commands/patch/lint-ignore-from.js +3 -4
- package/dist/src/commands/patch/move-files-adopt.d.ts +33 -0
- package/dist/src/commands/patch/move-files-adopt.js +65 -0
- package/dist/src/commands/patch/move-files-create.js +41 -20
- package/dist/src/commands/patch/move-files-into.d.ts +18 -0
- package/dist/src/commands/patch/move-files-into.js +125 -60
- package/dist/src/commands/patch/move-files-retire.d.ts +39 -0
- package/dist/src/commands/patch/move-files-retire.js +91 -0
- package/dist/src/commands/patch/move-files.d.ts +3 -0
- package/dist/src/commands/patch/move-files.js +42 -12
- package/dist/src/commands/patch/move-size-tier.d.ts +27 -0
- package/dist/src/commands/patch/move-size-tier.js +66 -0
- package/dist/src/commands/patch/rename.js +1 -1
- package/dist/src/commands/patch/reorder-projection.d.ts +17 -0
- package/dist/src/commands/patch/reorder-projection.js +49 -0
- package/dist/src/commands/patch/reorder-shift.d.ts +30 -0
- package/dist/src/commands/patch/reorder-shift.js +307 -0
- package/dist/src/commands/patch/reorder.d.ts +9 -15
- package/dist/src/commands/patch/reorder.js +52 -50
- package/dist/src/commands/patch/split-plan.d.ts +31 -3
- package/dist/src/commands/patch/split-plan.js +36 -12
- package/dist/src/commands/patch/split-staged.d.ts +2 -2
- package/dist/src/commands/patch/split-staged.js +2 -2
- package/dist/src/commands/patch/split.js +18 -5
- package/dist/src/commands/patch/staged-dependency-entries.d.ts +9 -1
- package/dist/src/commands/patch/staged-dependency-entries.js +32 -4
- package/dist/src/commands/patch/staged-dependency-from.js +15 -9
- package/dist/src/commands/patch/staged-dependency-remove.d.ts +26 -4
- package/dist/src/commands/patch/staged-dependency-remove.js +60 -23
- package/dist/src/commands/patch/staged-dependency.js +35 -24
- package/dist/src/commands/patch/tier.js +2 -2
- package/dist/src/commands/patch-rename-map.d.ts +14 -3
- package/dist/src/commands/patch-rename-map.js +21 -3
- package/dist/src/commands/re-export-adjacent.d.ts +4 -5
- package/dist/src/commands/re-export-lint.d.ts +4 -3
- package/dist/src/commands/re-export-lint.js +4 -3
- package/dist/src/commands/re-export-options.js +8 -2
- package/dist/src/commands/re-export-preflight.js +1 -2
- package/dist/src/commands/re-export-purity-scope.d.ts +1 -1
- package/dist/src/commands/re-export-purity-scope.js +13 -7
- package/dist/src/commands/re-export-retired-declarations.d.ts +22 -0
- package/dist/src/commands/re-export-retired-declarations.js +113 -0
- package/dist/src/commands/re-export-single.js +2 -2
- package/dist/src/commands/re-export-stale-registrations.d.ts +27 -6
- package/dist/src/commands/re-export-stale-registrations.js +65 -21
- package/dist/src/commands/re-export.js +4 -0
- package/dist/src/commands/rebase/continue.js +3 -3
- package/dist/src/commands/register.js +5 -4
- package/dist/src/commands/run.js +11 -4
- package/dist/src/commands/status.js +1 -1
- package/dist/src/commands/test-build-furnace.d.ts +1 -2
- package/dist/src/commands/test-build-furnace.js +1 -2
- package/dist/src/commands/test-build-phase.d.ts +8 -0
- package/dist/src/commands/test-build-phase.js +42 -7
- package/dist/src/commands/test-control-restore.d.ts +40 -0
- package/dist/src/commands/test-control-restore.js +86 -0
- package/dist/src/commands/test-dispatch.js +68 -7
- package/dist/src/commands/test-multi-verdict.js +1 -0
- package/dist/src/commands/test-orchestrate.d.ts +6 -0
- package/dist/src/commands/test-orchestrate.js +32 -1
- package/dist/src/commands/test-perf-scope.d.ts +1 -1
- package/dist/src/commands/test-perf-scope.js +1 -1
- package/dist/src/commands/test-prelock.d.ts +18 -8
- package/dist/src/commands/test-prelock.js +42 -14
- package/dist/src/commands/test-register.js +4 -3
- package/dist/src/commands/test-results.d.ts +10 -1
- package/dist/src/commands/test-results.js +20 -3
- package/dist/src/commands/test-run.d.ts +6 -0
- package/dist/src/commands/test-run.js +23 -4
- package/dist/src/commands/test-shards.d.ts +7 -3
- package/dist/src/commands/test-shards.js +24 -7
- package/dist/src/commands/test-stale-gate.d.ts +6 -1
- package/dist/src/commands/test-stale-gate.js +40 -2
- package/dist/src/commands/test-verdict.d.ts +5 -3
- package/dist/src/commands/test.js +14 -2
- package/dist/src/commands/token.js +2 -2
- package/dist/src/commands/verify.js +1 -1
- package/dist/src/commands/watch.js +1 -1
- package/dist/src/commands/wire.js +1 -1
- package/dist/src/core/build-audit-resolve.d.ts +4 -5
- package/dist/src/core/build-audit-resolve.js +4 -5
- package/dist/src/core/build-audit-skip.d.ts +2 -2
- package/dist/src/core/build-audit.d.ts +3 -4
- package/dist/src/core/build-baseline-types.d.ts +24 -3
- package/dist/src/core/build-baseline-validate.d.ts +30 -1
- package/dist/src/core/build-baseline-validate.js +127 -35
- package/dist/src/core/build-baseline.d.ts +8 -2
- package/dist/src/core/build-baseline.js +25 -16
- package/dist/src/core/build-jar-escalation.d.ts +4 -4
- package/dist/src/core/build-jar-escalation.js +4 -4
- package/dist/src/core/build-prepare.js +4 -4
- package/dist/src/core/config-validate.js +4 -4
- package/dist/src/core/coverage-extend.d.ts +5 -3
- package/dist/src/core/coverage-extend.js +8 -3
- package/dist/src/core/coverage-records.d.ts +4 -5
- package/dist/src/core/coverage-records.js +4 -5
- package/dist/src/core/destructive.d.ts +2 -2
- package/dist/src/core/destructive.js +2 -2
- package/dist/src/core/discard-baseline.d.ts +2 -2
- package/dist/src/core/discard-baseline.js +3 -3
- package/dist/src/core/engine-session-lock.d.ts +1 -1
- package/dist/src/core/engine-session-lock.js +1 -1
- package/dist/src/core/file-lock-owner.d.ts +5 -5
- package/dist/src/core/file-lock-owner.js +5 -5
- package/dist/src/core/file-lock-queue.js +6 -8
- package/dist/src/core/file-lock-shared.d.ts +4 -4
- package/dist/src/core/file-lock-shared.js +4 -4
- package/dist/src/core/file-lock.js +7 -10
- package/dist/src/core/firefox.js +2 -2
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +1 -1
- package/dist/src/core/furnace-apply-overwrite-warn.js +1 -1
- package/dist/src/core/furnace-apply.js +3 -3
- package/dist/src/core/furnace-operation.js +5 -5
- package/dist/src/core/furnace-registration-jar-inplace.js +5 -6
- package/dist/src/core/furnace-registration-rename.d.ts +5 -5
- package/dist/src/core/furnace-registration-rename.js +5 -5
- package/dist/src/core/furnace-registration-validate.d.ts +2 -1
- package/dist/src/core/furnace-registration-validate.js +2 -1
- package/dist/src/core/furnace-registration.js +2 -2
- package/dist/src/core/git-base.js +4 -3
- package/dist/src/core/git-diff.js +1 -1
- package/dist/src/core/git.js +1 -1
- package/dist/src/core/harness-orphans.d.ts +6 -6
- package/dist/src/core/harness-orphans.js +6 -6
- package/dist/src/core/harness-port-reservation.d.ts +60 -0
- package/dist/src/core/harness-port-reservation.js +122 -0
- package/dist/src/core/history-log-file.d.ts +9 -9
- package/dist/src/core/history-log-file.js +15 -15
- package/dist/src/core/history-log.d.ts +3 -3
- package/dist/src/core/history-log.js +3 -3
- package/dist/src/core/launchable-build.d.ts +39 -0
- package/dist/src/core/launchable-build.js +85 -0
- package/dist/src/core/marionette-port.js +1 -3
- package/dist/src/core/moz-manifest-rules.js +3 -2
- package/dist/src/core/negative-control-compiled.d.ts +13 -3
- package/dist/src/core/negative-control-compiled.js +27 -5
- package/dist/src/core/negative-control-diff.js +31 -6
- package/dist/src/core/parser-fallback.d.ts +5 -5
- package/dist/src/core/parser-fallback.js +5 -5
- package/dist/src/core/patch-identifier-suggest.d.ts +6 -0
- package/dist/src/core/patch-identifier-suggest.js +11 -4
- package/dist/src/core/patch-lint-checkjs.d.ts +1 -1
- package/dist/src/core/patch-lint-checkjs.js +1 -1
- package/dist/src/core/patch-lint-css.js +2 -2
- package/dist/src/core/patch-lint-file-size.d.ts +5 -7
- package/dist/src/core/patch-lint-file-size.js +5 -7
- package/dist/src/core/patch-lint-ignore.d.ts +3 -3
- package/dist/src/core/patch-lint-ignore.js +3 -3
- package/dist/src/core/patch-lint-prettier.d.ts +4 -6
- package/dist/src/core/patch-lint-prettier.js +4 -6
- package/dist/src/core/patch-lint-projection.d.ts +1 -1
- package/dist/src/core/patch-lint-projection.js +1 -1
- package/dist/src/core/patch-lint-queue-types.d.ts +2 -2
- package/dist/src/core/patch-lint-queue-types.js +2 -2
- package/dist/src/core/patch-manifest-consistency.d.ts +2 -2
- package/dist/src/core/patch-manifest-consistency.js +2 -2
- package/dist/src/core/patch-manifest-io.d.ts +5 -1
- package/dist/src/core/patch-manifest-io.js +12 -10
- package/dist/src/core/patch-manifest-key-order.d.ts +3 -4
- package/dist/src/core/patch-manifest-key-order.js +3 -4
- package/dist/src/core/patch-parse.d.ts +3 -3
- package/dist/src/core/patch-parse.js +3 -3
- package/dist/src/core/patch-policy.d.ts +1 -1
- package/dist/src/core/patch-policy.js +1 -1
- package/dist/src/core/patch-source-metadata.d.ts +1 -1
- package/dist/src/core/patch-source-metadata.js +1 -1
- package/dist/src/core/patch-subset.d.ts +5 -3
- package/dist/src/core/patch-subset.js +8 -7
- package/dist/src/core/patch-transform.d.ts +2 -2
- package/dist/src/core/patch-transform.js +2 -2
- package/dist/src/core/rebase-session.js +4 -6
- package/dist/src/core/register-xpcshell-test.d.ts +28 -7
- package/dist/src/core/register-xpcshell-test.js +76 -27
- package/dist/src/core/run-log.d.ts +8 -8
- package/dist/src/core/run-log.js +8 -8
- package/dist/src/core/status-classify.d.ts +1 -2
- package/dist/src/core/status-classify.js +1 -2
- package/dist/src/core/test-harness-crash.d.ts +5 -3
- package/dist/src/core/test-harness-crash.js +13 -14
- package/dist/src/core/test-harness-infra.d.ts +32 -0
- package/dist/src/core/test-harness-infra.js +69 -0
- package/dist/src/core/test-harness-signature.d.ts +6 -0
- package/dist/src/core/test-stale-check.d.ts +38 -0
- package/dist/src/core/test-stale-check.js +82 -1
- package/dist/src/core/test-stall-triage.js +5 -7
- package/dist/src/core/token-category.js +2 -2
- package/dist/src/core/token-inventory.js +3 -3
- package/dist/src/core/token-manager.d.ts +2 -2
- package/dist/src/core/token-manager.js +5 -7
- package/dist/src/core/token-variant.d.ts +6 -6
- package/dist/src/core/token-variant.js +7 -7
- package/dist/src/core/typecheck-shim.js +1 -1
- package/dist/src/core/wire-destroy.d.ts +1 -1
- package/dist/src/core/wire-destroy.js +1 -1
- package/dist/src/core/wire-dom-fragment.js +1 -1
- package/dist/src/core/wire-init.d.ts +1 -1
- package/dist/src/core/wire-init.js +1 -1
- package/dist/src/core/wire-subscript.d.ts +1 -1
- package/dist/src/core/wire-subscript.js +1 -1
- package/dist/src/core/wire-utils.d.ts +2 -2
- package/dist/src/core/wire-utils.js +3 -3
- package/dist/src/errors/base.d.ts +1 -1
- package/dist/src/errors/base.js +1 -1
- package/dist/src/errors/rebase.d.ts +1 -1
- package/dist/src/errors/rebase.js +1 -1
- package/dist/src/types/commands/options.d.ts +38 -3
- package/dist/src/types/config.d.ts +5 -7
- package/dist/src/utils/options.js +2 -2
- package/dist/src/utils/process.js +2 -2
- package/dist/src/utils/regex.d.ts +2 -2
- package/dist/src/utils/regex.js +3 -3
- package/dist/src/utils/sleep.d.ts +5 -6
- package/dist/src/utils/sleep.js +5 -6
- package/dist/src/utils/validation.js +2 -2
- package/docs/configuration.md +28 -23
- package/docs/exit-codes.md +8 -11
- package/docs/furnace.md +3 -3
- package/docs/lifecycle-invariants.md +36 -45
- package/docs/machine-output.md +41 -24
- package/docs/patch-workflow.md +140 -29
- package/docs/run-logs.md +8 -9
- package/docs/testing.md +114 -48
- package/package.json +1 -1
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The single awaitable delay used across FireForge.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* `
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Both behaviours now live here, and callers state which one they need.
|
|
4
|
+
* Callers use this rather than a private `sleep`/`delay` or an inline
|
|
5
|
+
* `new Promise((resolve) => setTimeout(resolve, ms))`, because such copies
|
|
6
|
+
* disagree on the one property that actually matters (whether the pending
|
|
7
|
+
* timer holds the event loop open) and the disagreement is invisible at each
|
|
8
|
+
* call site. Both behaviours live here, and callers state which one they need.
|
|
10
9
|
*
|
|
11
10
|
* The default is a ref'd timer, because the dangerous mistake is the other
|
|
12
11
|
* one: an unref'd delay awaited between a SIGTERM and its escalation lets Node
|
package/dist/src/utils/sleep.js
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* The single awaitable delay used across FireForge.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Both behaviours now live here, and callers state which one they need.
|
|
5
|
+
* Callers use this rather than a private `sleep`/`delay` or an inline
|
|
6
|
+
* `new Promise((resolve) => setTimeout(resolve, ms))`, because such copies
|
|
7
|
+
* disagree on the one property that actually matters (whether the pending
|
|
8
|
+
* timer holds the event loop open) and the disagreement is invisible at each
|
|
9
|
+
* call site. Both behaviours live here, and callers state which one they need.
|
|
11
10
|
*
|
|
12
11
|
* The default is a ref'd timer, because the dangerous mistake is the other
|
|
13
12
|
* one: an unref'd delay awaited between a SIGTERM and its escalation lets Node
|
|
@@ -20,8 +20,8 @@ export function isString(value) {
|
|
|
20
20
|
*/
|
|
21
21
|
export function isNumber(value) {
|
|
22
22
|
// Number.isFinite matches the documented contract: NaN and ±Infinity are
|
|
23
|
-
// excluded (a JSON config field of 1e999 parses to Infinity
|
|
24
|
-
// validate as a legal number).
|
|
23
|
+
// excluded (a JSON config field of 1e999 parses to Infinity, which must
|
|
24
|
+
// not validate as a legal number).
|
|
25
25
|
return typeof value === 'number' && Number.isFinite(value);
|
|
26
26
|
}
|
|
27
27
|
/**
|
package/docs/configuration.md
CHANGED
|
@@ -21,11 +21,10 @@ uncommitted pin, and the tree is then building a different version than the
|
|
|
21
21
|
config claims.
|
|
22
22
|
|
|
23
23
|
`fireforge source set`, `fireforge config <key> <value>` and `furnace init`
|
|
24
|
-
edit `fireforge.json` in place
|
|
24
|
+
edit `fireforge.json` in place. Only the values that change
|
|
25
25
|
are rewritten. Indentation, key order, and objects or arrays kept on one
|
|
26
26
|
line stay as they are, so a pin move is a diff of the `firefox` block alone.
|
|
27
|
-
New keys follow the layout of the object they land in.
|
|
28
|
-
write re-serialized the whole file and expanded every compact section.
|
|
27
|
+
New keys follow the layout of the object they land in.
|
|
29
28
|
|
|
30
29
|
`fireforge doctor`'s "Source pin matches engine" check compares the pin with
|
|
31
30
|
the engine's committed `browser/config/version.txt`. That file never carries
|
|
@@ -93,7 +92,7 @@ Most globals in it are `any`. `Cu` is typed as `CuShim`, the members of
|
|
|
93
92
|
`nsIXPCComponents_Utils` (`js/xpconnect/idl/xpccomponents.idl`) with loose
|
|
94
93
|
parameter and result types, so a call to a member `Cu` does not have (such
|
|
95
94
|
as `Cu.now()`, which is `ChromeUtils.now()`) fails `typecheck` and per-patch
|
|
96
|
-
lint instead of throwing at runtime
|
|
95
|
+
lint instead of throwing at runtime. The same shim backs
|
|
97
96
|
`fireforge typecheck`.
|
|
98
97
|
|
|
99
98
|
- `patchLint.checkJsExtraShim` adds members to the structured shim globals
|
|
@@ -137,7 +136,7 @@ lint instead of throwing at runtime (since 0.50.0). The same shim backs
|
|
|
137
136
|
structured `stagedDeclarations`, so a `lint --per-patch --report` file
|
|
138
137
|
can be applied with one `patch staged-dependency <patch> --add --from
|
|
139
138
|
<report>` per patch instead of one call per edge. The setting is opt-in because a queue
|
|
140
|
-
that
|
|
139
|
+
that was never checked for these carriers can carry many such edges, and a new error would red a
|
|
141
140
|
`--max-warnings 0` gate on install. The same census is on the public API as
|
|
142
141
|
`findForwardRegistrations(patchesDir, { scope })`, which defaults to
|
|
143
142
|
`'extended'`, for a consumer that keeps its own ratchet over these edges.
|
|
@@ -168,7 +167,7 @@ lint instead of throwing at runtime (since 0.50.0). The same shim backs
|
|
|
168
167
|
what `file-too-large` counts. `'raw'` counts every line, the way `wc -l`
|
|
169
168
|
does. `'code'` blanks comments with acorn's tokenizer (module first, then
|
|
170
169
|
script, since chrome subscripts are scripts) and counts the lines left
|
|
171
|
-
non-blank, so JSDoc and blank lines
|
|
170
|
+
non-blank, so JSDoc and blank lines do not count. A file acorn cannot
|
|
172
171
|
tokenize is counted in raw lines, the upper bound, and a
|
|
173
172
|
`file-size-unparsed` notice names it. Every message says which unit it
|
|
174
173
|
counted ("lines" or "code lines"). The counter is on the public API as
|
|
@@ -260,7 +259,7 @@ lint instead of throwing at runtime (since 0.50.0). The same shim backs
|
|
|
260
259
|
`@font-feature-values`, `@font-palette-values`, `@page` and its margin
|
|
261
260
|
boxes) are descriptors, not properties, and are not judged.
|
|
262
261
|
|
|
263
|
-
|
|
262
|
+
A scale also takes:
|
|
264
263
|
|
|
265
264
|
- `prefix` as a list (`["--mybrowser-space-", "--mybrowser-gap-"]`) for a
|
|
266
265
|
scale whose steps are spelled more than one way.
|
|
@@ -297,9 +296,9 @@ FireForge version. Diagnostics always use a fresh project
|
|
|
297
296
|
program: prior incremental diagnostic state is never restored. Cached and
|
|
298
297
|
`--no-cache` runs therefore check the same complete file set. `--no-cache`
|
|
299
298
|
also disables build-info writes. A jsconfig's own `incremental` and
|
|
300
|
-
`tsBuildInfoFile`
|
|
299
|
+
`tsBuildInfoFile` are ignored.
|
|
301
300
|
|
|
302
|
-
`typecheck.litTypes: true` (
|
|
301
|
+
`typecheck.litTypes: true` (default off) types Lit in the
|
|
303
302
|
shim: `LitElement` and the helpers of
|
|
304
303
|
`chrome://global/content/vendor/lit.all.mjs`, and `MozLitElement` of
|
|
305
304
|
`chrome://global/content/lit-utils.mjs`. The element classes carry closed
|
|
@@ -307,7 +306,7 @@ member lists, as `Cu` does, so a misspelt member of a widget host is an
|
|
|
307
306
|
error rather than `any`. Template helpers and directives stay loose. It is
|
|
308
307
|
off by default because a reactive property declared only in
|
|
309
308
|
`static properties` or `static queries` then needs a declaration to be
|
|
310
|
-
known.
|
|
309
|
+
known. The shim declares the global type
|
|
311
310
|
`MozLitElementWith<Extra>`: a widget casts its base to it, and its
|
|
312
311
|
instances carry `Extra` beside MozLitElement's members. A query getter
|
|
313
312
|
cannot be declared any other way: a class field redefines the getter
|
|
@@ -327,7 +326,7 @@ checks in both. A project shim can add members by merging
|
|
|
327
326
|
`interface LitElementShimMembers`; a jsconfig `paths` entry that maps these
|
|
328
327
|
URLs to real sources takes precedence.
|
|
329
328
|
|
|
330
|
-
Per-patch checkJs gives each test script its own program.
|
|
329
|
+
Per-patch checkJs gives each test script its own program. A
|
|
331
330
|
test's `resource:///` and `chrome://` imports (including a
|
|
332
331
|
`typeof import("…")` cast) resolve to the modules the queue creates up to
|
|
333
332
|
the test's own patch, so a test of an earlier patch's module is checked
|
|
@@ -441,11 +440,11 @@ carries `invocationId` (shared by every record one command writes), `pid`,
|
|
|
441
440
|
`ppid`, and `sessionId` when the environment sets `FIREFORGE_SESSION_ID`, so
|
|
442
441
|
a session sharing the checkout can select its own lines.
|
|
443
442
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
443
|
+
If a log exists at `patches/.fireforge-history.jsonl`, inside the tracked
|
|
444
|
+
queue, the next append moves it to `history.path`; when both files exist, its
|
|
445
|
+
records are appended to the `history.path` file rather than either being
|
|
446
|
+
overwritten. Setting `history.path` to `patches/.fireforge-history.jsonl`
|
|
447
|
+
keeps the log at that location.
|
|
449
448
|
|
|
450
449
|
## `buildAudit`
|
|
451
450
|
|
|
@@ -611,7 +610,7 @@ The dark and variant blocks mirror it and appear in `token show`.
|
|
|
611
610
|
- `token-undeclared`: a `var(--<prefix>…)` in the tokens CSS, or in any CSS
|
|
612
611
|
file a patch in the queue touches, names a token no block of the tokens
|
|
613
612
|
CSS declares. A property declared in the same file, and the `furnace.json`
|
|
614
|
-
`tokenAllowlist` and `runtimeVariables` names, are exempt.
|
|
613
|
+
`tokenAllowlist` and `runtimeVariables` names, are exempt. A
|
|
615
614
|
reference with a fallback (`var(--x, 0)`) is optional and not reported,
|
|
616
615
|
and a token a sibling sheet declares counts as declared. Sheets are
|
|
617
616
|
siblings when one queue document links both (`<link rel="stylesheet">`,
|
|
@@ -633,7 +632,7 @@ non-CI launches print a warning saying so. Exit codes 12 and 13 separate a
|
|
|
633
632
|
console regression from a launch failure. See
|
|
634
633
|
[`exit-codes.md`](exit-codes.md).
|
|
635
634
|
|
|
636
|
-
A smoke run starts on a fresh temporary profile by default
|
|
635
|
+
A smoke run starts on a fresh temporary profile by default.
|
|
637
636
|
The step exists to prove what the build does on a clean start. The
|
|
638
637
|
developer's `obj-*/tmp/profile-default` carries whatever the last session
|
|
639
638
|
left (a pre-reset database, a restored hand-made applet), and those reds
|
|
@@ -649,7 +648,7 @@ owning process is gone.
|
|
|
649
648
|
|
|
650
649
|
- `--profile <path>` launches with a named profile directory and leaves it
|
|
651
650
|
in place. Under `--smoke-exit` it replaces the fresh default. Firefox also
|
|
652
|
-
gets `-purgecaches
|
|
651
|
+
gets `-purgecaches`, which discards the profile's startup
|
|
653
652
|
cache of compiled chrome scripts. That cache is keyed on the build id, and
|
|
654
653
|
a `build --ui` does not change it, so without the purge a kept profile runs
|
|
655
654
|
the chrome scripts an earlier build cached. `--no-purge-caches` keeps the
|
|
@@ -657,14 +656,20 @@ owning process is gone.
|
|
|
657
656
|
every run, and a temporary profile starts without one.
|
|
658
657
|
- `--temp-profile` gives a plain `run` the same fresh, removed-afterwards
|
|
659
658
|
profile.
|
|
659
|
+
- Arguments after `--` go to the browser, after the profile ones. A headed
|
|
660
|
+
session on a kept profile that a chrome-context Marionette client drives
|
|
661
|
+
is `fireforge run --profile <dir> -- -marionette -remote-allow-system-access`,
|
|
662
|
+
with `marionette.port` set in the profile's `user.js` so peers' harnesses
|
|
663
|
+
keep 2828. The objdir app launched directly gets neither `-purgecaches`
|
|
664
|
+
nor the startup-cache cleanup, so it can serve a widget script an earlier
|
|
665
|
+
launch cached.
|
|
660
666
|
|
|
661
667
|
A smoke run whose browser exits with a clean status before the window
|
|
662
|
-
elapses, without printing any console output, fails with exit 13
|
|
663
|
-
|
|
668
|
+
elapses, without printing any console output, fails with exit 13.
|
|
669
|
+
Lines from mach's own log (the timestamped command echo) do not
|
|
664
670
|
count as output. A launch that exits silently never reached a window: a
|
|
665
671
|
stale `.parentlock`, or a profile whose run of SIGTERM-ended smoke runs
|
|
666
|
-
counts as a startup-crash streak (`toolkit.startup.recent_crashes`).
|
|
667
|
-
0.50.0 such a run passed as a clean exit.
|
|
672
|
+
counts as a startup-crash streak (`toolkit.startup.recent_crashes`).
|
|
668
673
|
|
|
669
674
|
A plain `run` without either flag keeps mach's `profile-default`. `mach run`'s
|
|
670
675
|
desktop parser has no `--profile` option (its `--profile/-P` belongs to the
|
package/docs/exit-codes.md
CHANGED
|
@@ -29,8 +29,7 @@ which error class produces each one.
|
|
|
29
29
|
|
|
30
30
|
Usage errors that commander detects itself (an unknown command, an unknown
|
|
31
31
|
or malformed option, a missing required argument) never reach a command
|
|
32
|
-
action.
|
|
33
|
-
and printed no refusal envelope under `--json`. `createProgram` now installs
|
|
32
|
+
action. `createProgram` installs
|
|
34
33
|
commander's `exitOverride()`, and the entry point maps the resulting
|
|
35
34
|
`CommanderError` to `INVALID_ARGUMENT` (8) with the standard envelope on
|
|
36
35
|
stdout. `--help` and `--version` take the same path and still exit 0, and so
|
|
@@ -46,10 +45,10 @@ action.
|
|
|
46
45
|
change something, and a retry may then help. `INTERNAL_ERROR` means nothing
|
|
47
46
|
they could change would have helped. Escalate it, do not retry.
|
|
48
47
|
|
|
49
|
-
**Red, never ran, or thrown away.** These are three different facts,
|
|
50
|
-
|
|
48
|
+
**Red, never ran, or thrown away.** These are three different facts, each
|
|
49
|
+
with its own code.
|
|
51
50
|
|
|
52
|
-
- `BUILD_ERROR` (5) is a suite that failed.
|
|
51
|
+
- `BUILD_ERROR` (5) is a suite that failed. It is thrown as
|
|
53
52
|
`TestFailureError`, which keeps the code but carries test remedies rather
|
|
54
53
|
than build ones (`--json` reports it as `test-failure`).
|
|
55
54
|
- `LOCK_TIMEOUT` (15) is a run that never started, because another FireForge
|
|
@@ -59,18 +58,16 @@ before 0.44.0 two of them shared exit 1.
|
|
|
59
58
|
`engine/` moved underneath it. The code may be perfectly green, so
|
|
60
59
|
reporting it as red is wrong.
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
them. The `FIREFORGE-VERDICT:` line's `reason=` key carries the same
|
|
61
|
+
Separate codes keep a summary line from showing opposite facts as the same
|
|
62
|
+
kind of failure, such as `FAIL - exit 1` beside `FAIL - exit 5`. The `FIREFORGE-VERDICT:` line's `reason=` key carries the same
|
|
65
63
|
distinction for humans.
|
|
66
64
|
|
|
67
65
|
`LockContentionError` backs every lock in FireForge (engine session, patch
|
|
68
66
|
directory, build, furnace), so all four exit 15. That is intentional: the
|
|
69
67
|
fact is the same whichever lock was contended.
|
|
70
68
|
|
|
71
|
-
**Interrupted or declined.**
|
|
72
|
-
|
|
73
|
-
not tell them apart. They are now distinct: an interrupt raises
|
|
69
|
+
**Interrupted or declined.** A Ctrl+C and a deliberate "no" at a
|
|
70
|
+
confirmation are distinct, so a script can tell them apart: an interrupt raises
|
|
74
71
|
`CancellationError` and exits 130, and a declined confirmation returns
|
|
75
72
|
normally and exits 0, because the run did what it was asked and the answer
|
|
76
73
|
was no.
|
package/docs/furnace.md
CHANGED
|
@@ -115,7 +115,7 @@ warning asking for the entry to be deleted. A run over one component judges
|
|
|
115
115
|
only that component's entries. `deploy` honours the same entries when it
|
|
116
116
|
validates, but leaves the staleness report to `validate`.
|
|
117
117
|
|
|
118
|
-
An entry never suppresses an error
|
|
118
|
+
An entry never suppresses an error: an error blocks apply,
|
|
119
119
|
and a review record cannot make a broken component deployable. The error
|
|
120
120
|
stays counted, and the entry is reported as a
|
|
121
121
|
`validation-exception-on-error` error until the finding is fixed and the
|
|
@@ -136,7 +136,7 @@ entries cover all of them:
|
|
|
136
136
|
}
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
An optional `file`
|
|
139
|
+
An optional `file` narrows an entry the same way to findings
|
|
140
140
|
in one module of the component, by file name. `hardcoded-text` names the
|
|
141
141
|
modules it found text in, so a vendored bundle whose bytes are pinned (and
|
|
142
142
|
so cannot carry a `furnace-ignore` comment) can be accepted while the
|
|
@@ -155,7 +155,7 @@ authored modules beside it keep the check. An entry names a `tag` or a
|
|
|
155
155
|
Accessibility checks judge the composed component: the host
|
|
156
156
|
`<tag>.mjs` and its companion modules (`<tag>-*.mjs`, tests and stories
|
|
157
157
|
left out) read as one source. Moving a template between the component's
|
|
158
|
-
modules therefore
|
|
158
|
+
modules therefore does not change its findings: a keyboard handler in a
|
|
159
159
|
companion covers an `@click` in the host, and an `@click` in a companion
|
|
160
160
|
is judged too. `hardcoded-text` judges each module on its own, so a
|
|
161
161
|
`// furnace-ignore: hardcoded-text` comment covers the file it is in, not
|
|
@@ -25,7 +25,7 @@ command, read the decision table at the bottom first.
|
|
|
25
25
|
exception: it writes nothing, runs its git plumbing on a private index
|
|
26
26
|
(so even the `--intent-to-add` staging an untracked binary needs never
|
|
27
27
|
reaches the shared `.git/index`), and serializes only against other dry
|
|
28
|
-
runs, so a preview
|
|
28
|
+
runs, so a preview does not queue behind a peer's build or test run.
|
|
29
29
|
|
|
30
30
|
3. **A furnace mutation that does not finish restores the engine or says
|
|
31
31
|
so.** Both a signal (SIGINT or SIGTERM) and a thrown error trigger a
|
|
@@ -33,14 +33,11 @@ command, read the decision table at the bottom first.
|
|
|
33
33
|
`pendingRepair` marker blocks all further furnace mutations until
|
|
34
34
|
`fireforge doctor --repair-furnace` reconciles.
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
it rolls back on collected `result.errors` and `stepErrors`, but a throw
|
|
42
|
-
from its pre-loop or post-loop work escaped both. The wrapper now runs
|
|
43
|
-
cleanups, restores the journal, and rethrows the original error. A
|
|
36
|
+
On a thrown error `runFurnaceMutation` runs cleanups, restores the
|
|
37
|
+
journal, and rethrows the original error, so a throw outside a body's own
|
|
38
|
+
catch does not leave the checkout torn with no marker. `applyAllComponents`
|
|
39
|
+
rolls back on collected `result.errors` and `stepErrors`, but a throw from
|
|
40
|
+
its pre-loop or post-loop work escapes both and relies on the wrapper. A
|
|
44
41
|
rollback failure becomes a marker plus a warning, never a replacement
|
|
45
42
|
error.
|
|
46
43
|
|
|
@@ -70,17 +67,15 @@ command, read the decision table at the bottom first.
|
|
|
70
67
|
refusal on structural conflicts (`--force-unsafe` to override), and a
|
|
71
68
|
JSONL history entry appended only after the mutation succeeded. This
|
|
72
69
|
covers metadata mutations too: `patch tier` and `patch lint-ignore` route
|
|
73
|
-
through `confirmDestructive`.
|
|
74
|
-
prompting, so the flag only showed up in the history record. Enforced by
|
|
70
|
+
through `confirmDestructive`. Enforced by
|
|
75
71
|
`patch-tier-and-lint-ignore.integration.test.ts`.
|
|
76
72
|
|
|
77
73
|
The history log is write-only: FireForge appends to it and no command
|
|
78
74
|
reads it back, so nothing depends on its contents or location. It lives
|
|
79
75
|
at `.fireforge/history.jsonl` (or `fireforge.json#history.path`), outside
|
|
80
|
-
the tracked patch queue.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
overwriting either. Each record carries `invocationId` (one per FireForge
|
|
76
|
+
the tracked patch queue. If `patches/.fireforge-history.jsonl` exists,
|
|
77
|
+
the next append moves it there, and appends its records when both exist
|
|
78
|
+
rather than overwriting either. Each record carries `invocationId` (one per FireForge
|
|
84
79
|
process), `pid`, `ppid`, and `sessionId` when `FIREFORGE_SESSION_ID` is
|
|
85
80
|
set, so a session sharing the checkout can select its own lines.
|
|
86
81
|
Enforced by `history-log-file.test.ts`.
|
|
@@ -117,14 +112,14 @@ command, read the decision table at the bottom first.
|
|
|
117
112
|
and `tree remove` refuses while a live PID holds a tree lock and checks
|
|
118
113
|
that its `rm -rf` target is contained in the tree path.
|
|
119
114
|
|
|
120
|
-
In-tree `test`
|
|
115
|
+
In-tree `test` is the one conditional carve-out, and it is
|
|
121
116
|
marker-gated. mach objdirs embed absolute `topsrcdir` and `topobjdir`
|
|
122
117
|
paths, so `tree create --with-objdir` rewrites the cloned objdir's
|
|
123
118
|
`mozinfo.json` to the tree using the same safe-relocation rewriter that
|
|
124
119
|
`build --rewrite-mozinfo` uses, scrubs the cloned `_virtualenvs` (they
|
|
125
120
|
carry primary shebangs, and mach rebuilds them in-tree), and runs
|
|
126
121
|
`mach configure` inside the tree so the configure-generated root files are
|
|
127
|
-
regenerated against the tree's paths rather than keeping the primary's.
|
|
122
|
+
regenerated against the tree's paths rather than keeping the primary's.
|
|
128
123
|
Before configure, relocation rewrites old-source symlinks, `.pp`/`.d`,
|
|
129
124
|
FasterMake and Cargo fingerprint metadata, and removes copied
|
|
130
125
|
`config.statusd/*/config.track` inventories. Those inventories contain
|
|
@@ -151,14 +146,14 @@ command, read the decision table at the bottom first.
|
|
|
151
146
|
**Both halves of that enforcement fail closed on an unreadable state,
|
|
152
147
|
because "we cannot tell" is not "there is nothing there."** A marker that
|
|
153
148
|
exists but does not parse reports `corrupt`, not `absent`, and refuses the
|
|
154
|
-
command. Reading it as absent
|
|
155
|
-
set on the strength of a file that failed to parse. A lock directory whose
|
|
149
|
+
command. Reading it as absent would grant a snapshot the full mutating
|
|
150
|
+
command set on the strength of a file that failed to parse. A lock directory whose
|
|
156
151
|
owner cannot be identified reports `unknown`, not free, and refuses
|
|
157
|
-
removal.
|
|
152
|
+
removal. `withFileLock` treats its owner-record write as
|
|
158
153
|
fatal (`writeLockOwner` in `file-lock-owner.ts` removes the just-created
|
|
159
154
|
directory and throws a `GeneralError` if the record cannot be written or
|
|
160
|
-
does not read back as written), so an owner-less lock is only
|
|
161
|
-
|
|
155
|
+
does not read back as written), so an owner-less lock is left only by a
|
|
156
|
+
crash inside that write or by a holder that never wrote a record. It is refused,
|
|
162
157
|
for the same reason. The one exception is a lock directory that vanished
|
|
163
158
|
between the probe and the owner read: that is a clean release, and reads
|
|
164
159
|
as free.
|
|
@@ -168,7 +163,7 @@ command, read the decision table at the bottom first.
|
|
|
168
163
|
refusal spares the read-only commands that are unconditionally allowed
|
|
169
164
|
(`status`, `lint`, `typecheck`, `verify`): their verdict never consults
|
|
170
165
|
marker fields, so an unreadable marker cannot change their answer, and
|
|
171
|
-
blocking them
|
|
166
|
+
blocking them would leave the operator unable to diagnose the very tree that
|
|
172
167
|
needs inspecting. `conditional` verdicts can write, and stay refused.
|
|
173
168
|
Enforced by `tree-guard.test.ts` (verdict drift gate and corrupt-marker
|
|
174
169
|
refusal), `tree-store.integration.test.ts` (marker tri-state,
|
|
@@ -208,7 +203,7 @@ command, read the decision table at the bottom first.
|
|
|
208
203
|
`GIT_INDEX_FILE` from the repository's own index so that every refresh
|
|
209
204
|
lands there and is discarded. `typecheck` additionally ignores a
|
|
210
205
|
jsconfig's own `incremental` and `tsBuildInfoFile`, so no sidecar is
|
|
211
|
-
written under `engine/`. Its incremental build info
|
|
206
|
+
written under `engine/`. Its incremental build info lives in the
|
|
212
207
|
project's `.fireforge/typecheck/`, outside the engine. The scope fails open, meaning an unresolvable git dir
|
|
213
208
|
simply does not install it, and it is not reentrant. This exists so that
|
|
214
209
|
invariant 8 stays evidential: a concurrent `fireforge test` must not be
|
|
@@ -221,16 +216,14 @@ command, read the decision table at the bottom first.
|
|
|
221
216
|
in `<lock>.waiters/` named `<startedAtMs>-<pid>-<uuid>` and deregisters in
|
|
222
217
|
a `finally` that covers both outcomes: acquired the lock, or timed out.
|
|
223
218
|
A newcomer that finds live tickets takes one before trying the lock at
|
|
224
|
-
all.
|
|
219
|
+
all. The tickets decide the grant: only the waiter with no
|
|
225
220
|
live ticket ahead of it (arrival time, then ticket name) attempts the
|
|
226
|
-
lock, so "You are next" is a promise.
|
|
227
|
-
and a waiter whose poll had backed off lost each free moment to later
|
|
228
|
-
arrivals. Because a ticket now blocks the queue, a dead one must not: a
|
|
221
|
+
lock, so "You are next" is a promise. Because a ticket blocks the queue, a dead one must not: a
|
|
229
222
|
ticket whose PID is gone (or reused, where the start tick can tell) is
|
|
230
223
|
skipped and removed, and one its owner has not refreshed for 30 s (every
|
|
231
224
|
waiter rewrites its ticket every 5 s) is skipped, which covers a stopped
|
|
232
225
|
waiter and PID reuse elsewhere. A registry that cannot be written falls
|
|
233
|
-
back to
|
|
226
|
+
back to unordered contention rather than failing an acquisition.
|
|
234
227
|
This applies to every `withFileLock` lock: the engine-session, patch,
|
|
235
228
|
furnace and build locks among them. `fireforge status --lock` and the
|
|
236
229
|
`--wait-lock` progress lines read it, and the lines name the ordering
|
|
@@ -258,7 +251,7 @@ command, read the decision table at the bottom first.
|
|
|
258
251
|
Enforced by `patch-manifest-repair.test.ts` (real temp queues) and the
|
|
259
252
|
repair cases in `doctor.test.ts`.
|
|
260
253
|
|
|
261
|
-
## Lock release
|
|
254
|
+
## Lock release
|
|
262
255
|
|
|
263
256
|
`releaseLockIfOwned(lockPath)` in `src/core/file-lock.ts` is the
|
|
264
257
|
ownership-checked removal for callers that hold no acquisition token.
|
|
@@ -266,13 +259,12 @@ Currently that is the signal-time furnace sweeper
|
|
|
266
259
|
(`forceReleaseFurnaceLocksForActiveOperations`). It verifies the PID before
|
|
267
260
|
removing, which is the half of `releaseLock`'s guard a sweeper can still
|
|
268
261
|
perform: the sweeper knows which lock paths its own operations opened, but
|
|
269
|
-
not the per-acquisition UUID they minted.
|
|
262
|
+
not the per-acquisition UUID they minted. A bare `rm` could
|
|
270
263
|
delete a lock that a different process had acquired in the window between our
|
|
271
264
|
operation dying and the sweep running.
|
|
272
265
|
|
|
273
266
|
`completeJournalRollback` in `src/core/furnace-operation.ts` owns the
|
|
274
|
-
mutation-body rollback sequence that eight furnace commands
|
|
275
|
-
duplicated verbatim. The ordering is the invariant: `markRolledBack()` runs
|
|
267
|
+
mutation-body rollback sequence that eight furnace commands share. The ordering is the invariant: `markRolledBack()` runs
|
|
276
268
|
before the restore, so a restore that itself fails does not leave the
|
|
277
269
|
lifecycle wrapper replaying the same journal on the way out, and the original
|
|
278
270
|
error is rethrown unless the rollback is what failed.
|
|
@@ -297,7 +289,7 @@ seconds while waiting, so a holder dying mid-wait cannot strand waiters until
|
|
|
297
289
|
The owner-record write is fatal. A failed or unverifiable write releases the
|
|
298
290
|
just-created lock and throws a `GeneralError` instead of running the
|
|
299
291
|
operation. Without that, a lock with no readable owner is reaped by the age
|
|
300
|
-
heuristic after 5 minutes, which for a multi-hour build
|
|
292
|
+
heuristic after 5 minutes, which for a multi-hour build would mean a second holder
|
|
301
293
|
inside the critical section. Covered by `file-lock.test.ts`, "owner record
|
|
302
294
|
write at acquisition": write failure, corrupt read-back, recorded acquisition
|
|
303
295
|
time.
|
|
@@ -312,8 +304,7 @@ other layer.
|
|
|
312
304
|
Wait ergonomics are opt-in: `pollMaxMs` (the poll interval doubles from
|
|
313
305
|
`pollMs` up to the cap) and `waitProgressMs` with `onWaitProgress` (a periodic
|
|
314
306
|
progress callback carrying the holder's PID, liveness, and owner-metadata
|
|
315
|
-
lines from the pid file). All three are inert when unset
|
|
316
|
-
keep byte-identical behavior. Within one poll iteration a due progress probe
|
|
307
|
+
lines from the pid file). All three are inert when unset. Within one poll iteration a due progress probe
|
|
317
308
|
runs before the deadline check, so a wait that times out has always reported
|
|
318
309
|
the holder at least once when its budget exceeds `waitProgressMs`, however
|
|
319
310
|
slow the host (`file-lock.test.ts`, "budget shorter than one iteration").
|
|
@@ -321,8 +312,8 @@ slow the host (`file-lock.test.ts`, "budget shorter than one iteration").
|
|
|
321
312
|
### `src/core/file-lock-owner.ts`
|
|
322
313
|
|
|
323
314
|
The owner record (the `pid` file) itself: its format (PID, token,
|
|
324
|
-
`acquired-at-ms=` and `start-tick=` lines, plus free-form metadata
|
|
325
|
-
|
|
315
|
+
`acquired-at-ms=` and `start-tick=` lines, plus free-form metadata; a record
|
|
316
|
+
without the mechanical lines parses too), the write-and-verify
|
|
326
317
|
contract described above (a read-back that errors is retried before it counts
|
|
327
318
|
as a failed write, while a missing or mismatching record fails immediately),
|
|
328
319
|
and PID-reuse liveness.
|
|
@@ -333,13 +324,13 @@ re-verification, status snapshot and timeout message uses. Beyond
|
|
|
333
324
|
tick (`/proc/self/stat` field 22), and the probe reads the candidate's tick
|
|
334
325
|
from `/proc/<pid>/stat`. A different tick means a different process, so the
|
|
335
326
|
lock is stale. A crashed build's PID handed to a long-lived daemon therefore
|
|
336
|
-
|
|
327
|
+
does not keep the dead lock honoured until the waiter's timeout. It uses
|
|
337
328
|
ticks rather than wall-clock times because `btime` moves with clock steps, and
|
|
338
329
|
a wall-clock comparison would reap a live holder after NTP steps the clock
|
|
339
330
|
forward. macOS and Windows have no cheap start-time source (a `ps` spawn per
|
|
340
331
|
poll is not worth it) and keep the PID-only answer, and so do records without
|
|
341
|
-
a start tick. Enforced by `file-lock-owner.test.ts`:
|
|
342
|
-
|
|
332
|
+
a start tick. Enforced by `file-lock-owner.test.ts`: parsing of records without the
|
|
333
|
+
mechanical lines, forged mechanical lines dropped, transient read-back error retried
|
|
343
334
|
versus persistent error versus mismatch, fake-procfs tick parsing, reused-PID
|
|
344
335
|
versus genuine-holder verdicts, stepped-clock immunity, and on Linux a
|
|
345
336
|
real-procfs `withFileLock` reap of a live-PID stale record.
|
|
@@ -360,9 +351,9 @@ log or the engine-session lock shows one in the window (`re-export-purity-scope.
|
|
|
360
351
|
|
|
361
352
|
Contention fails fast after about a second by default, with the fixed message
|
|
362
353
|
"Another FireForge engine-mutating command is already running. Wait for it to
|
|
363
|
-
finish, then retry `<command>`."
|
|
364
|
-
|
|
365
|
-
`--wait-lock [seconds]` (bare flag means 60, valid 1 to
|
|
354
|
+
finish, then retry `<command>`." The same message also closes the bounded
|
|
355
|
+
wait. Each of those commands accepts
|
|
356
|
+
`--wait-lock [seconds]` (bare flag means 60, valid 1 to 86400) for a bounded
|
|
366
357
|
operator wait instead: polling backs off exponentially from 100 ms to 2 s, and
|
|
367
358
|
roughly every 5 s a progress line identifies the holder from the lock's
|
|
368
359
|
owner-metadata lines, in the form `Waiting for the FireForge engine lock held
|
|
@@ -432,7 +423,7 @@ hold it.
|
|
|
432
423
|
The destructive-operation contract: `confirmDestructive` (summary, prompt,
|
|
433
424
|
`--yes`, `--dry-run`, conflict refusal, `--force-unsafe`) and the
|
|
434
425
|
append-only history log (`src/core/history-log-file.ts` resolves its path,
|
|
435
|
-
|
|
426
|
+
moves a `patches/.fireforge-history.jsonl` it finds to that path, and stamps each
|
|
436
427
|
record's invocation and session).
|
|
437
428
|
|
|
438
429
|
### `src/core/tree-store.ts`
|