@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
package/README.md CHANGED
@@ -18,27 +18,49 @@ cd packages/jira-clockify && pnpm link --global
18
18
 
19
19
  ## Setup
20
20
 
21
- ### 1. Jira OAuth
21
+ Run `jcf` with nothing set up and it asks about each system in turn; either can be skipped and
22
+ added later. `jcf auth status` shows what is connected and what to run next. Every step below can
23
+ also be run on its own.
24
+
25
+ ### 1. Jira
26
+
27
+ ```bash
28
+ jcf auth jira token # Site, email and an API token from https://id.atlassian.com/manage-profile/security/api-tokens
29
+ ```
30
+
31
+ The token is checked against Jira before it is saved to `~/.jcf/jira.json` (owner-only, `0600`) and is
32
+ never printed. Only Jira Cloud addresses (`*.atlassian.net`) are accepted, so a typo or look-alike
33
+ domain never receives the token. Classic and scoped tokens both work: a scoped token, which the
34
+ site itself refuses, is used through Atlassian's gateway for that site (`api.atlassian.com/ex/jira/<cloud id>`). A failed check says whether the site, the token or the network was
35
+ the problem.
36
+
37
+ Advanced: connect through your own Atlassian OAuth app instead.
22
38
 
23
39
  ```bash
24
- jcf auth jira create # Opens Atlassian console — create OAuth 2.0 app
40
+ jcf auth jira create # Opens Atlassian console — create OAuth 2.0 app
25
41
  jcf auth jira configure # Set client ID and secret
26
42
  jcf auth jira login # Authenticate via browser
27
43
  ```
28
44
 
45
+ When both exist, the API token is used. `jcf auth jira logout` removes both.
46
+
29
47
  ### 2. Clockify API Key
30
48
 
31
49
  ```bash
32
50
  jcf auth clockify setup # Enter API key from https://app.clockify.me/manage-api-keys
51
+ jcf auth clockify setup --api-key <key> --workspace <name> # For scripts; the key is visible to other processes
33
52
  ```
34
53
 
54
+ Commands that need a system that is not connected fail with one line naming the command that
55
+ connects it, and exit non-zero.
56
+
35
57
  ### 3. Configure Defaults
36
58
 
37
59
  ```bash
38
60
  jcf config set project # Select default Clockify project
39
61
  jcf config set billable # Set default billable flag
40
62
  jcf config set jql <jql> # Set default JQL filter
41
- jcf config show # Show current config
63
+ jcf config show # Show current config; marks values that are jcf's defaults
42
64
  jcf config reset # Reset to defaults
43
65
  ```
44
66
 
@@ -96,8 +118,13 @@ jcf sync reconcile jira-to-clockify # Fill Clockify from Jira
96
118
  jcf sync reconcile --agent claude # Propose worklogs from local Claude Code sessions
97
119
  jcf sync reconcile --agent claude --calendar # ...with an hour-by-hour grid of when it happened
98
120
  jcf sync reconcile --agent claude --json # Reporting only: one JSON value, nothing logged
