@knpkv/jira-clockify 1.4.1 → 1.6.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 (147) hide show
  1. package/README.md +105 -22
  2. package/dist/package.json +1 -1
  3. package/dist/src/agent/schedule.d.ts +6 -5
  4. package/dist/src/agent/schedule.d.ts.map +1 -1
  5. package/dist/src/agent/schedule.js +117 -102
  6. package/dist/src/agent/schedule.js.map +1 -1
  7. package/dist/src/agent/sessions.d.ts +27 -33
  8. package/dist/src/agent/sessions.d.ts.map +1 -1
  9. package/dist/src/agent/sessions.js +121 -83
  10. package/dist/src/agent/sessions.js.map +1 -1
  11. package/dist/src/agent/writePlanning.d.ts +2 -0
  12. package/dist/src/agent/writePlanning.d.ts.map +1 -1
  13. package/dist/src/agent/writePlanning.js +4 -1
  14. package/dist/src/agent/writePlanning.js.map +1 -1
  15. package/dist/src/bin.js +16 -5
  16. package/dist/src/bin.js.map +1 -1
  17. package/dist/src/cli/CommandFailed.d.ts +27 -0
  18. package/dist/src/cli/CommandFailed.d.ts.map +1 -0
  19. package/dist/src/cli/CommandFailed.js +25 -0
  20. package/dist/src/cli/CommandFailed.js.map +1 -0
  21. package/dist/src/cli/agentWrite.d.ts.map +1 -1
  22. package/dist/src/cli/agentWrite.js +12 -5
  23. package/dist/src/cli/agentWrite.js.map +1 -1
  24. package/dist/src/cli/auth.d.ts +59 -2
  25. package/dist/src/cli/auth.d.ts.map +1 -1
  26. package/dist/src/cli/auth.js +151 -106
  27. package/dist/src/cli/auth.js.map +1 -1
  28. package/dist/src/cli/config.d.ts +4 -3
  29. package/dist/src/cli/config.d.ts.map +1 -1
  30. package/dist/src/cli/config.js +73 -31
  31. package/dist/src/cli/config.js.map +1 -1
  32. package/dist/src/cli/fetchTicket.d.ts +3 -3
  33. package/dist/src/cli/fetchTicket.d.ts.map +1 -1
  34. package/dist/src/cli/fetchTicket.js +7 -7
  35. package/dist/src/cli/fetchTicket.js.map +1 -1
  36. package/dist/src/cli/layers.d.ts +6 -5
  37. package/dist/src/cli/layers.d.ts.map +1 -1
  38. package/dist/src/cli/layers.js +16 -15
  39. package/dist/src/cli/layers.js.map +1 -1
  40. package/dist/src/cli/list.d.ts +3 -2
  41. package/dist/src/cli/list.d.ts.map +1 -1
  42. package/dist/src/cli/list.js +11 -5
  43. package/dist/src/cli/list.js.map +1 -1
  44. package/dist/src/cli/reconcile.d.ts +18 -3
  45. package/dist/src/cli/reconcile.d.ts.map +1 -1
  46. package/dist/src/cli/reconcile.js +73 -23
  47. package/dist/src/cli/reconcile.js.map +1 -1
  48. package/dist/src/cli/root.d.ts.map +1 -1
  49. package/dist/src/cli/root.js +3 -3
  50. package/dist/src/cli/root.js.map +1 -1
  51. package/dist/src/cli/setup.d.ts +14 -4
  52. package/dist/src/cli/setup.d.ts.map +1 -1
  53. package/dist/src/cli/setup.js +45 -94
  54. package/dist/src/cli/setup.js.map +1 -1
  55. package/dist/src/cli/timer/discard.d.ts +1 -1
  56. package/dist/src/cli/timer/discard.d.ts.map +1 -1
  57. package/dist/src/cli/timer/discard.js +2 -1
  58. package/dist/src/cli/timer/discard.js.map +1 -1
  59. package/dist/src/cli/timer/log.d.ts +1 -1
  60. package/dist/src/cli/timer/log.d.ts.map +1 -1
  61. package/dist/src/cli/timer/log.js +2 -1
  62. package/dist/src/cli/timer/log.js.map +1 -1
  63. package/dist/src/cli/timer/start.d.ts +2 -1
  64. package/dist/src/cli/timer/start.d.ts.map +1 -1
  65. package/dist/src/cli/timer/start.js +6 -8
  66. package/dist/src/cli/timer/start.js.map +1 -1
  67. package/dist/src/cli/timer/stop.d.ts +1 -1
  68. package/dist/src/cli/timer/stop.d.ts.map +1 -1
  69. package/dist/src/cli/timer.d.ts.map +1 -1
  70. package/dist/src/cli/timer.js +8 -1
  71. package/dist/src/cli/timer.js.map +1 -1
  72. package/dist/src/cli/unknownCommand.d.ts +24 -0
  73. package/dist/src/cli/unknownCommand.d.ts.map +1 -0
  74. package/dist/src/cli/unknownCommand.js +84 -0
  75. package/dist/src/cli/unknownCommand.js.map +1 -0
  76. package/dist/src/cli/watch.d.ts +2 -2
  77. package/dist/src/cli/watch.d.ts.map +1 -1
  78. package/dist/src/services/AgentSessionReader.d.ts +26 -12
  79. package/dist/src/services/AgentSessionReader.d.ts.map +1 -1
  80. package/dist/src/services/AgentSessionReader.js +163 -69
  81. package/dist/src/services/AgentSessionReader.js.map +1 -1
  82. package/dist/src/services/CodexTranscript.d.ts +50 -13
  83. package/dist/src/services/CodexTranscript.d.ts.map +1 -1
  84. package/dist/src/services/CodexTranscript.js +49 -13
  85. package/dist/src/services/CodexTranscript.js.map +1 -1
  86. package/dist/src/services/ConfigService.d.ts +4 -0
  87. package/dist/src/services/ConfigService.d.ts.map +1 -1
  88. package/dist/src/services/ConfigService.js +6 -2
  89. package/dist/src/services/ConfigService.js.map +1 -1
  90. package/dist/src/services/IssueFacts.d.ts +2 -2
  91. package/dist/src/services/IssueFacts.d.ts.map +1 -1
  92. package/dist/src/services/IssueFacts.js +5 -5
  93. package/dist/src/services/IssueFacts.js.map +1 -1
  94. package/dist/src/services/JiraAccess.d.ts +140 -0
  95. package/dist/src/services/JiraAccess.d.ts.map +1 -0
  96. package/dist/src/services/JiraAccess.js +204 -0
  97. package/dist/src/services/JiraAccess.js.map +1 -0
  98. package/dist/src/services/ProviderSnapshots.d.ts +41 -0
  99. package/dist/src/services/ProviderSnapshots.d.ts.map +1 -0
  100. package/dist/src/services/ProviderSnapshots.js +71 -0
  101. package/dist/src/services/ProviderSnapshots.js.map +1 -0
  102. package/dist/src/services/ReconcileService.d.ts +12 -4
  103. package/dist/src/services/ReconcileService.d.ts.map +1 -1
  104. package/dist/src/services/ReconcileService.js +223 -113
  105. package/dist/src/services/ReconcileService.js.map +1 -1
  106. package/dist/src/services/SavedEntries.d.ts +24 -4
  107. package/dist/src/services/SavedEntries.d.ts.map +1 -1
  108. package/dist/src/services/SavedEntries.js +335 -19
  109. package/dist/src/services/SavedEntries.js.map +1 -1
  110. package/dist/src/services/SessionAttributor.d.ts +12 -0
  111. package/dist/src/services/SessionAttributor.d.ts.map +1 -1
  112. package/dist/src/services/SessionAttributor.js +13 -1
  113. package/dist/src/services/SessionAttributor.js.map +1 -1
  114. package/dist/src/services/SessionLine.d.ts +29 -0
  115. package/dist/src/services/SessionLine.d.ts.map +1 -0
  116. package/dist/src/services/SessionLine.js +8 -0
  117. package/dist/src/services/SessionLine.js.map +1 -0
  118. package/dist/src/services/SourceLedger.d.ts +84 -1
  119. package/dist/src/services/SourceLedger.d.ts.map +1 -1
  120. package/dist/src/services/SourceLedger.js +178 -12
  121. package/dist/src/services/SourceLedger.js.map +1 -1
  122. package/dist/src/services/TicketRanking.d.ts +39 -0
  123. package/dist/src/services/TicketRanking.d.ts.map +1 -0
  124. package/dist/src/services/TicketRanking.js +87 -0
  125. package/dist/src/services/TicketRanking.js.map +1 -0
  126. package/dist/src/services/TimerService.d.ts +3 -3
  127. package/dist/src/services/TimerService.d.ts.map +1 -1
  128. package/dist/src/services/TimerService.js +6 -17
  129. package/dist/src/services/TimerService.js.map +1 -1
  130. package/dist/src/services/internal/retryTransport.d.ts +9 -0
  131. package/dist/src/services/internal/retryTransport.d.ts.map +1 -0
  132. package/dist/src/services/internal/retryTransport.js +15 -0
  133. package/dist/src/services/internal/retryTransport.js.map +1 -0
  134. package/dist/src/testing/fakeHeadless.d.ts +12 -1
  135. package/dist/src/testing/fakeHeadless.d.ts.map +1 -1
  136. package/dist/src/testing/fakeHeadless.js +83 -10
  137. package/dist/src/testing/fakeHeadless.js.map +1 -1
  138. package/dist/src/tui/App.js +1 -1
  139. package/dist/src/tui/atoms/runtime.d.ts +1 -1
  140. package/dist/src/tui/atoms/runtime.d.ts.map +1 -1
  141. package/dist/src/utils/hints.d.ts +4 -2
  142. package/dist/src/utils/hints.d.ts.map +1 -1
  143. package/dist/src/utils/hints.js +4 -2
  144. package/dist/src/utils/hints.js.map +1 -1
  145. package/dist/tsconfig.tsbuildinfo +1 -1
  146. package/package.json +8 -8
  147. package/skills/jcf/SKILL.md +9 -6
