@knpkv/jira-clockify 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -18
- package/dist/package.json +1 -1
- package/dist/src/agent/schedule.d.ts +6 -5
- package/dist/src/agent/schedule.d.ts.map +1 -1
- package/dist/src/agent/schedule.js +117 -102
- package/dist/src/agent/schedule.js.map +1 -1
- package/dist/src/agent/sessions.d.ts +27 -33
- package/dist/src/agent/sessions.d.ts.map +1 -1
- package/dist/src/agent/sessions.js +121 -83
- package/dist/src/agent/sessions.js.map +1 -1
- package/dist/src/agent/writePlanning.d.ts +2 -0
- package/dist/src/agent/writePlanning.d.ts.map +1 -1
- package/dist/src/agent/writePlanning.js +4 -1
- package/dist/src/agent/writePlanning.js.map +1 -1
- package/dist/src/cli/agentWrite.d.ts.map +1 -1
- package/dist/src/cli/agentWrite.js +12 -5
- package/dist/src/cli/agentWrite.js.map +1 -1
- package/dist/src/cli/auth.d.ts +39 -2
- package/dist/src/cli/auth.d.ts.map +1 -1
- package/dist/src/cli/auth.js +29 -5
- package/dist/src/cli/auth.js.map +1 -1
- package/dist/src/cli/config.d.ts +2 -2
- package/dist/src/cli/config.d.ts.map +1 -1
- package/dist/src/cli/config.js +34 -6
- package/dist/src/cli/config.js.map +1 -1
- package/dist/src/cli/layers.d.ts.map +1 -1
- package/dist/src/cli/layers.js +1 -1
- package/dist/src/cli/layers.js.map +1 -1
- package/dist/src/cli/reconcile.d.ts +6 -0
- package/dist/src/cli/reconcile.d.ts.map +1 -1
- package/dist/src/cli/reconcile.js +2 -0
- package/dist/src/cli/reconcile.js.map +1 -1
- package/dist/src/cli/setup.d.ts +1 -1
- package/dist/src/cli/setup.d.ts.map +1 -1
- package/dist/src/services/AgentSessionReader.d.ts +26 -12
- package/dist/src/services/AgentSessionReader.d.ts.map +1 -1
- package/dist/src/services/AgentSessionReader.js +163 -69
- package/dist/src/services/AgentSessionReader.js.map +1 -1
- package/dist/src/services/CodexTranscript.d.ts +50 -13
- package/dist/src/services/CodexTranscript.d.ts.map +1 -1
- package/dist/src/services/CodexTranscript.js +49 -13
- package/dist/src/services/CodexTranscript.js.map +1 -1
- package/dist/src/services/ConfigService.d.ts +2 -0
- package/dist/src/services/ConfigService.d.ts.map +1 -1
- package/dist/src/services/ConfigService.js +4 -1
- package/dist/src/services/ConfigService.js.map +1 -1
- package/dist/src/services/ProviderSnapshots.d.ts +41 -0
- package/dist/src/services/ProviderSnapshots.d.ts.map +1 -0
- package/dist/src/services/ProviderSnapshots.js +81 -0
- package/dist/src/services/ProviderSnapshots.js.map +1 -0
- package/dist/src/services/ReconcileService.d.ts +11 -3
- package/dist/src/services/ReconcileService.d.ts.map +1 -1
- package/dist/src/services/ReconcileService.js +212 -109
- package/dist/src/services/ReconcileService.js.map +1 -1
- package/dist/src/services/SavedEntries.d.ts +24 -4
- package/dist/src/services/SavedEntries.d.ts.map +1 -1
- package/dist/src/services/SavedEntries.js +335 -19
- package/dist/src/services/SavedEntries.js.map +1 -1
- package/dist/src/services/SessionAttributor.d.ts +12 -0
- package/dist/src/services/SessionAttributor.d.ts.map +1 -1
- package/dist/src/services/SessionAttributor.js +13 -1
- package/dist/src/services/SessionAttributor.js.map +1 -1
- package/dist/src/services/SessionLine.d.ts +29 -0
- package/dist/src/services/SessionLine.d.ts.map +1 -0
- package/dist/src/services/SessionLine.js +8 -0
- package/dist/src/services/SessionLine.js.map +1 -0
- package/dist/src/services/SourceLedger.d.ts +84 -1
- package/dist/src/services/SourceLedger.d.ts.map +1 -1
- package/dist/src/services/SourceLedger.js +178 -12
- package/dist/src/services/SourceLedger.js.map +1 -1
- package/dist/src/services/TicketRanking.d.ts +39 -0
- package/dist/src/services/TicketRanking.d.ts.map +1 -0
- package/dist/src/services/TicketRanking.js +87 -0
- package/dist/src/services/TicketRanking.js.map +1 -0
- package/dist/src/services/internal/retryTransport.d.ts +9 -0
- package/dist/src/services/internal/retryTransport.d.ts.map +1 -0
- package/dist/src/services/internal/retryTransport.js +15 -0
- package/dist/src/services/internal/retryTransport.js.map +1 -0
- package/dist/src/testing/fakeHeadless.d.ts +11 -0
- package/dist/src/testing/fakeHeadless.d.ts.map +1 -1
- package/dist/src/testing/fakeHeadless.js +66 -3
- package/dist/src/testing/fakeHeadless.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -119,20 +119,33 @@ Codex rollouts live under `~/.codex/sessions` in creation-date directories. Thos
|
|
|
119
119
|
identify the working project, so JCF decodes their metadata locally before applying session roots
|
|
120
120
|
to each stretch of work. Resumed rollouts in older directories remain eligible for the current
|
|
121
121
|
week. Large tool payloads are discarded while streaming the file. Current `UserMessage` events
|
|
122
|
-
and older `user_message` events
|
|
123
|
-
copies, compacted history and native subagent
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
122
|
+
and older `user_message` events open a turn; completed items continue it and `task_complete` ends
|
|
123
|
+
it. Injected instructions, response-item prompt copies, compacted history and native subagent
|
|
124
|
+
rollouts establish nothing. Selecting Claude or Codex as the matching agent does not restrict which
|
|
125
|
+
of these two transcript sources is scanned.
|
|
126
|
+
|
|
127
|
+
Presence is a _supervised turn_. A message you typed — including one typed while the agent was busy,
|
|
128
|
+
which Claude stores as a queued command — opens a turn, and the agent's work inside it counts until
|
|
129
|
+
the agent ends the turn, a task notification or auto-continuation takes over, or the agent is silent
|
|
130
|
+
for longer than the idle cap. Agent output outside a turn you started never counts: a task
|
|
131
|
+
notification, an expanded skill (`isMeta`) or a subagent's own prompt cannot open one, since they
|
|
132
|
+
show the agent was busy rather than that you were working. Gaps longer than the idle cap are
|
|
131
133
|
credited to nothing, and any moment you were working on several tickets at once is divided equally
|
|
132
|
-
between them — so a day's proposals can never add up to more than that day's wall clock.
|
|
133
|
-
spent reading and thinking between prompts is therefore under-counted rather than over-counted; a day
|
|
134
|
+
between them — so a day's proposals can never add up to more than that day's wall clock. A day
|
|
134
135
|
with a timer still running is reported but never proposed.
|
|
135
136
|
|
|
137
|
+
When parallel tickets compete for the same minutes, tickets in your open sprint come first, then
|
|
138
|
+
tickets you have not logged that day, then the strength of their evidence. Key-only JQL searches —
|
|
139
|
+
one for the open sprint, one per day for logged tickets — supply those facts, which also appear beside candidates in the matching prompt as tie-breakers.
|
|
140
|
+
When Jira cannot answer, every ticket ranks equally. Inside one unbroken stretch each ticket gets a
|
|
141
|
+
single block, ordered by when it first appeared and packed back to back; a ticket that cannot reach
|
|
142
|
+
a minute folds into the one ranked above it. Work an orchestrator agent prompts into a worker pane
|
|
143
|
+
counts like your own typing. An orchestrating session that no branch, path or confident agent answer
|
|
144
|
+
places is split across the open-sprint tickets assigned to you that it mentions, weighted by mentions
|
|
145
|
+
and computed per active stretch, so settled time never moves when the session later mentions more.
|
|
146
|
+
Splitting needs a verified Jira answer about the sprint; without one the session stays unplaced.
|
|
147
|
+
`jcf watch` reads deterministically and never splits: such a session stays unplaced there.
|
|
148
|
+
|
|
136
149
|
Everything you need to judge a row is on the row itself, in the picker: when the work item started
|
|
137
150
|
and ended, the issue summary, its assignee, the attribution signal, what each side already holds, and
|
|
138
151
|
how many blocks the total spans. So the number is checkable against your memory of the day rather
|
|
@@ -175,12 +188,13 @@ edits, including removal of the source suffix, do not reset its consumed seconds
|
|
|
175
188
|
read still observes genuine duration changes and deletions. The suffix can import a legacy entry on
|
|
176
189
|
first read, but text alone does not override an existing ID binding.
|
|
177
190
|
|
|
178
|
-
The same private file now stores version
|
|
191
|
+
The same private file now stores version 5: it also remembers the IDs and original starts of ordinary
|
|
179
192
|
entries seen in a newly reviewed forward interval, separately by provider and account. Repeated or
|
|
180
193
|
overlapping review can recognize those entries. A new unmarked entry in older coverage or a changed
|
|
181
194
|
start for a remembered ID needs manual review; the tool does not infer its origin from a timestamp.
|
|
182
|
-
Versions 1
|
|
183
|
-
|
|
195
|
+
Versions 1 through 4 upgrade only on a successful atomic write. Versions 1 and 2 load without
|
|
196
|
+
inventing ordinary entries; earlier versions never invent replacement intents or Jira creation
|
|
197
|
+
checkpoints. New Clockify evidence is scoped to the configured endpoint, workspace, and user verified by
|
|
184
198
|
that credential. Older Clockify scopes cannot prove the endpoint: affected windows, observations,
|
|
185
199
|
pending intents, and bindings remain intact and held for private manual review. Neither switching
|
|
186
200
|
the endpoint nor editing a description turns them into a fresh empty account. Jira evidence remains
|
|
@@ -328,14 +342,37 @@ an explicit full read collects new session evidence.
|
|
|
328
342
|
### Ticket overlap and live matching
|
|
329
343
|
|
|
330
344
|
With the default 900-second dwell floor, overlapping attributed work is allocated
|
|
331
|
-
in sequential blocks
|
|
332
|
-
|
|
333
|
-
tickets
|
|
345
|
+
in sequential blocks across every evidenced ticket. Each ticket receives a writable
|
|
346
|
+
minute when the stretch permits it. Open-sprint tickets assigned to you rank first,
|
|
347
|
+
then tickets not yet logged that day, then evidence weight. Shorter shares remain
|
|
348
|
+
credited; the scheduler never invents minutes. Mixed stretches reserve unplaced credit before allocating known tickets. Separate
|
|
334
349
|
work, idle gaps, wholly unplaced stretches and midnight stay
|
|
335
350
|
separate. Short standalone work is never inflated. Setting dwell to zero retains
|
|
336
351
|
raw overlap sharing. Proposal blocks and confirmed amounts use the same timeline;
|
|
337
352
|
`activeSeconds` retains the original activity duration.
|
|
338
353
|
|
|
354
|
+
### Ignoring session tickets
|
|
355
|
+
|
|
356
|
+
```sh
|
|
357
|
+
jcf config set session-ignore PROJ-42 # Ignore in every week
|
|
358
|
+
jcf config unset session-ignore PROJ-42 # Restore
|
|
359
|
+
jcf config # Lists ignored tickets
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
`sessionIgnoredTickets` defaults to `[]` and persists validated issue keys. Ignored
|
|
363
|
+
branch, path or standing matches fall through to the attribution agent, whose
|
|
364
|
+
candidate list excludes ignored keys. An ignored key cannot become a final match.
|
|
365
|
+
If the agent chooses another evidenced key, that work can be proposed there.
|
|
366
|
+
Otherwise the ignored session's windows are removed before sharing: overlapping
|
|
367
|
+
tickets receive those minutes; solo time is not offered elsewhere.
|
|
368
|
+
|
|
369
|
+
Session reports and `--json` include `ignored` rows with `ticketKey`, `day` and
|
|
370
|
+
`seconds`. These are raw active windows unioned per ignored ticket/day, before
|
|
371
|
+
sharing, so simultaneous sessions on one key count once. They explain suppressed
|
|
372
|
+
evidence and must not be added to allocated totals. A fresh recorded read also
|
|
373
|
+
filters newly ignored tickets out of retained proposals; rescan sessions to
|
|
374
|
+
redistribute overlapping credit or restore an ignored ticket.
|
|
375
|
+
|
|
339
376
|
`SessionAttributor.attribute` accepts an optional activity observer. Reconciliation
|
|
340
377
|
forwards visible text and process status as `AgentActivity`, tagged with the batch
|
|
341
378
|
number and batch count. JCF web streams these events during matching, while the CLI
|
|
@@ -354,7 +391,7 @@ totals; their days are excluded from proposals until the timer stops.
|
|
|
354
391
|
`SavedEntries.layer` is included in `Headless.layer`. Its `update` operation takes a
|
|
355
392
|
server-retained `RecordedEntry` snapshot plus new start/end milliseconds and description,
|
|
356
393
|
rechecks provider ownership and the current snapshot, and returns the actual saved
|
|
357
|
-
entry. `SavedEntryError.reason` distinguishes validation, conflict and
|
|
394
|
+
entry. `SavedEntryError.reason` distinguishes validation, conflict, provider and partial failures.
|
|
358
395
|
Recorded intervals carry optional whole-entry metadata, including exact original
|
|
359
396
|
bounds and description, even when the calendar slices an entry at midnight.
|
|
360
397
|
|
|
@@ -369,6 +406,23 @@ media have no plain-text representation. Updates leave
|
|
|
369
406
|
Jira estimates and visibility unchanged. The service serializes local updates, but the
|
|
370
407
|
provider APIs offer no atomic protection from external edits between re-read and save.
|
|
371
408
|
|
|
409
|
+
Changing tickets creates a replacement before deleting the original. Before POST, the private
|
|
410
|
+
ledger stores a `Pending` replacement intent containing the provider/account scope, original entry
|
|
411
|
+
ID and ticket, and requested ticket, bounds and description. The returned replacement ID is persisted
|
|
412
|
+
before verification. A verified replacement retains the original session claim, or is remembered as
|
|
413
|
+
ordinary provider time, before DELETE. Deleting the original atomically releases its tracking and
|
|
414
|
+
clears the intent. The provider/account scope and intent stay in the owner-only ledger. Entry IDs,
|
|
415
|
+
ticket, bounds and description appear in the authenticated saved-entry snapshot; HTTP responses
|
|
416
|
+
never carry private provider account locators or credentials.
|
|
417
|
+
|
|
418
|
+
An interrupted or uncertain create stays held and is never repeated automatically. A partial move
|
|
419
|
+
holds session writes for that provider, including after restart. Refresh and inspect both entries;
|
|
420
|
+
if the replacement was verified, explicitly deleting either entry resolves the intent while keeping
|
|
421
|
+
the other entry's tracking. An unverified replacement, or a remote delete whose local completion
|
|
422
|
+
could not persist, requires private ledger recovery after checking the provider. Never clear an
|
|
423
|
+
intent just to retry POST. Ordinary replacements keep their ID and actual start, so extending a
|
|
424
|
+
reviewed window does not turn the tool's own move into an unknown-entry hold.
|
|
425
|
+
|
|
372
426
|
Session reports optionally retain `sessionEvidence` with each session's ticket and
|
|
373
427
|
individual active intervals. This lets web description requests correlate saved time
|
|
374
428
|
without another scan. `SessionAttributor.describe` accepts a nullable ticket key for
|
package/dist/package.json
CHANGED
|
@@ -2,6 +2,7 @@ interface Run {
|
|
|
2
2
|
readonly startMs: number;
|
|
3
3
|
readonly endMs: number;
|
|
4
4
|
readonly bucketIds: ReadonlyArray<string>;
|
|
5
|
+
readonly weights?: ReadonlyMap<string, number> | undefined;
|
|
5
6
|
}
|
|
6
7
|
export interface ScheduledRun extends Run {
|
|
7
8
|
/** Earliest source instant needed to reconstruct this allocation. */
|
|
@@ -10,11 +11,11 @@ export interface ScheduledRun extends Run {
|
|
|
10
11
|
readonly settlementEndMs: number;
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Pack a contiguous stretch into one block per ticket, then its reserved unplaced credit.
|
|
15
|
+
* First activity orders the blocks; priority determines writable shares when time is scarce.
|
|
16
|
+
* Blocks may move anywhere inside their source cluster, but never invent time or bridge idle gaps.
|
|
17
|
+
* Sub-minute shares fold upward in rank; an entirely shorter stretch keeps its raw short evidence.
|
|
17
18
|
*/
|
|
18
|
-
export declare const scheduleRuns: (runs: ReadonlyArray<Run>,
|
|
19
|
+
export declare const scheduleRuns: (runs: ReadonlyArray<Run>, dwellSeconds: number, attributed: (id: string) => boolean, priority?: (id: string, day: string) => number) => ReadonlyArray<ScheduledRun>;
|
|
19
20
|
export {};
|
|
20
21
|
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../src/agent/schedule.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../src/agent/schedule.ts"],"names":[],"mappings":"AAIA,UAAU,GAAG;IACX,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAC3D;AAID,MAAM,WAAW,YAAa,SAAQ,GAAG;IACvC,qEAAqE;IACrE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,uEAAuE;IACvE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CACjC;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,SACjB,aAAa,CAAC,GAAG,CAAC,gBACV,MAAM,cACR,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,aACxB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,KAC7C,aAAa,CAAC,YAAY,CAoL5B,CAAA"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Data } from "effect";
|
|
2
2
|
import { localDay } from "../utils/time.js";
|
|
3
|
+
import { MINIMUM_WRITE_SECONDS } from "./writePlanning.js";
|
|
3
4
|
class ScheduleAllocationError extends Data.TaggedError("ScheduleAllocationError") {
|
|
4
5
|
}
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Pack a contiguous stretch into one block per ticket, then its reserved unplaced credit.
|
|
8
|
+
* First activity orders the blocks; priority determines writable shares when time is scarce.
|
|
9
|
+
* Blocks may move anywhere inside their source cluster, but never invent time or bridge idle gaps.
|
|
10
|
+
* Sub-minute shares fold upward in rank; an entirely shorter stretch keeps its raw short evidence.
|
|
10
11
|
*/
|
|
11
|
-
export const scheduleRuns = (runs,
|
|
12
|
-
if (
|
|
12
|
+
export const scheduleRuns = (runs, dwellSeconds, attributed, priority) => {
|
|
13
|
+
if (dwellSeconds <= 0) {
|
|
13
14
|
return runs.map((run) => ({ ...run, sourceStartMs: run.startMs, settlementEndMs: run.endMs }));
|
|
14
15
|
}
|
|
15
16
|
const settlementEndByRun = new Map();
|
|
@@ -38,25 +39,34 @@ export const scheduleRuns = (runs, minimumSeconds, attributed) => {
|
|
|
38
39
|
const settlementEndMs = settlementEndByRun.get(first) ?? last.endMs;
|
|
39
40
|
const weights = new Map();
|
|
40
41
|
const active = new Map();
|
|
42
|
+
const firstActivity = new Map();
|
|
41
43
|
for (const run of cluster) {
|
|
44
|
+
const totalWeight = run.bucketIds.reduce((sum, id) => sum + (run.weights?.get(id) ?? 1), 0);
|
|
42
45
|
for (const id of run.bucketIds) {
|
|
43
|
-
|
|
46
|
+
const weight = (run.endMs - run.startMs) * (run.weights?.get(id) ?? 1) / totalWeight;
|
|
47
|
+
weights.set(id, (weights.get(id) ?? 0) + weight);
|
|
44
48
|
active.set(id, (active.get(id) ?? 0) + run.endMs - run.startMs);
|
|
49
|
+
// Mention ratios may evolve while a group is live. Ordering uses its raw first presence,
|
|
50
|
+
// so later text cannot swap two same-start tickets after a restart.
|
|
51
|
+
if (!firstActivity.has(id)) {
|
|
52
|
+
firstActivity.set(id, { startMs: run.startMs, weight: (run.endMs - run.startMs) / run.bucketIds.length });
|
|
53
|
+
}
|
|
45
54
|
}
|
|
46
55
|
}
|
|
47
56
|
const duration = Math.floor((last.endMs - first.startMs) / 1000);
|
|
48
57
|
const unplaced = [...weights].filter(([id]) => !attributed(id));
|
|
49
58
|
const reserved = Math.floor(unplaced.reduce((sum, [, weight]) => sum + weight, 0) / 1000);
|
|
50
59
|
const available = duration - reserved;
|
|
51
|
-
const
|
|
52
|
-
const
|
|
60
|
+
const day = localDay(new Date(first.startMs));
|
|
61
|
+
const stableOwners = [...weights].filter(([id]) => attributed(id))
|
|
53
62
|
.sort(([a, weightA], [b, weightB]) => weightB - weightA || a.localeCompare(b));
|
|
54
|
-
const
|
|
63
|
+
const rankedOwners = [...stableOwners]
|
|
64
|
+
.sort(([a, weightA], [b, weightB]) => (priority?.(b, day) ?? 0) - (priority?.(a, day) ?? 0) || weightB - weightA || a.localeCompare(b));
|
|
55
65
|
const allocations = new Map();
|
|
56
66
|
let remaining = available;
|
|
57
|
-
let remainingWeight =
|
|
58
|
-
for (const [index, [id, weight]] of
|
|
59
|
-
const proportional = index ===
|
|
67
|
+
let remainingWeight = stableOwners.reduce((sum, [, weight]) => sum + weight, 0);
|
|
68
|
+
for (const [index, [id, weight]] of stableOwners.entries()) {
|
|
69
|
+
const proportional = index === stableOwners.length - 1
|
|
60
70
|
? remaining
|
|
61
71
|
: Math.floor(remaining * weight / remainingWeight);
|
|
62
72
|
const seconds = Math.min(proportional, Math.floor((active.get(id) ?? 0) / 1000));
|
|
@@ -64,105 +74,110 @@ export const scheduleRuns = (runs, minimumSeconds, attributed) => {
|
|
|
64
74
|
remaining -= seconds;
|
|
65
75
|
remainingWeight -= weight;
|
|
66
76
|
}
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
remaining -= seconds;
|
|
78
|
-
}
|
|
79
|
-
const remainingMs = new Map([...allocations].map(([id, seconds]) => [id, seconds * 1000]));
|
|
80
|
-
const futureActiveMs = new Map(active);
|
|
81
|
-
const lastActiveMs = new Map();
|
|
82
|
-
for (const run of cluster)
|
|
83
|
-
for (const id of run.bucketIds)
|
|
84
|
-
lastActiveMs.set(id, run.endMs);
|
|
85
|
-
const placementOrder = rankedOwners.map(([id]) => id).sort((a, b) => (lastActiveMs.get(a) ?? 0) - (lastActiveMs.get(b) ?? 0));
|
|
86
|
-
const gaps = [];
|
|
87
|
-
for (const run of cluster) {
|
|
88
|
-
const runMs = run.endMs - run.startMs;
|
|
89
|
-
for (const id of run.bucketIds)
|
|
90
|
-
futureActiveMs.set(id, (futureActiveMs.get(id) ?? 0) - runMs);
|
|
91
|
-
const present = placementOrder.filter((id) => run.bucketIds.includes(id) && (remainingMs.get(id) ?? 0) > 0);
|
|
92
|
-
let cursor = run.startMs;
|
|
93
|
-
for (const id of present) {
|
|
94
|
-
const reservedForOthers = present.reduce((sum, other) => other === id ?
|
|
95
|
-
sum :
|
|
96
|
-
sum + Math.max(0, (remainingMs.get(other) ?? 0) - (futureActiveMs.get(other) ?? 0)), 0);
|
|
97
|
-
const placedMs = Math.min(remainingMs.get(id) ?? 0, Math.max(0, run.endMs - cursor - reservedForOthers));
|
|
98
|
-
if (placedMs <= 0)
|
|
77
|
+
// Place credit inside its supporting runs. An augmenting path can move an existing owner's
|
|
78
|
+
// credit to another supporting run, freeing room without stealing that owner's allocation.
|
|
79
|
+
const placed = cluster.map(() => new Map());
|
|
80
|
+
const claimed = new Map();
|
|
81
|
+
const move = (id, wantedMs, visited) => {
|
|
82
|
+
let leftMs = wantedMs;
|
|
83
|
+
for (const [index, run] of cluster.entries()) {
|
|
84
|
+
if (leftMs <= 0)
|
|
85
|
+
break;
|
|
86
|
+
if (!run.bucketIds.includes(id) || visited.has(index))
|
|
99
87
|
continue;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
88
|
+
const held = placed[index];
|
|
89
|
+
if (held === undefined)
|
|
90
|
+
continue;
|
|
91
|
+
visited.add(index);
|
|
92
|
+
const freeMs = run.endMs - run.startMs - [...held.values()].reduce((sum, value) => sum + value, 0);
|
|
93
|
+
const directMs = Math.min(leftMs, freeMs);
|
|
94
|
+
held.set(id, (held.get(id) ?? 0) + directMs);
|
|
95
|
+
leftMs -= directMs;
|
|
96
|
+
for (const [donor, donorMs] of [...held]) {
|
|
97
|
+
if (leftMs <= 0)
|
|
98
|
+
break;
|
|
99
|
+
if (donor === id || donorMs <= 0)
|
|
100
|
+
continue;
|
|
101
|
+
const movedMs = move(donor, Math.min(leftMs, donorMs), visited);
|
|
102
|
+
held.set(donor, (held.get(donor) ?? 0) - movedMs);
|
|
103
|
+
held.set(id, (held.get(id) ?? 0) + movedMs);
|
|
104
|
+
leftMs -= movedMs;
|
|
105
|
+
}
|
|
109
106
|
}
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
return wantedMs - leftMs;
|
|
108
|
+
};
|
|
109
|
+
let budgetMs = available * 1000;
|
|
110
|
+
const claim = (id, targetSeconds) => {
|
|
111
|
+
let wantedMs = Math.min(budgetMs, Math.max(0, targetSeconds * 1000 - (claimed.get(id) ?? 0)));
|
|
112
|
+
while (wantedMs > 0) {
|
|
113
|
+
const movedMs = move(id, wantedMs, new Set());
|
|
114
|
+
if (movedMs <= 0)
|
|
115
|
+
break;
|
|
116
|
+
claimed.set(id, (claimed.get(id) ?? 0) + movedMs);
|
|
117
|
+
budgetMs -= movedMs;
|
|
118
|
+
wantedMs -= movedMs;
|
|
112
119
|
}
|
|
113
|
-
}
|
|
114
|
-
let gapIndex = 0;
|
|
115
|
-
let gapCursor = gaps[0]?.startMs ?? last.endMs;
|
|
116
|
-
const nextGap = () => {
|
|
117
|
-
gapIndex++;
|
|
118
|
-
gapCursor = gaps[gapIndex]?.startMs ?? last.endMs;
|
|
119
120
|
};
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
|
|
121
|
+
// Retain each owner's first second, then offer writable minutes in priority order. A floor is
|
|
122
|
+
// bounded by joint source availability, not just the owner's independent active-time cap.
|
|
123
|
+
for (const [id] of rankedOwners)
|
|
124
|
+
claim(id, 1);
|
|
125
|
+
for (const [id] of rankedOwners)
|
|
126
|
+
claim(id, MINIMUM_WRITE_SECONDS);
|
|
127
|
+
for (const [id] of rankedOwners)
|
|
128
|
+
claim(id, allocations.get(id) ?? 0);
|
|
129
|
+
for (const [id] of rankedOwners)
|
|
130
|
+
claim(id, Math.floor((active.get(id) ?? 0) / 1000));
|
|
131
|
+
if (budgetMs > 0) {
|
|
132
|
+
throw new ScheduleAllocationError({ message: "Attribution cannot fit inside its source activity" });
|
|
133
|
+
}
|
|
134
|
+
if (available >= MINIMUM_WRITE_SECONDS) {
|
|
135
|
+
// Folding from lowest rank upward can combine two short shares into another writable minute.
|
|
136
|
+
for (let index = rankedOwners.length - 1; index > 0; index--) {
|
|
137
|
+
const owner = rankedOwners[index];
|
|
138
|
+
const higher = rankedOwners[index - 1];
|
|
139
|
+
if (owner === undefined || higher === undefined)
|
|
140
|
+
continue;
|
|
141
|
+
const milliseconds = claimed.get(owner[0]) ?? 0;
|
|
142
|
+
if (milliseconds <= 0 || milliseconds >= MINIMUM_WRITE_SECONDS * 1000)
|
|
143
|
+
continue;
|
|
144
|
+
claimed.set(higher[0], (claimed.get(higher[0]) ?? 0) + milliseconds);
|
|
145
|
+
claimed.set(owner[0], 0);
|
|
146
|
+
}
|
|
147
|
+
const highest = rankedOwners[0]?.[0];
|
|
148
|
+
const highestMs = highest === undefined ? 0 : claimed.get(highest) ?? 0;
|
|
149
|
+
if (highest !== undefined && highestMs > 0 && highestMs < MINIMUM_WRITE_SECONDS * 1000) {
|
|
150
|
+
const writable = rankedOwners.find(([id]) => (claimed.get(id) ?? 0) >= MINIMUM_WRITE_SECONDS * 1000)?.[0];
|
|
151
|
+
if (writable !== undefined) {
|
|
152
|
+
claimed.set(writable, (claimed.get(writable) ?? 0) + highestMs);
|
|
153
|
+
claimed.set(highest, 0);
|
|
154
|
+
}
|
|
140
155
|
}
|
|
141
|
-
offset += seconds;
|
|
142
156
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (recipient === undefined)
|
|
152
|
-
continue;
|
|
153
|
-
const startMs = index === gapIndex ? gapCursor : gap.startMs;
|
|
154
|
-
const placedMs = Math.min(residualMs, gap.endMs - startMs);
|
|
157
|
+
// Later work may change total weights, but never the first-activity order. Logging can change
|
|
158
|
+
// advisory rank without moving an unchanged packed allocation and its consumed source identity.
|
|
159
|
+
const orderedOwners = [...stableOwners].sort(([a], [b]) => (firstActivity.get(a)?.startMs ?? 0) - (firstActivity.get(b)?.startMs ?? 0) ||
|
|
160
|
+
(firstActivity.get(b)?.weight ?? 0) - (firstActivity.get(a)?.weight ?? 0) || a.localeCompare(b));
|
|
161
|
+
let cursor = first.startMs;
|
|
162
|
+
const append = (id, milliseconds) => {
|
|
163
|
+
if (milliseconds <= 0)
|
|
164
|
+
return;
|
|
155
165
|
result.push({
|
|
156
|
-
bucketIds: [
|
|
157
|
-
startMs,
|
|
158
|
-
endMs:
|
|
166
|
+
bucketIds: [id],
|
|
167
|
+
startMs: cursor,
|
|
168
|
+
endMs: cursor + milliseconds,
|
|
159
169
|
sourceStartMs: first.startMs,
|
|
160
170
|
settlementEndMs
|
|
161
171
|
});
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
172
|
+
cursor += milliseconds;
|
|
173
|
+
};
|
|
174
|
+
for (const [id] of orderedOwners)
|
|
175
|
+
append(id, claimed.get(id) ?? 0);
|
|
176
|
+
let offset = available;
|
|
177
|
+
for (const [index, [id, weight]] of unplaced.entries()) {
|
|
178
|
+
const seconds = index === unplaced.length - 1 ? duration - offset : Math.floor(weight / 1000);
|
|
179
|
+
append(id, seconds * 1000);
|
|
180
|
+
offset += seconds;
|
|
166
181
|
}
|
|
167
182
|
cluster = [];
|
|
168
183
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../../src/agent/schedule.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../../src/agent/schedule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAS1D,MAAM,uBAAwB,SAAQ,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAA+B;CAAG;AASlH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,IAAwB,EACxB,YAAoB,EACpB,UAAmC,EACnC,QAA8C,EACjB,EAAE;IAC/B,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,aAAa,EAAE,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAChG,CAAC;IACD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAe,CAAA;IACjD,IAAI,cAAc,GAAG,CAAC,CAAA;IACtB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QAC3B,IACE,QAAQ,KAAK,SAAS;YACtB,CAAC,OAAO,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,KAAK,OAAO,CAAC,OAAO;gBAC1D,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAC/E,CAAC;YACD,KAAK,IAAI,EAAE,GAAG,cAAc,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC;gBAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAA;gBACpB,IAAI,GAAG,KAAK,SAAS;oBAAE,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;YACpE,CAAC;YACD,cAAc,GAAG,KAAK,CAAA;QACxB,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAwB,EAAE,CAAA;IACtC,IAAI,OAAO,GAAe,EAAE,CAAA;IAC5B,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACxB,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3B,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;YAAE,OAAM;QACrD,MAAM,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAA;QACnE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;QACzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;QACxC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAiE,CAAA;QAC9F,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YAC3F,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;gBAC/B,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,WAAW,CAAA;gBACpF,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAA;gBAChD,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,CAAA;gBAC/D,yFAAyF;gBACzF,oEAAoE;gBACpE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC3B,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;gBAC3G,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;QAChE,MAAM,QAAQ,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;QACzF,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;QACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;QAC7C,MAAM,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;aAC/D,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;QAChF,MAAM,YAAY,GAAG,CAAC,GAAG,YAAY,CAAC;aACnC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CACnC,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CACjG,CAAA;QACH,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAA;QAC7C,IAAI,SAAS,GAAG,SAAS,CAAA;QACzB,IAAI,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,EAAE,CAAC,CAAC,CAAA;QAC/E,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3D,MAAM,YAAY,GAAG,KAAK,KAAK,YAAY,CAAC,MAAM,GAAG,CAAC;gBACpD,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,GAAG,eAAe,CAAC,CAAA;YACpD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;YAChF,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;YAC5B,SAAS,IAAI,OAAO,CAAA;YACpB,eAAe,IAAI,MAAM,CAAA;QAC3B,CAAC;QACD,2FAA2F;QAC3F,2FAA2F;QAC3F,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,EAAkB,CAAC,CAAA;QAC3D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;QACzC,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,QAAgB,EAAE,OAAoB,EAAU,EAAE;YAC1E,IAAI,MAAM,GAAG,QAAQ,CAAA;YACrB,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC7C,IAAI,MAAM,IAAI,CAAC;oBAAE,MAAK;gBACtB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,SAAQ;gBAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;gBAC1B,IAAI,IAAI,KAAK,SAAS;oBAAE,SAAQ;gBAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;gBAClB,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAA;gBAClG,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;gBACzC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAA;gBAC5C,MAAM,IAAI,QAAQ,CAAA;gBAClB,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;oBACzC,IAAI,MAAM,IAAI,CAAC;wBAAE,MAAK;oBACtB,IAAI,KAAK,KAAK,EAAE,IAAI,OAAO,IAAI,CAAC;wBAAE,SAAQ;oBAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;oBAC/D,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;oBACjD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;oBAC3C,MAAM,IAAI,OAAO,CAAA;gBACnB,CAAC;YACH,CAAC;YACD,OAAO,QAAQ,GAAG,MAAM,CAAA;QAC1B,CAAC,CAAA;QACD,IAAI,QAAQ,GAAG,SAAS,GAAG,IAAI,CAAA;QAC/B,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,aAAqB,EAAE,EAAE;YAClD,IAAI,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAC7F,OAAO,QAAQ,GAAG,CAAC,EAAE,CAAC;gBACpB,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;gBAC7C,IAAI,OAAO,IAAI,CAAC;oBAAE,MAAK;gBACvB,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;gBACjD,QAAQ,IAAI,OAAO,CAAA;gBACnB,QAAQ,IAAI,OAAO,CAAA;YACrB,CAAC;QACH,CAAC,CAAA;QACD,8FAA8F;QAC9F,0FAA0F;QAC1F,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,YAAY;YAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QAC7C,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,YAAY;YAAE,KAAK,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAA;QACjE,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,YAAY;YAAE,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QACpE,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,YAAY;YAAE,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;QACpF,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,MAAM,IAAI,uBAAuB,CAAC,EAAE,OAAO,EAAE,mDAAmD,EAAE,CAAC,CAAA;QACrG,CAAC;QACD,IAAI,SAAS,IAAI,qBAAqB,EAAE,CAAC;YACvC,6FAA6F;YAC7F,KAAK,IAAI,KAAK,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC7D,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;gBACjC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;gBACtC,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS;oBAAE,SAAQ;gBACzD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;gBAC/C,IAAI,YAAY,IAAI,CAAC,IAAI,YAAY,IAAI,qBAAqB,GAAG,IAAI;oBAAE,SAAQ;gBAC/E,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC,CAAA;gBACpE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YAC1B,CAAC;YACD,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,SAAS,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YACvE,IAAI,OAAO,KAAK,SAAS,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,qBAAqB,GAAG,IAAI,EAAE,CAAC;gBACvF,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,qBAAqB,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBACzG,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC3B,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;oBAC/D,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;QACD,8FAA8F;QAC9F,gGAAgG;QAChG,MAAM,aAAa,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACxD,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC;YAC3E,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAChG,CAAA;QACD,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,CAAA;QAC1B,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,YAAoB,EAAE,EAAE;YAClD,IAAI,YAAY,IAAI,CAAC;gBAAE,OAAM;YAC7B,MAAM,CAAC,IAAI,CAAC;gBACV,SAAS,EAAE,CAAC,EAAE,CAAC;gBACf,OAAO,EAAE,MAAM;gBACf,KAAK,EAAE,MAAM,GAAG,YAAY;gBAC5B,aAAa,EAAE,KAAK,CAAC,OAAO;gBAC5B,eAAe;aAChB,CAAC,CAAA;YACF,MAAM,IAAI,YAAY,CAAA;QACxB,CAAC,CAAA;QACD,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,aAAa;YAAE,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QAClE,IAAI,MAAM,GAAG,SAAS,CAAA;QACtB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YACvD,MAAM,OAAO,GAAG,KAAK,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;YAC7F,MAAM,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC,CAAA;YAC1B,MAAM,IAAI,OAAO,CAAA;QACnB,CAAC;QACD,OAAO,GAAG,EAAE,CAAA;IACd,CAAC,CAAA;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC/B,IACE,QAAQ,KAAK,SAAS;YACtB,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,OAAO;gBAC7F,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3E,KAAK,EAAE,CAAA;QACT,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,KAAK,EAAE,CAAA;YACP,MAAM,CAAC,IAAI,CAAC;gBACV,GAAG,GAAG;gBACN,aAAa,EAAE,GAAG,CAAC,OAAO;gBAC1B,eAAe,EAAE,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;aAC1D,CAAC,CAAA;QACJ,CAAC;;YAAM,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IACD,KAAK,EAAE,CAAA;IACP,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;AAC/F,CAAC,CAAA"}
|
|
@@ -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
|
|
230
|
+
* Coalesce rapid ownership changes without removing overlapping tickets.
|
|
217
231
|
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
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;
|