121
+ jcf sync reconcile --agent claude --only clockify # Read and write Clockify alone (or --only jira)
99
122
  ```
100
123
 
124
+ An agent run reads both systems before it proposes anything, because a side it cannot read looks the
125
+ same as a side with nothing recorded. If one is not connected the run stops before planning and says
126
+ how to connect it, or to pass `--only` for the other one.
127
+
101
128
  `--agent claude` is for time _neither_ side recorded: it reads Claude Code and Codex transcripts,
102
129
  keeps work inside your session roots, and works out which issue each
103
130
  session belongs to and how long it accounts for, subtracts
@@ -119,20 +146,33 @@ Codex rollouts live under `~/.codex/sessions` in creation-date directories. Thos
119
146
  identify the working project, so JCF decodes their metadata locally before applying session roots
120
147
  to each stretch of work. Resumed rollouts in older directories remain eligible for the current
121
148
  week. Large tool payloads are discarded while streaming the file. Current `UserMessage` events
122
- and older `user_message` events count as presence; injected instructions, response-item prompt
123
- copies, compacted history and native subagent rollouts do not. Selecting Claude or Codex as the
124
- matching agent does not restrict which of these two transcript sources is scanned.
125
-
126
- Only messages _you typed_ count as presence — the agent's own output, its tool results, and the
127
- prompts it sends its own subagents do not, since they show it was busy rather than that you were
128
- working. On one real day that was 66 events out
129
- of 1641, and the difference between 1h 53m and 3h 51m. A session counts as active between its own
130
- consecutive prompts, gaps longer than the idle cap are
149
+ and older `user_message` events open a turn; completed items continue it and `task_complete` ends
150
+ it. Injected instructions, response-item prompt copies, compacted history and native subagent
151
+ rollouts establish nothing. Selecting Claude or Codex as the matching agent does not restrict which
152
+ of these two transcript sources is scanned.
153
+
154
+ Presence is a _supervised turn_. A message you typed — including one typed while the agent was busy,
155
+ which Claude stores as a queued command — opens a turn, and the agent's work inside it counts until
156
+ the agent ends the turn, a task notification or auto-continuation takes over, or the agent is silent
157
+ for longer than the idle cap. Agent output outside a turn you started never counts: a task
158
+ notification, an expanded skill (`isMeta`) or a subagent's own prompt cannot open one, since they
159
+ show the agent was busy rather than that you were working. Gaps longer than the idle cap are
131
160
  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. Time
133
- spent reading and thinking between prompts is therefore under-counted rather than over-counted; a day
161
+ between them — so a day's proposals can never add up to more than that day's wall clock. A day
134
162
  with a timer still running is reported but never proposed.
135
163
 
164
+ When parallel tickets compete for the same minutes, tickets in your open sprint come first, then
165
+ tickets you have not logged that day, then the strength of their evidence. Key-only JQL searches —
166
+ 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.
167
+ When Jira cannot answer, every ticket ranks equally. Inside one unbroken stretch each ticket gets a
168
+ single block, ordered by when it first appeared and packed back to back; a ticket that cannot reach
169
+ a minute folds into the one ranked above it. Work an orchestrator agent prompts into a worker pane
170
+ counts like your own typing. An orchestrating session that no branch, path or confident agent answer
171
+ places is split across the open-sprint tickets assigned to you that it mentions, weighted by mentions
172
+ and computed per active stretch, so settled time never moves when the session later mentions more.
173
+ Splitting needs a verified Jira answer about the sprint; without one the session stays unplaced.
174
+ `jcf watch` reads deterministically and never splits: such a session stays unplaced there.
175
+
136
176
  Everything you need to judge a row is on the row itself, in the picker: when the work item started
137
177
  and ended, the issue summary, its assignee, the attribution signal, what each side already holds, and
138
178
  how many blocks the total spans. So the number is checkable against your memory of the day rather
@@ -175,12 +215,13 @@ edits, including removal of the source suffix, do not reset its consumed seconds
175
215
  read still observes genuine duration changes and deletions. The suffix can import a legacy entry on
176
216
  first read, but text alone does not override an existing ID binding.
177
217
 
178
- The same private file now stores version 3: it also remembers the IDs and original starts of ordinary
218
+ The same private file now stores version 5: it also remembers the IDs and original starts of ordinary
179
219
  entries seen in a newly reviewed forward interval, separately by provider and account. Repeated or
180
220
  overlapping review can recognize those entries. A new unmarked entry in older coverage or a changed
181
221
  start for a remembered ID needs manual review; the tool does not infer its origin from a timestamp.
182
- Versions 1 and 2 load without inventing ordinary entries and upgrade only on a successful atomic
183
- write. New Clockify evidence is scoped to the configured endpoint, workspace, and user verified by
222
+ Versions 1 through 4 upgrade only on a successful atomic write. Versions 1 and 2 load without
223
+ inventing ordinary entries; earlier versions never invent replacement intents or Jira creation
224
+ checkpoints. New Clockify evidence is scoped to the configured endpoint, workspace, and user verified by
184
225
  that credential. Older Clockify scopes cannot prove the endpoint: affected windows, observations,
185
226
  pending intents, and bindings remain intact and held for private manual review. Neither switching
186
227
  the endpoint nor editing a description turns them into a fresh empty account. Jira evidence remains
@@ -305,12 +346,14 @@ Stored in `~/.jcf/`:
305
346
  ~/.jcf/
306
347
  ├── config.json # JQL, project, billable defaults, session roots
307
348
  ├── clockify.json # Clockify API key, workspace, user
349
+ ├── jira.json # Jira site, cloud id, email, API token, account (0600)
308
350
  ├── poll.lock # Kernel lock held by the active managed poll
309
351
  ├── poll.stamp # Last managed poll attempt, including failures
310
352
  └── state.json # Current timer state and polling authority
311
353
  ```
