@gitroll/tacitt-cli 0.6.14 → 0.6.15

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 (37) hide show
  1. package/dist/{agent-setup-CEPQfjBv.mjs → agent-setup-Bv73EZ2b.mjs} +2 -2
  2. package/dist/agent-setup-worker.mjs +5 -5
  3. package/dist/cli.mjs +10 -10
  4. package/dist/codex-title-worker.mjs +1 -1
  5. package/dist/configured-preview-worker.mjs +5 -5
  6. package/dist/configured-session-worker.mjs +5 -5
  7. package/dist/{frame-CRm99088.mjs → frame-0v_mLdvG.mjs} +1 -1
  8. package/dist/{heap-Bh9tySJp.mjs → heap-aWke8lrK.mjs} +3 -3
  9. package/dist/inspection-worker.mjs +4 -4
  10. package/dist/{job-CsWKWcM4.mjs → job-ILnqW1ge.mjs} +4 -4
  11. package/dist/{locate-CP2t26j2.mjs → locate-LpCex6Xj.mjs} +5 -94
  12. package/dist/{model-ChHuVKoB.mjs → model-BEWsfkIU.mjs} +1 -1
  13. package/dist/operation-executor.mjs +3 -3
  14. package/dist/preview-worker.mjs +1 -1
  15. package/dist/privacy-validator.mjs +1 -1
  16. package/dist/{query-D28k3XOr.mjs → query-BX8QwaBi.mjs} +93 -9
  17. package/dist/{run-CiJmV__5.mjs → run-P_uZgSYa.mjs} +4 -4
  18. package/dist/{src-B3il9x5F.mjs → src-CHy3-siB.mjs} +59 -26
  19. package/dist/{src-CWMrGXJK.mjs → src-ikYI-1c5.mjs} +4 -4
  20. package/dist/{src-CmvEJj46.mjs → src-sERffIem.mjs} +8 -31
  21. package/dist/store-database-worker.mjs +1 -1
  22. package/package.json +1 -1
  23. package/skills/tacitt/SKILL.md +1 -1
  24. package/skills/tacitt/references/bootstrap.md +1 -1
  25. package/skills/tacitt/references/classification.md +2 -0
  26. package/skills/tacitt/references/commands.md +5 -4
  27. package/skills/tacitt/references/journey.md +2 -2
  28. package/skills/tacitt/references/parallel-review.md +3 -3
  29. package/skills/tacitt/scripts/INDEX.md +4 -4
  30. package/skills/tacitt/scripts/journey-classification-progress.mjs +6 -0
  31. package/skills/tacitt/scripts/journey-classification-tasks.mjs +9 -1
  32. package/skills/tacitt/scripts/journey-classification-validation.d.mts +14 -1
  33. package/skills/tacitt/scripts/journey-classification-validation.mjs +45 -0
  34. package/skills/tacitt/scripts/journey-consolidation-submit.mjs +22 -5
  35. package/skills/tacitt/scripts/journey-scan-timing.mjs +1 -1
  36. package/skills/tacitt/scripts/journey.mjs +15 -7
  37. package/skills/tacitt/scripts/review.mjs +2 -2
@@ -50,10 +50,23 @@ async function knownProjects(classification, manifest) {
50
50
  return result
51
51
  }
52
52
 
53
+ /** ADR 0276 slice H: join items, with no description, project type or recommendation (Q6). */
54
+ function accountJoinItems(classification) {
55
+ return (classification.accountJoins ?? []).map((join) => ({
56
+ accountWorkId: join.accountWorkId,
57
+ rootSessionIds: join.rootKeys.map((key) => {
58
+ const root = classification.roots.find((entry) => entry.key === key)
59
+ if (!root) throw new Error('CLASSIFICATION_ROOT_COVERAGE_INVALID')
60
+ return root.rootSessionId
61
+ }),
62
+ }))
63
+ }
64
+
53
65
  /**
54
66
  * E2: once every known project has its metadata, its Works are published while the unresolved
55
67
  * roots are still being grouped; they wait as `pendingRootSessionIds`. Null while metadata is
56
- * missing or when nothing remains to group.
68
+ * missing or when nothing remains to group. Roots joining a rebuilt Work also wait, so the
69
+ * complete proposal joins them once from the pending Work (ADR 0276 slice H).
57
70
  */
