footprintjs 10.1.0 → 10.2.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.
Files changed (64) hide show
  1. package/CLAUDE.md +18 -0
  2. package/dist/esm/index.d.ts +2 -0
  3. package/dist/esm/index.js +1 -1
  4. package/dist/esm/lib/attempt/category.d.ts +6 -0
  5. package/dist/esm/lib/attempt/category.js +26 -2
  6. package/dist/esm/lib/attempt/runner.d.ts +3 -1
  7. package/dist/esm/lib/attempt/runner.js +26 -6
  8. package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +36 -6
  9. package/dist/esm/lib/engine/handlers/DeciderHandler.js +9 -5
  10. package/dist/esm/lib/engine/handlers/SelectorHandler.js +6 -5
  11. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +5 -2
  12. package/dist/esm/lib/engine/handlers/commitStage.d.ts +7 -0
  13. package/dist/esm/lib/engine/handlers/commitStage.js +22 -4
  14. package/dist/esm/lib/engine/handlers/stageError.d.ts +2 -0
  15. package/dist/esm/lib/engine/handlers/stageError.js +13 -1
  16. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.d.ts +2 -1
  17. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +6 -2
  18. package/dist/esm/lib/engine/narrative/types.d.ts +4 -1
  19. package/dist/esm/lib/engine/narrative/types.js +1 -1
  20. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +14 -6
  21. package/dist/esm/lib/errors/terminalFailure.d.ts +29 -0
  22. package/dist/esm/lib/errors/terminalFailure.js +60 -0
  23. package/dist/esm/lib/memory/StageContext.d.ts +14 -0
  24. package/dist/esm/lib/memory/StageContext.js +32 -1
  25. package/dist/esm/lib/memory/attention.d.ts +26 -0
  26. package/dist/esm/lib/memory/attention.js +171 -0
  27. package/dist/esm/lib/memory/frameTypes.d.ts +8 -0
  28. package/dist/esm/lib/memory/frameTypes.js +1 -1
  29. package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +14 -0
  30. package/dist/esm/lib/recorder/ControlDepRecorder.js +18 -1
  31. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +4 -0
  32. package/dist/esm/lib/runner/FlowChartExecutor.js +163 -127
  33. package/dist/index.js +1 -1
  34. package/dist/lib/attempt/category.js +27 -2
  35. package/dist/lib/attempt/runner.js +25 -5
  36. package/dist/lib/engine/handlers/ChildrenExecutor.js +36 -6
  37. package/dist/lib/engine/handlers/DeciderHandler.js +7 -3
  38. package/dist/lib/engine/handlers/SelectorHandler.js +4 -3
  39. package/dist/lib/engine/handlers/SubflowExecutor.js +5 -2
  40. package/dist/lib/engine/handlers/commitStage.js +24 -5
  41. package/dist/lib/engine/handlers/stageError.js +15 -2
  42. package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +6 -2
  43. package/dist/lib/engine/narrative/types.js +1 -1
  44. package/dist/lib/engine/traversal/FlowchartTraverser.js +12 -4
  45. package/dist/lib/errors/terminalFailure.js +64 -0
  46. package/dist/lib/memory/StageContext.js +32 -1
  47. package/dist/lib/memory/attention.js +175 -0
  48. package/dist/lib/memory/frameTypes.js +1 -1
  49. package/dist/lib/recorder/ControlDepRecorder.js +18 -1
  50. package/dist/lib/runner/FlowChartExecutor.js +163 -127
  51. package/dist/types/index.d.ts +2 -0
  52. package/dist/types/lib/attempt/category.d.ts +6 -0
  53. package/dist/types/lib/attempt/runner.d.ts +3 -1
  54. package/dist/types/lib/engine/handlers/commitStage.d.ts +7 -0
  55. package/dist/types/lib/engine/handlers/stageError.d.ts +2 -0
  56. package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +2 -1
  57. package/dist/types/lib/engine/narrative/types.d.ts +4 -1
  58. package/dist/types/lib/errors/terminalFailure.d.ts +29 -0
  59. package/dist/types/lib/memory/StageContext.d.ts +14 -0
  60. package/dist/types/lib/memory/attention.d.ts +26 -0
  61. package/dist/types/lib/memory/frameTypes.d.ts +8 -0
  62. package/dist/types/lib/recorder/ControlDepRecorder.d.ts +14 -0
  63. package/dist/types/lib/runner/FlowChartExecutor.d.ts +4 -0
  64. package/package.json +6 -6