@@ -3,7 +3,7 @@ import * as SourceConsumption from "./sourceConsumption.js";
3
3
  * Which evidence placed a session on an Issue Key. `none` means no signal did — the session is
4
4
  * an Unattributed Session and is reported with its hours rather than guessed at.
5
5
  */
6
- export type AttributionSignal = "branch" | "path" | "standing" | "agent" | "none";
6
+ export type AttributionSignal = "branch" | "path" | "standing" | "agent" | "split" | "none";
7
7
  /**
8
8
  * Attribution Signals in precedence order — the first to yield an Issue Key wins. Also the
9
9
  * trust order: a bucket built from several sessions reports its *weakest* signal, because a row
@@ -19,6 +19,8 @@ export interface AttributableSession {
19
19
  readonly gitBranch: string | null;
20
20
  /** Issue Keys mined from the transcript — the closed choice set for a Coding Agent. */
21
21
  readonly candidateKeys: ReadonlyArray<string>;
22
+ /** Counts from the full in-scope transcript, before its bounded agent digest is constructed. */
23
+ readonly mentionCounts?: ReadonlyMap<string, number>;
22
24
  }
23
25
  /** How one Agent Session was placed (or not placed) on an Issue Key. */
24
26
  export interface SessionAttribution {
@@ -32,7 +34,16 @@ export interface SessionAttribution {
32
34
  * Such credit is reported so the hours stay visible, but is never offered for confirmation.
33
35
  */
34
36
  readonly belowConfidenceFloor: boolean;
37
+ /** Sprint candidates sharing this session, weighted by transcript mentions. Absent for single-ticket attribution. */
38
+ readonly targets?: ReadonlyArray<{
39
+ readonly ticketKey: string;
40
+ readonly weight: number;
41
+ }>;
35
42
  }
43
+ /** Count transcript mentions without deduplicating repeated ticket keys. */
44
+ export declare const ticketMentionCounts: (text: string) => ReadonlyMap<string, number>;
45
+ /** Split only unplaced or low-confidence sessions onto evidenced tickets in my known open sprint. */
46
+ export declare const splitSessionAttribution: (session: AttributableSession, attribution: SessionAttribution, sprint: ReadonlySet<string> | undefined, ignored: ReadonlySet<string>) => SessionAttribution;
36
47
  /**
37
48
  * True when a string is an Issue Key and nothing else.
38
49
  *
@@ -104,6 +115,7 @@ export interface DeterministicAttribution {
104
115
  */
105
116
  export declare const deterministicAttribution: (session: AttributableSession, options: {
106
117
  readonly standingMap: Readonly<Record<string, string>>;
118
+ readonly ignoredTickets?: ReadonlySet<string> | undefined;
107
119
  }) => DeterministicAttribution | null;
108
120
  /** What a Coding Agent decided about one session. `null` is a valid, expected answer. */
109
121
  export interface AgentChoice {
@@ -120,6 +132,7 @@ export declare const attributeSession: (session: AttributableSession, options: {
120
132
  /** Only consulted when no deterministic signal placed the session. */
121
133
  readonly agentChoice?: AgentChoice | null | undefined;
122
134
  readonly confidenceFloor: number;
135
+ readonly ignoredTickets?: ReadonlySet<string> | undefined;
123
136
  }) => SessionAttribution;
124
137
  /** One recorded moment of work inside an Agent Session. */
125
138
  export interface SessionActivity {
@@ -211,41 +224,16 @@ export interface OwnedRun {
211
224
  readonly startMs: number;
212
225
  readonly endMs: number;
213
226
  readonly bucketIds: ReadonlyArray<string>;
227
+ readonly weights?: ReadonlyMap<string, number> | undefined;
214
228
  }
215
229
  /**
216
- * Coalesce ownership so it changes no more often than the Dwell Floor.
230
+ * Coalesce rapid ownership changes without removing overlapping tickets.
217
231
  *
218
- * **What this is for.** Three concurrent sessions on three Issue Keys interleave their prompts, and
219
- * read literally that says the work changed ticket every few minutes. It did not — that is an
220
- * artefact of reading several transcripts at once. A day of it is two dozen slivers on a calendar and
221
- * indefensible on a timesheet.
222
- *
223
- * **Two rules, in order.**
224
- *
225
- * 1. *A ticket present for less than the floor inside one connected source cluster, interrupting work
226
- * that resumes after it, was not a ticket that was worked on.* It was a keystroke inside other work — a branch
227
- * checked, a file opened, a question asked — so its time goes to the work around it. This is what
228
- * actually removes the slivers: they rarely touch anything, because a transcript goes quiet
229
- * between prompts, and they are as often overlapping as adjacent, because concurrent sessions
230
- * overlap by definition. Adjacency and overlap were both tried as the test and both left the
231
- * interleaving as they found it. The requirement for work on *both* sides is what keeps a genuine
232
- * short piece of work — eight minutes on another ticket, and then the day moves on — from being
233
- * swallowed by what came before it.
234
- * 2. *Tenancy, not adjacency.* Between tickets that were genuinely worked on, whoever takes the
235
- * timeline holds it for at least the floor: a stretch beginning inside that tenure and owned by
236
- * someone else is credited to the incumbent. This catches two real tickets alternating quickly.
237
- *
238
- * **What it never does.** It reassigns time and never creates or drops any — idle gaps are not swept
239
- * into a tenure — so the inequality that makes a proposal safe to accept survives intact. Nothing is
240
- * ever welded across a local midnight, because runs are bucketed by the day they start in.
241
- *
242
- * **Unplaced hours take no part.** A stretch nothing placed neither holds a tenure nor loses its time
243
- * to one: promoting it would bill work no transcript placed on that ticket, and demoting an
244
- * attributed sliver into it would quietly discard billable work. An attributed tenure simply
245
- * continues across it.
246
- *
247
- * **A minor ticket with nothing to belong to keeps its own time.** Four minutes alone in an otherwise
248
- * empty day has no surrounding work to join, and dropping it would lose work that happened.
232
+ * A short sole-owner interruption returns to surrounding major work only when that work resumes
233
+ * in the same connected source cluster. Overlapping tickets keep their ownership regardless of
234
+ * their presence length. Tenancy holds between disjoint attributed owners for the dwell period.
235
+ * Unplaced time retains its own credit and cannot acquire or lose an attributed ticket's time.
236
+ * Idle gaps and local midnight are barriers; no coalescing creates additional wall-clock time.
249
237
  */
250
238
  export declare const applyDwellFloor: (slices: ReadonlyArray<OwnedRun>, options: {
251
239
  readonly dwellSeconds: number;
@@ -324,6 +312,10 @@ export declare const splitCredits: (windows: ReadonlyArray<SessionWindows>, attr
324
312
  * {@link DEFAULT_DWELL_SECONDS}; zero turns the rule off and reports the raw interleaving.
325
313
  */
326
314
  readonly dwellSeconds?: number | undefined;
315
+ /** Higher values receive writable minutes first when a shared stretch is too short. */
316
+ readonly priority?: ((ticketKey: string, day: string) => number) | undefined;
317
+ /** Remove these tickets' windows before sharing; overlapping tickets absorb them, never solo time. */
318
+ readonly ignoredTickets?: ReadonlySet<string> | undefined;
327
319
  }) => CreditSplit;
328
320
  /** What Clockify and Jira already hold for one `(Issue Key, day)` bucket. */
329
321
  export interface RecordedBucket {
@@ -346,6 +338,8 @@ export interface RecordedBucket {
346
338
  }
347
339
  /** A Proposed Worklog: the gap between what a session accounts for and what is already recorded. */
348
340
  export interface SessionProposal {
341
+ /** Provider-window review holds. Evidence remains readable; the named providers cannot write it. */
342
+ readonly writeBlocked?: Readonly<Partial<Record<SourceConsumption.Source, string>>> | undefined;
349
343
  readonly ticketKey: string;
350
344
  readonly day: string;
351
345
  readonly signal: AttributionSignal;
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/agent/sessions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/agent/sessions.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,7 @@ export const ATTRIBUTION_PRECEDENCE = [
44
44
  "path",
45
45
  "standing",
46
46
  "agent",
47
+ "split",
47
48
  "none"
48
49
  ];
49
50
  const signalRank = (signal) => {
@@ -62,6 +63,34 @@ const signalRank = (signal) => {
62
63
  */
63
64
  const TICKET_KEY = /(?<![A-Za-z0-9])[A-Z][A-Z0-9]{1,9}-\d{1,6}(?![A-Za-z0-9])/g;
64
65
  const matchTicketKeys = (text) => [...text.matchAll(TICKET_KEY)].map((m) => m[0]);
66
+ /** Count transcript mentions without deduplicating repeated ticket keys. */
67
+ export const ticketMentionCounts = (text) => {
68
+ const counts = new Map();
69
+ for (const key of matchTicketKeys(text))
70
+ counts.set(key, (counts.get(key) ?? 0) + 1);
71
+ return counts;
72
+ };
73
+ /** Split only unplaced or low-confidence sessions onto evidenced tickets in my known open sprint. */
74
+ export const splitSessionAttribution = (session, attribution, sprint, ignored) => {
75
+ const counts = session.mentionCounts;
76
+ if (sprint === undefined || counts === undefined ||
77
+ (attribution.ticketKey !== null && !attribution.belowConfidenceFloor))
78
+ return attribution;
79
+ const targets = [...new Set(session.candidateKeys)]
80
+ .filter((key) => sprint.has(key) && !ignored.has(key))
81
+ .flatMap((ticketKey) => {
82
+ const weight = counts.get(ticketKey);
83
+ return weight === undefined ? [] : [{ ticketKey, weight }];
84
+ });
85
+ return targets.length === 0 ? attribution : {
86
+ sessionId: attribution.sessionId,
87
+ ticketKey: null,
88
+ signal: "split",
89
+ confidence: null,
90
+ belowConfidenceFloor: false,
91
+ targets
92
+ };
93
+ };
65
94
  /**
66
95
  * True when a string is an Issue Key and nothing else.
67
96
  *
@@ -189,14 +218,17 @@ export const standingAttribution = (cwd, map) => {
189
218
  */
190
219
  export const deterministicAttribution = (session, options) => {
191
220
  const fromBranch = ticketKeyFromBranch(session.gitBranch);
192
- if (fromBranch !== null)
193
- return { ticketKey: fromBranch, signal: "branch" };
221
+ if (fromBranch !== null) {
222
+ return options.ignoredTickets?.has(fromBranch) === true ? null : { ticketKey: fromBranch, signal: "branch" };
223
+ }
194
224
  const fromPath = ticketKeyFromPath(session.cwd);
195
- if (fromPath !== null)
196
- return { ticketKey: fromPath, signal: "path" };
225
+ if (fromPath !== null) {
226
+ return options.ignoredTickets?.has(fromPath) === true ? null : { ticketKey: fromPath, signal: "path" };
227
+ }
197
228
  const standing = standingAttribution(session.cwd, options.standingMap);
198
- if (standing !== null)
199
- return { ticketKey: standing, signal: "standing" };
229
+ if (standing !== null) {
230
+ return options.ignoredTickets?.has(standing) === true ? null : { ticketKey: standing, signal: "standing" };
231
+ }
200
232
  return null;
201
233
  };
202
234
  /**
@@ -205,7 +237,7 @@ export const deterministicAttribution = (session, options) => {
205
237
  * choice below `confidenceFloor` is marked so it can be reported without being offered.
206
238
  */
207
239
  export const attributeSession = (session, options) => {
208
- const deterministic = deterministicAttribution(session, { standingMap: options.standingMap });
240
+ const deterministic = deterministicAttribution(session, options);
209
241
  if (deterministic !== null) {
210
242
  return {
211
243
  sessionId: session.sessionId,
@@ -225,7 +257,8 @@ export const attributeSession = (session, options) => {
225
257
  };
226
258
  // The choice set is closed over the transcript's own text: a key the transcript never
227
259
  // mentioned cannot reach a worklog, however confidently it was named.
228
- if (choice === null || choice === undefined || !session.candidateKeys.includes(choice.ticketKey)) {
260
+ if (choice === null || choice === undefined || options.ignoredTickets?.has(choice.ticketKey) === true ||
261
+ !session.candidateKeys.includes(choice.ticketKey)) {
229
262
  return unattributed;
230
263
  }
231
264
  return {
@@ -340,11 +373,15 @@ const overlapSlices = (spansByBucket) => {
340
373
  for (let i = 0; i < ordered.length - 1; i++) {
341
374
  const startMs = ordered[i];
342
375
  const endMs = ordered[i + 1];
343
- const bucketIds = [...spansByBucket.entries()]
344
- .filter(([, spans]) => spans.some((span) => span.startMs <= startMs && span.endMs >= endMs))
345
- .map(([bucketId]) => bucketId);
346
- if (bucketIds.length > 0)
347
- slices.push({ startMs, endMs, bucketIds });
376
+ const weights = new Map([...spansByBucket].flatMap(([id, spans]) => {
377
+ const active = spans.filter((span) => span.startMs <= startMs && span.endMs >= endMs);
378
+ // Duplicate sessions on one ticket union their presence, rather than winning extra time.
379
+ return active.length === 0
380
+ ? []
381
+ : [[id, Math.max(...active.map((span) => span.weight ?? 1))]];
382
+ }));
383
+ if (weights.size > 0)
384
+ slices.push({ startMs, endMs, bucketIds: [...weights.keys()], weights });
348
385
  }
349
386
  return slices;
350
387
  };
@@ -367,6 +404,7 @@ const sameOwners = (a, b) => a.length === b.length && a.every((id, index) => id
367
404
  */
368
405
  const joinable = (previous, next) => previous.endMs === next.startMs &&
369
406
  sameOwners(previous.bucketIds, next.bucketIds) &&
407
+ previous.bucketIds.every((id) => (previous.weights?.get(id) ?? 1) === (next.weights?.get(id) ?? 1)) &&
370
408
  localDay(new Date(previous.startMs)) === localDay(new Date(next.startMs));
371
409
  /** Join touching stretches with identical owners. A gap of idle time always separates two runs. */
372
410
  const mergeRuns = (runs) => {
@@ -382,39 +420,13 @@ const mergeRuns = (runs) => {
382
420
  return merged;
383
421
  };
384
422
  /**
385
- * Coalesce ownership so it changes no more often than the Dwell Floor.
386
- *
387
- * **What this is for.** Three concurrent sessions on three Issue Keys interleave their prompts, and
388
- * read literally that says the work changed ticket every few minutes. It did not — that is an
389
- * artefact of reading several transcripts at once. A day of it is two dozen slivers on a calendar and
390
- * indefensible on a timesheet.
423
+ * Coalesce rapid ownership changes without removing overlapping tickets.
391
424
  *
392
- * **Two rules, in order.**
393
- *
394
- * 1. *A ticket present for less than the floor inside one connected source cluster, interrupting work
395
- * that resumes after it, was not a ticket that was worked on.* It was a keystroke inside other work — a branch
396
- * checked, a file opened, a question asked — so its time goes to the work around it. This is what
397
- * actually removes the slivers: they rarely touch anything, because a transcript goes quiet
398
- * between prompts, and they are as often overlapping as adjacent, because concurrent sessions
399
- * overlap by definition. Adjacency and overlap were both tried as the test and both left the
400
- * interleaving as they found it. The requirement for work on *both* sides is what keeps a genuine
401
- * short piece of work — eight minutes on another ticket, and then the day moves on — from being
402
- * swallowed by what came before it.
403
- * 2. *Tenancy, not adjacency.* Between tickets that were genuinely worked on, whoever takes the
404
- * timeline holds it for at least the floor: a stretch beginning inside that tenure and owned by
405
- * someone else is credited to the incumbent. This catches two real tickets alternating quickly.
406
- *
407
- * **What it never does.** It reassigns time and never creates or drops any — idle gaps are not swept
408
- * into a tenure — so the inequality that makes a proposal safe to accept survives intact. Nothing is
409
- * ever welded across a local midnight, because runs are bucketed by the day they start in.
410
- *
411
- * **Unplaced hours take no part.** A stretch nothing placed neither holds a tenure nor loses its time
412
- * to one: promoting it would bill work no transcript placed on that ticket, and demoting an
413
- * attributed sliver into it would quietly discard billable work. An attributed tenure simply
414
- * continues across it.
415
- *
416
- * **A minor ticket with nothing to belong to keeps its own time.** Four minutes alone in an otherwise
417
- * empty day has no surrounding work to join, and dropping it would lose work that happened.
425
+ * A short sole-owner interruption returns to surrounding major work only when that work resumes
426
+ * in the same connected source cluster. Overlapping tickets keep their ownership regardless of
427
+ * their presence length. Tenancy holds between disjoint attributed owners for the dwell period.
428
+ * Unplaced time retains its own credit and cannot acquire or lose an attributed ticket's time.
429
+ * Idle gaps and local midnight are barriers; no coalescing creates additional wall-clock time.
418
430
  */
419
431
  export const applyDwellFloor = (slices, options) => {
420
432
  const dwellMs = Math.max(0, options.dwellSeconds) * 1000;
@@ -467,16 +479,15 @@ export const applyDwellFloor = (slices, options) => {
467
479
  };
468
480
  const withoutMinors = runs.map((run, index) => {
469
481
  const day = localDay(new Date(run.startMs));
470
- const kept = run.bucketIds.filter((id) => major(id, index));
471
- if (kept.length > 0)
472
- return { ...run, bucketIds: kept };
482
+ if (run.bucketIds.length > 1 || run.bucketIds.some((id) => major(id, index)))
483
+ return run;
473
484
  // Every owner was minor, so this is only an *interruption* if the work it interrupts resumes:
474
485
  // there has to be major work on both sides of it. Eight minutes on another ticket after half an
475
486
  // hour, with nothing after it, is a short piece of work rather than a keystroke inside a longer
476
487
  // one — and swallowing it would lose the change of ticket a person actually made.
477
488
  const before = majorOwnersToward(index, day, -1);
478
489
  const after = majorOwnersToward(index, day, 1);
479
- return before === undefined || after === undefined ? run : { ...run, bucketIds: before };
490
+ return before === undefined || after === undefined ? run : { ...run, bucketIds: before, weights: undefined };
480
491
  });
481
492
  // Phase two: between tickets that were genuinely worked on, ownership holds for the floor.
482
493
  let tenant = null;
@@ -499,7 +510,7 @@ export const applyDwellFloor = (slices, options) => {
499
510
  }
500
511
  const overlapsTenant = tenant !== null && run.bucketIds.some((id) => tenant.bucketIds.includes(id));
501
512
  if (tenant !== null && sameDay && run.startMs - tenant.sinceMs < dwellMs && !overlapsTenant) {
502
- held.push({ ...run, bucketIds: tenant.bucketIds });
513
+ held.push({ ...run, bucketIds: tenant.bucketIds, weights: undefined });
503
514
  continue;
504
515
  }
505
516
  tenant = { bucketIds: run.bucketIds, sinceMs: run.startMs };
@@ -585,8 +596,10 @@ const wholeSeconds = (spans, totalSeconds) => {
585
596
  * Issue Key that time belongs to.
586
597
  *
587
598
  * A slice's duration is divided, never duplicated, so the total across every bucket can never
588
- * exceed the wall clock of the day. With a positive dwell floor, overlapping attributed runs
589
- * are scheduled evenly among the strongest tickets that fit; zero preserves raw shares.
599
+ * exceed the wall clock of the day. With a positive dwell floor, each ticket receives one packed
600
+ * block per connected cluster, ordered by its first activity. Touching same-ticket blocks coalesce
601
+ * after packing; idle gaps remain separate. Sub-minute shares fold into another ranked ticket when
602
+ * the cluster has a writable minute; zero preserves raw shares.
590
603
  */
591
604
  const shareBetweenBuckets = (spansByBucket, options) => {
592
605
  const totals = new Map();
@@ -603,7 +616,7 @@ const shareBetweenBuckets = (spansByBucket, options) => {
603
616
  ...run,
604
617
  bucketIds: run.bucketIds.filter((id) => !options.coveredByCertain(id, run.bucketIds))
605
618
  })), options);
606
- const runs = scheduleRuns(originalRuns, options.dwellSeconds, options.attributed);
619
+ const runs = scheduleRuns(originalRuns, options.dwellSeconds, options.attributed, options.priority);
607
620
  for (const run of originalRuns) {
608
621
  for (const id of run.bucketIds)
609
622
  add(id, localDay(new Date(run.startMs)), 0, run.endMs - run.startMs);
@@ -617,8 +630,10 @@ const shareBetweenBuckets = (spansByBucket, options) => {
617
630
  const duration = run.endMs - run.startMs;
618
631
  // Divided, never duplicated: this is the one place an instant becomes seconds, and it is the
619
632
  // same number that reaches the row's total and the block a person accepts.
620
- const creditedMs = duration / run.bucketIds.length;
621
- for (const [index, bucketId] of run.bucketIds.entries()) {
633
+ const totalWeight = run.bucketIds.reduce((sum, id) => sum + (run.weights?.get(id) ?? 1), 0);
634
+ let cursorMs = run.startMs;
635
+ for (const bucketId of run.bucketIds) {
636
+ const creditedMs = duration * (run.weights?.get(bucketId) ?? 1) / totalWeight;
622
637
  add(bucketId, day, creditedMs, 0);
623
638
  const byDay = settlementEnds.get(bucketId) ?? new Map();
624
639
  byDay.set(day, Math.max(byDay.get(day) ?? 0, run.settlementEndMs));
@@ -628,10 +643,11 @@ const shareBetweenBuckets = (spansByBucket, options) => {
628
643
  sourceStarts.set(bucketId, startsByDay);
629
644
  runSpans.set(bucketId, [...(runSpans.get(bucketId) ?? []), {
630
645
  creditedMs,
631
- endMs: options.dwellSeconds > 0 ? run.startMs + creditedMs * (index + 1) : run.endMs,
632
- startMs: options.dwellSeconds > 0 ? run.startMs + creditedMs * index : run.startMs,
646
+ endMs: options.dwellSeconds > 0 ? cursorMs + creditedMs : run.endMs,
647
+ startMs: options.dwellSeconds > 0 ? cursorMs : run.startMs,
633
648
  sourceStartMs: run.sourceStartMs
634
649
  }]);
650
+ cursorMs += creditedMs;
635
651
  }
636
652
  }
637
653
  const result = new Map();
@@ -671,6 +687,8 @@ const weakerConfidence = (a, b) => {
671
687
  const bucketId = (kind, ticketKey) => `${kind}\u0000${ticketKey ?? ""}`;
672
688
  class MissingDayAttributionError extends Data.TaggedError("MissingDayAttributionError") {
673
689
  }
690
+ class InvalidAttributionWeightError extends Data.TaggedError("InvalidAttributionWeightError") {
691
+ }
674
692
  /**
675
693
  * Fold per-session active windows onto Issue Keys, dividing every overlap between *distinct* keys.
676
694
  *
@@ -693,34 +711,50 @@ export const splitCredits = (windows, attributions, options) => {
693
711
  const dayKey = (bucketId, day) => `${bucketId}\u0000${day}`;
694
712
  for (const session of windows) {
695
713
  const attribution = bySession.get(session.sessionId);
696
- const ticketKey = attribution?.ticketKey ?? null;
697
- const kind = ticketKey === null
698
- ? "unattributed"
699
- : attribution?.belowConfidenceFloor === true
700
- ? "withheld"
701
- : "attributed";
702
- const id = bucketId(kind, ticketKey);
703
- spansByBucket.set(id, [...(spansByBucket.get(id) ?? []), ...session.spans]);
704
- // Session windows are already day-bounded, so a span belongs to exactly one day.
705
- for (const span of session.spans) {
706
- const key = dayKey(id, localDay(new Date(span.startMs)));
707
- sessionsByBucketDay.set(key, (sessionsByBucketDay.get(key) ?? new Set()).add(session.sessionId));
708
- const previous = evidenceByBucketDay.get(key);
709
- const signal = attribution?.signal ?? "none";
710
- const confidence = attribution?.confidence ?? null;
711
- evidenceByBucketDay.set(key, {
712
- signal: previous === undefined || signalRank(signal) > signalRank(previous.signal) ? signal : previous.signal,
713
- confidence: previous === undefined ? confidence : weakerConfidence(previous.confidence, confidence)
714
+ const targets = attribution?.targets ?? [{ ticketKey: attribution?.ticketKey ?? null, weight: 1 }];
715
+ if (targets.some((target) => !Number.isFinite(target.weight) || target.weight <= 0)) {
716
+ throw new InvalidAttributionWeightError({ message: "Split targets require finite positive weights" });
717
+ }
718
+ const allowed = targets.filter((target) => target.ticketKey === null || options?.ignoredTickets?.has(target.ticketKey) !== true);
719
+ const totalWeight = allowed.reduce((sum, target) => sum + target.weight, 0);
720
+ for (const target of allowed) {
721
+ const ticketKey = target.ticketKey;
722
+ if (ticketKey !== null && options?.ignoredTickets?.has(ticketKey) === true)
723
+ continue;
724
+ const kind = ticketKey === null
725
+ ? "unattributed"
726
+ : attribution?.belowConfidenceFloor === true
727
+ ? "withheld"
728
+ : "attributed";
729
+ const id = bucketId(kind, ticketKey);
730
+ spansByBucket.set(id, [
731
+ ...(spansByBucket.get(id) ?? []),
732
+ ...session.spans.map((span) => ({
733
+ ...span,
734
+ weight: target.weight / totalWeight
735
+ }))
736
+ ]);
737
+ // Session windows are already day-bounded, so a span belongs to exactly one day.
738
+ for (const span of session.spans) {
739
+ const key = dayKey(id, localDay(new Date(span.startMs)));
740
+ sessionsByBucketDay.set(key, (sessionsByBucketDay.get(key) ?? new Set()).add(session.sessionId));
741
+ const previous = evidenceByBucketDay.get(key);
742
+ const signal = attribution?.signal ?? "none";
743
+ const confidence = attribution?.confidence ?? null;
744
+ evidenceByBucketDay.set(key, {
745
+ signal: previous === undefined || signalRank(signal) > signalRank(previous.signal) ? signal : previous.signal,
746
+ confidence: previous === undefined ? confidence : weakerConfidence(previous.confidence, confidence)
747
+ });
748
+ }
749
+ const existing = metaByBucket.get(id);
750
+ metaByBucket.set(id, {
751
+ kind,
752
+ ticketKey,
753
+ sessions: new Set([...(existing?.sessions ?? []), session.sessionId])
714
754
  });
715
755
  }
716
- const existing = metaByBucket.get(id);
717
- metaByBucket.set(id, {
718
- kind,
719
- ticketKey,
720
- sessions: new Set([...(existing?.sessions ?? []), session.sessionId])
721
- });
722
756
  }
723
- const shared = shareBetweenBuckets(new Map([...spansByBucket.entries()].map(([id, spans]) => [id, mergeSpansWithinDays(spans)])), {
757
+ const shared = shareBetweenBuckets(spansByBucket, {
724
758
  attributed: (id) => metaByBucket.get(id)?.kind === "attributed",
725
759
  coveredByCertain: (id, activeIds) => {
726
760
  const held = metaByBucket.get(id);
@@ -729,7 +763,11 @@ export const splitCredits = (windows, attributions, options) => {
729
763
  return certain?.kind === "attributed" && certain.ticketKey === held.ticketKey;
730
764
  });
731
765
  },
732
- dwellSeconds: options?.dwellSeconds ?? DEFAULT_DWELL_SECONDS
766
+ dwellSeconds: options?.dwellSeconds ?? DEFAULT_DWELL_SECONDS,
767
+ priority: (id, day) => {
768
+ const ticketKey = metaByBucket.get(id)?.ticketKey;
769
+ return ticketKey === null || ticketKey === undefined ? 0 : options?.priority?.(ticketKey, day) ?? 0;
770
+ }
733
771
  });
734
772
  const attributed = [];
735
773
  const withheld = [];