@gitroll/tacitt-cli 0.6.12 → 0.6.13
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/dist/{agent-setup-B12VbvN_.mjs → agent-setup-Doy_AnPY.mjs} +2 -2
- package/dist/agent-setup-worker.mjs +5 -5
- package/dist/cli.mjs +10 -10
- package/dist/codex-title-worker.mjs +1 -1
- package/dist/configured-preview-worker.mjs +5 -5
- package/dist/configured-session-worker.mjs +5 -5
- package/dist/{frame-B3He21G8.mjs → frame-BPbypzmt.mjs} +1 -1
- package/dist/{heap-Blrat--4.mjs → heap-DCS_WXIA.mjs} +7 -3
- package/dist/inspection-worker.mjs +4 -4
- package/dist/{job-CBuIMTQ0.mjs → job--zxwgaPy.mjs} +135 -36
- package/dist/{locate-D-ZaHpI0.mjs → locate-PLEyLYW-.mjs} +287 -236
- package/dist/{model-DR9odhWP.mjs → model-CyXvsWLz.mjs} +1 -1
- package/dist/operation-executor.mjs +3 -3
- package/dist/preview-worker.mjs +1 -1
- package/dist/privacy-validator.mjs +1 -1
- package/dist/{query-BYDcNKy2.mjs → query-BC7MIaWc.mjs} +335 -115
- package/dist/{run-DQ9xyKSt.mjs → run-Dod7Vykp.mjs} +6 -6
- package/dist/{src-DeNJ8vOD.mjs → src-CP-K2PBv.mjs} +1779 -1686
- package/dist/{src-Do-qzuMn.mjs → src-CttNuxOn.mjs} +590 -542
- package/dist/{src-CKQlTA2Z.mjs → src-dL6y2mcu.mjs} +180 -30
- package/dist/store-database-worker.mjs +1 -1
- package/package.json +1 -1
- package/skills/tacitt/SKILL.md +3 -3
- package/skills/tacitt/references/b-method.md +4 -2
- package/skills/tacitt/references/bootstrap.md +1 -1
- package/skills/tacitt/references/commands.md +10 -4
- package/skills/tacitt/references/journey.md +3 -3
- package/skills/tacitt/references/parallel-review.md +22 -9
- package/skills/tacitt/references/remote-workers.md +6 -2
- package/skills/tacitt/scripts/INDEX.md +4 -4
- package/skills/tacitt/scripts/answer.mjs +12 -1
- package/skills/tacitt/scripts/describe.mjs +3 -2
- package/skills/tacitt/scripts/journey-classification.mjs +1 -0
- package/skills/tacitt/scripts/journey-scan-timing.mjs +3 -2
- package/skills/tacitt/scripts/journey.mjs +1 -1
- package/skills/tacitt/scripts/privacy-validator.mjs +84 -33
- package/skills/tacitt/scripts/review.d.mts +1 -0
- package/skills/tacitt/scripts/review.mjs +296 -35
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<!-- index-entries
|
|
7
7
|
./ | Source / reference | Release-pinned phase and review helpers using the paired CLI for frozen inputs and batch persistence.
|
|
8
8
|
INDEX.md | Directory index | Lists executable helpers shipped with the exact Skill release.
|
|
9
|
-
answer.mjs | CLI publisher | Validates task-bound classification and privacy drafts, including required privacy unit coverage and reused-card policy with repair diagnostics, reports card issue paths without mutating validator errors,
|
|
10
|
-
describe.mjs | Runtime | Binds proposed generated metadata
|
|
9
|
+
answer.mjs | CLI publisher | Validates task-bound classification and privacy drafts, including required privacy unit coverage and reused-card policy with repair diagnostics, reports card issue paths without mutating validator errors, atomically publishes canonical answers, and emits hash-verified source pages with manifest-derived byte framing while preserving legacy page output.
|
|
10
|
+
describe.mjs | Runtime | Binds proposed generated metadata to the current decision/context. A value the person hid is shown as `[hidden]` in the Work title and the workspace title; descriptions stay unchanged and titles the person typed are not masked by Hide answers.
|
|
11
11
|
journey-card-consolidation.d.mts | Declaration | Types global card generation, policy comparison, identity boundaries, answer validation and final key expansion.
|
|
12
12
|
journey-card-consolidation.mjs | Runtime | Immutably merges matching existing-policy extensions without a second model task (ADR 0251); policy or identity mismatches fall back to digest-bound global review, with exact key coverage and five/ten question limits.
|
|
13
13
|
journey-card-values.d.mts | Declaration | Types card value settlement for helper tests.
|
|
@@ -19,7 +19,7 @@ journey-classification-tasks.d.mts | Declaration | Types initial classification
|
|
|
19
19
|
journey-classification-tasks.mjs | Runtime | Original-root routing, capacity-balanced bounded tasks and unresolved-first ready ordering with stable assignments.
|
|
20
20
|
journey-classification-validation.d.mts | Declaration | Shared classification validator contracts.
|
|
21
21
|
journey-classification-validation.mjs | Runtime | Shared root judgment, stable target identity, fixed project metadata, consolidation validation, target-preserving assignment expansion and the late check that an item joins only placed Works with one access record (ADR 0274).
|
|
22
|
-
journey-classification.mjs | Runtime | Batched known-project metadata, unknown-root grouping and
|
|
22
|
+
journey-classification.mjs | Runtime | Batched known-project metadata, unknown-root grouping and streamed four-row evidence, versioned checkpoints and generation progress.
|
|
23
23
|
journey-consolidation-submit.mjs | Runtime | Expands candidate assignments, applies per-root overrides, combines small topics into Unsorted, attaches known projects and checks exact root coverage.
|
|
24
24
|
journey-consolidation.d.mts | Declaration | Consolidation helper contract for bounded evidence regression tests.
|
|
25
25
|
journey-consolidation.mjs | Runtime | Builds proposed-name and stable-target candidate buckets, persists complete reconciliation input, and returns compact dispatch descriptors.
|
|
@@ -38,7 +38,7 @@ local-cli.mjs | Read-only package verifier | Validates an explicit installed CLI
|
|
|
38
38
|
review-stream-client.d.mts | Type declarations | Types the fixed request/shutdown limits, private lifecycle callbacks and review-stream client methods.
|
|
39
39
|
review-stream-client.mjs | Runtime | Bounds requests and owned-child shutdown, permits retry only for explicit pre-request startup busy, and preserves unknown lost-write outcomes for receipt replay.
|
|
40
40
|
review.d.mts | Type declarations | Types the review helper's exported task rendering, answer reading, per-Work progress and entry functions for tests.
|
|
41
|
-
review.mjs | Runtime | Session-ready scanning,
|
|
41
|
+
review.mjs | Runtime | Session-ready scanning, ready-pack-first twenty-four-slot refill, 30000-token pack target, manifest-derived page byte capture, default reader pull with native self-binding, host-capability fallback and replayable slot transfer, blocked-Work exclusion, largest-Work queue ordering, isolated retries, batched native reader and turn receipts with launch reservations, bounded reissue and visible interruption recovery, planned card capacity, outcome-reported preparation recovery and read-only status, metadata-gated questions, Track B-gated final preview and hash-bound answer recovery.
|
|
42
42
|
verify-cli.mjs | Verification entry | Checks a managed local receipt and its current package bytes before the Skill starts a journey.
|
|
43
43
|
-->
|
|
44
44
|
|
|
@@ -82,8 +82,19 @@ async function publish(args) {
|
|
|
82
82
|
const receipt = /\nREAD_RECEIPT ([a-f0-9]{64})\n$/u.exec(output)?.[1]
|
|
83
83
|
if (!receipt || createHash('sha256').update(output).digest('hex') !== line.slice(prefix.length))
|
|
84
84
|
throw new Error('SOURCE_BINDING')
|
|
85
|
+
const bytePrefix = 'Page bytes ' + ref + '/' + ordinal + ' '
|
|
86
|
+
const byteLine = lines.slice(start + 1).find((item) => item.startsWith(bytePrefix))
|
|
87
|
+
const expectedBytes = byteLine?.slice(bytePrefix.length)
|
|
88
|
+
if (
|
|
89
|
+
expectedBytes !== undefined &&
|
|
90
|
+
(!/^[1-9]\d*$/u.test(expectedBytes) || Number(expectedBytes) !== Buffer.byteLength(output))
|
|
91
|
+
)
|
|
92
|
+
throw new Error('SOURCE_BINDING')
|
|
93
|
+
// Legacy manifests keep their original output; new capture code consumes this trusted framing.
|
|
94
|
+
const framed =
|
|
95
|
+
expectedBytes === undefined ? output : 'READ_BYTES ' + expectedBytes + '\n' + output
|
|
85
96
|
await new Promise((done, reject) =>
|
|
86
|
-
process.stdout.write(
|
|
97
|
+
process.stdout.write(framed, (error) => (error ? reject(error) : done())),
|
|
87
98
|
)
|
|
88
99
|
// A new page is a heartbeat; repeated reads of the same page cannot renew a lost reader.
|
|
89
100
|
const directory = taskPath.replace(/\.md$/u, '.reads')
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto'
|
|
2
2
|
|
|
3
|
-
// The parent supplies only its authorized context and proposed generated metadata
|
|
4
|
-
//
|
|
3
|
+
// The parent supplies only its authorized context and proposed generated metadata.
|
|
4
|
+
// A value the person hid is shown as [hidden] in the Work title and the workspace title.
|
|
5
|
+
// Descriptions stay unchanged; titles the person typed are not masked by Hide answers.
|
|
5
6
|
const object = (value) => typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
6
7
|
const fail = () => {
|
|
7
8
|
throw new Error('INVALID_DESCRIPTION_ANNOTATIONS')
|
|
@@ -102,6 +102,7 @@ export async function classificationEvidence(directory, manifest, view, call, li
|
|
|
102
102
|
let cursor
|
|
103
103
|
for (let pageNumber = 0; pageNumber < 2; pageNumber++) {
|
|
104
104
|
const content = await call('journey.classificationRead', {
|
|
105
|
+
limit: 4,
|
|
105
106
|
journeyId: view.journeyId,
|
|
106
107
|
workId,
|
|
107
108
|
rootSessionId: root.rootSessionId,
|
|
@@ -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:
|
|
201
|
+
slots: { capacity: 24, busyChildMs: 0, waitingBatchWallMs: 0, refillGapMs: [], children: [] },
|
|
202
202
|
preparation: {
|
|
203
203
|
intervals: [],
|
|
204
204
|
milliseconds: { 'before-first-batch': 0, 'mid-run': 0, tail: 0 },
|
|
@@ -207,7 +207,8 @@ export async function observeScanTiming(run, observation) {
|
|
|
207
207
|
observationBasis: {
|
|
208
208
|
dispatch: 'helper-reservation',
|
|
209
209
|
publication: 'answer-file-mtime',
|
|
210
|
-
slotRelease:
|
|
210
|
+
slotRelease:
|
|
211
|
+
'confirmed-native-close-or-persistent-assignment-handoff-otherwise-helper-observation',
|
|
211
212
|
cards: 'parent-reported-count-at-helper-boundary',
|
|
212
213
|
preparation: 'helper-observed-interval',
|
|
213
214
|
lockWait: 'unavailable-in-rpc',
|
|
@@ -212,7 +212,7 @@ async function runPhaseCore(
|
|
|
212
212
|
{ run, journeyId, command, stage, refresh = false, limit = 3, waitMs = 0, sleep, ensureHost },
|
|
213
213
|
call,
|
|
214
214
|
) {
|
|
215
|
-
if (!Number.isSafeInteger(limit) || limit < 1 || limit >
|
|
215
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 24) throw new Error('INVALID_ARGUMENTS')
|
|
216
216
|
// Append-batch consolidation uses immutable local drafts. No current journey view is
|
|
217
217
|
// needed until publication; retain write recovery and live value settlement on that path.
|
|
218
218
|
if (stage === 'cards' && !refresh && ['consolidate', 'ingest'].includes(command)) {
|
|
@@ -9833,6 +9833,8 @@ const decisionCardSchema = decisionCardInputSchema.extend({ answer: object({
|
|
|
9833
9833
|
rule: string().max(4001),
|
|
9834
9834
|
additionalRule: string().max(2e3),
|
|
9835
9835
|
remember: boolean(),
|
|
9836
|
+
/** Where the answer came from; only the person's panel Hide is remembered (issue #126). */
|
|
9837
|
+
source: _enum(["conversation", "panel"]).optional(),
|
|
9836
9838
|
excludedTermKeys: array(string().min(1)).max(2e4).optional()
|
|
9837
9839
|
}).strict().nullable() }).strict();
|
|
9838
9840
|
const journeyPrivacySchema = object({
|
|
@@ -10340,6 +10342,11 @@ object({
|
|
|
10340
10342
|
/** ADR 0086: per-value Hide or Keep over the term types' answers; absent means none. */
|
|
10341
10343
|
valueOverrides: array(journeyValueOverrideSchema).max(1e4).optional(),
|
|
10342
10344
|
/**
|
|
10345
|
+
* Values the person hid in earlier journeys on this machine, frozen at formation (issue #126).
|
|
10346
|
+
* Private: never in a view, reader guidance or anything sent.
|
|
10347
|
+
*/
|
|
10348
|
+
rememberedHides: array(string().min(1).max(1024)).max(1e5).optional(),
|
|
10349
|
+
/**
|
|
10343
10350
|
* ADR 0086: the snapshot is read by dictionary review. A snapshot without it was read by B
|
|
10344
10351
|
* review, whose evidence this release no longer renders, so it is obsolete.
|
|
10345
10352
|
*/
|
|
@@ -10644,43 +10651,82 @@ object({
|
|
|
10644
10651
|
reviewBatchSchema.omit({ digest: true });
|
|
10645
10652
|
//#endregion
|
|
10646
10653
|
//#region packages/application/src/journey/terms/locate.ts
|
|
10647
|
-
/**
|
|
10648
|
-
|
|
10649
|
-
|
|
10654
|
+
/**
|
|
10655
|
+
* Issue #140: per batch and field, contiguous core and context chunks in offset order, never
|
|
10656
|
+
* joined across fields, field revisions or gaps. A core boundary maps to the NFC length of the
|
|
10657
|
+
* text before it.
|
|
10658
|
+
*/
|
|
10659
|
+
function* termSearchRuns(batches) {
|
|
10650
10660
|
for (const batch of batches) {
|
|
10651
|
-
const fields = Map.groupBy(batch.chunks
|
|
10652
|
-
for (const
|
|
10653
|
-
let
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
+
const fields = Map.groupBy(batch.chunks, (chunk) => JSON.stringify([chunk.fieldId, chunk.fieldHash]));
|
|
10662
|
+
for (const group of fields.values()) {
|
|
10663
|
+
let run = [];
|
|
10664
|
+
const runs = [run];
|
|
10665
|
+
for (const chunk of group.toSorted((a, b) => a.offset - b.offset)) {
|
|
10666
|
+
const last = run.at(-1);
|
|
10667
|
+
if (last && last.offset + last.text.length !== chunk.offset) runs.push(run = []);
|
|
10668
|
+
run.push(chunk);
|
|
10669
|
+
}
|
|
10670
|
+
for (const chunks of runs) {
|
|
10671
|
+
if (!chunks.some((chunk) => chunk.core)) continue;
|
|
10672
|
+
const raw = chunks.map((chunk) => chunk.text).join("");
|
|
10673
|
+
const text = raw.normalize("NFC");
|
|
10674
|
+
const at = (end) => Math.min(text.length, raw.slice(0, end).normalize("NFC").length);
|
|
10675
|
+
const cores = [];
|
|
10676
|
+
let offset = 0;
|
|
10677
|
+
for (const chunk of chunks) {
|
|
10678
|
+
const start = offset;
|
|
10679
|
+
offset += chunk.text.length;
|
|
10680
|
+
if (!chunk.core) continue;
|
|
10681
|
+
const last = cores.at(-1);
|
|
10682
|
+
if (last && last[1] === start) last[1] = offset;
|
|
10683
|
+
else cores.push([start, offset]);
|
|
10661
10684
|
}
|
|
10662
|
-
|
|
10663
|
-
|
|
10685
|
+
yield {
|
|
10686
|
+
batch,
|
|
10687
|
+
chunks,
|
|
10688
|
+
text,
|
|
10689
|
+
cores: cores.map(([start, end]) => [at(start), at(end)])
|
|
10690
|
+
};
|
|
10664
10691
|
}
|
|
10665
|
-
if (text) texts.push({
|
|
10666
|
-
workId: batch.workId,
|
|
10667
|
-
text: text.normalize("NFC")
|
|
10668
|
-
});
|
|
10669
10692
|
}
|
|
10670
10693
|
}
|
|
10671
|
-
return texts;
|
|
10672
10694
|
}
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10695
|
+
/**
|
|
10696
|
+
* Occurrences of `value` in a run: `owned` counts non-overlapping occurrences that start in a
|
|
10697
|
+
* core range; `first` is the first occurrence overlapping a core range, or -1. An occurrence that
|
|
10698
|
+
* starts outside the core is skipped by one position only, so it never hides an owned one.
|
|
10699
|
+
*/
|
|
10700
|
+
function runOccurrences(run, value) {
|
|
10701
|
+
let owned = 0, first = -1;
|
|
10702
|
+
if (!value) return {
|
|
10703
|
+
owned,
|
|
10704
|
+
first
|
|
10705
|
+
};
|
|
10706
|
+
for (let at = run.text.indexOf(value); at >= 0;) {
|
|
10707
|
+
const end = at + value.length;
|
|
10708
|
+
if (run.cores.some(([start, stop]) => at >= start && at < stop)) {
|
|
10709
|
+
owned++;
|
|
10710
|
+
if (first < 0) first = at;
|
|
10711
|
+
at = run.text.indexOf(value, end);
|
|
10712
|
+
continue;
|
|
10713
|
+
}
|
|
10714
|
+
if (first < 0 && run.cores.some(([start, stop]) => at < stop && end > start)) first = at;
|
|
10715
|
+
at = run.text.indexOf(value, at + 1);
|
|
10716
|
+
}
|
|
10717
|
+
return {
|
|
10718
|
+
owned,
|
|
10719
|
+
first
|
|
10720
|
+
};
|
|
10677
10721
|
}
|
|
10678
10722
|
/**
|
|
10679
|
-
* ADR 0086: a value is kept only if it occurs verbatim (NFC,
|
|
10680
|
-
*
|
|
10723
|
+
* ADR 0086, refined by issue #140: a value is kept only if it occurs verbatim (NFC,
|
|
10724
|
+
* case-sensitive) in a pack field's contiguous core and context text, overlapping a core chunk;
|
|
10725
|
+
* only occurrences that start in a core chunk are counted. Its complete admitted NFC value
|
|
10726
|
+
* becomes one dictionary entry (ADR 0088).
|
|
10681
10727
|
*/
|
|
10682
10728
|
function locateTerms(batches, terms) {
|
|
10683
|
-
const
|
|
10729
|
+
const runs = [...termSearchRuns(batches)];
|
|
10684
10730
|
const located = /* @__PURE__ */ new Map();
|
|
10685
10731
|
const unlocatedIndices = [];
|
|
10686
10732
|
let kept = 0, unlocated = 0;
|
|
@@ -10693,20 +10739,25 @@ function locateTerms(batches, terms) {
|
|
|
10693
10739
|
}];
|
|
10694
10740
|
}));
|
|
10695
10741
|
for (const { type, value, index } of unique.values()) {
|
|
10696
|
-
|
|
10742
|
+
let count = 0;
|
|
10743
|
+
let workId;
|
|
10744
|
+
if (!value.includes("█") && admitCustomTerm(value)?.value === value) for (const run of runs) {
|
|
10745
|
+
const { owned, first } = runOccurrences(run, value);
|
|
10746
|
+
if (first < 0) continue;
|
|
10747
|
+
count += owned;
|
|
10748
|
+
workId ??= run.batch.workId;
|
|
10749
|
+
}
|
|
10750
|
+
if (workId === void 0) {
|
|
10697
10751
|
unlocated++;
|
|
10698
10752
|
unlocatedIndices.push(index);
|
|
10699
10753
|
continue;
|
|
10700
10754
|
}
|
|
10701
10755
|
kept++;
|
|
10702
|
-
const holders = texts.filter((item) => item.text.includes(value));
|
|
10703
|
-
const first = holders[0];
|
|
10704
|
-
if (!first) continue;
|
|
10705
10756
|
located.set(JSON.stringify([type, value]), {
|
|
10706
10757
|
type,
|
|
10707
10758
|
value,
|
|
10708
|
-
count
|
|
10709
|
-
workId
|
|
10759
|
+
count,
|
|
10760
|
+
workId
|
|
10710
10761
|
});
|
|
10711
10762
|
}
|
|
10712
10763
|
return {
|