312
354
 
313
- Jira OAuth credentials stored via `@knpkv/atlassian-common` in `~/.config/atlassian/`.
355
+ Jira OAuth credentials (the advanced path) are stored via `@knpkv/atlassian-common` in
356
+ `~/.config/atlassian/`. That store holds OAuth logins only, so the API token lives in `~/.jcf/jira.json`.
314
357
 
315
358
  ## License
316
359
 
@@ -328,14 +371,37 @@ an explicit full read collects new session evidence.
328
371
  ### Ticket overlap and live matching
329
372
 
330
373
  With the default 900-second dwell floor, overlapping attributed work is allocated
331
- in sequential blocks of at least fifteen minutes when the stretch permits it.
332
- Tickets share the stretch evenly; if fewer slots fit, the strongest credited
333
- tickets retain them. Mixed stretches reserve unplaced credit before allocating known tickets. Separate
374
+ in sequential blocks across every evidenced ticket. Each ticket receives a writable
375
+ minute when the stretch permits it. Open-sprint tickets assigned to you rank first,
376
+ then tickets not yet logged that day, then evidence weight. Shorter shares remain
377
+ credited; the scheduler never invents minutes. Mixed stretches reserve unplaced credit before allocating known tickets. Separate
334
378
  work, idle gaps, wholly unplaced stretches and midnight stay
335
379
  separate. Short standalone work is never inflated. Setting dwell to zero retains
336
380
  raw overlap sharing. Proposal blocks and confirmed amounts use the same timeline;
337
381
  `activeSeconds` retains the original activity duration.
338
382
 
383
+ ### Ignoring session tickets
384
+
385
+ ```sh
386
+ jcf config set session-ignore PROJ-42 # Ignore in every week
387
+ jcf config unset session-ignore PROJ-42 # Restore
388
+ jcf config # Lists ignored tickets
389
+ ```
390
+
391
+ `sessionIgnoredTickets` defaults to `[]` and persists validated issue keys. Ignored
392
+ branch, path or standing matches fall through to the attribution agent, whose
393
+ candidate list excludes ignored keys. An ignored key cannot become a final match.
394
+ If the agent chooses another evidenced key, that work can be proposed there.
395
+ Otherwise the ignored session's windows are removed before sharing: overlapping
396
+ tickets receive those minutes; solo time is not offered elsewhere.
397
+
398
+ Session reports and `--json` include `ignored` rows with `ticketKey`, `day` and
399
+ `seconds`. These are raw active windows unioned per ignored ticket/day, before
400
+ sharing, so simultaneous sessions on one key count once. They explain suppressed
401
+ evidence and must not be added to allocated totals. A fresh recorded read also
402
+ filters newly ignored tickets out of retained proposals; rescan sessions to
403
+ redistribute overlapping credit or restore an ignored ticket.
404
+
339
405
  `SessionAttributor.attribute` accepts an optional activity observer. Reconciliation
