@telora/daemon 0.22.137 → 0.22.146

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 (78) hide show
  1. package/build-info.json +13 -3
  2. package/dist/audit/audit-phase.d.ts +34 -1
  3. package/dist/audit/audit-phase.d.ts.map +1 -1
  4. package/dist/audit/audit-phase.js +92 -9
  5. package/dist/audit/audit-phase.js.map +1 -1
  6. package/dist/audit/audit-prompt.d.ts +174 -0
  7. package/dist/audit/audit-prompt.d.ts.map +1 -1
  8. package/dist/audit/audit-prompt.js +365 -2
  9. package/dist/audit/audit-prompt.js.map +1 -1
  10. package/dist/completion/review-coverage-shas.d.ts +49 -0
  11. package/dist/completion/review-coverage-shas.d.ts.map +1 -0
  12. package/dist/completion/review-coverage-shas.js +128 -0
  13. package/dist/completion/review-coverage-shas.js.map +1 -0
  14. package/dist/completion/review-exit-deps.d.ts +15 -2
  15. package/dist/completion/review-exit-deps.d.ts.map +1 -1
  16. package/dist/completion/review-exit-deps.js +9 -3
  17. package/dist/completion/review-exit-deps.js.map +1 -1
  18. package/dist/delivery/delivery-review-coverage.d.ts +216 -0
  19. package/dist/delivery/delivery-review-coverage.d.ts.map +1 -0
  20. package/dist/delivery/delivery-review-coverage.js +208 -0
  21. package/dist/delivery/delivery-review-coverage.js.map +1 -0
  22. package/dist/queries/focus-branch-work-evidence.d.ts +55 -0
  23. package/dist/queries/focus-branch-work-evidence.d.ts.map +1 -0
  24. package/dist/queries/focus-branch-work-evidence.js +65 -0
  25. package/dist/queries/focus-branch-work-evidence.js.map +1 -0
  26. package/dist/queries/focus-criteria-standing.d.ts +138 -0
  27. package/dist/queries/focus-criteria-standing.d.ts.map +1 -0
  28. package/dist/queries/focus-criteria-standing.js +98 -0
  29. package/dist/queries/focus-criteria-standing.js.map +1 -0
  30. package/dist/queries/focus-review-watermark.d.ts +35 -0
  31. package/dist/queries/focus-review-watermark.d.ts.map +1 -0
  32. package/dist/queries/focus-review-watermark.js +47 -0
  33. package/dist/queries/focus-review-watermark.js.map +1 -0
  34. package/dist/queries/focuses.d.ts +0 -9
  35. package/dist/queries/focuses.d.ts.map +1 -1
  36. package/dist/queries/focuses.js +0 -14
  37. package/dist/queries/focuses.js.map +1 -1
  38. package/dist/queries/shared.js +1 -1
  39. package/dist/queries/verification.d.ts +23 -25
  40. package/dist/queries/verification.d.ts.map +1 -1
  41. package/dist/queries/verification.js +66 -45
  42. package/dist/queries/verification.js.map +1 -1
  43. package/dist/resolvers/assembly-engine.d.ts +51 -0
  44. package/dist/resolvers/assembly-engine.d.ts.map +1 -1
  45. package/dist/resolvers/assembly-engine.js +10 -20
  46. package/dist/resolvers/assembly-engine.js.map +1 -1
  47. package/dist/resolvers/branch-work-arming.d.ts +133 -0
  48. package/dist/resolvers/branch-work-arming.d.ts.map +1 -0
  49. package/dist/resolvers/branch-work-arming.js +67 -0
  50. package/dist/resolvers/branch-work-arming.js.map +1 -0
  51. package/dist/resolvers/focus-criteria-standing.d.ts +24 -0
  52. package/dist/resolvers/focus-criteria-standing.d.ts.map +1 -0
  53. package/dist/resolvers/focus-criteria-standing.js +234 -0
  54. package/dist/resolvers/focus-criteria-standing.js.map +1 -0
  55. package/dist/resolvers/focus-review-coverage.d.ts +189 -0
  56. package/dist/resolvers/focus-review-coverage.d.ts.map +1 -0
  57. package/dist/resolvers/focus-review-coverage.js +516 -0
  58. package/dist/resolvers/focus-review-coverage.js.map +1 -0
  59. package/dist/resolvers/git-diff-against-base.d.ts.map +1 -1
  60. package/dist/resolvers/git-diff-against-base.js +11 -0
  61. package/dist/resolvers/git-diff-against-base.js.map +1 -1
  62. package/dist/resolvers/index.d.ts.map +1 -1
  63. package/dist/resolvers/index.js +7 -1
  64. package/dist/resolvers/index.js.map +1 -1
  65. package/dist/resolvers/reality-tree-snapshot.d.ts +9 -4
  66. package/dist/resolvers/reality-tree-snapshot.d.ts.map +1 -1
  67. package/dist/resolvers/reality-tree-snapshot.js +64 -17
  68. package/dist/resolvers/reality-tree-snapshot.js.map +1 -1
  69. package/dist/resolvers/shared/branch-fact-provenance.d.ts +258 -0
  70. package/dist/resolvers/shared/branch-fact-provenance.d.ts.map +1 -0
  71. package/dist/resolvers/shared/branch-fact-provenance.js +571 -0
  72. package/dist/resolvers/shared/branch-fact-provenance.js.map +1 -0
  73. package/dist/resolvers/shared/reality-tree-arrival.d.ts +71 -0
  74. package/dist/resolvers/shared/reality-tree-arrival.d.ts.map +1 -0
  75. package/dist/resolvers/shared/reality-tree-arrival.js +129 -0
  76. package/dist/resolvers/shared/reality-tree-arrival.js.map +1 -0
  77. package/dist/testing/fixtures/index.js +1 -1
  78. package/package.json +2 -2
