@telora/daemon 0.22.160 → 0.22.181
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/build-info.json +10 -3
- package/dist/audit/audit-phase.d.ts +11 -1
- package/dist/audit/audit-phase.d.ts.map +1 -1
- package/dist/audit/audit-phase.js +2 -14
- package/dist/audit/audit-phase.js.map +1 -1
- package/dist/audit/audit-prompt.d.ts +7 -4
- package/dist/audit/audit-prompt.d.ts.map +1 -1
- package/dist/audit/audit-prompt.js +34 -23
- package/dist/audit/audit-prompt.js.map +1 -1
- package/dist/completion/advancement-stall-watchdog.d.ts +12 -0
- package/dist/completion/advancement-stall-watchdog.d.ts.map +1 -0
- package/dist/completion/advancement-stall-watchdog.js +79 -0
- package/dist/completion/advancement-stall-watchdog.js.map +1 -0
- package/dist/completion/arm-visible-progress-inputs.d.ts +51 -0
- package/dist/completion/arm-visible-progress-inputs.d.ts.map +1 -0
- package/dist/completion/arm-visible-progress-inputs.js +19 -0
- package/dist/completion/arm-visible-progress-inputs.js.map +1 -0
- package/dist/completion/commit-verdict-release.d.ts +37 -1
- package/dist/completion/commit-verdict-release.d.ts.map +1 -1
- package/dist/completion/commit-verdict-release.js +90 -15
- package/dist/completion/commit-verdict-release.js.map +1 -1
- package/dist/completion/delivery-advancement-guard.d.ts.map +1 -1
- package/dist/completion/delivery-advancement-guard.js +1 -0
- package/dist/completion/delivery-advancement-guard.js.map +1 -1
- package/dist/completion/event-entry-phases.d.ts.map +1 -1
- package/dist/completion/event-entry-phases.js +9 -2
- package/dist/completion/event-entry-phases.js.map +1 -1
- package/dist/completion/event-phases.d.ts +15 -8
- package/dist/completion/event-phases.d.ts.map +1 -1
- package/dist/completion/event-phases.js +26 -64
- package/dist/completion/event-phases.js.map +1 -1
- package/dist/completion/event.d.ts.map +1 -1
- package/dist/completion/event.js +7 -1
- package/dist/completion/event.js.map +1 -1
- package/dist/completion/review-exit-verdict-gate.d.ts +11 -5
- package/dist/completion/review-exit-verdict-gate.d.ts.map +1 -1
- package/dist/completion/review-exit-verdict-gate.js +6 -3
- package/dist/completion/review-exit-verdict-gate.js.map +1 -1
- package/dist/completion/shutdown-attribution.d.ts +107 -0
- package/dist/completion/shutdown-attribution.d.ts.map +1 -0
- package/dist/completion/shutdown-attribution.js +106 -0
- package/dist/completion/shutdown-attribution.js.map +1 -0
- package/dist/completion/team-lifecycle.d.ts.map +1 -1
- package/dist/completion/team-lifecycle.js +16 -0
- package/dist/completion/team-lifecycle.js.map +1 -1
- package/dist/delivery/commit-verdict-hold.d.ts.map +1 -1
- package/dist/delivery/commit-verdict-hold.js +2 -1
- package/dist/delivery/commit-verdict-hold.js.map +1 -1
- package/dist/delivery/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery/delivery-lifecycle.js +1 -0
- package/dist/delivery/delivery-lifecycle.js.map +1 -1
- package/dist/directive/directive-assembly.d.ts +19 -1
- package/dist/directive/directive-assembly.d.ts.map +1 -1
- package/dist/directive/directive-assembly.js +15 -3
- package/dist/directive/directive-assembly.js.map +1 -1
- package/dist/directive/directive-dispatch.d.ts +67 -2
- package/dist/directive/directive-dispatch.d.ts.map +1 -1
- package/dist/directive/directive-dispatch.js +188 -45
- package/dist/directive/directive-dispatch.js.map +1 -1
- package/dist/directive/directive-executor.d.ts +2 -2
- package/dist/directive/directive-executor.d.ts.map +1 -1
- package/dist/directive/directive-executor.js +49 -12
- package/dist/directive/directive-executor.js.map +1 -1
- package/dist/directive/directive-queue.d.ts.map +1 -1
- package/dist/directive/directive-queue.js +1 -0
- package/dist/directive/directive-queue.js.map +1 -1
- package/dist/directive/stage-tracker.d.ts +20 -0
- package/dist/directive/stage-tracker.d.ts.map +1 -1
- package/dist/directive/stage-tracker.js +29 -1
- package/dist/directive/stage-tracker.js.map +1 -1
- package/dist/directive/stranded-review-reroute.js +1 -1
- package/dist/directive/stranded-review-reroute.js.map +1 -1
- package/dist/focus/focus-engine.d.ts.map +1 -1
- package/dist/focus/focus-engine.js +5 -1
- package/dist/focus/focus-engine.js.map +1 -1
- package/dist/focus/focus-executor.d.ts.map +1 -1
- package/dist/focus/focus-executor.js +14 -3
- package/dist/focus/focus-executor.js.map +1 -1
- package/dist/focus/focus-phase.d.ts +11 -1
- package/dist/focus/focus-phase.d.ts.map +1 -1
- package/dist/focus/focus-phase.js +12 -2
- package/dist/focus/focus-phase.js.map +1 -1
- package/dist/focus/focus-team-state.js +1 -1
- package/dist/focus/listener-auto-advance.d.ts.map +1 -1
- package/dist/focus/listener-auto-advance.js +1 -0
- package/dist/focus/listener-auto-advance.js.map +1 -1
- package/dist/focus/listener-spawn.d.ts.map +1 -1
- package/dist/focus/listener-spawn.js +33 -10
- package/dist/focus/listener-spawn.js.map +1 -1
- package/dist/focus/listener.d.ts.map +1 -1
- package/dist/focus/listener.js +21 -8
- package/dist/focus/listener.js.map +1 -1
- package/dist/focus/live-arm-facts.d.ts +10 -0
- package/dist/focus/live-arm-facts.d.ts.map +1 -0
- package/dist/focus/live-arm-facts.js +47 -0
- package/dist/focus/live-arm-facts.js.map +1 -0
- package/dist/focus/pending-review-approved-head.d.ts +1 -1
- package/dist/focus/pending-review-approved-head.d.ts.map +1 -1
- package/dist/focus/pending-review-approved-head.js +4 -3
- package/dist/focus/pending-review-approved-head.js.map +1 -1
- package/dist/focus/recorded-new-intent.d.ts +81 -0
- package/dist/focus/recorded-new-intent.d.ts.map +1 -0
- package/dist/focus/recorded-new-intent.js +147 -0
- package/dist/focus/recorded-new-intent.js.map +1 -0
- package/dist/focus/stage-watermark-seeding.d.ts +39 -0
- package/dist/focus/stage-watermark-seeding.d.ts.map +1 -0
- package/dist/focus/stage-watermark-seeding.js +60 -0
- package/dist/focus/stage-watermark-seeding.js.map +1 -0
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts +19 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/wedge-watchdog.js +19 -3
- package/dist/focus-stage-lifecycle/wedge-watchdog.js.map +1 -1
- package/dist/prompt/focus-prompt-builder.d.ts +2 -1
- package/dist/prompt/focus-prompt-builder.d.ts.map +1 -1
- package/dist/prompt/focus-prompt-builder.js +10 -1
- package/dist/prompt/focus-prompt-builder.js.map +1 -1
- package/dist/prompt/team-prompt-base.d.ts.map +1 -1
- package/dist/prompt/team-prompt-base.js +4 -2
- package/dist/prompt/team-prompt-base.js.map +1 -1
- package/dist/prompt-sections/execution-sections.d.ts +22 -1
- package/dist/prompt-sections/execution-sections.d.ts.map +1 -1
- package/dist/prompt-sections/execution-sections.js +23 -2
- package/dist/prompt-sections/execution-sections.js.map +1 -1
- package/dist/prompt-sections/shared.d.ts +9 -0
- package/dist/prompt-sections/shared.d.ts.map +1 -1
- package/dist/prompt-sections/shared.js +2 -1
- package/dist/prompt-sections/shared.js.map +1 -1
- package/dist/queries/arm-covered-targets.d.ts +84 -0
- package/dist/queries/arm-covered-targets.d.ts.map +1 -0
- package/dist/queries/arm-covered-targets.js +129 -0
- package/dist/queries/arm-covered-targets.js.map +1 -0
- package/dist/queries/deliveries.d.ts +3 -0
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +10 -3
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/delivery-gate-state.d.ts +10 -0
- package/dist/queries/delivery-gate-state.d.ts.map +1 -1
- package/dist/queries/delivery-gate-state.js +2 -2
- package/dist/queries/delivery-gate-state.js.map +1 -1
- package/dist/queries/delivery-write-discipline.d.ts.map +1 -1
- package/dist/queries/delivery-write-discipline.js +2 -1
- package/dist/queries/delivery-write-discipline.js.map +1 -1
- package/dist/queries/directive-undelivered.d.ts +104 -0
- package/dist/queries/directive-undelivered.d.ts.map +1 -0
- package/dist/queries/directive-undelivered.js +162 -0
- package/dist/queries/directive-undelivered.js.map +1 -0
- package/dist/queries/focus-discovery.d.ts +16 -0
- package/dist/queries/focus-discovery.d.ts.map +1 -1
- package/dist/queries/focus-discovery.js +3 -0
- package/dist/queries/focus-discovery.js.map +1 -1
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +3 -1
- package/dist/queries/focuses.js.map +1 -1
- package/dist/queries/issues.d.ts.map +1 -1
- package/dist/queries/issues.js +1 -0
- package/dist/queries/issues.js.map +1 -1
- package/dist/queries/recorded-targets-record.d.ts +46 -0
- package/dist/queries/recorded-targets-record.d.ts.map +1 -0
- package/dist/queries/recorded-targets-record.js +29 -0
- package/dist/queries/recorded-targets-record.js.map +1 -0
- package/dist/queries/schemas.d.ts +4 -0
- package/dist/queries/schemas.d.ts.map +1 -1
- package/dist/queries/schemas.js +14 -0
- package/dist/queries/schemas.js.map +1 -1
- package/dist/queries/shared.js +1 -1
- package/dist/queries/verification.js +1 -1
- package/dist/queries/workflows.d.ts.map +1 -1
- package/dist/queries/workflows.js +1 -0
- package/dist/queries/workflows.js.map +1 -1
- package/dist/resolvers/assembly-engine.d.ts +13 -0
- package/dist/resolvers/assembly-engine.d.ts.map +1 -1
- package/dist/resolvers/assembly-engine.js +1 -1
- package/dist/resolvers/assembly-engine.js.map +1 -1
- package/dist/resolvers/compose/loop-delivery-index-compose.d.ts +23 -3
- package/dist/resolvers/compose/loop-delivery-index-compose.d.ts.map +1 -1
- package/dist/resolvers/compose/loop-delivery-index-compose.js +90 -43
- package/dist/resolvers/compose/loop-delivery-index-compose.js.map +1 -1
- package/dist/resolvers/delivery-listing.d.ts +27 -0
- package/dist/resolvers/delivery-listing.d.ts.map +1 -1
- package/dist/resolvers/delivery-listing.js +52 -36
- package/dist/resolvers/delivery-listing.js.map +1 -1
- package/dist/resolvers/loop-delivery-index.d.ts +8 -0
- package/dist/resolvers/loop-delivery-index.d.ts.map +1 -1
- package/dist/resolvers/loop-delivery-index.js +68 -7
- package/dist/resolvers/loop-delivery-index.js.map +1 -1
- package/dist/resolvers/shared/loop.d.ts +7 -0
- package/dist/resolvers/shared/loop.d.ts.map +1 -1
- package/dist/resolvers/shared/loop.js.map +1 -1
- package/dist/resolvers/shared/review-window-commits.d.ts.map +1 -1
- package/dist/resolvers/shared/review-window-commits.js +2 -1
- package/dist/resolvers/shared/review-window-commits.js.map +1 -1
- package/dist/spawn/helpers.d.ts.map +1 -1
- package/dist/spawn/helpers.js +4 -2
- package/dist/spawn/helpers.js.map +1 -1
- package/dist/spawn/lead-continuation.d.ts.map +1 -1
- package/dist/spawn/lead-continuation.js +8 -2
- package/dist/spawn/lead-continuation.js.map +1 -1
- package/dist/spawn/lead-send.d.ts +97 -0
- package/dist/spawn/lead-send.d.ts.map +1 -0
- package/dist/spawn/lead-send.js +80 -0
- package/dist/spawn/lead-send.js.map +1 -0
- package/dist/spawn/process-group-kill.d.ts.map +1 -1
- package/dist/spawn/process-group-kill.js +12 -1
- package/dist/spawn/process-group-kill.js.map +1 -1
- package/dist/spawn/process-spawn.d.ts.map +1 -1
- package/dist/spawn/process-spawn.js +6 -0
- package/dist/spawn/process-spawn.js.map +1 -1
- package/dist/spawn/prompt-assembly.d.ts +8 -0
- package/dist/spawn/prompt-assembly.d.ts.map +1 -1
- package/dist/spawn/prompt-assembly.js +2 -1
- package/dist/spawn/prompt-assembly.js.map +1 -1
- package/dist/spawn/spawn-decision.d.ts +25 -1
- package/dist/spawn/spawn-decision.d.ts.map +1 -1
- package/dist/spawn/spawn-decision.js +19 -3
- package/dist/spawn/spawn-decision.js.map +1 -1
- package/dist/spawn/worktree-session.d.ts +3 -0
- package/dist/spawn/worktree-session.d.ts.map +1 -1
- package/dist/spawn/worktree-session.js +2 -1
- package/dist/spawn/worktree-session.js.map +1 -1
- package/dist/testing/fixtures/index.js +1 -1
- package/dist/types/focus.d.ts +19 -0
- package/dist/types/focus.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/verify/commit-gate-configured.d.ts.map +1 -1
- package/dist/verify/commit-gate-configured.js +1 -1
- package/dist/verify/commit-gate-configured.js.map +1 -1
- package/dist/verify/commit-verdict-pull.d.ts +48 -0
- package/dist/verify/commit-verdict-pull.d.ts.map +1 -0
- package/dist/verify/commit-verdict-pull.js +148 -0
- package/dist/verify/commit-verdict-pull.js.map +1 -0
- package/dist/verify/commit-verdict-record.js +1 -1
- package/dist/verify/credit-rearm.js +1 -1
- package/dist/verify/credit-rearm.js.map +1 -1
- package/dist/verify/default-on-guards.d.ts +74 -0
- package/dist/verify/default-on-guards.d.ts.map +1 -0
- package/dist/verify/default-on-guards.js +305 -0
- package/dist/verify/default-on-guards.js.map +1 -0
- package/dist/verify/explicit-rearm.d.ts.map +1 -1
- package/dist/verify/explicit-rearm.js +1 -0
- package/dist/verify/explicit-rearm.js.map +1 -1
- package/dist/verify/gate-run-registry.d.ts.map +1 -1
- package/dist/verify/gate-run-registry.js +1 -0
- package/dist/verify/gate-run-registry.js.map +1 -1
- package/dist/verify/injection-stamp.d.ts +30 -0
- package/dist/verify/injection-stamp.d.ts.map +1 -1
- package/dist/verify/injection-stamp.js +37 -1
- package/dist/verify/injection-stamp.js.map +1 -1
- package/dist/verify/judged-ancestor.d.ts +41 -0
- package/dist/verify/judged-ancestor.d.ts.map +1 -0
- package/dist/verify/judged-ancestor.js +101 -0
- package/dist/verify/judged-ancestor.js.map +1 -0
- package/dist/verify/no-own-delta-verdict.d.ts +7 -2
- package/dist/verify/no-own-delta-verdict.d.ts.map +1 -1
- package/dist/verify/no-own-delta-verdict.js +14 -17
- package/dist/verify/no-own-delta-verdict.js.map +1 -1
- package/dist/verify/recorded-targets.d.ts +103 -0
- package/dist/verify/recorded-targets.d.ts.map +1 -0
- package/dist/verify/recorded-targets.js +159 -0
- package/dist/verify/recorded-targets.js.map +1 -0
- package/dist/verify/rework-attribution.d.ts +71 -0
- package/dist/verify/rework-attribution.d.ts.map +1 -0
- package/dist/verify/rework-attribution.js +263 -0
- package/dist/verify/rework-attribution.js.map +1 -0
- package/dist/verify/shortfall-rulings.d.ts.map +1 -1
- package/dist/verify/shortfall-rulings.js +3 -2
- package/dist/verify/shortfall-rulings.js.map +1 -1
- package/dist/verify/verification-boundary-env.d.ts +63 -15
- package/dist/verify/verification-boundary-env.d.ts.map +1 -1
- package/dist/verify/verification-boundary-env.js +81 -12
- package/dist/verify/verification-boundary-env.js.map +1 -1
- package/dist/verify/verification-commit-sharing.d.ts.map +1 -1
- package/dist/verify/verification-commit-sharing.js +2 -1
- package/dist/verify/verification-commit-sharing.js.map +1 -1
- package/dist/verify/verification-config.d.ts.map +1 -1
- package/dist/verify/verification-config.js +1 -0
- package/dist/verify/verification-config.js.map +1 -1
- package/dist/verify/verification-default-on.d.ts +0 -32
- package/dist/verify/verification-default-on.d.ts.map +1 -1
- package/dist/verify/verification-default-on.js +10 -234
- package/dist/verify/verification-default-on.js.map +1 -1
- package/dist/verify/verification-deps-default.d.ts.map +1 -1
- package/dist/verify/verification-deps-default.js +24 -2
- package/dist/verify/verification-deps-default.js.map +1 -1
- package/dist/verify/verification-deps.d.ts +17 -1
- package/dist/verify/verification-deps.d.ts.map +1 -1
- package/dist/verify/verification-engine.d.ts +2 -1
- package/dist/verify/verification-engine.d.ts.map +1 -1
- package/dist/verify/verification-engine.js +62 -50
- package/dist/verify/verification-engine.js.map +1 -1
- package/dist/verify/verification-feedback.d.ts +1 -1
- package/dist/verify/verification-feedback.d.ts.map +1 -1
- package/dist/verify/verification-feedback.js +5 -0
- package/dist/verify/verification-feedback.js.map +1 -1
- package/dist/verify/verification-rework-issue.d.ts +48 -7
- package/dist/verify/verification-rework-issue.d.ts.map +1 -1
- package/dist/verify/verification-rework-issue.js +111 -9
- package/dist/verify/verification-rework-issue.js.map +1 -1
- package/dist/verify/verify-restatement.d.ts +27 -33
- package/dist/verify/verify-restatement.d.ts.map +1 -1
- package/dist/verify/verify-restatement.js +74 -1
- package/dist/verify/verify-restatement.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/verify/judged-ancestor.test.ts
|
|
3
|
+
// PINNED-BY-END
|
|
4
|
+
/**
|
|
5
|
+
* The newest ancestor of a commit that a gate run already judged -- and, for the
|
|
6
|
+
* verify boundary, the newest one it judged GREEN.
|
|
7
|
+
*
|
|
8
|
+
* Two callers ask almost the same question of git and the per-commit verdict
|
|
9
|
+
* record (verify/commit-verdict-record.ts), so the walk lives here once:
|
|
10
|
+
*
|
|
11
|
+
* - verify/no-own-delta-verdict.ts asks for the newest JUDGED ancestor, to
|
|
12
|
+
* carry its verdict to a tip that adds nothing of the focus's own;
|
|
13
|
+
* - verify/verification-boundary-env.ts asks for the newest ancestor judged
|
|
14
|
+
* PASSING under the gate this run applies, to bound what the gate's own
|
|
15
|
+
* stages diff against.
|
|
16
|
+
*
|
|
17
|
+
* WHY A GREEN ANCESTOR IS THE RIGHT BOUNDARY. The gate's two expensive stages --
|
|
18
|
+
* the conditional types-drift check and the targeted-test selection -- scope
|
|
19
|
+
* themselves from a diff base. Taking that base from merge-base(HEAD,
|
|
20
|
+
* integration) makes it the focus branch's CUMULATIVE delta, which only grows:
|
|
21
|
+
* every area eventually crosses the "no precise pin map" line and widens to its
|
|
22
|
+
* whole suite, so a per-delivery run ends up executing the daemon suite, the root
|
|
23
|
+
* vitest suite, the mcp suite, the scripts self-tests and the deno functions
|
|
24
|
+
* suite -- the last for a second time, having already run as the gate's first
|
|
25
|
+
* stage. Measured on mars 2026-09-20: 76 files/22 min, 102/42, 101/28, 115/30 for
|
|
26
|
+
* one delivery, against 5 min for a run with an empty delta.
|
|
27
|
+
*
|
|
28
|
+
* A green ancestor bounds it correctly rather than merely cheaply: everything up
|
|
29
|
+
* to that commit was covered by a gate run that PASSED on a tree containing it,
|
|
30
|
+
* so the delta from there is exactly what no green gate has covered. That is the
|
|
31
|
+
* same rigor the selector already operates at (its pin map plus its widen rules),
|
|
32
|
+
* applied to a smaller and more accurate input -- not a new approximation.
|
|
33
|
+
*
|
|
34
|
+
* Every failure is answered with null, and every caller reads null as "use the
|
|
35
|
+
* base you would have used anyway". A base that is too OLD costs time; one that
|
|
36
|
+
* is too NEW launders a pass. So the walk fails toward the older base, always:
|
|
37
|
+
* an unreadable worktree, an unreadable rev-list, a verdict recorded under
|
|
38
|
+
* another gate, and a FAILED verdict all decline to anchor.
|
|
39
|
+
*
|
|
40
|
+
* A leaf: git and the verdict reader, nothing else.
|
|
41
|
+
*
|
|
42
|
+
* @module verify/judged-ancestor
|
|
43
|
+
*/
|
|
44
|
+
import { runGitSync } from '../git/types.js';
|
|
45
|
+
/** How many ancestors of the tip are searched for the newest judged one. */
|
|
46
|
+
export const ANCESTOR_SEARCH_DEPTH = 200;
|
|
47
|
+
export const defaultListAncestors = (worktreePath, tip, depth) => {
|
|
48
|
+
const r = runGitSync(['rev-list', '--topo-order', `--max-count=${depth}`, '--skip=1', tip], worktreePath);
|
|
49
|
+
if (!r.success)
|
|
50
|
+
return null;
|
|
51
|
+
return r.output.split('\n').map((l) => l.trim()).filter((l) => l !== '');
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* The newest ancestor of `tip` whose recorded verdict satisfies `accept`, with
|
|
55
|
+
* that verdict; null when none does, or when the ancestors are unreadable.
|
|
56
|
+
*/
|
|
57
|
+
export function findJudgedAncestor(productId, focusId, tip, gate, deps, accept = () => true) {
|
|
58
|
+
const ancestors = (deps.listAncestors ?? defaultListAncestors)(deps.worktreePath, tip, ANCESTOR_SEARCH_DEPTH);
|
|
59
|
+
if (!ancestors)
|
|
60
|
+
return null;
|
|
61
|
+
for (const sha of ancestors) {
|
|
62
|
+
const verdict = deps.readCommitVerdict(productId, focusId, sha, gate);
|
|
63
|
+
// A verdict under another gate reads as null here (the record is gate-keyed),
|
|
64
|
+
// so an unjudged ancestor and a differently-gated one are both simply walked
|
|
65
|
+
// past -- never taken as a boundary the gate did not actually establish.
|
|
66
|
+
if (verdict && accept(verdict))
|
|
67
|
+
return { sha, verdict };
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The newest ancestor of `tip` this gate judged PASSING: the commit up to which
|
|
73
|
+
* the gate's stages need not look. Null when none is found, which every caller
|
|
74
|
+
* reads as "keep the base you already had".
|
|
75
|
+
*
|
|
76
|
+
* A FAILED verdict never anchors -- the walk continues past it to an older green
|
|
77
|
+
* one. A failure says the tree was bad there, not that anything was covered.
|
|
78
|
+
*/
|
|
79
|
+
export function findGreenAncestor(productId, focusId, tip, gate, deps) {
|
|
80
|
+
return findJudgedAncestor(productId, focusId, tip, gate, deps, (v) => v.outcome === 'passed')?.sha ?? null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* True when `maybeAncestor` is an ancestor of `descendant` (or the same commit).
|
|
84
|
+
* Undetermined (`null`) when git cannot answer.
|
|
85
|
+
*
|
|
86
|
+
* Ancestry, never commit dates: every coding spawn rebases the focus worktree
|
|
87
|
+
* (spawn/worktree-session.ts), so author and commit dates are shuffled relative
|
|
88
|
+
* to branch order and would rank the two bases wrongly.
|
|
89
|
+
*/
|
|
90
|
+
export function isAncestorOf(worktreePath, maybeAncestor, descendant) {
|
|
91
|
+
if (maybeAncestor === descendant)
|
|
92
|
+
return true;
|
|
93
|
+
const r = runGitSync(['merge-base', '--is-ancestor', maybeAncestor, descendant], worktreePath);
|
|
94
|
+
if (r.success)
|
|
95
|
+
return true;
|
|
96
|
+
// git exits 1 for "not an ancestor" and >1 for a real error; the runner
|
|
97
|
+
// collapses both to !success, so confirm the refs are readable before saying no.
|
|
98
|
+
const readable = [maybeAncestor, descendant].every((rev) => runGitSync(['rev-parse', '--verify', '--quiet', `${rev}^{commit}`], worktreePath).success);
|
|
99
|
+
return readable ? false : null;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=judged-ancestor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judged-ancestor.js","sourceRoot":"","sources":["../../src/verify/judged-ancestor.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,gEAAgE;AAChE,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAKzC,MAAM,CAAC,MAAM,oBAAoB,GAAmB,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IAC/E,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,UAAU,EAAE,cAAc,EAAE,eAAe,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC;IAC1G,IAAI,CAAC,CAAC,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,SAAiB,EACjB,OAAe,EACf,GAAW,EACX,IAAuB,EACvB,IAAsG,EACtG,SAA8C,GAAG,EAAE,CAAC,IAAI;IAExD,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,oBAAoB,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,qBAAqB,CAAC,CAAC;IAC9G,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACtE,8EAA8E;QAC9E,6EAA6E;QAC7E,yEAAyE;QACzE,IAAI,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC;YAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAiB,EACjB,OAAe,EACf,GAAW,EACX,IAAuB,EACvB,IAAsG;IAEtG,OAAO,kBAAkB,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC;AAC7G,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,YAAoB,EAAE,aAAqB,EAAE,UAAkB;IAC1F,IAAI,aAAa,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAC9C,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;IAC/F,IAAI,CAAC,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC3B,wEAAwE;IACxE,iFAAiF;IACjF,MAAM,QAAQ,GAAG,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,KAAK,CAChD,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,GAAG,WAAW,CAAC,EAAE,YAAY,CAAC,CAAC,OAAO,CACnG,CAAC;IACF,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -19,8 +19,13 @@
|
|
|
19
19
|
* @module verify/no-own-delta-verdict
|
|
20
20
|
*/
|
|
21
21
|
import { isForeignOnlyExtension } from '../git/focus-own-delta.js';
|
|
22
|
+
import { type AncestorLister } from './judged-ancestor.js';
|
|
22
23
|
import type { CommitVerdict, CommitVerdictGate, CommitVerdictReader } from './commit-verdict-record.js';
|
|
23
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* How many ancestors of the tip are searched for the newest judged one. Kept as
|
|
26
|
+
* this module's name for the walk's depth, which now lives in
|
|
27
|
+
* verify/judged-ancestor.ts beside the walk itself.
|
|
28
|
+
*/
|
|
24
29
|
export declare const CARRIED_VERDICT_SEARCH_DEPTH = 200;
|
|
25
30
|
/** The reads a carried verdict is resolved from. */
|
|
26
31
|
export interface CarriedVerdictDeps {
|
|
@@ -31,7 +36,7 @@ export interface CarriedVerdictDeps {
|
|
|
31
36
|
listFocusDeliveryIds: (focusId: string) => Promise<readonly string[]>;
|
|
32
37
|
readCommitVerdict: CommitVerdictReader;
|
|
33
38
|
/** Ancestors of `tip`, newest first, excluding `tip`; null when unreadable. */
|
|
34
|
-
listAncestors?:
|
|
39
|
+
listAncestors?: AncestorLister;
|
|
35
40
|
isForeignOnlyExtension?: typeof isForeignOnlyExtension;
|
|
36
41
|
}
|
|
37
42
|
/** A verdict carried to `head`, and the judged commit it came from. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-own-delta-verdict.d.ts","sourceRoot":"","sources":["../../src/verify/no-own-delta-verdict.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"no-own-delta-verdict.d.ts","sourceRoot":"","sources":["../../src/verify/no-own-delta-verdict.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAA6C,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtG,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAExG;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,MAAwB,CAAC;AAElE,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACxD,qEAAqE;IACrE,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IACtE,iBAAiB,EAAE,mBAAmB,CAAC;IACvC,+EAA+E;IAC/E,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B,sBAAsB,CAAC,EAAE,OAAO,sBAAsB,CAAC;CACxD;AAED,uEAAuE;AACvE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,aAAa,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA+BhC"}
|
|
@@ -23,15 +23,13 @@
|
|
|
23
23
|
* @module verify/no-own-delta-verdict
|
|
24
24
|
*/
|
|
25
25
|
import { isForeignOnlyExtension } from '../git/focus-own-delta.js';
|
|
26
|
-
import {
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return r.output.split('\n').map((l) => l.trim()).filter((l) => l !== '');
|
|
34
|
-
}
|
|
26
|
+
import { ANCESTOR_SEARCH_DEPTH, findJudgedAncestor } from './judged-ancestor.js';
|
|
27
|
+
/**
|
|
28
|
+
* How many ancestors of the tip are searched for the newest judged one. Kept as
|
|
29
|
+
* this module's name for the walk's depth, which now lives in
|
|
30
|
+
* verify/judged-ancestor.ts beside the walk itself.
|
|
31
|
+
*/
|
|
32
|
+
export const CARRIED_VERDICT_SEARCH_DEPTH = ANCESTOR_SEARCH_DEPTH;
|
|
35
33
|
/**
|
|
36
34
|
* The verdict `head` carries from its newest judged ancestor when it adds nothing
|
|
37
35
|
* of the focus's own (module doc), or null.
|
|
@@ -40,15 +38,14 @@ export async function resolveCarriedVerdict(productId, focusId, head, gate, deps
|
|
|
40
38
|
const worktreePath = deps.resolveWorktreePath(focusId);
|
|
41
39
|
if (!worktreePath)
|
|
42
40
|
return null;
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const recorded = deps.readCommitVerdict(productId, focusId, judged, gate);
|
|
50
|
-
if (!recorded)
|
|
41
|
+
const found = findJudgedAncestor(productId, focusId, head, gate, {
|
|
42
|
+
worktreePath,
|
|
43
|
+
readCommitVerdict: deps.readCommitVerdict,
|
|
44
|
+
...(deps.listAncestors ? { listAncestors: deps.listAncestors } : {}),
|
|
45
|
+
});
|
|
46
|
+
if (!found)
|
|
51
47
|
return null;
|
|
48
|
+
const { sha: judged, verdict: recorded } = found;
|
|
52
49
|
let ids;
|
|
53
50
|
try {
|
|
54
51
|
ids = await deps.listFocusDeliveryIds(focusId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-own-delta-verdict.js","sourceRoot":"","sources":["../../src/verify/no-own-delta-verdict.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,8FAA8F;AAC9F,mEAAmE;AACnE,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"no-own-delta-verdict.js","sourceRoot":"","sources":["../../src/verify/no-own-delta-verdict.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,8FAA8F;AAC9F,mEAAmE;AACnE,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAuB,MAAM,sBAAsB,CAAC;AAGtG;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,qBAAqB,CAAC;AAqBlE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAiB,EACjB,OAAe,EACf,IAAY,EACZ,IAAuB,EACvB,IAAwB;IAExB,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,KAAK,GAAG,kBAAkB,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE;QAC/D,YAAY;QACZ,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;QACzC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE,CAAC,CAAC;IACH,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACjD,IAAI,GAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,sBAAsB,IAAI,sBAAsB,CAAC,CACzE,YAAY,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,CACjE,CAAC;IACF,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,UAAU,GAAG,gBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,iEAAiE;UAClH,kDAAkD,CAAC;IACvD,OAAO;QACL,WAAW,EAAE,MAAM;QACnB,OAAO,EAAE;YACP,GAAG,QAAQ;YACX,GAAG,EAAE,IAAI;YACT,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,UAAU;SACpF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Report the targets a verify run did NOT hold its delivery to: named in the
|
|
3
|
+
* daemon log, and RECORDED on the delivery's gate_state, where an operator and a
|
|
4
|
+
* later pass can read them.
|
|
5
|
+
*
|
|
6
|
+
* An arm covers the effects the focus held when the human said go, and the verify
|
|
7
|
+
* reconciliation narrows what it judges to those (verify/verify-restatement.ts
|
|
8
|
+
* narrowToArmCoverage, over queries/arm-covered-targets.ts). A target added after
|
|
9
|
+
* the arm produces no shortfall, no hold and no re-work issue -- it waits for the
|
|
10
|
+
* next arm. That is the intended behaviour, but an intended silence and an
|
|
11
|
+
* accidental one read identically: a gate that sets work aside without recording
|
|
12
|
+
* it is indistinguishable from a gate that never saw the work. So the set is
|
|
13
|
+
* stated at the same altitude as the verdict (the log) AND kept where the verdict
|
|
14
|
+
* is kept (the delivery row), because a log line does not survive the run and
|
|
15
|
+
* cannot be read by the next pass.
|
|
16
|
+
*
|
|
17
|
+
* WHEN THE WRITE HAPPENS. Last, after the run's own gate_state writers have
|
|
18
|
+
* settled (the shortfall hold, the evidence-unavailable re-work, the
|
|
19
|
+
* deterministic failure feedback, and the pass's history reset all rewrite the
|
|
20
|
+
* gate). Writing earlier would hand those writers a gate_state they did not read
|
|
21
|
+
* this record from, and the record would be dropped by the very run that made it.
|
|
22
|
+
* Written last, it stamps ONLY its own key over the FRESH row in the delivery's
|
|
23
|
+
* serialized write turn (queries/deliveries.ts
|
|
24
|
+
* rewriteDeliveryGateStateAtOwnStatus), at the row's own status, so it never
|
|
25
|
+
* moves a delivery and never erases what those writers left.
|
|
26
|
+
*
|
|
27
|
+
* WHAT CHANGES IT. Only a reconciliation's own result: a run that reconciled
|
|
28
|
+
* records what it set aside, or removes a record it no longer sets aside (the
|
|
29
|
+
* next arm covered those targets, so a standing record would lie). A run that
|
|
30
|
+
* never reconciled -- a deterministic failure, a security-gate demotion, a
|
|
31
|
+
* delivery that left verify -- leaves the record exactly as it stands: it learned
|
|
32
|
+
* nothing about coverage, and silence is not an answer.
|
|
33
|
+
*
|
|
34
|
+
* Its lifetime is the gate's. It is a record of THIS gate, so it clears with the
|
|
35
|
+
* rest of gate_state when the delivery finally routes -- the same lifetime as the
|
|
36
|
+
* verdict it qualifies.
|
|
37
|
+
*
|
|
38
|
+
* @module verify/recorded-targets
|
|
39
|
+
*/
|
|
40
|
+
import { type DeliveryGateRowIo, type DeliveryGateState } from '../queries/deliveries.js';
|
|
41
|
+
import { type RecordedTargetsRecord } from '../queries/recorded-targets-record.js';
|
|
42
|
+
/** The delivery a verify run is reporting about, and the injection it verified. */
|
|
43
|
+
export interface RecordedTargetsSubject {
|
|
44
|
+
deliveryId: string;
|
|
45
|
+
injectionNodeId: string | null;
|
|
46
|
+
}
|
|
47
|
+
/** Injected row IO for the durable write (the real row read and physical write by default). */
|
|
48
|
+
export interface RecordedTargetsWriteDeps extends DeliveryGateRowIo {
|
|
49
|
+
now: () => string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Persist a verify run's set-aside targets on its delivery's gate_state
|
|
53
|
+
* (verify/recorded-targets.ts). Bound in defaultDeps; a test may bind its own.
|
|
54
|
+
*/
|
|
55
|
+
export type RecordedTargetsPersist = (deliveryId: string, injectionNodeId: string | null, nodeIds: string[]) => Promise<unknown>;
|
|
56
|
+
/** The recorded-targets record `gateState` carries; null when absent or malformed. Pure. */
|
|
57
|
+
export declare function readRecordedTargets(gateState: unknown): RecordedTargetsRecord | null;
|
|
58
|
+
/**
|
|
59
|
+
* `gateState` with its recorded targets REPLACED: set to `recorded` when the run
|
|
60
|
+
* set targets aside, removed when it set none aside, so a stale set never stands
|
|
61
|
+
* for a newer run. Every other key is untouched, and a gate left holding nothing
|
|
62
|
+
* is null. A record stamped on a null gate_state rides beside an EMPTY `blocking`
|
|
63
|
+
* array, like carried history, so it is never read as a live block. Pure.
|
|
64
|
+
*/
|
|
65
|
+
export declare function stampRecordedTargets(gateState: unknown, recorded: RecordedTargetsRecord | null): DeliveryGateState | null;
|
|
66
|
+
/**
|
|
67
|
+
* Record on the delivery's gate_state the targets its verify run set aside --
|
|
68
|
+
* `nodeIds`, of the injection `injectionNodeId` -- or REMOVE the standing record
|
|
69
|
+
* when the run set none aside.
|
|
70
|
+
*
|
|
71
|
+
* Reads the row FRESH and writes it at the row's OWN status inside one serialized
|
|
72
|
+
* write turn (see the module header), so the gate-only write never moves the
|
|
73
|
+
* delivery and never carries a stale copy of what another writer left. Nothing is
|
|
74
|
+
* written when the record would not change, when there is no record to remove, or
|
|
75
|
+
* for a delivery that is not found, done or cancelled. Best-effort: never throws
|
|
76
|
+
* -- a record that failed to land holds nothing and is written by the next run.
|
|
77
|
+
* Returns whether a write landed.
|
|
78
|
+
*/
|
|
79
|
+
export declare function persistRecordedTargets(deliveryId: string, injectionNodeId: string | null, nodeIds: readonly string[], deps?: Partial<RecordedTargetsWriteDeps>): Promise<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Name the targets the arm did NOT cover, so narrowing what verify judges never
|
|
82
|
+
* looks like losing track of it.
|
|
83
|
+
*
|
|
84
|
+
* Targets recorded after the arm produce no shortfall, no hold and no re-work
|
|
85
|
+
* issue -- they wait for the next arm. That is the intended behaviour, but an
|
|
86
|
+
* intended silence and an accidental one read identically in a log, so the
|
|
87
|
+
* reconciliation reports the set and this states it at the same altitude as the
|
|
88
|
+
* verdict.
|
|
89
|
+
*/
|
|
90
|
+
export declare function logRecordedTargets(v: RecordedTargetsSubject, recordedTargetNodeIds: readonly string[]): void;
|
|
91
|
+
/**
|
|
92
|
+
* Report a verify run's set-aside targets: state them in the log, then record
|
|
93
|
+
* them on the delivery (see the module header).
|
|
94
|
+
*
|
|
95
|
+
* `recordedTargetNodeIds` is null when NO reconciliation ran, and the record is
|
|
96
|
+
* then left exactly as it stands -- this run learned nothing about coverage. An
|
|
97
|
+
* empty array is an answer: the run reconciled and set nothing aside, so a
|
|
98
|
+
* standing record is removed. `persist` is the durable writer; absent, the set is
|
|
99
|
+
* logged only (defaultDeps binds persistRecordedTargets). Best-effort: never
|
|
100
|
+
* throws, so reporting never demotes a rendered verdict.
|
|
101
|
+
*/
|
|
102
|
+
export declare function reportRecordedTargets(v: RecordedTargetsSubject, recordedTargetNodeIds: string[] | null, persist?: RecordedTargetsPersist): Promise<void>;
|
|
103
|
+
//# sourceMappingURL=recorded-targets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorded-targets.d.ts","sourceRoot":"","sources":["../../src/verify/recorded-targets.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAKzG,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,+FAA+F;AAC/F,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,GAAG,EAAE,MAAM,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,OAAO,EAAE,MAAM,EAAE,KACd,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,qBAAqB,GAAG,IAAI,CAKpF;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,qBAAqB,GAAG,IAAI,GACrC,iBAAiB,GAAG,IAAI,CAW1B;AAcD;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,GAAE,OAAO,CAAC,wBAAwB,CAAM,GAC3C,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,sBAAsB,EACzB,qBAAqB,EAAE,SAAS,MAAM,EAAE,GACvC,IAAI,CAON;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CACzC,CAAC,EAAE,sBAAsB,EACzB,qBAAqB,EAAE,MAAM,EAAE,GAAG,IAAI,EACtC,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAYf"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
+
// Pinned by: packages/daemon/src/queries/delivery-gate-record-wire-parity.test.ts,
|
|
3
|
+
// packages/daemon/src/verify/recorded-targets.test.ts,
|
|
4
|
+
// packages/daemon/src/verify/verification-deps-default.test.ts
|
|
5
|
+
// PINNED-BY-END
|
|
6
|
+
/**
|
|
7
|
+
* Report the targets a verify run did NOT hold its delivery to: named in the
|
|
8
|
+
* daemon log, and RECORDED on the delivery's gate_state, where an operator and a
|
|
9
|
+
* later pass can read them.
|
|
10
|
+
*
|
|
11
|
+
* An arm covers the effects the focus held when the human said go, and the verify
|
|
12
|
+
* reconciliation narrows what it judges to those (verify/verify-restatement.ts
|
|
13
|
+
* narrowToArmCoverage, over queries/arm-covered-targets.ts). A target added after
|
|
14
|
+
* the arm produces no shortfall, no hold and no re-work issue -- it waits for the
|
|
15
|
+
* next arm. That is the intended behaviour, but an intended silence and an
|
|
16
|
+
* accidental one read identically: a gate that sets work aside without recording
|
|
17
|
+
* it is indistinguishable from a gate that never saw the work. So the set is
|
|
18
|
+
* stated at the same altitude as the verdict (the log) AND kept where the verdict
|
|
19
|
+
* is kept (the delivery row), because a log line does not survive the run and
|
|
20
|
+
* cannot be read by the next pass.
|
|
21
|
+
*
|
|
22
|
+
* WHEN THE WRITE HAPPENS. Last, after the run's own gate_state writers have
|
|
23
|
+
* settled (the shortfall hold, the evidence-unavailable re-work, the
|
|
24
|
+
* deterministic failure feedback, and the pass's history reset all rewrite the
|
|
25
|
+
* gate). Writing earlier would hand those writers a gate_state they did not read
|
|
26
|
+
* this record from, and the record would be dropped by the very run that made it.
|
|
27
|
+
* Written last, it stamps ONLY its own key over the FRESH row in the delivery's
|
|
28
|
+
* serialized write turn (queries/deliveries.ts
|
|
29
|
+
* rewriteDeliveryGateStateAtOwnStatus), at the row's own status, so it never
|
|
30
|
+
* moves a delivery and never erases what those writers left.
|
|
31
|
+
*
|
|
32
|
+
* WHAT CHANGES IT. Only a reconciliation's own result: a run that reconciled
|
|
33
|
+
* records what it set aside, or removes a record it no longer sets aside (the
|
|
34
|
+
* next arm covered those targets, so a standing record would lie). A run that
|
|
35
|
+
* never reconciled -- a deterministic failure, a security-gate demotion, a
|
|
36
|
+
* delivery that left verify -- leaves the record exactly as it stands: it learned
|
|
37
|
+
* nothing about coverage, and silence is not an answer.
|
|
38
|
+
*
|
|
39
|
+
* Its lifetime is the gate's. It is a record of THIS gate, so it clears with the
|
|
40
|
+
* rest of gate_state when the delivery finally routes -- the same lifetime as the
|
|
41
|
+
* verdict it qualifies.
|
|
42
|
+
*
|
|
43
|
+
* @module verify/recorded-targets
|
|
44
|
+
*/
|
|
45
|
+
import { rewriteDeliveryGateStateAtOwnStatus, } from '../queries/deliveries.js';
|
|
46
|
+
import { isEmptyClear } from '../queries/delivery-gate-state.js';
|
|
47
|
+
import { parseRecordedTargets } from '../queries/recorded-targets-record.js';
|
|
48
|
+
import { createLogger } from '../shell/log.js';
|
|
49
|
+
const log = createLogger({ module: 'verification' });
|
|
50
|
+
/** The recorded-targets record `gateState` carries; null when absent or malformed. Pure. */
|
|
51
|
+
export function readRecordedTargets(gateState) {
|
|
52
|
+
const gate = gateState != null && typeof gateState === 'object' && !Array.isArray(gateState)
|
|
53
|
+
? gateState
|
|
54
|
+
: null;
|
|
55
|
+
return parseRecordedTargets(gate?.recordedTargets);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* `gateState` with its recorded targets REPLACED: set to `recorded` when the run
|
|
59
|
+
* set targets aside, removed when it set none aside, so a stale set never stands
|
|
60
|
+
* for a newer run. Every other key is untouched, and a gate left holding nothing
|
|
61
|
+
* is null. A record stamped on a null gate_state rides beside an EMPTY `blocking`
|
|
62
|
+
* array, like carried history, so it is never read as a live block. Pure.
|
|
63
|
+
*/
|
|
64
|
+
export function stampRecordedTargets(gateState, recorded) {
|
|
65
|
+
const gate = gateState != null && typeof gateState === 'object' && !Array.isArray(gateState)
|
|
66
|
+
? gateState
|
|
67
|
+
: null;
|
|
68
|
+
let next;
|
|
69
|
+
if (gate)
|
|
70
|
+
next = { ...gate };
|
|
71
|
+
else if (recorded)
|
|
72
|
+
next = { blocking: [], warnings: [], evaluatedAt: recorded.recordedAt };
|
|
73
|
+
else
|
|
74
|
+
return null;
|
|
75
|
+
delete next.recordedTargets;
|
|
76
|
+
if (recorded)
|
|
77
|
+
next.recordedTargets = recorded;
|
|
78
|
+
return isEmptyClear(next) ? null : next;
|
|
79
|
+
}
|
|
80
|
+
/** Whether a standing record already states exactly this run's set-aside targets. Pure. */
|
|
81
|
+
function alreadyRecorded(standing, injectionNodeId, nodeIds) {
|
|
82
|
+
return standing !== null
|
|
83
|
+
&& standing.injectionNodeId === injectionNodeId
|
|
84
|
+
&& standing.nodeIds.length === nodeIds.length
|
|
85
|
+
&& standing.nodeIds.every((id, i) => id === nodeIds[i]);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Record on the delivery's gate_state the targets its verify run set aside --
|
|
89
|
+
* `nodeIds`, of the injection `injectionNodeId` -- or REMOVE the standing record
|
|
90
|
+
* when the run set none aside.
|
|
91
|
+
*
|
|
92
|
+
* Reads the row FRESH and writes it at the row's OWN status inside one serialized
|
|
93
|
+
* write turn (see the module header), so the gate-only write never moves the
|
|
94
|
+
* delivery and never carries a stale copy of what another writer left. Nothing is
|
|
95
|
+
* written when the record would not change, when there is no record to remove, or
|
|
96
|
+
* for a delivery that is not found, done or cancelled. Best-effort: never throws
|
|
97
|
+
* -- a record that failed to land holds nothing and is written by the next run.
|
|
98
|
+
* Returns whether a write landed.
|
|
99
|
+
*/
|
|
100
|
+
export async function persistRecordedTargets(deliveryId, injectionNodeId, nodeIds, deps = {}) {
|
|
101
|
+
const now = deps.now ?? (() => new Date().toISOString());
|
|
102
|
+
try {
|
|
103
|
+
const written = await rewriteDeliveryGateStateAtOwnStatus(deliveryId, (row) => {
|
|
104
|
+
const standing = readRecordedTargets(row.gateState);
|
|
105
|
+
if (nodeIds.length === 0)
|
|
106
|
+
return standing ? stampRecordedTargets(row.gateState, null) : undefined;
|
|
107
|
+
if (alreadyRecorded(standing, injectionNodeId, nodeIds))
|
|
108
|
+
return undefined;
|
|
109
|
+
return stampRecordedTargets(row.gateState, { injectionNodeId, nodeIds: [...nodeIds], recordedAt: now() });
|
|
110
|
+
}, { io: deps });
|
|
111
|
+
return written === 'written';
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
log.warn(`[verification] failed to record the targets the arm did not cover for delivery ${deliveryId}:`, err.message);
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Name the targets the arm did NOT cover, so narrowing what verify judges never
|
|
120
|
+
* looks like losing track of it.
|
|
121
|
+
*
|
|
122
|
+
* Targets recorded after the arm produce no shortfall, no hold and no re-work
|
|
123
|
+
* issue -- they wait for the next arm. That is the intended behaviour, but an
|
|
124
|
+
* intended silence and an accidental one read identically in a log, so the
|
|
125
|
+
* reconciliation reports the set and this states it at the same altitude as the
|
|
126
|
+
* verdict.
|
|
127
|
+
*/
|
|
128
|
+
export function logRecordedTargets(v, recordedTargetNodeIds) {
|
|
129
|
+
if (recordedTargetNodeIds.length === 0)
|
|
130
|
+
return;
|
|
131
|
+
log.info(`[verification] injection ${v.injectionNodeId} carries ${recordedTargetNodeIds.length} ` +
|
|
132
|
+
`target(s) the focus's arm did not cover -- recorded, not judged, and not held against ` +
|
|
133
|
+
`delivery ${v.deliveryId}; they run on the next arm: ${recordedTargetNodeIds.join(', ')}`);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Report a verify run's set-aside targets: state them in the log, then record
|
|
137
|
+
* them on the delivery (see the module header).
|
|
138
|
+
*
|
|
139
|
+
* `recordedTargetNodeIds` is null when NO reconciliation ran, and the record is
|
|
140
|
+
* then left exactly as it stands -- this run learned nothing about coverage. An
|
|
141
|
+
* empty array is an answer: the run reconciled and set nothing aside, so a
|
|
142
|
+
* standing record is removed. `persist` is the durable writer; absent, the set is
|
|
143
|
+
* logged only (defaultDeps binds persistRecordedTargets). Best-effort: never
|
|
144
|
+
* throws, so reporting never demotes a rendered verdict.
|
|
145
|
+
*/
|
|
146
|
+
export async function reportRecordedTargets(v, recordedTargetNodeIds, persist) {
|
|
147
|
+
if (recordedTargetNodeIds === null)
|
|
148
|
+
return;
|
|
149
|
+
logRecordedTargets(v, recordedTargetNodeIds);
|
|
150
|
+
if (!persist)
|
|
151
|
+
return;
|
|
152
|
+
try {
|
|
153
|
+
await persist(v.deliveryId, v.injectionNodeId, recordedTargetNodeIds);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
log.warn(`[verification] failed to report the targets the arm did not cover for delivery ${v.deliveryId}:`, err.message);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=recorded-targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorded-targets.js","sourceRoot":"","sources":["../../src/verify/recorded-targets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type ReviewWindowCommit } from '../resolvers/shared/review-window-commits.js';
|
|
2
|
+
import { findGreenAncestor } from './judged-ancestor.js';
|
|
3
|
+
import { type CommitVerdict, type CommitVerdictGate } from './commit-verdict-record.js';
|
|
4
|
+
/** Injectable seams; each defaults to the real read. */
|
|
5
|
+
export interface ReworkAttributionDeps {
|
|
6
|
+
/** The focus worktree the failed commit was judged in; null when the daemon holds none. */
|
|
7
|
+
resolveWorktreePath: (focusId: string) => string | null;
|
|
8
|
+
/** The verdict recorded for a commit; without a gate, the newest under any gate (which carries its own). */
|
|
9
|
+
readCommitVerdict: (productId: string, focusId: string, sha: string, gate?: CommitVerdictGate) => CommitVerdict | null;
|
|
10
|
+
/** The newest ancestor of `tip` this gate judged PASSING (verify/judged-ancestor.ts). */
|
|
11
|
+
findGreenAncestor: typeof findGreenAncestor;
|
|
12
|
+
/** The non-merge commits in base..tip with their trailer attribution; null when git could not answer. */
|
|
13
|
+
listWindow: (worktreePath: string, base: string, tip: string) => readonly ReviewWindowCommit[] | null;
|
|
14
|
+
/**
|
|
15
|
+
* The focus's deliveries sitting in verify -- the candidate set an unattributable
|
|
16
|
+
* failure is settled over, so a pass that was handed one delivery can still ask the
|
|
17
|
+
* focus-wide question (module doc).
|
|
18
|
+
*/
|
|
19
|
+
listVerifyCandidates: (focusId: string) => Promise<readonly string[]>;
|
|
20
|
+
}
|
|
21
|
+
export declare const defaultReworkAttributionDeps: () => ReworkAttributionDeps;
|
|
22
|
+
/** The focus commit whose failure is being attributed. */
|
|
23
|
+
export interface FailedCommit {
|
|
24
|
+
productId: string;
|
|
25
|
+
focusId: string;
|
|
26
|
+
/** The commit the gate failed on. */
|
|
27
|
+
sha: string;
|
|
28
|
+
}
|
|
29
|
+
/** Who owns a failed verdict, and how that was decided. */
|
|
30
|
+
export interface FailureOwnership {
|
|
31
|
+
/** The deliveries whose own commits are in the judged range; empty when none is attributable. */
|
|
32
|
+
causingDeliveryIds: ReadonlySet<string>;
|
|
33
|
+
/** Those deliveries in range order, NEWEST COMMIT FIRST -- the ranking the owner is taken from. */
|
|
34
|
+
causingNewestFirst: readonly string[];
|
|
35
|
+
/** The delivery whose dispatch ran the gate -- the owner when nothing is attributable. */
|
|
36
|
+
judgedDeliveryId: string;
|
|
37
|
+
/** The ONE delivery this failure's rework belongs on: the newest causing commit's, else the judged one. */
|
|
38
|
+
owningDeliveryId: string;
|
|
39
|
+
/** False when the range could not be read at all (git or the green ancestor); the fallback then decides alone. */
|
|
40
|
+
rangeRead: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Who a failed verdict belongs to (module doc), or null when its verdict cannot be
|
|
44
|
+
* read -- the one answer that means "cannot tell". Never throws.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveFailureOwnership(at: FailedCommit, deps?: ReworkAttributionDeps): FailureOwnership | null;
|
|
47
|
+
/**
|
|
48
|
+
* The ONE delivery a failed verdict's rework belongs on, chosen from the
|
|
49
|
+
* `candidates` a filing pass would otherwise fan out over (module doc). Null means
|
|
50
|
+
* "cannot tell" -- the verdict itself was unreadable or is not a failure -- and the
|
|
51
|
+
* caller files as it did before. Never throws.
|
|
52
|
+
*/
|
|
53
|
+
export declare function selectReworkOwner(candidates: readonly string[], at: FailedCommit, deps?: ReworkAttributionDeps): string | null;
|
|
54
|
+
/**
|
|
55
|
+
* Rung 3: the owner of a failure NOTHING attributes, over the candidates that could
|
|
56
|
+
* carry it. The lowest id -- arbitrary on purpose, and a pure function of the set, so
|
|
57
|
+
* a sibling, a later poll, a restarted daemon and the per-focus filer all name the
|
|
58
|
+
* same one delivery. Null only when there is no candidate at all.
|
|
59
|
+
*/
|
|
60
|
+
export declare function unattributableOwner(candidates: readonly string[]): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Whether the rework Bug for `failedSha` belongs on `deliveryId` (module doc): it is
|
|
63
|
+
* the ONE owner the range names -- the delivery of the newest commit in it, or, with
|
|
64
|
+
* nothing attributable there, the delivery whose dispatch ran the gate. An unreadable
|
|
65
|
+
* verdict names no owner from the commit, so the question is asked of the FOCUS
|
|
66
|
+
* instead: the candidate set settles it by rung 3, identically for every asker and
|
|
67
|
+
* across a restart. A candidate read that fails files nothing this poll (the retry
|
|
68
|
+
* owns that case). Never throws.
|
|
69
|
+
*/
|
|
70
|
+
export declare function deliveryOwnsFailure(deliveryId: string, at: FailedCommit, deps?: ReworkAttributionDeps): Promise<boolean>;
|
|
71
|
+
//# sourceMappingURL=rework-attribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rework-attribution.d.ts","sourceRoot":"","sources":["../../src/verify/rework-attribution.ts"],"names":[],"mappings":"AAsGA,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,8CAA8C,CAAC;AAChH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAqB,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAK3G,wDAAwD;AACxD,MAAM,WAAW,qBAAqB;IACpC,2FAA2F;IAC3F,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACxD,4GAA4G;IAC5G,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,KAAK,aAAa,GAAG,IAAI,CAAC;IACvH,yFAAyF;IACzF,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,yGAAyG;IACzG,UAAU,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACtG;;;;OAIG;IACH,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;CACvE;AAED,eAAO,MAAM,4BAA4B,QAAO,qBAQ9C,CAAC;AAEH,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,2DAA2D;AAC3D,MAAM,WAAW,gBAAgB;IAC/B,iGAAiG;IACjG,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACxC,mGAAmG;IACnG,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,0FAA0F;IAC1F,gBAAgB,EAAE,MAAM,CAAC;IACzB,2GAA2G;IAC3G,gBAAgB,EAAE,MAAM,CAAC;IACzB,kHAAkH;IAClH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,YAAY,EAChB,IAAI,GAAE,qBAAsD,GAC3D,gBAAgB,GAAG,IAAI,CAkBzB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,EAAE,EAAE,YAAY,EAChB,IAAI,GAAE,qBAAsD,GAC3D,MAAM,GAAG,IAAI,CAoBf;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAIhF;AA4BD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,YAAY,EAChB,IAAI,GAAE,qBAAsD,GAC3D,OAAO,CAAC,OAAO,CAAC,CAiBlB"}
|