340
406
  forwards visible text and process status as `AgentActivity`, tagged with the batch
341
407
  number and batch count. JCF web streams these events during matching, while the CLI
@@ -354,7 +420,7 @@ totals; their days are excluded from proposals until the timer stops.
354
420
  `SavedEntries.layer` is included in `Headless.layer`. Its `update` operation takes a
355
421
  server-retained `RecordedEntry` snapshot plus new start/end milliseconds and description,
356
422
  rechecks provider ownership and the current snapshot, and returns the actual saved
357
- entry. `SavedEntryError.reason` distinguishes validation, conflict and provider failures.
423
+ entry. `SavedEntryError.reason` distinguishes validation, conflict, provider and partial failures.
358
424
  Recorded intervals carry optional whole-entry metadata, including exact original
359
425
  bounds and description, even when the calendar slices an entry at midnight.
360
426
 
@@ -369,6 +435,23 @@ media have no plain-text representation. Updates leave
369
435
  Jira estimates and visibility unchanged. The service serializes local updates, but the
370
436
  provider APIs offer no atomic protection from external edits between re-read and save.
371
437
 
438
+ Changing tickets creates a replacement before deleting the original. Before POST, the private
439
+ ledger stores a `Pending` replacement intent containing the provider/account scope, original entry
440
+ ID and ticket, and requested ticket, bounds and description. The returned replacement ID is persisted
441
+ before verification. A verified replacement retains the original session claim, or is remembered as
442
+ ordinary provider time, before DELETE. Deleting the original atomically releases its tracking and
443
+ clears the intent. The provider/account scope and intent stay in the owner-only ledger. Entry IDs,
444
+ ticket, bounds and description appear in the authenticated saved-entry snapshot; HTTP responses
445
+ never carry private provider account locators or credentials.
446
+
447
+ An interrupted or uncertain create stays held and is never repeated automatically. A partial move
448
+ holds session writes for that provider, including after restart. Refresh and inspect both entries;
449
+ if the replacement was verified, explicitly deleting either entry resolves the intent while keeping
450
+ the other entry's tracking. An unverified replacement, or a remote delete whose local completion
451
+ could not persist, requires private ledger recovery after checking the provider. Never clear an
452
+ intent just to retry POST. Ordinary replacements keep their ID and actual start, so extending a
453
+ reviewed window does not turn the tool's own move into an unknown-entry hold.
454
+
372
455
  Session reports optionally retain `sessionEvidence` with each session's ticket and
373
456
  individual active intervals. This lets web description requests correlate saved time
374
457
  without another scan. `SessionAttributor.describe` accepts a nullable ticket key for
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knpkv/jira-clockify",
3
- "version": "1.4.1",
3
+ "version": "1.6.0",
4
4
  "description": "TUI for Jira-Clockify time tracking, attachable to neovim",
5
5
  "license": "MIT",
6
6
  "author": "knpkv",