@@ -0,0 +1,29 @@
1
+ import type { AttemptCategory } from '../attempt/types.js';
2
+ /** Safe context for the failure that escaped a native run; never the exception itself. */
3
+ export interface TerminalFailureContext {
4
+ readonly category: AttemptCategory;
5
+ /** Absent when no native stage owns this failure (for example input admission or run retention). */
6
+ readonly stage?: {
7
+ readonly runId: string;
8
+ readonly runtimeStageId: string;
9
+ };
10
+ }
11
+ /**
12
+ * @internal One execution chain's failure ownership, not an error history.
13
+ * Sequential frames share it; forks and subflows do not. Only an explicitly
14
+ * selected escaping rejection may transfer ownership to its parent chain.
15
+ * Raw identity lives in a private slot and is released when the leg settles.
16
+ */
17
+ export declare class NativeFailureState {
18
+ #private;
19
+ get result(): TerminalFailureContext | undefined;
20
+ capture(error: unknown, category: AttemptCategory, stage: NonNullable<TerminalFailureContext['stage']>): void;
21
+ /** A runner already classified this exact native failure before it was served. */
22
+ owns(error: unknown): boolean;
23
+ adopt(child: NativeFailureState, error: unknown): void;
24
+ /** Publish at the run event boundary; keep ownership until executor settlement. */
25
+ announce(error: unknown): TerminalFailureContext;
26
+ finish(error: unknown): void;
27
+ /** Success or pause has no terminal failure. Also closes contained branch ownership. */
28
+ complete(): void;
29
+ }
@@ -0,0 +1,60 @@
1
+ const UNKNOWN = Object.freeze({ category: 'unknown' });
2
+ /**
3
+ * @internal One execution chain's failure ownership, not an error history.
4
+ * Sequential frames share it; forks and subflows do not. Only an explicitly
5
+ * selected escaping rejection may transfer ownership to its parent chain.
6
+ * Raw identity lives in a private slot and is released when the leg settles.
7
+ */
8
+ export class NativeFailureState {
9
+ #pending;
10
+ #result;
11
+ #sealed = false;
12
+ get result() {
13
+ return this.#result;
14
+ }
15
+ capture(error, category, stage) {
16
+ if (this.#sealed)
17
+ return;
18
+ this.#pending = {
19
+ error,
20
+ context: Object.freeze({
21
+ category,
22
+ stage: Object.freeze({ runId: stage.runId, runtimeStageId: stage.runtimeStageId }),
23
+ }),
24
+ };
25
+ }
26
+ /** A runner already classified this exact native failure before it was served. */
27
+ owns(error) {
28
+ return this.#pending !== undefined && Object.is(this.#pending.error, error);
29
+ }
30
+ adopt(child, error) {
31
+ if (!this.#sealed)
32
+ this.#pending = child.owns(error) ? child.#pending : undefined;
33
+ child.complete();
34
+ }
35
+ /** Publish at the run event boundary; keep ownership until executor settlement. */
36
+ announce(error) {
37
+ if (this.#sealed)
38
+ return this.#result ?? UNKNOWN;
39
+ const pending = this.#pending;
40
+ const context = pending && Object.is(pending.error, error) ? pending.context : UNKNOWN;
41
+ this.#result = context;
42
+ return context;
43
+ }
44
+ finish(error) {
45
+ if (this.#sealed)
46
+ return;
47
+ this.announce(error);
48
+ this.#pending = undefined;
49
+ this.#sealed = true;
50
+ }
51
+ /** Success or pause has no terminal failure. Also closes contained branch ownership. */
52
+ complete() {
53
+ if (this.#sealed)
54
+ return;
55
+ this.#pending = undefined;
56
+ this.#result = undefined;
57
+ this.#sealed = true;
58
+ }
59
+ }
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVybWluYWxGYWlsdXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9lcnJvcnMvdGVybWluYWxGYWlsdXJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVlBLE1BQU0sT0FBTyxHQUEyQixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7QUFFL0U7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBQzdCLFFBQVEsQ0FBdUQ7SUFDL0QsT0FBTyxDQUEwQjtJQUNqQyxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBRWhCLElBQUksTUFBTTtRQUNSLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRUQsT0FBTyxDQUFDLEtBQWMsRUFBRSxRQUF5QixFQUFFLEtBQW1EO1FBQ3BHLElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUc7WUFDZCxLQUFLO1lBQ0wsT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUM7Z0JBQ3JCLFFBQVE7Z0JBQ1IsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2FBQ25GLENBQUM7U0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELGtGQUFrRjtJQUNsRixJQUFJLENBQUMsS0FBYztRQUNqQixPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUF5QixFQUFFLEtBQWM7UUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDbEYsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFRCxtRkFBbUY7SUFDbkYsUUFBUSxDQUFDLEtBQWM7UUFDckIsSUFBSSxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUM7UUFDakQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUM5QixNQUFNLE9BQU8sR0FBRyxPQUFPLElBQUksTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDdkYsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFjO1FBQ25CLElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUM7UUFDMUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFDdEIsQ0FBQztJQUVELHdGQUF3RjtJQUN4RixRQUFRO1FBQ04sSUFBSSxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU87UUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUM7UUFDMUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUM7UUFDekIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFDdEIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBBdHRlbXB0Q2F0ZWdvcnkgfSBmcm9tICcuLi9hdHRlbXB0L3R5cGVzLmpzJztcblxuLyoqIFNhZmUgY29udGV4dCBmb3IgdGhlIGZhaWx1cmUgdGhhdCBlc2NhcGVkIGEgbmF0aXZlIHJ1bjsgbmV2ZXIgdGhlIGV4Y2VwdGlvbiBpdHNlbGYuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlcm1pbmFsRmFpbHVyZUNvbnRleHQge1xuICByZWFkb25seSBjYXRlZ29yeTogQXR0ZW1wdENhdGVnb3J5O1xuICAvKiogQWJzZW50IHdoZW4gbm8gbmF0aXZlIHN0YWdlIG93bnMgdGhpcyBmYWlsdXJlIChmb3IgZXhhbXBsZSBpbnB1dCBhZG1pc3Npb24gb3IgcnVuIHJldGVudGlvbikuICovXG4gIHJlYWRvbmx5IHN0YWdlPzoge1xuICAgIHJlYWRvbmx5IHJ1bklkOiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgcnVudGltZVN0YWdlSWQ6IHN0cmluZztcbiAgfTtcbn1cblxuY29uc3QgVU5LTk9XTjogVGVybWluYWxGYWlsdXJlQ29udGV4dCA9IE9iamVjdC5mcmVlemUoeyBjYXRlZ29yeTogJ3Vua25vd24nIH0pO1xuXG4vKipcbiAqIEBpbnRlcm5hbCBPbmUgZXhlY3V0aW9uIGNoYWluJ3MgZmFpbHVyZSBvd25lcnNoaXAsIG5vdCBhbiBlcnJvciBoaXN0b3J5LlxuICogU2VxdWVudGlhbCBmcmFtZXMgc2hhcmUgaXQ7IGZvcmtzIGFuZCBzdWJmbG93cyBkbyBub3QuIE9ubHkgYW4gZXhwbGljaXRseVxuICogc2VsZWN0ZWQgZXNjYXBpbmcgcmVqZWN0aW9uIG1heSB0cmFuc2ZlciBvd25lcnNoaXAgdG8gaXRzIHBhcmVudCBjaGFpbi5cbiAqIFJhdyBpZGVudGl0eSBsaXZlcyBpbiBhIHByaXZhdGUgc2xvdCBhbmQgaXMgcmVsZWFzZWQgd2hlbiB0aGUgbGVnIHNldHRsZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBOYXRpdmVGYWlsdXJlU3RhdGUge1xuICAjcGVuZGluZz86IHsgZXJyb3I6IHVua25vd247IGNvbnRleHQ6IFRlcm1pbmFsRmFpbHVyZUNvbnRleHQgfTtcbiAgI3Jlc3VsdD86IFRlcm1pbmFsRmFpbHVyZUNvbnRleHQ7XG4gICNzZWFsZWQgPSBmYWxzZTtcblxuICBnZXQgcmVzdWx0KCk6IFRlcm1pbmFsRmFpbHVyZUNvbnRleHQgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLiNyZXN1bHQ7XG4gIH1cblxuICBjYXB0dXJlKGVycm9yOiB1bmtub3duLCBjYXRlZ29yeTogQXR0ZW1wdENhdGVnb3J5LCBzdGFnZTogTm9uTnVsbGFibGU8VGVybWluYWxGYWlsdXJlQ29udGV4dFsnc3RhZ2UnXT4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy4jc2VhbGVkKSByZXR1cm47XG4gICAgdGhpcy4jcGVuZGluZyA9IHtcbiAgICAgIGVycm9yLFxuICAgICAgY29udGV4dDogT2JqZWN0LmZyZWV6ZSh7XG4gICAgICAgIGNhdGVnb3J5LFxuICAgICAgICBzdGFnZTogT2JqZWN0LmZyZWV6ZSh7IHJ1bklkOiBzdGFnZS5ydW5JZCwgcnVudGltZVN0YWdlSWQ6IHN0YWdlLnJ1bnRpbWVTdGFnZUlkIH0pLFxuICAgICAgfSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBBIHJ1bm5lciBhbHJlYWR5IGNsYXNzaWZpZWQgdGhpcyBleGFjdCBuYXRpdmUgZmFpbHVyZSBiZWZvcmUgaXQgd2FzIHNlcnZlZC4gKi9cbiAgb3ducyhlcnJvcjogdW5rbm93bik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLiNwZW5kaW5nICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0LmlzKHRoaXMuI3BlbmRpbmcuZXJyb3IsIGVycm9yKTtcbiAgfVxuXG4gIGFkb3B0KGNoaWxkOiBOYXRpdmVGYWlsdXJlU3RhdGUsIGVycm9yOiB1bmtub3duKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLiNzZWFsZWQpIHRoaXMuI3BlbmRpbmcgPSBjaGlsZC5vd25zKGVycm9yKSA/IGNoaWxkLiNwZW5kaW5nIDogdW5kZWZpbmVkO1xuICAgIGNoaWxkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKiogUHVibGlzaCBhdCB0aGUgcnVuIGV2ZW50IGJvdW5kYXJ5OyBrZWVwIG93bmVyc2hpcCB1bnRpbCBleGVjdXRvciBzZXR0bGVtZW50LiAqL1xuICBhbm5vdW5jZShlcnJvcjogdW5rbm93bik6IFRlcm1pbmFsRmFpbHVyZUNvbnRleHQge1xuICAgIGlmICh0aGlzLiNzZWFsZWQpIHJldHVybiB0aGlzLiNyZXN1bHQgPz8gVU5LTk9XTjtcbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy4jcGVuZGluZztcbiAgICBjb25zdCBjb250ZXh0ID0gcGVuZGluZyAmJiBPYmplY3QuaXMocGVuZGluZy5lcnJvciwgZXJyb3IpID8gcGVuZGluZy5jb250ZXh0IDogVU5LTk9XTjtcbiAgICB0aGlzLiNyZXN1bHQgPSBjb250ZXh0O1xuICAgIHJldHVybiBjb250ZXh0O1xuICB9XG5cbiAgZmluaXNoKGVycm9yOiB1bmtub3duKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuI3NlYWxlZCkgcmV0dXJuO1xuICAgIHRoaXMuYW5ub3VuY2UoZXJyb3IpO1xuICAgIHRoaXMuI3BlbmRpbmcgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy4jc2VhbGVkID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBTdWNjZXNzIG9yIHBhdXNlIGhhcyBubyB0ZXJtaW5hbCBmYWlsdXJlLiBBbHNvIGNsb3NlcyBjb250YWluZWQgYnJhbmNoIG93bmVyc2hpcC4gKi9cbiAgY29tcGxldGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuI3NlYWxlZCkgcmV0dXJuO1xuICAgIHRoaXMuI3BlbmRpbmcgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy4jcmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuI3NlYWxlZCA9IHRydWU7XG4gIH1cbn1cbiJdfQ==
@@ -15,6 +15,7 @@ import type { CommitPhase, EmitSourcePosition, UntrackedSource } from 'foottrace
15
15
  import type { EventLog, SharedMemory } from 'foottrace/write';
16
16
  import type { AttemptContext, AttemptRecord, AttemptSummary, LateWrite } from '../attempt/types.js';
17
17
  import type { StructuredErrorInfo } from '../errors/errorInfo.js';
18
+ import { type TerminalFailureContext, NativeFailureState } from '../errors/terminalFailure.js';
18
19
  import { type DiagnosticChannel, DiagnosticCollector } from './DiagnosticCollector.js';
19
20
  import type { FlowControlType, StageSnapshot } from './frameTypes.js';
20
21
  import type { RedactionVerdict } from './redaction.js';
@@ -27,6 +28,13 @@ import type { RunPolicy } from './runPolicy.js';
27
28
  */
28
29
  export declare const MAX_CALL_RECORDS = 1000;
29
30
  export declare class StageContext {
31
+ #private;
32
+ /** @internal Ownership of an escaping failure. Shared only by sequential frames, never serialized. */
33
+ failureState: NativeFailureState;
34
+ /** @internal The native frame stamp, independent of mutable recorder event context. */
35
+ get failureIdentity(): NonNullable<TerminalFailureContext['stage']> | undefined;
36
+ /** @internal Stamped before observers; never inherited by another frame or persisted. */
37
+ bindFailureIdentity(runId: string, runtimeStageId: string): void;
30
38
  /**
31
39
  * The record half of this frame (`RecordFrame.ts`, L3, C3): the heap and,
32
40
  * when the run keeps them, the redacted mirror and the log; the address;
@@ -156,6 +164,8 @@ export declare class StageContext {
156
164
  private _attempts?;
157
165
  /** The attempt series at a glance, stamped once when it ends. */
158
166
  private _attemptSummary?;
167
+ /** Facts collected for this execution only; retry discards deliberately keep them. */
168
+ private _attention?;
159
169
  /**
160
170
  * The attempt now running (P1b) — set by `StageRunner` before the scope is built, so the facade can hand it out
161
171
  * (`scope.$attempt()`) and fence its own attempt. Absent for a stage the attempt runner does not run.
@@ -485,6 +495,10 @@ export declare class StageContext {
485
495
  recordAttempt(record: AttemptRecord): void;
486
496
  /** Stamp the series' summary — once, when the runner ends the series. */
487
497
  endAttempts(summary: AttemptSummary): void;
498
+ /** Reset only at the node's execution stamp, never between attempts. */
499
+ beginAttention(): void;
500
+ /** Delegate the explicit retained-error fact; attention owns validation of its proof. */
501
+ markStageFailure(): void;
488
502
  /**
489
503
  * The crash-safe record (10.1, P6): an attempt that ended is noted in the run's sink AT ONCE, beside this frame's
490
504
  * log — so a process killed before the stage commits (mid-retry) still leaves every attempt that ended. The