@@ -0,0 +1,234 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/resolvers/focus-criteria-standing.test.ts
3
+ // PINNED-BY-END
4
+ /**
5
+ * focus.criteria_standing
6
+ *
7
+ * The focus's OWN declared acceptance criteria, each stated with whether a
8
+ * current delivery addresses it (and which), plus the STATED FLOOR and the
9
+ * basis that floor rests on.
10
+ *
11
+ * WHY A SCOPING PASS NEEDS THIS. An audit pass reads the branch, finds facts,
12
+ * and anchors remediation deliveries. Nothing in that loop ever asks what the
13
+ * focus SAID IT WAS FOR, so the elaboration has no condition under which it
14
+ * stops: a focus can triple its delivery count while its declared criteria sit
15
+ * close to met, because no step measures them. `acceptance_criteria` had a
16
+ * single reader in the whole repo, and only at the instant a review lands
17
+ * approved -- which is to say, never at the moment scoping decides to cut
18
+ * another delivery. This section is that measurement, in front of the pass,
19
+ * between reviews, with no review having to run.
20
+ *
21
+ * WHAT THE FLOOR IS AND IS NOT. `floorReached` says every declared criterion
22
+ * has at least one delivery pointing at it. It does NOT say the work is
23
+ * correct, complete or good -- satisfaction is a REVIEW act under separation of
24
+ * duties. The distinction is carried into the rendered prose, because a pass
25
+ * that reads "floor reached" as "the focus is done" has been handed the wrong
26
+ * instrument.
27
+ *
28
+ * `no_criteria_declared` IS NOT A FLOOR. A focus that declared nothing has gone
29
+ * UNMEASURED, not arrived; the rendering says so in those words. Treating an
30
+ * empty criteria set as satisfied would hand a perfect score to exactly the
31
+ * focuses that declared nothing to be measured against.
32
+ *
33
+ * FAILS SOFT, NEVER SILENT. Every failure path renders an EXPLICIT failure
34
+ * line. An absent or empty section reads to the pass as "there is nothing left
35
+ * to address", i.e. as a floor -- the precise inversion this section exists to
36
+ * prevent -- so "returns ''" is a FAILING outcome for this resolver.
37
+ *
38
+ * NO MATCHING LOGIC LIVES HERE. The standing is computed by the shared composer
39
+ * `supabase/functions/_shared/focus-criteria-standing.ts` behind the `focus_criteria_standing`
40
+ * product-api action and read through `queries/focus-criteria-standing.ts`.
41
+ * This module renders it. A second matcher in the daemon would drift from the
42
+ * one a review verdicts with.
43
+ */
44
+ import { registerSourceResolver } from './assembly-engine.js';
45
+ import { createLogger } from '../shell/log.js';
46
+ const log = createLogger({ module: 'assembly-engine' });
47
+ /** Section heading, shared by the rendered standing and the failure line. */
48
+ export const CRITERIA_STANDING_HEADING = '## Focus acceptance criteria standing (what did THIS focus declare it was for?)';
49
+ /** The one-line disclaimer that keeps "addressed" from being read as "met". */
50
+ const ADDRESSED_IS_NOT_MET = '**"Addressed" is not "met".** A criterion is addressed when a current delivery POINTS AT it; ' +
51
+ 'whether the work satisfies it is a REVIEW judgement, not a computed one.';
52
+ // ── Pure rendering ───────────────────────────────────────────────────
53
+ /** The floor line: the verdict, the count behind it, and the basis it rests on. */
54
+ function renderFloorLine(standing) {
55
+ const total = standing.criteria.length;
56
+ const open = standing.openCriteria.length;
57
+ if (standing.floorBasis === 'no_criteria_declared') {
58
+ return [
59
+ '**Floor: NOT REACHED -- this focus DECLARED NO acceptance criteria.** ' +
60
+ 'Basis: `no_criteria_declared`.',
61
+ 'An absent criteria set is UNMEASURED, not arrived. It is NOT a floor and must not be read ' +
62
+ 'as one: nothing here states what this focus is for, so nothing here can tell you to stop.',
63
+ ];
64
+ }
65
+ if (standing.floorBasis === 'all_criteria_addressed') {
66
+ return [
67
+ `**Floor: REACHED -- all ${total} declared criteria are addressed by a current delivery.** ` +
68
+ 'Basis: `all_criteria_addressed`.',
69
+ ];
70
+ }
71
+ return [
72
+ `**Floor: NOT REACHED -- ${open} of ${total} declared criteria are still OPEN.** ` +
73
+ 'Basis: `open_criteria_remain`.',
74
+ ];
75
+ }
76
+ /** One criterion: its state, its verbatim text, and every delivery claiming it. */
77
+ function renderCriterion(entry, index) {
78
+ const state = entry.status === 'addressed' ? 'ADDRESSED' : 'OPEN';
79
+ const lines = [`${index + 1}. **${state}** -- "${entry.criterion}"`];
80
+ for (const match of entry.addressedBy) {
81
+ lines.push(` - addressed by **${match.deliveryName}** (\`${match.deliveryId}\`) -- ` +
82
+ `basis \`${match.matchBasis}\`, overlap ${match.overlap} ` +
83
+ `(${match.matchedTokens.length}/${match.significantTokenCount} significant tokens)`);
84
+ }
85
+ return lines;
86
+ }
87
+ /** The open set, echoed verbatim: this is the work the focus still owes. */
88
+ function renderOpenPartition(openCriteria) {
89
+ const lines = [`### Still OPEN (${openCriteria.length}) -- the work that remains`, ''];
90
+ if (openCriteria.length === 0) {
91
+ lines.push('_None -- every declared criterion is addressed by a current delivery._');
92
+ return lines;
93
+ }
94
+ for (const criterion of openCriteria)
95
+ lines.push(`- "${criterion}"`);
96
+ return lines;
97
+ }
98
+ /** The scan bounds. An unreported or truncated scan is STATED, never assumed away. */
99
+ function renderScanBasis(standing) {
100
+ const scan = standing.deliveryScan;
101
+ if (!scan) {
102
+ return [
103
+ '- The read did NOT report its delivery-scan bounds, so it is unknown whether every ' +
104
+ 'delivery on this focus was considered. Treat an ADDRESSED criterion as the weaker claim.',
105
+ ];
106
+ }
107
+ if (scan.truncated) {
108
+ return [
109
+ `- The delivery scan was TRUNCATED at its bound of ${scan.limit} (${scan.evaluated} ` +
110
+ 'deliveries evaluated). Unseen deliveries can only ADD matches, so an OPEN criterion ' +
111
+ 'here may be a false open -- but a REACHED floor is still sound.',
112
+ ];
113
+ }
114
+ return [
115
+ `- Measured against ${scan.evaluated} current non-cancelled deliveries ` +
116
+ `(scan bound ${scan.limit}, not reached).`,
117
+ ];
118
+ }
119
+ /** The closing reading rule. The full instruction lives in the audit prompt. */
120
+ const READING_RULE = [
121
+ '**How to read this.** Before you anchor anything, ask what is left to address. An OPEN',
122
+ 'criterion IS the work that remains -- anchor against it by name. When every criterion is',
123
+ 'addressed, the focus has reached its STATED FLOOR: anchor nothing further unless you have a',
124
+ 'genuinely new root cause, and say in your audit summary that the floor is reached.',
125
+ ];
126
+ /** Render the standing. Never returns an empty string. */
127
+ export function renderFocusCriteriaStanding(standing) {
128
+ const lines = [
129
+ CRITERIA_STANDING_HEADING,
130
+ '',
131
+ ...renderFloorLine(standing),
132
+ '',
133
+ ADDRESSED_IS_NOT_MET,
134
+ '',
135
+ ...renderScanBasis(standing),
136
+ '',
137
+ ];
138
+ if (standing.criteria.length === 0) {
139
+ lines.push('_This focus declared no acceptance criteria, so there are none to list._');
140
+ return lines.join('\n');
141
+ }
142
+ lines.push(`### Declared criteria (${standing.criteria.length})`, '');
143
+ standing.criteria.forEach((entry, i) => lines.push(...renderCriterion(entry, i)));
144
+ lines.push('', ...renderOpenPartition(standing.openCriteria), '', ...READING_RULE);
145
+ return lines.join('\n');
146
+ }
147
+ /**
148
+ * Render the EXPLICIT failure line. Rendered instead of nothing on every read
149
+ * failure, because an absent section reads as "there is nothing left to
150
+ * address" -- a floor nobody measured.
151
+ */
152
+ export function renderFocusCriteriaStandingFailure(reason) {
153
+ return [
154
+ CRITERIA_STANDING_HEADING,
155
+ '',
156
+ '**READ FAILED -- this focus\'s criteria standing is UNKNOWN.**',
157
+ `Reason: ${reason}`,
158
+ '',
159
+ 'This section could not be computed, which is NOT the same as "every declared criterion is',
160
+ 'addressed". You have NO floor here: do not conclude the focus has reached one, and do not',
161
+ 'treat the silence as licence to anchor freely either. Judge each candidate on the tree\'s',
162
+ 'own evidence, anchor only a genuinely new root cause, and record in your audit summary that',
163
+ 'the criteria standing was unreadable on this pass.',
164
+ ].join('\n');
165
+ }
166
+ /**
167
+ * The real read.
168
+ *
169
+ * `queries/focus-criteria-standing.js` is reached through a DEFERRED dynamic
170
+ * import, not a static one (the type import above erases). A static import
171
+ * would put it -- and its `queries/shared.js` + zod chain -- in the module
172
+ * graph of `resolvers/index.js`, which several resolver tests load while
173
+ * holding a PARTIAL `mock.module` over `queries/shared.js`; under the tsx mock
174
+ * loader a partial namespace makes every unlisted export (here
175
+ * `callApiValidated`) a load-time SyntaxError for anything importing it, and
176
+ * ten unrelated resolver test files go red. Deferring keeps that chain out of
177
+ * every test that does not actually run this resolver -- the documented escape
178
+ * (packages/daemon/CLAUDE.md on the mock-loader quirk; same move in
179
+ * `focus-review-coverage.ts` and `listener-auto-advance.ts`).
180
+ */
181
+ async function readCriteriaStanding(focusId) {
182
+ const { getFocusCriteriaStanding } = await import('../queries/focus-criteria-standing.js');
183
+ return getFocusCriteriaStanding(focusId);
184
+ }
185
+ const defaultDeps = {
186
+ getStanding: readCriteriaStanding,
187
+ };
188
+ /**
189
+ * A standing whose own fields disagree is not a reading, and the direction that
190
+ * matters is one-way: a `floorReached: true` that arrives alongside open
191
+ * criteria (or no criteria at all) would render a FALSE FLOOR, which is silent
192
+ * and unrecoverable for the pass. Returns the contradiction to report, or null.
193
+ */
194
+ function describeContradiction(standing) {
195
+ const floorClaimed = standing.floorReached || standing.floorBasis === 'all_criteria_addressed';
196
+ if (!floorClaimed)
197
+ return null;
198
+ if (standing.floorReached !== (standing.floorBasis === 'all_criteria_addressed')) {
199
+ return `floorReached=${standing.floorReached} contradicts floorBasis='${standing.floorBasis}'`;
200
+ }
201
+ if (standing.openCriteria.length > 0) {
202
+ return `the floor is reported as reached while ${standing.openCriteria.length} criteria are open`;
203
+ }
204
+ if (standing.criteria.length === 0) {
205
+ return 'the floor is reported as reached over an EMPTY criteria set';
206
+ }
207
+ return null;
208
+ }
209
+ /**
210
+ * Resolve the section. Exported (with an injectable deps seam) so tests drive
211
+ * it without registering a module mock.
212
+ */
213
+ export async function resolveFocusCriteriaStanding(context, deps = defaultDeps) {
214
+ let standing;
215
+ try {
216
+ standing = await deps.getStanding(context.focusId);
217
+ }
218
+ catch (err) {
219
+ const message = err.message;
220
+ log.warn(`focus.criteria_standing: read failed: ${message}`);
221
+ return renderFocusCriteriaStandingFailure(`the criteria-standing read failed (${message})`);
222
+ }
223
+ const contradiction = describeContradiction(standing);
224
+ if (contradiction !== null) {
225
+ log.warn(`focus.criteria_standing: inconsistent standing: ${contradiction}`);
226
+ return renderFocusCriteriaStandingFailure(`the read contradicted itself (${contradiction}), so no floor can be stated from it`);
227
+ }
228
+ return renderFocusCriteriaStanding(standing);
229
+ }
230
+ /** Register this module's resolver(s). Called from initResolvers() -- not an import side effect. */
231
+ export function registerFocusCriteriaStandingResolver() {
232
+ registerSourceResolver('focus.criteria_standing', async (context) => resolveFocusCriteriaStanding(context));
233
+ }
234
+ //# sourceMappingURL=focus-criteria-standing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-criteria-standing.js","sourceRoot":"","sources":["../../src/resolvers/focus-criteria-standing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ import type { AssemblyContext } from './assembly-engine.js';
2
+ import { type BlameRange, type RawCommitFact } from './shared/branch-fact-provenance.js';
3
+ import { type DeliveryReviewCoverage, type DeliveryReviewCoverageReason } from '../delivery/delivery-review-coverage.js';
4
+ import type { FocusDeliveryInfo } from '../types/focus.js';
5
+ /**
6
+ * focus.review_coverage
7
+ *
8
+ * The focus's deliveries PARTITIONED BY REVIEW STATE -- reviewed, unreviewed,
9
+ * no-work-yet -- each named with its injection anchor, and the whole reading
10
+ * carrying the basis it stands on (the coverage watermark and the last
11
+ * completed review's completion time).
12
+ *
13
+ * WHY A SCOPING PASS NEEDS THIS. An audit pass reads the focus branch and sees
14
+ * FACTS: files, behaviours, commits. Round 5 of its prompt then anchors one
15
+ * remediation delivery per injection. Without this section the pass cannot tell
16
+ * whether a fact it just observed came from a delivery a reviewer has looked at
17
+ * or from one still in flight -- so residue of unreviewed work gets anchored as
18
+ * a fresh sibling and the focus grows a backlog with no floor: it re-opens on
19
+ * new work while the pass that produced the work is never judged.
20
+ *
21
+ * AND THE JOIN, NOT JUST THE PARTITION. A partition of DELIVERIES sitting beside
22
+ * a diff of CHANGES leaves the pass to work out which delivery produced which
23
+ * hunk -- the very inference this section exists to remove. So the reading also
24
+ * carries a FACT-LEVEL provenance mapping (commit -> delivery -> review state,
25
+ * and file -> the delivery or deliveries that touched it), built from the
26
+ * durable `Telora-Delivery` trailer by
27
+ * `resolvers/shared/branch-fact-provenance.ts`. A fact it cannot tie to one of
28
+ * this focus's deliveries is rendered UNATTRIBUTED and counted UNREVIEWED; it
29
+ * is never attributed on a guess.
30
+ *
31
+ * READ FROM THE REPOSITORY, NOT FROM A CHECKOUT. The branch reads resolve
32
+ * against `context.worktreePath` when the assembly has one and against
33
+ * `config.repoPath` otherwise. `git log <ref>` reads refs, not the working
34
+ * tree, so a focus with no live worktree -- the audit pass, which assembles
35
+ * with `worktreePath: null` -- still gets a real reading instead of a
36
+ * uniformly-pessimistic one that carries no information at all.
37
+ *
38
+ * FAILS SOFT, NEVER SILENT. Every failure path renders an EXPLICIT failure
39
+ * line. A silently absent section reads to the pass as "there is no unreviewed
40
+ * work here", which is the exact inversion this resolver exists to prevent.
41
+ *
42
+ * The classification rules are NOT re-derived here: they are
43
+ * `delivery/delivery-review-coverage.ts`, the Node mirror of the Deno module
44
+ * the product-api create gate runs, held in agreement by
45
+ * `delivery-review-coverage-parity.test.ts`. So the state this section reports
46
+ * is the same state that gate will enforce.
47
+ */
48
+ /** Section heading, shared by the rendered reading and the failure line. */
49
+ export declare const REVIEW_COVERAGE_HEADING = "## Delivery review coverage (has a reviewer seen this delivery's work?)";
50
+ /** How the merge-commit half of the basis was resolved (or why it was not). */
51
+ export type ShaCoverageResolution =
52
+ /** No completed review on the focus, so there is no range to resolve against. */
53
+ 'no_review_yet'
54
+ /** Resolved against the watermark commit in the focus's repository. */
55
+ | 'resolved'
56
+ /** Neither a worktree nor a repo path is available -- no repository to ask. */
57
+ | 'no_repo'
58
+ /** The watermark commit does not resolve in the repository (unfetched, rewritten). */
59
+ | 'watermark_unresolvable';
60
+ /** The stated basis a partition rests on. A partition without one is an assertion. */
61
+ export interface ReviewCoverageBasis {
62
+ /** product_focuses.reviewed_through_sha, verbatim (null: no completed review). */
63
+ reviewedThroughSha: string | null;
64
+ /** completed_at of the most recent COMPLETED focus review (null: none). */
65
+ latestCompletedReviewAt: string | null;
66
+ /** How merge-commit coverage was resolved. */
67
+ shaResolution: ShaCoverageResolution;
68
+ }
69
+ /** One delivery, classified and labelled for rendering. */
70
+ export interface ClassifiedDeliveryRow {
71
+ id: string;
72
+ name: string;
73
+ executionStatus: string | null;
74
+ coverage: DeliveryReviewCoverage;
75
+ reason: DeliveryReviewCoverageReason;
76
+ /** "injection #4 -- <statement>", the raw injection id, or null when unanchored. */
77
+ anchor: string | null;
78
+ }
79
+ /**
80
+ * Render the partitioned reading, with the fact-level provenance mapping
81
+ * appended. `provenance` is ALWAYS a rendered block -- the reading or the
82
+ * explicit NOT AVAILABLE line -- never an empty string, so the partition is
83
+ * never presented without saying how to join a fact to it.
84
+ */
85
+ export declare function renderFocusReviewCoverage(rows: readonly ClassifiedDeliveryRow[], basis: ReviewCoverageBasis, provenance: string): string;
86
+ /**
87
+ * Render the EXPLICIT failure line. Rendered instead of nothing on every read
88
+ * failure, because an absent section reads as "no unreviewed work".
89
+ */
90
+ export declare function renderFocusReviewCoverageFailure(reason: string): string;
91
+ /** Injected seams; the defaults are the real queries and a real git process. */
92
+ export interface FocusReviewCoverageDeps {
93
+ getFocusDeliveries: (focusId: string) => Promise<FocusDeliveryInfo[]>;
94
+ /**
95
+ * The focus's coverage watermark AND its pinned git branch identity
96
+ * (`product_focuses.branch_name`). Both come off the same active-focus row,
97
+ * so they are read together rather than paid for twice. `branchName` is what
98
+ * lets the branch reads resolve without a checkout.
99
+ */
100
+ getReviewedThroughSha: (context: AssemblyContext) => Promise<{
101
+ found: boolean;
102
+ sha: string | null;
103
+ branchName: string | null;
104
+ }>;
105
+ getLatestCompletedReviewAt: (focusId: string) => Promise<string | null>;
106
+ getAnchorLabels: (injectionIds: string[]) => Promise<Map<string, string>>;
107
+ /** True iff `sha` is an ancestor of `tip` in `repoPath`. False when unreadable. */
108
+ isAncestor: (repoPath: string, sha: string, tip: string) => boolean;
109
+ /** True iff `sha` resolves to a commit in `repoPath`. */
110
+ commitResolves: (repoPath: string, sha: string) => boolean;
111
+ /**
112
+ * Does `ref` carry commits bearing this delivery's `Telora-Delivery`
113
+ * trailer? The BRANCH-DERIVED committed-work evidence the delivery row
114
+ * cannot carry: a fast-forward merge-back stamps no `merge_commit_sha`, and
115
+ * a cancelled delivery's commits sit on the branch with nothing on the row
116
+ * naming them. Without it a delivery holding real residue reads as
117
+ * `no_work_yet` and its residue escapes the hold entirely.
118
+ *
119
+ * Asked ONLY once the ref has been proved to resolve (`makeBranchWorkEvidence`),
120
+ * because the underlying trailer search swallows git errors as an empty set:
121
+ * a `false` from it against an unreadable ref would be indistinguishable
122
+ * from a real "searched, found none" -- and while neither answer releases
123
+ * anything any more, an unreadable ref must not be recorded as a SEARCHED
124
+ * branch either: the reading the daemon persists is the gate's only source
125
+ * of positive evidence, and overwriting real ids with an empty list because
126
+ * git could not be asked drops holds.
127
+ */
128
+ hasBranchCommits: (repoPath: string, ref: string, deliveryId: string) => boolean;
129
+ /**
130
+ * Every commit in `<base>..<ref>` with its trailer and touched paths -- the
131
+ * raw material of the fact-level provenance mapping. Null when git cannot
132
+ * read the window, which renders the explicit NOT AVAILABLE block rather
133
+ * than a silently absent mapping.
134
+ */
135
+ readBranchFacts: (repoPath: string, base: string, ref: string) => RawCommitFact[] | null;
136
+ /**
137
+ * One path's blame runs at the branch tip -- the LINE-grain read. Spent only
138
+ * on files more than one contributor touched, where the file row cannot say
139
+ * which produced a given line. Null when git cannot answer, which renders a
140
+ * DECLARED gap for that file rather than an absent one.
141
+ */
142
+ readBlameRanges: (repoPath: string, tip: string, path: string) => BlameRange[] | null;
143
+ /**
144
+ * Persist the delivery ids the branch search found commits for
145
+ * (`product_focuses.branch_work_delivery_ids`), so the product-api
146
+ * delivery-create residue gate -- which has no repository and cannot run
147
+ * this search -- enforces on the same evidence this reading shows the
148
+ * scoping pass. Called ONLY when the branch was actually read; see
149
+ * `makeBranchWorkEvidence`.
150
+ *
151
+ * The write is ADDITIVE at the gate: an id in the set makes a delivery
152
+ * work-bearing and therefore holdable, and an id NOT in the set releases
153
+ * nothing there. So a write that never lands costs holds, never grants
154
+ * them -- which is why there is no compensating retraction to pair with it
155
+ * (there used to be, and its unavailability in the one failure that needed
156
+ * it was the defect).
157
+ */
158
+ persistBranchWork: (focusId: string, deliveryIds: readonly string[]) => Promise<void>;
159
+ }
160
+ /**
161
+ * The PRODUCTION wiring: the real queries, a real git process, and the real
162
+ * evidence writes. Exported because the binding itself is a failure mode --
163
+ * swap `persistBranchWork` for a no-op and every behavioural test below stays
164
+ * green while the create gate goes blind -- so the cross-runtime seam test
165
+ * (`completion/review-coverage-seam.test.ts`) drives THESE, replacing only the
166
+ * DB reads and the transport under the production write.
167
+ */
168
+ export declare const defaultFocusReviewCoverageDeps: FocusReviewCoverageDeps;
169
+ /**
170
+ * WHERE the branch reads run and WHICH ref they read.
171
+ *
172
+ * `git log <ref>` / `merge-base --is-ancestor` read REFS, not a working tree,
173
+ * so an assembly with no worktree (the audit pass) can still read the focus's
174
+ * branch out of the daemon's main repository. The ref is the focus's pinned
175
+ * `branch_name` when it has one; with a worktree and no pinned name, that
176
+ * worktree's `HEAD` is the branch by construction. Null ref = nothing to read.
177
+ */
178
+ export declare function resolveBranchReadTarget(context: AssemblyContext, branchName: string | null): {
179
+ repoPath: string | null;
180
+ ref: string | null;
181
+ };
182
+ /**
183
+ * Resolve the section. Exported (with an injectable deps seam) so tests drive
184
+ * it without registering a module mock.
185
+ */
186
+ export declare function resolveFocusReviewCoverage(context: AssemblyContext, deps?: FocusReviewCoverageDeps): Promise<string>;
187
+ /** Register this module's resolver(s). Called from initResolvers() -- not an import side effect. */
188
+ export declare function registerFocusReviewCoverageResolver(): void;
189
+ //# sourceMappingURL=focus-review-coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-review-coverage.d.ts","sourceRoot":"","sources":["../../src/resolvers/focus-review-coverage.ts"],"names":[],"mappings":"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"}