@@ -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
- * Arrange a contiguous stretch into sequential allocations. Keep the strongest tickets when there
14
- * is not enough time for every ticket to receive the floor. Wholly unplaced time and midnight are barriers. Mixed stretches reserve their unplaced credit
15
- * before allocating known tickets; changing unplaced shares must not fragment every known ticket.
16
- * A genuinely shorter stretch stays short: allocation must never invent time or bridge idle gaps.
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>, minimumSeconds: number, attributed: (id: string) => boolean) => ReadonlyArray<ScheduledRun>;
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":"AAGA,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;CAC1C;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,kBACR,MAAM,cACV,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,KAClC,aAAa,CAAC,YAAY,CA6K5B,CAAA"}
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
- * Arrange a contiguous stretch into sequential allocations. Keep the strongest tickets when there
7
- * is not enough time for every ticket to receive the floor. Wholly unplaced time and midnight are barriers. Mixed stretches reserve their unplaced credit
8
- * before allocating known tickets; changing unplaced shares must not fragment every known ticket.
9
- * A genuinely shorter stretch stays short: allocation must never invent time or bridge idle gaps.
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, minimumSeconds, attributed) => {
12
- if (minimumSeconds <= 0) {
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
- weights.set(id, (weights.get(id) ?? 0) + (run.endMs - run.startMs) / run.bucketIds.length);
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 limit = Math.max(1, Math.floor(available / minimumSeconds));
52
- const rankedOwners = [...weights].filter(([id]) => attributed(id))
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 owners = rankedOwners.slice(0, limit);
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 = owners.reduce((sum, [, weight]) => sum + weight, 0);
58
- for (const [index, [id, weight]] of owners.entries()) {
59
- const proportional = index === owners.length - 1
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
- // An activity cap can leave part of a proportional share unused. Offer that residual to every
68
- // attributable owner, including one omitted by the normal minimum-size limit, rather than
69
- // silently losing credited time. The residual itself may be shorter than the normal floor.
70
- for (const [id] of rankedOwners) {
71
- if (remaining <= 0)
72
- break;
73
- const allocated = allocations.get(id) ?? 0;
74
- const capacity = Math.floor((active.get(id) ?? 0) / 1000) - allocated;
75
- const seconds = Math.min(remaining, Math.max(0, capacity));
76
- allocations.set(id, allocated + seconds);
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
- result.push({
101
- bucketIds: [id],
102
- startMs: cursor,
103
- endMs: cursor + placedMs,
104
- sourceStartMs: first.startMs,
105
- settlementEndMs
106
- });
107
- remainingMs.set(id, (remainingMs.get(id) ?? 0) - placedMs);
108
- cursor += placedMs;
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
- if (cursor < run.endMs) {
111
- gaps.push({ startMs: cursor, endMs: run.endMs, bucketIds: run.bucketIds });
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
- let offset = available;
121
- for (const [index, [id, weight]] of unplaced.entries()) {
122
- const seconds = index === unplaced.length - 1 ? duration - offset : Math.floor(weight / 1000);
123
- let milliseconds = seconds * 1000;
124
- while (milliseconds > 0) {
125
- const gap = gaps[gapIndex];
126
- if (gap === undefined)
127
- throw new ScheduleAllocationError({ message: "Unplaced credit exceeds source activity" });
128
- const placedMs = Math.min(milliseconds, gap.endMs - gapCursor);
129
- result.push({
130
- bucketIds: [id],
131
- startMs: gapCursor,
132
- endMs: gapCursor + placedMs,
133
- sourceStartMs: first.startMs,
134
- settlementEndMs
135
- });
136
- milliseconds -= placedMs;
137
- gapCursor += placedMs;
138
- if (gapCursor === gap.endMs)
139
- nextGap();
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
- let residualMs = [...remainingMs.values()].reduce((sum, milliseconds) => sum + milliseconds, 0);
144
- for (let index = gapIndex; index < gaps.length && residualMs > 0; index++) {
145
- const gap = gaps[index];
146
- if (gap === undefined)
147
- continue;
148
- if (residualMs <= 0)
149
- break;
150
- const recipient = rankedOwners.find(([id]) => gap.bucketIds.includes(id))?.[0];
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: [recipient],
157
- startMs,
158
- endMs: startMs + placedMs,
166
+ bucketIds: [id],
167
+ startMs: cursor,
168
+ endMs: cursor + milliseconds,
159
169
  sourceStartMs: first.startMs,
160
170
  settlementEndMs
161
171
  });
162
- residualMs -= placedMs;
163
- }
164
- if (residualMs > 0) {
165
- throw new ScheduleAllocationError({ message: "Attribution cannot fit inside its source activity" });
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":"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"}