agentera 3.0.0-dev.72 → 3.0.0-dev.74
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 +111 -0
- package/bundle/.agentera-build-source.json +8 -0
- package/bundle/CHANGELOG.md +17 -17
- package/bundle/extract-corpus-parity.json +1 -1
- package/bundle/references/adapters/package-publication.json +49 -53
- package/bundle/references/adapters/package-registry.yaml +5 -1
- package/bundle/references/adapters/package-surface-characterization.md +6 -4
- package/bundle/references/analysis/evidence-tier-authority.yaml +45 -4
- package/bundle/references/analysis/personal-glossary-evaluation-authority.yaml +175 -0
- package/bundle/references/analysis/personal-glossary-evaluation-corpus.yaml +291 -0
- package/bundle/references/analysis/personal-glossary-holdout.yaml +192 -0
- package/bundle/references/artifacts/glossary-entry-contract.yaml +1533 -35
- package/bundle/references/cli/update-channels.yaml +2 -2
- package/bundle/references/cli/vocabulary.md +1 -1
- package/bundle/references/meta/retained-reference-authority.yaml +15 -0
- package/bundle/skills/agentera/capabilities/profile/schemas/artifacts.yaml +11 -7
- package/bundle/skills/agentera/capabilities/profile/schemas/exit.yaml +6 -3
- package/bundle/skills/agentera/capabilities/profile/schemas/validation.yaml +13 -7
- package/bundle/skills/agentera/schemas/artifacts/glossary.yaml +5 -0
- package/bundle/skills/agentera/schemas/artifacts/plan.yaml +7 -0
- package/dist/.agentera-build-source.json +8 -0
- package/dist/analytics/extractCorpus/copilotSessions.js +13 -4
- package/dist/analytics/extractCorpus/core.js +223 -3
- package/dist/analytics/extractCorpus/corpus.js +18 -1
- package/dist/analytics/extractCorpus/cursorSessions.js +22 -4
- package/dist/analytics/extractCorpus/evidenceTiers.js +123 -17
- package/dist/analytics/extractCorpus/filesystemSources.js +4 -0
- package/dist/analytics/extractCorpus/index.js +2 -2
- package/dist/analytics/extractCorpus/jsonlSessions.js +52 -3
- package/dist/analytics/extractCorpus/sqliteSessions.js +12 -3
- package/dist/analytics/personalGlossaryAdmission.js +26 -46
- package/dist/analytics/personalGlossaryCandidateProjection.js +692 -0
- package/dist/analytics/personalGlossaryCandidateProjectionExcerpts.js +144 -0
- package/dist/analytics/personalGlossaryCandidateReadView.js +23 -0
- package/dist/analytics/personalGlossaryCurrentGeneration.js +25 -0
- package/dist/analytics/personalGlossaryDecision.js +203 -0
- package/dist/analytics/personalGlossaryExplicit.js +788 -0
- package/dist/analytics/personalGlossaryExplicitMining.js +285 -0
- package/dist/analytics/personalGlossaryExplicitScope.js +41 -0
- package/dist/analytics/personalGlossaryExplicitSegments.js +418 -0
- package/dist/analytics/personalGlossaryExplicitTypes.js +26 -0
- package/dist/analytics/personalGlossaryLexicalClassifier.js +175 -0
- package/dist/analytics/personalGlossaryProfile.js +13 -3
- package/dist/analytics/personalGlossaryRecurrence.js +618 -0
- package/dist/analytics/personalGlossaryReviewRecordStorage.js +428 -0
- package/dist/analytics/personalGlossaryReviewRecords.js +332 -0
- package/dist/capabilities/index.js +5 -1
- package/dist/capabilities/profile/instructions.js +50 -15
- package/dist/cli/commands/personalGlossaryCandidateReads.js +744 -0
- package/dist/cli/commands/personalGlossaryDecision.js +349 -0
- package/dist/cli/commands/personalGlossaryPublish.js +484 -0
- package/dist/cli/commands/personalGlossaryReviewRecordReads.js +209 -0
- package/dist/cli/commands/personalGlossaryReviewRecords.js +623 -0
- package/dist/cli/commands/prime/briefOrientation.js +118 -19
- package/dist/cli/commands/report.js +18 -2
- package/dist/cli/commands/schema.js +179 -0
- package/dist/cli/commands/verify.js +51 -9
- package/dist/cli/dispatch/lifecycle.js +51 -6
- package/dist/cli/help.js +48 -2
- package/dist/cli/migrationRequired.js +4 -1
- package/dist/core/atomicWriter.js +4 -1
- package/dist/core/developmentInvocation.js +4 -1
- package/dist/core/yaml.js +53 -1
- package/dist/eval/glossaryEvaluation.js +751 -0
- package/dist/eval/glossaryEvaluationProcess.js +29 -0
- package/dist/eval/glossaryEvaluationRunner.js +571 -0
- package/dist/eval/glossaryEvaluationSuccessReport.js +297 -0
- package/dist/registries/activationTuples.js +31 -3
- package/dist/registries/evidenceTierContract.js +4 -0
- package/dist/registries/explicitSegmentGrammarContract.js +619 -0
- package/dist/registries/glossaryCandidateContractPaths.js +6 -0
- package/dist/registries/glossaryCandidateContracts.js +820 -0
- package/dist/registries/glossaryCandidateDecisionAuthority.js +119 -0
- package/dist/registries/glossaryCandidateDecisionContract.js +62 -0
- package/dist/registries/glossaryCandidateProjectionAuthority.js +197 -0
- package/dist/registries/glossaryCandidateProjectionContract.js +104 -0
- package/dist/registries/glossaryEntryContract.js +105 -103
- package/dist/registries/glossaryEntryTemporal.js +12 -0
- package/dist/registries/glossaryMiningAuthority.js +764 -0
- package/dist/registries/glossaryProfileFullContract.js +24 -0
- package/dist/registries/glossaryReviewRecordsAuthority.js +426 -0
- package/dist/registries/glossaryReviewRecordsContract.js +129 -0
- package/dist/registries/glossaryTermIdentity.js +122 -0
- package/dist/registries/packagePublication.js +3 -3
- package/dist/registries/personalGlossaryContracts.js +1 -0
- package/dist/release/releaseMetadata.js +14 -7
- package/dist/upgrade/npxPlatformStatus.js +2 -1
- package/dist/upgrade/projectIntegration.js +7 -1
- package/dist/validate/activationArtifactEvidence.js +18 -4
- package/dist/validate/activationEvidenceManifest.js +101 -22
- package/package.json +2 -4
- package/dist/cli/commands/personalGlossary.js +0 -176
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { readCurrentPersonalGlossaryCandidateProjection, } from "../../analytics/personalGlossaryCurrentGeneration.js";
|
|
3
|
+
import { decidePersonalGlossaryCandidate, evaluatePersonalGlossaryCandidate, } from "../../analytics/personalGlossaryDecision.js";
|
|
4
|
+
import { loadYamlMapping, withReadOnlyYamlMappingCache } from "../../core/yaml.js";
|
|
5
|
+
import { createGlossaryHostClassificationReceipt, } from "../../registries/glossaryCandidateContracts.js";
|
|
6
|
+
import { personalGlossaryCandidateDecisionContract } from "../../registries/glossaryCandidateDecisionContract.js";
|
|
7
|
+
import { emitInvalidInput } from "../errors.js";
|
|
8
|
+
const COMMAND = "agentera report personal-glossary-decision --input <file|-> --format json";
|
|
9
|
+
const RECOVERY = "Correct the bounded decision request and retry; no projection, review, profile, or project bytes were changed.";
|
|
10
|
+
const SHA256 = /^[a-f0-9]{64}$/u;
|
|
11
|
+
const MAX_BINDING_UTF8_BYTES = 256;
|
|
12
|
+
function mapping(value) {
|
|
13
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
14
|
+
? value
|
|
15
|
+
: null;
|
|
16
|
+
}
|
|
17
|
+
function invalid(io, body) {
|
|
18
|
+
return emitInvalidInput(io, { format: "json", body: { ...body, recovery: body.recovery ?? RECOVERY } });
|
|
19
|
+
}
|
|
20
|
+
function validContract(value) {
|
|
21
|
+
return !(value.command !== "agentera report personal-glossary-decision" ||
|
|
22
|
+
value.requestSchemaVersion !== "agentera.personalGlossaryAdmissionRequest.v1" ||
|
|
23
|
+
JSON.stringify(value.requestFields) !== JSON.stringify(["schema_version", "receipt"]) ||
|
|
24
|
+
value.maxRequestUtf8Bytes !== 16_384 ||
|
|
25
|
+
value.resultSchemaVersion !== "agentera.personalGlossaryAdmissionResult.v1" ||
|
|
26
|
+
JSON.stringify(value.resultFields) !==
|
|
27
|
+
JSON.stringify(["schemaVersion", "command", "status", "decision", "reason", "effects"]) ||
|
|
28
|
+
JSON.stringify(value.resultStatuses) !==
|
|
29
|
+
JSON.stringify(["automatic_admission", "review_required", "abstain"]) ||
|
|
30
|
+
value.maxResultUtf8Bytes !== 4_096 ||
|
|
31
|
+
value.receiptConstructionRequestSchemaVersion !== "agentera.personalGlossaryAdmissionRequest.v2" ||
|
|
32
|
+
JSON.stringify(value.receiptConstructionRequestFields) !==
|
|
33
|
+
JSON.stringify([
|
|
34
|
+
"schema_version",
|
|
35
|
+
"candidate_id",
|
|
36
|
+
"candidate_revision",
|
|
37
|
+
"candidate_capsule_sha256",
|
|
38
|
+
"candidate_projection_sha256",
|
|
39
|
+
"generation",
|
|
40
|
+
"policy_version",
|
|
41
|
+
"classification",
|
|
42
|
+
]) ||
|
|
43
|
+
value.receiptConstructionMaxRequestUtf8Bytes !== 16_384 ||
|
|
44
|
+
value.receiptConstructionResultSchemaVersion !== "agentera.personalGlossaryAdmissionResult.v2" ||
|
|
45
|
+
JSON.stringify(value.receiptConstructionResultFields) !==
|
|
46
|
+
JSON.stringify(["schemaVersion", "command", "status", "receipt", "decision", "reason", "effects"]) ||
|
|
47
|
+
JSON.stringify(value.receiptConstructionResultStatuses) !==
|
|
48
|
+
JSON.stringify(["automatic_admission", "review_required", "abstain"]) ||
|
|
49
|
+
value.receiptConstructionMaxResultUtf8Bytes !== 16_384 ||
|
|
50
|
+
value.automaticProvenance !== "provenance_variants.personal_explicit_definition" ||
|
|
51
|
+
value.inferredAutomaticAdmission !== "disabled" ||
|
|
52
|
+
value.qualityGate !== "personal_mining_authority.admission.quality_threshold");
|
|
53
|
+
}
|
|
54
|
+
function contract(precomputed) {
|
|
55
|
+
const value = precomputed ?? personalGlossaryCandidateDecisionContract();
|
|
56
|
+
if (!validContract(value)) {
|
|
57
|
+
throw new Error("personal glossary decision contract is unavailable");
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
function parseArgs(argv) {
|
|
62
|
+
let input;
|
|
63
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
64
|
+
const [name, inline] = argv[index].split("=", 2);
|
|
65
|
+
if (name !== "--input" && name !== "--format") {
|
|
66
|
+
return { class: "unrecognized_argument", message: `unrecognized arguments: ${name}`, syntax: COMMAND };
|
|
67
|
+
}
|
|
68
|
+
const value = inline ?? argv[++index];
|
|
69
|
+
if (!value || value.startsWith("--")) {
|
|
70
|
+
return { class: "missing_argument", message: `${name} requires a value`, syntax: `${name} VALUE` };
|
|
71
|
+
}
|
|
72
|
+
if (name === "--format") {
|
|
73
|
+
if (value !== "json") {
|
|
74
|
+
return {
|
|
75
|
+
class: "invalid_choice",
|
|
76
|
+
message: "personal-glossary-decision requires --format json",
|
|
77
|
+
valid_values: ["json"],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (input !== undefined) {
|
|
83
|
+
return { class: "mutually_exclusive", message: "--input may only be supplied once" };
|
|
84
|
+
}
|
|
85
|
+
input = value;
|
|
86
|
+
}
|
|
87
|
+
return input ? { input } : { class: "missing_argument", message: "--input is required", syntax: COMMAND };
|
|
88
|
+
}
|
|
89
|
+
function readBoundedDescriptor(fd, maxBytes) {
|
|
90
|
+
const bytes = Buffer.allocUnsafe(maxBytes + 1);
|
|
91
|
+
let offset = 0;
|
|
92
|
+
while (offset < bytes.length) {
|
|
93
|
+
const count = fs.readSync(fd, bytes, offset, bytes.length - offset, null);
|
|
94
|
+
if (count === 0)
|
|
95
|
+
break;
|
|
96
|
+
offset += count;
|
|
97
|
+
}
|
|
98
|
+
if (offset > maxBytes)
|
|
99
|
+
throw new Error("over bound");
|
|
100
|
+
return bytes.subarray(0, offset);
|
|
101
|
+
}
|
|
102
|
+
function sameIdentity(left, right) {
|
|
103
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
104
|
+
}
|
|
105
|
+
function readBoundedFile(source, maxBytes) {
|
|
106
|
+
const observed = fs.lstatSync(source, { bigint: true });
|
|
107
|
+
if (observed.isSymbolicLink() || !observed.isFile() || observed.size > BigInt(maxBytes)) {
|
|
108
|
+
throw new Error("over bound or unreadable");
|
|
109
|
+
}
|
|
110
|
+
let fd = null;
|
|
111
|
+
try {
|
|
112
|
+
fd = fs.openSync(source, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
113
|
+
const opened = fs.fstatSync(fd, { bigint: true });
|
|
114
|
+
if (!opened.isFile() || !sameIdentity(observed, opened) || opened.size > BigInt(maxBytes)) {
|
|
115
|
+
throw new Error("over bound or unreadable");
|
|
116
|
+
}
|
|
117
|
+
return readBoundedDescriptor(fd, maxBytes);
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
if (fd !== null)
|
|
121
|
+
fs.closeSync(fd);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function readBoundedStdin(maxBytes, io) {
|
|
125
|
+
if (io.stdin) {
|
|
126
|
+
const value = io.stdin();
|
|
127
|
+
if (Buffer.byteLength(value, "utf8") > maxBytes)
|
|
128
|
+
throw new Error("over bound");
|
|
129
|
+
return Buffer.from(value, "utf8");
|
|
130
|
+
}
|
|
131
|
+
if (process.stdin.isTTY)
|
|
132
|
+
return Buffer.alloc(0);
|
|
133
|
+
return readBoundedDescriptor(0, maxBytes);
|
|
134
|
+
}
|
|
135
|
+
function readRequest(source, maxBytes, io) {
|
|
136
|
+
const bytes = source === "-" ? readBoundedStdin(maxBytes, io) : readBoundedFile(source, maxBytes);
|
|
137
|
+
const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
138
|
+
const value = mapping(loadYamlMapping(text));
|
|
139
|
+
if (!value)
|
|
140
|
+
throw new Error("not a mapping");
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
function exactFields(request, fields) {
|
|
144
|
+
const keys = Object.keys(request);
|
|
145
|
+
return keys.length === fields.length &&
|
|
146
|
+
keys.every((key) => fields.includes(key)) &&
|
|
147
|
+
fields.every((field) => field in request);
|
|
148
|
+
}
|
|
149
|
+
function boundedBinding(value) {
|
|
150
|
+
return typeof value === "string" && value.length > 0 &&
|
|
151
|
+
Buffer.byteLength(value, "utf8") <= MAX_BINDING_UTF8_BYTES;
|
|
152
|
+
}
|
|
153
|
+
function validateRequest(request, value) {
|
|
154
|
+
if (request.schema_version === value.requestSchemaVersion) {
|
|
155
|
+
if (!exactFields(request, value.requestFields)) {
|
|
156
|
+
return {
|
|
157
|
+
error: {
|
|
158
|
+
class: "schema_violation",
|
|
159
|
+
message: "personal glossary decision request fields are invalid",
|
|
160
|
+
valid_values: value.requestFields,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (!mapping(request.receipt)) {
|
|
165
|
+
return {
|
|
166
|
+
error: {
|
|
167
|
+
class: "schema_violation",
|
|
168
|
+
message: `request requires ${value.requestSchemaVersion} and one receipt mapping`,
|
|
169
|
+
valid_values: [value.requestSchemaVersion, "receipt"],
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return { kind: "receipt", receipt: request.receipt };
|
|
174
|
+
}
|
|
175
|
+
if (request.schema_version !== value.receiptConstructionRequestSchemaVersion) {
|
|
176
|
+
return {
|
|
177
|
+
error: {
|
|
178
|
+
class: "schema_violation",
|
|
179
|
+
message: "personal glossary decision request schema is invalid",
|
|
180
|
+
valid_values: [
|
|
181
|
+
value.requestSchemaVersion,
|
|
182
|
+
value.receiptConstructionRequestSchemaVersion,
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (!exactFields(request, value.receiptConstructionRequestFields)) {
|
|
188
|
+
return {
|
|
189
|
+
error: {
|
|
190
|
+
class: "schema_violation",
|
|
191
|
+
message: "personal glossary receipt-construction request fields are invalid",
|
|
192
|
+
valid_values: value.receiptConstructionRequestFields,
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
if (!SHA256.test(String(request.candidate_id)) ||
|
|
197
|
+
!SHA256.test(String(request.candidate_revision)) ||
|
|
198
|
+
!SHA256.test(String(request.candidate_capsule_sha256)) ||
|
|
199
|
+
!SHA256.test(String(request.candidate_projection_sha256)) ||
|
|
200
|
+
!boundedBinding(request.generation) ||
|
|
201
|
+
!boundedBinding(request.policy_version) ||
|
|
202
|
+
!mapping(request.classification)) {
|
|
203
|
+
return {
|
|
204
|
+
error: {
|
|
205
|
+
class: "schema_violation",
|
|
206
|
+
message: "receipt construction requires exact candidate bindings and one classification mapping",
|
|
207
|
+
valid_values: value.receiptConstructionRequestFields,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
kind: "receipt_construction",
|
|
213
|
+
request: {
|
|
214
|
+
candidateId: request.candidate_id,
|
|
215
|
+
candidateRevision: request.candidate_revision,
|
|
216
|
+
candidateCapsuleSha256: request.candidate_capsule_sha256,
|
|
217
|
+
candidateProjectionSha256: request.candidate_projection_sha256,
|
|
218
|
+
generation: request.generation,
|
|
219
|
+
policyVersion: request.policy_version,
|
|
220
|
+
classification: request.classification,
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function emitResult(value, maxResultUtf8Bytes, io) {
|
|
225
|
+
const text = `${JSON.stringify(value, null, 2)}\n`;
|
|
226
|
+
if (Buffer.byteLength(text, "utf8") > maxResultUtf8Bytes) {
|
|
227
|
+
return invalid(io, {
|
|
228
|
+
class: "invalid_request",
|
|
229
|
+
message: `personal glossary decision result exceeds ${maxResultUtf8Bytes} UTF-8 bytes`,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
(io.out ?? ((line) => process.stdout.write(line)))(text);
|
|
233
|
+
return 0;
|
|
234
|
+
}
|
|
235
|
+
function constructReceipt(request, options, precomputedCurrentProjection) {
|
|
236
|
+
let current = precomputedCurrentProjection;
|
|
237
|
+
if (current === undefined) {
|
|
238
|
+
try {
|
|
239
|
+
current = readCurrentPersonalGlossaryCandidateProjection(options);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return { kind: "unavailable", reason: "current_generation_unavailable" };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (current.status !== "current" || current.projection === null) {
|
|
246
|
+
return {
|
|
247
|
+
kind: "unavailable",
|
|
248
|
+
reason: current.status === "projection_stale"
|
|
249
|
+
? "projection_stale"
|
|
250
|
+
: current.status === "current_generation_unavailable"
|
|
251
|
+
? "current_generation_unavailable"
|
|
252
|
+
: "projection_unavailable",
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
const candidate = current.projection.candidates.find(({ capsule }) => capsule.candidate_id === request.candidateId &&
|
|
256
|
+
capsule.candidate_revision === request.candidateRevision &&
|
|
257
|
+
capsule.capsule_sha256 === request.candidateCapsuleSha256 &&
|
|
258
|
+
capsule.generation === request.generation &&
|
|
259
|
+
capsule.policy_version === request.policyVersion &&
|
|
260
|
+
current.projection.projection_sha256 === request.candidateProjectionSha256);
|
|
261
|
+
if (!candidate)
|
|
262
|
+
return { kind: "unavailable", reason: "candidate_unavailable" };
|
|
263
|
+
try {
|
|
264
|
+
return {
|
|
265
|
+
kind: "created",
|
|
266
|
+
receipt: createGlossaryHostClassificationReceipt({
|
|
267
|
+
capsule: candidate.capsule,
|
|
268
|
+
candidate_projection_sha256: current.projection.projection_sha256,
|
|
269
|
+
classification: request.classification,
|
|
270
|
+
}),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return {
|
|
275
|
+
kind: "invalid",
|
|
276
|
+
error: {
|
|
277
|
+
class: "schema_violation",
|
|
278
|
+
message: "receipt construction classification is invalid for the exact current candidate",
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function receiptConstructionResult(receipt, decision, reason, contractValue) {
|
|
284
|
+
return {
|
|
285
|
+
schemaVersion: contractValue.receiptConstructionResultSchemaVersion,
|
|
286
|
+
command: "report personal-glossary-decision",
|
|
287
|
+
status: decision?.status ?? "abstain",
|
|
288
|
+
receipt,
|
|
289
|
+
decision: decision?.decision ?? null,
|
|
290
|
+
reason: decision?.reason ?? reason,
|
|
291
|
+
effects: [],
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function runPersonalGlossaryDecisionCommandInternal(argv, io, options, evaluation, precomputedExplicitMining, precomputedCurrentProjection, precomputedDecisionContract) {
|
|
295
|
+
let contractValue;
|
|
296
|
+
try {
|
|
297
|
+
contractValue = contract(precomputedDecisionContract);
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
return invalid(io, {
|
|
301
|
+
class: "invalid_request",
|
|
302
|
+
message: "personal glossary decision contract is unavailable",
|
|
303
|
+
recovery: "Restore the bundled glossary authority, then retry; no bytes were changed.",
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
const parsedArgs = parseArgs(argv);
|
|
307
|
+
if ("class" in parsedArgs)
|
|
308
|
+
return invalid(io, parsedArgs);
|
|
309
|
+
let request;
|
|
310
|
+
try {
|
|
311
|
+
request = readRequest(parsedArgs.input, contractValue.maxRequestUtf8Bytes, io);
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
return invalid(io, {
|
|
315
|
+
class: "invalid_format",
|
|
316
|
+
message: "--input must be one readable bounded UTF-8 YAML or JSON mapping",
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
const validated = validateRequest(request, contractValue);
|
|
320
|
+
if ("error" in validated)
|
|
321
|
+
return invalid(io, validated.error);
|
|
322
|
+
const decide = (receipt) => evaluation
|
|
323
|
+
? evaluatePersonalGlossaryCandidate(receipt, options, precomputedExplicitMining, precomputedCurrentProjection)
|
|
324
|
+
: decidePersonalGlossaryCandidate(receipt, options);
|
|
325
|
+
if (validated.kind === "receipt") {
|
|
326
|
+
return emitResult(decide(validated.receipt), contractValue.maxResultUtf8Bytes, io);
|
|
327
|
+
}
|
|
328
|
+
const constructed = constructReceipt(validated.request, options, precomputedCurrentProjection);
|
|
329
|
+
if (constructed.kind === "invalid")
|
|
330
|
+
return invalid(io, constructed.error);
|
|
331
|
+
if (constructed.kind === "unavailable") {
|
|
332
|
+
return emitResult(receiptConstructionResult(null, null, constructed.reason, contractValue), contractValue.receiptConstructionMaxResultUtf8Bytes, io);
|
|
333
|
+
}
|
|
334
|
+
const decision = decide(constructed.receipt);
|
|
335
|
+
return emitResult(receiptConstructionResult(constructed.receipt, decision, null, contractValue), contractValue.receiptConstructionMaxResultUtf8Bytes, io);
|
|
336
|
+
}
|
|
337
|
+
/** Run the read-only host-receipt validation and deterministic decision boundary. */
|
|
338
|
+
export function runPersonalGlossaryDecisionCommand(argv, io) {
|
|
339
|
+
// The cache is scoped to one V2 request, not CLI startup or persistent state.
|
|
340
|
+
return withReadOnlyYamlMappingCache(() => runPersonalGlossaryDecisionCommandInternal(argv, io, {}, false));
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Internal evaluator entry point. It preserves the V2 parser and receipt
|
|
344
|
+
* construction path while measuring explicit admission before its own gate.
|
|
345
|
+
* CLI dispatch never invokes this function.
|
|
346
|
+
*/
|
|
347
|
+
export function runPersonalGlossaryEvaluationDecisionCommand(argv, io, options) {
|
|
348
|
+
return runPersonalGlossaryDecisionCommandInternal(argv, io, options, true, options.precomputedExplicitMining, options.precomputedCurrentProjection, options.precomputedDecisionContract);
|
|
349
|
+
}
|