58
71
  export async function partialClassificationSubmission(manifest) {
59
72
  const classification = manifest.classification
@@ -67,8 +80,11 @@ export async function partialClassificationSubmission(manifest) {
67
80
  if (!(await optional(item.answer))) return null
68
81
  const known = await knownProjects(classification, manifest)
69
82
  const rootByKey = new Map(classification.roots.map((root) => [root.key, root.rootSessionId]))
70
- const pendingRootSessionIds = classification.unknown.map((item) => {
71
- const id = rootByKey.get(item.rootKey)
83
+ const pendingRootSessionIds = [
84
+ ...classification.unknown.map((item) => item.rootKey),
85
+ ...(classification.accountJoins ?? []).flatMap((join) => join.rootKeys),
86
+ ].map((key) => {
87
+ const id = rootByKey.get(key)
72
88
  if (!id) throw new Error('CLASSIFICATION_ROOT_COVERAGE_INVALID')
73
89
  return id
74
90
  })
@@ -192,10 +208,11 @@ export async function classificationSubmission(manifest) {
192
208
  })
193
209
  }
194
210
  }
211
+ const output = [...normalized(result), ...accountJoinItems(classification)]
195
212
  const expectedRootIds = classification.roots
196
213
  .map((root) => root.rootSessionId)
197
214
  .toSorted((left, right) => left.localeCompare(right))
198
- const submittedRootIds = result
215
+ const submittedRootIds = output
199
216
  .flatMap((item) => item.rootSessionIds)
200
217
  .toSorted((left, right) => left.localeCompare(right))
201
218
  if (
@@ -203,7 +220,7 @@ export async function classificationSubmission(manifest) {
203
220
  JSON.stringify(expectedRootIds) !== JSON.stringify(submittedRootIds)
204
221
  )
205
222
  throw new Error('CLASSIFICATION_ROOT_COVERAGE_INVALID')
206
- return normalized(result)
223
+ return output
207
224
  }
208
225
 
209
226
  /** Trimmed submission items; one project name never carries two different metadata sets. */
@@ -198,7 +198,7 @@ export async function observeScanTiming(run, observation) {
198
198
  if (!receipt || receipt.completedAt) return
199
199
  const at = observation.at
200
200
  const measurements = receipt.measurements ?? {
201
- slots: { capacity: 24, busyChildMs: 0, waitingBatchWallMs: 0, refillGapMs: [], children: [] },
201
+ slots: { capacity: 48, busyChildMs: 0, waitingBatchWallMs: 0, refillGapMs: [], children: [] },
202
202
  preparation: {
203
203
  intervals: [],
204
204
  milliseconds: { 'before-first-batch': 0, 'mid-run': 0, tail: 0 },
@@ -25,7 +25,10 @@ import {
25
25
  uncoveredPending,
26
26
  } from './journey-state.mjs'
27
27
  import { classificationTasks } from './journey-classification-tasks.mjs'
28
- import { validateLatePlacedWorks } from './journey-classification-validation.mjs'
28
+ import {
29
+ validateAccountWorkJoins,
30
+ validateLatePlacedWorks,
31
+ } from './journey-classification-validation.mjs'
29
32
  import { classificationEvidence, classificationFormat } from './journey-classification.mjs'
30
33
  import {
31
34
  consolidateClassification,
@@ -238,7 +241,7 @@ async function runPhaseCore(
238
241
  { run, journeyId, command, stage, refresh = false, limit = 3, waitMs = 0, sleep, ensureHost },
239
242
  call,
240
243
  ) {
241
- if (!Number.isSafeInteger(limit) || limit < 1 || limit > 24) throw new Error('INVALID_ARGUMENTS')
244
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 48) throw new Error('INVALID_ARGUMENTS')
242
245
  // Append-batch consolidation uses immutable local drafts. No current journey view is
243
246
  // needed until publication; retain write recovery and live value settlement on that path.
244
247
  if (stage === 'cards' && !refresh && ['consolidate', 'ingest'].includes(command)) {
@@ -605,11 +608,14 @@ async function runPhaseCore(
605
608
 
606
609
  /**
607
610
  * The complete proposal, checked before commit: after scope confirmation an item never joins
608
- * placed Works with different visibility (ADR 0274), which CLI would refuse.
611
+ * placed Works with different visibility (ADR 0274), and account Work joins follow ADR 0276
612
+ * slice H; CLI would refuse either.
609
613
  */
610
614
  async function classificationItems(manifest, view) {
611
615
  const items = await classificationSubmission(manifest, view)
612
- if (view.scope?.status === 'confirmed') validateLatePlacedWorks(items, view.works)
616
+ const confirmed = view.scope?.status === 'confirmed'
617
+ validateAccountWorkJoins(items, view.works, confirmed)
618
+ if (confirmed) validateLatePlacedWorks(items, view.works)
613
619
  return items
614
620
  }
615
621
 
@@ -656,6 +662,7 @@ async function ingestKnownWorks(directory, manifest, view, call, partial) {
656
662
  const terminalClassificationErrors = new Set([
657
663
  'INVALID_SELECTION',
658
664
  'CLASSIFICATION_LATE_SEVERAL_WORKS',
665
+ 'CLASSIFICATION_ACCOUNT_WORK_JOIN',
659
666
  'CLASSIFICATION_PROJECT_NAME_CONFLICT',
660
667
  'CLASSIFICATION_ROOT_COVERAGE_INVALID',
661
668
  'CLASSIFICATION_THEME_TOO_SMALL',
@@ -735,15 +742,16 @@ export async function main(argv) {
735
742
  }
736
743
  const safeId = /^[A-Za-z0-9._:-]{1,128}$/u
737
744
  /**
738
- * Stderr for a failed command: the code, and for CLASSIFICATION_LATE_SEVERAL_WORKS one line per
739
- * refused item with its index and the placed Work ids, never a title or path (ADR 0274).
745
+ * Stderr for a failed command: the code, and for CLASSIFICATION_LATE_SEVERAL_WORKS and
746
+ * CLASSIFICATION_ACCOUNT_WORK_JOIN one line per refused item with its index and the Work ids,
747
+ * never a title or path (ADR 0274, ADR 0276 slice H).
740
748
  */
741
749
  export function failureOutput(error) {
742
750
  const message = error?.message ?? ''
743
751
  if (error?.code?.startsWith('ERR_PARSE_ARGS')) return 'INVALID_ARGUMENTS\n'
744
752
  const code = /^[A-Z_]{3,80}$/u.test(message) ? message : 'JOURNEY_HELPER_FAILED'
745
753
  const lines = [code]
746
- if (code === 'CLASSIFICATION_LATE_SEVERAL_WORKS')
754
+ if (code === 'CLASSIFICATION_LATE_SEVERAL_WORKS' || code === 'CLASSIFICATION_ACCOUNT_WORK_JOIN')
747
755
  for (const conflict of error.conflicts ?? [])
748
756
  if (Number.isInteger(conflict.item))
749
757
  lines.push(
@@ -55,7 +55,7 @@ const COMMAND_BUDGET_MS = 75_000
55
55
  const LOCK_WAIT_MS = 60_000
56
56
  const LOCK_POLL_MS = 200
57
57
  // Native child slots shared by every phase; `--agents auto` fills all of them with privacy packs.
58
- const SLOTS = 24
58
+ const SLOTS = 48
59
59
  // While `--agents auto` waits, journey input (newly published sessions) is rechecked this often.
60
60
  const AUTO_RECHECK_MS = 3_000
61
61
  const PREPARATION_WAIT_MS = 60_000
@@ -1547,7 +1547,7 @@ async function outstandingPacks(ctx) {
1547
1547
  return outstanding
1548
1548
  }
1549
1549
  /**
1550
- * `ingest --agents auto`: ingest and refill every free slot of the twenty-four. While nothing is new,
1550
+ * `ingest --agents auto`: ingest and refill every free slot of the forty-eight. While nothing is new,
1551
1551
  * wait up to `--wait-ms` (within half the command budget) for a published answer, rechecking
1552
1552
  * journey input periodically, so the parent loops: dispatch the returned prompts, call again.
1553
1553
  */