agentera 3.0.0-dev.72 → 3.0.0-dev.75
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/analysis/verification-policy.yaml +8 -13
- 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 +16 -1
- 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 +15 -8
- 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
|
@@ -3,6 +3,9 @@ import { projectGlossaryDevelopmentValue } from "../core/developmentInvocation.j
|
|
|
3
3
|
import { resolveSourceRoot } from "../core/sourceRoot.js";
|
|
4
4
|
import { loadYamlMappingFile } from "../core/yaml.js";
|
|
5
5
|
import { validateConsumerBoundary, validateConsumerEvidenceOwner, } from "./glossaryConsumerContractValidation.js";
|
|
6
|
+
import { validatePersonalCandidateContracts } from "./glossaryCandidateContracts.js";
|
|
7
|
+
import { validateConversationProvenance, validateHistoryEvidence, validatePersonalMiningAuthority, validateProvenanceVariants, } from "./glossaryMiningAuthority.js";
|
|
8
|
+
import { isGlossaryIsoCalendarDate } from "./glossaryEntryTemporal.js";
|
|
6
9
|
export class GlossaryEntryBoundError extends Error {
|
|
7
10
|
}
|
|
8
11
|
const DEFERRED_CAPABILITIES = ["profile", "audit", "discuss", "plan", "build"];
|
|
@@ -24,10 +27,33 @@ export function personalGlossaryAdmissionContract(pathname = glossaryEntryAuthor
|
|
|
24
27
|
const authority = contract(pathname);
|
|
25
28
|
const personal = mapping(mapping(authority.ownership_contracts)?.personal);
|
|
26
29
|
const admission = mapping(personal?.admission);
|
|
30
|
+
const conversation = mapping(mapping(authority.provenance_variants)?.personal_inferred_conversation);
|
|
31
|
+
const explicitVariant = mapping(mapping(authority.provenance_variants)?.personal_explicit_definition);
|
|
32
|
+
const explicitDiscovery = mapping(mapping(authority.personal_mining_authority)?.explicit_discovery);
|
|
33
|
+
const explicitGrammar = mapping(explicitDiscovery?.grammar);
|
|
34
|
+
const expectedEvidence = mapping(conversation?.expected_evidence);
|
|
27
35
|
return {
|
|
28
36
|
explicitSignalTypes: strings(mapping(admission?.explicit)?.candidate_signal_types),
|
|
37
|
+
explicitGrammarIds: (Array.isArray(explicitGrammar?.forms) ? explicitGrammar.forms : [])
|
|
38
|
+
.map((item) => mapping(item))
|
|
39
|
+
.filter((item) => item !== null)
|
|
40
|
+
.map((item) => String(item.id))
|
|
41
|
+
.filter(Boolean),
|
|
42
|
+
explicitProvenanceFields: strings(mapping(explicitVariant?.source_provenance)?.required_fields),
|
|
29
43
|
inferredSignalTypes: strings(mapping(admission?.inferred)?.candidate_signal_types),
|
|
30
44
|
inferredSourceKinds: strings(mapping(admission?.inferred)?.source_kinds),
|
|
45
|
+
conversationSignalTypes: strings(conversation?.allowed_signal_types),
|
|
46
|
+
conversationSourceKinds: strings(conversation?.allowed_source_kinds),
|
|
47
|
+
conversationAuthorClasses: strings(conversation?.allowed_author_classes),
|
|
48
|
+
conversationEvidenceFields: strings(conversation?.required_evidence_fields),
|
|
49
|
+
conversationExpectedEvidenceContextFields: strings(expectedEvidence?.context_fields),
|
|
50
|
+
conversationMinimumEvidenceCount: typeof conversation?.minimum_evidence_count === "number"
|
|
51
|
+
? conversation.minimum_evidence_count
|
|
52
|
+
: 0,
|
|
53
|
+
conversationCompletenessAuthority: typeof conversation?.completeness_authority === "string"
|
|
54
|
+
? conversation.completeness_authority
|
|
55
|
+
: "",
|
|
56
|
+
conversationAdmission: typeof conversation?.admission === "string" ? conversation.admission : "",
|
|
31
57
|
insufficientRecovery: typeof admission?.insufficient_recovery === "string"
|
|
32
58
|
? admission.insufficient_recovery.trim()
|
|
33
59
|
: "",
|
|
@@ -45,12 +71,22 @@ export function personalGlossaryOutputContract(pathname = glossaryEntryAuthority
|
|
|
45
71
|
const output = mapping(personal?.profile_output);
|
|
46
72
|
const command = mapping(output?.command);
|
|
47
73
|
const request = mapping(command?.request);
|
|
74
|
+
const result = mapping(command?.result);
|
|
48
75
|
const section = mapping(output?.section);
|
|
76
|
+
const reviewAuthorization = mapping(request?.review_authorization);
|
|
49
77
|
return {
|
|
50
78
|
command: projectGlossaryDevelopmentValue(command?.canonical, "profile_output.command"),
|
|
51
79
|
requestSchemaVersion: typeof request?.schema_version === "string" ? request.schema_version : "",
|
|
80
|
+
requestFields: strings(request?.required_fields),
|
|
81
|
+
requestOptionalFields: strings(request?.optional_fields),
|
|
82
|
+
maxRequestUtf8Bytes: typeof request?.max_utf8_bytes === "number" ? request.max_utf8_bytes : 0,
|
|
83
|
+
resultSchemaVersion: typeof result?.schema_version === "string" ? result.schema_version : "",
|
|
84
|
+
resultFields: strings(result?.fields),
|
|
85
|
+
maxResultUtf8Bytes: typeof result?.max_utf8_bytes === "number" ? result.max_utf8_bytes : 0,
|
|
52
86
|
sectionSchemaVersion: typeof section?.document_schema_version === "string" ? section.document_schema_version : "",
|
|
53
87
|
outputStatuses: strings(command?.output_statuses),
|
|
88
|
+
reviewAuthorizationFields: strings(reviewAuthorization?.required_fields),
|
|
89
|
+
reviewAuthorizationDispositions: strings(reviewAuthorization?.dispositions),
|
|
54
90
|
};
|
|
55
91
|
}
|
|
56
92
|
export function personalProfileGroundingContract(pathname = glossaryEntryAuthorityPath()) {
|
|
@@ -119,19 +155,6 @@ export function isSafeProjectSourcePath(value) {
|
|
|
119
155
|
!path.win32.isAbsolute(value) &&
|
|
120
156
|
!value.split(/[\\/]/).includes(".."));
|
|
121
157
|
}
|
|
122
|
-
function isIsoCalendarDate(value) {
|
|
123
|
-
if (typeof value !== "string")
|
|
124
|
-
return false;
|
|
125
|
-
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
126
|
-
if (!match)
|
|
127
|
-
return false;
|
|
128
|
-
const [, year, month, day] = match.map(Number);
|
|
129
|
-
const date = new Date(`${value}T00:00:00.000Z`);
|
|
130
|
-
return (!Number.isNaN(date.getTime()) &&
|
|
131
|
-
date.getUTCFullYear() === year &&
|
|
132
|
-
date.getUTCMonth() + 1 === month &&
|
|
133
|
-
date.getUTCDate() === day);
|
|
134
|
-
}
|
|
135
158
|
export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityPath()) {
|
|
136
159
|
let authority;
|
|
137
160
|
try {
|
|
@@ -144,6 +167,8 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
144
167
|
if (authority.schema_version !== "agentera.glossaryEntryContract.v1") {
|
|
145
168
|
errors.push("schema_version must be agentera.glossaryEntryContract.v1");
|
|
146
169
|
}
|
|
170
|
+
errors.push(...validatePersonalMiningAuthority(authority));
|
|
171
|
+
errors.push(...validatePersonalCandidateContracts(authority));
|
|
147
172
|
const occurrence = mapping(authority.term_occurrence);
|
|
148
173
|
if (occurrence?.runtime !==
|
|
149
174
|
"packages/cli/src/registries/glossaryTermOccurrence.ts#containsGlossaryTerm" ||
|
|
@@ -201,51 +226,7 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
201
226
|
errors.push("provenance must derive its kind and evidence variants from provenance_variants");
|
|
202
227
|
}
|
|
203
228
|
const variants = mapping(authority.provenance_variants);
|
|
204
|
-
|
|
205
|
-
personal_explicit_definition: {
|
|
206
|
-
owner: "personal",
|
|
207
|
-
evidence_count: 1,
|
|
208
|
-
required_evidence_fields: ["source_id", "evidence_anchor", "signal_type"],
|
|
209
|
-
allowed_signal_types: ["correction", "decision", "instruction"],
|
|
210
|
-
},
|
|
211
|
-
personal_inferred_usage: {
|
|
212
|
-
owner: "personal",
|
|
213
|
-
evidence_count: 2,
|
|
214
|
-
required_evidence_fields: ["source_id", "evidence_anchor", "source_kind"],
|
|
215
|
-
allowed_source_kinds: ["instruction_document", "project_config_signal"],
|
|
216
|
-
},
|
|
217
|
-
project_file: {
|
|
218
|
-
owner: "project",
|
|
219
|
-
evidence_count: 1,
|
|
220
|
-
required_evidence_fields: ["source_path", "source_record_sha256"],
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
for (const [kind, expectedVariant] of Object.entries(variantExpectations)) {
|
|
224
|
-
const variant = mapping(variants?.[kind]);
|
|
225
|
-
if (!variant) {
|
|
226
|
-
errors.push(`provenance variant ${kind} is required`);
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
if (variant.owner !== expectedVariant.owner)
|
|
230
|
-
errors.push(`${kind}.owner must be ${expectedVariant.owner}`);
|
|
231
|
-
if (variant.evidence_count !== expectedVariant.evidence_count) {
|
|
232
|
-
errors.push(`${kind}.evidence_count must be ${expectedVariant.evidence_count}`);
|
|
233
|
-
}
|
|
234
|
-
if (!sameStrings(variant.required_evidence_fields, expectedVariant.required_evidence_fields)) {
|
|
235
|
-
errors.push(`${kind}.required_evidence_fields must match its provenance variant`);
|
|
236
|
-
}
|
|
237
|
-
if (variant.additional_evidence_fields !== "forbidden") {
|
|
238
|
-
errors.push(`${kind}.additional_evidence_fields must be forbidden`);
|
|
239
|
-
}
|
|
240
|
-
for (const allowedField of ["allowed_signal_types", "allowed_source_kinds"]) {
|
|
241
|
-
if (allowedField in expectedVariant &&
|
|
242
|
-
!sameStrings(variant[allowedField], expectedVariant[allowedField])) {
|
|
243
|
-
errors.push(`${kind}.${allowedField} must preserve the admitted evidence classes`);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
if (!nonEmpty(variant.resolution_rule))
|
|
247
|
-
errors.push(`${kind}.resolution_rule is required`);
|
|
248
|
-
}
|
|
229
|
+
errors.push(...validateProvenanceVariants(variants));
|
|
249
230
|
const ownership = mapping(authority.ownership_contracts);
|
|
250
231
|
const personal = mapping(ownership?.personal);
|
|
251
232
|
if (personal?.scope !== "user")
|
|
@@ -253,6 +234,7 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
253
234
|
if (!sameStrings(personal?.allowed_provenance, [
|
|
254
235
|
"personal_explicit_definition",
|
|
255
236
|
"personal_inferred_usage",
|
|
237
|
+
"personal_inferred_conversation",
|
|
256
238
|
])) {
|
|
257
239
|
errors.push("personal ownership must admit only personal provenance variants");
|
|
258
240
|
}
|
|
@@ -280,13 +262,19 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
280
262
|
if (personalImplementation?.status !== "active_partial" ||
|
|
281
263
|
!sameStrings(personalImplementation?.active, [
|
|
282
264
|
"bounded_admission",
|
|
265
|
+
"bounded_explicit_discovery",
|
|
266
|
+
"bounded_candidate_projection",
|
|
267
|
+
"bounded_candidate_retrieval",
|
|
268
|
+
"public_receipt_construction",
|
|
269
|
+
"host_classification_receipt_validation",
|
|
270
|
+
"deterministic_cli_admission_decision",
|
|
283
271
|
"explicit_classification",
|
|
284
272
|
"inferred_evidence_check",
|
|
285
|
-
"
|
|
286
|
-
"
|
|
273
|
+
"authorized_personal_publication",
|
|
274
|
+
"profile_section_persistence",
|
|
287
275
|
]) ||
|
|
288
276
|
!sameStrings(personalImplementation?.inactive, ["lookup"])) {
|
|
289
|
-
errors.push("personal
|
|
277
|
+
errors.push("personal implementation must be active_partial while lookup remains inactive");
|
|
290
278
|
}
|
|
291
279
|
if (!sameStrings(mapping(admission?.explicit)?.candidate_signal_types, [
|
|
292
280
|
"correction",
|
|
@@ -316,37 +304,36 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
316
304
|
if (!nonEmpty(decay?.[field]))
|
|
317
305
|
errors.push(`personal retention_and_decay.${field} is required`);
|
|
318
306
|
}
|
|
319
|
-
const profileOutput = mapping(personal?.profile_output);
|
|
320
|
-
const profileSection = mapping(profileOutput?.section);
|
|
307
|
+
const profileOutput = mapping(personal?.profile_output), profileSection = mapping(profileOutput?.section);
|
|
321
308
|
const mergeIdentity = mapping(profileOutput?.merge_identity);
|
|
322
|
-
const profileCommand = mapping(profileOutput?.command);
|
|
323
|
-
const
|
|
324
|
-
if (profileOutput?.owner !== "
|
|
325
|
-
profileOutput?.lifecycle_callable !==
|
|
326
|
-
|
|
327
|
-
profileCommand?.canonical !== "npx -y agentera@next report profile-glossary" ||
|
|
309
|
+
const profileCommand = mapping(profileOutput?.command), profileRequest = mapping(profileCommand?.request), profileFilesystem = mapping(profileOutput?.filesystem);
|
|
310
|
+
const reviewAuthorization = mapping(profileRequest?.review_authorization);
|
|
311
|
+
if (profileOutput?.owner !== "personal_profile_publication" ||
|
|
312
|
+
profileOutput?.lifecycle_callable !== "packages/cli/src/analytics/personalGlossaryProfile.ts#updatePersonalGlossaryProfile" ||
|
|
313
|
+
profileCommand?.canonical !== "npx -y agentera@next report personal-glossary-publish" ||
|
|
328
314
|
profileCommand?.namespace !== "report" ||
|
|
329
315
|
profileCommand?.input_flag !== "--input" ||
|
|
330
316
|
profileCommand?.stdin_value !== "-" ||
|
|
331
317
|
profileCommand?.format !== "json" ||
|
|
332
318
|
profileCommand?.dry_run_flag !== "--dry-run" ||
|
|
333
319
|
profileCommand?.project_checkout !== "not_required" ||
|
|
334
|
-
profileRequest?.schema_version !== "agentera.
|
|
335
|
-
!sameStrings(profileRequest?.required_fields, [
|
|
336
|
-
|
|
337
|
-
"profile_path",
|
|
338
|
-
"as_of",
|
|
339
|
-
"fresh_entries",
|
|
340
|
-
"retained_history",
|
|
341
|
-
]) ||
|
|
320
|
+
profileRequest?.schema_version !== "agentera.personalGlossaryPublishRequest.v1" ||
|
|
321
|
+
!sameStrings(profileRequest?.required_fields, ["schema_version", "receipt", "decision", "as_of"]) ||
|
|
322
|
+
!sameStrings(profileRequest?.optional_fields, ["review_authorization"]) ||
|
|
342
323
|
profileRequest?.additional_fields !== "forbidden" ||
|
|
324
|
+
profileRequest?.max_utf8_bytes !== 16384 ||
|
|
343
325
|
!nonEmpty(profileRequest?.profile_path_rule) ||
|
|
344
|
-
!nonEmpty(profileRequest?.
|
|
345
|
-
!sameStrings(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
326
|
+
!nonEmpty(profileRequest?.current_decision_rule) ||
|
|
327
|
+
!sameStrings(reviewAuthorization?.required_fields, ["review_id", "review_record_sha256"]) ||
|
|
328
|
+
reviewAuthorization?.additional_fields !== "forbidden" ||
|
|
329
|
+
!sameStrings(reviewAuthorization?.dispositions, ["accept", "correct"]) ||
|
|
330
|
+
reviewAuthorization?.source !== "personal_mining_authority.review_records.disposition.publication_authorization" ||
|
|
331
|
+
!nonEmpty(reviewAuthorization?.rule) ||
|
|
332
|
+
!nonEmpty(profileRequest?.date_rule) ||
|
|
333
|
+
mapping(profileCommand?.result)?.schema_version !==
|
|
334
|
+
"agentera.personalGlossaryPublicationResult.v1" ||
|
|
335
|
+
mapping(profileCommand?.result)?.max_utf8_bytes !== 4096 ||
|
|
336
|
+
!sameStrings(profileCommand?.output_statuses, ["changed", "unchanged_replay", "dry_run_candidate"]) ||
|
|
350
337
|
!nonEmpty(profileCommand?.rule) ||
|
|
351
338
|
profileSection?.heading !== "## Glossary" ||
|
|
352
339
|
profileSection?.start_marker !== "<!-- agentera:personal-glossary:start -->" ||
|
|
@@ -360,7 +347,13 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
360
347
|
!nonEmpty(mergeIdentity?.rule) ||
|
|
361
348
|
!nonEmpty(profileOutput?.refresh_rule) ||
|
|
362
349
|
!nonEmpty(profileOutput?.decay_rule) ||
|
|
363
|
-
!nonEmpty(profileOutput?.isolation_rule)
|
|
350
|
+
!nonEmpty(profileOutput?.isolation_rule) ||
|
|
351
|
+
profileFilesystem?.authority !== "host_filesystem" ||
|
|
352
|
+
profileFilesystem?.configured_path !== "canonical_user_profile_authority" ||
|
|
353
|
+
profileFilesystem?.outcomes !== "ordinary_permissions_and_io" ||
|
|
354
|
+
profileFilesystem?.same_user_path_manipulation !== "outside_agentera_threat_model" ||
|
|
355
|
+
profileFilesystem?.symlink_confinement !== "not_claimed" ||
|
|
356
|
+
!nonEmpty(profileFilesystem?.rule)) {
|
|
364
357
|
errors.push("personal profile output must define deterministic isolated rendering and lifecycle rules");
|
|
365
358
|
}
|
|
366
359
|
const project = mapping(ownership?.project);
|
|
@@ -458,7 +451,8 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
458
451
|
errors.push("project entry derivation must produce only the shared project_file primitive");
|
|
459
452
|
}
|
|
460
453
|
if (publication?.owner !== "build" ||
|
|
461
|
-
publication?.command !==
|
|
454
|
+
publication?.command !==
|
|
455
|
+
"npx -y agentera@next state glossary publish --input REQUEST --format json" ||
|
|
462
456
|
publicationRequest?.schema_version !== "agentera.glossaryPublicationRequest.v1" ||
|
|
463
457
|
!sameStrings(publicationRequest?.required_fields, [
|
|
464
458
|
"schema_version",
|
|
@@ -502,8 +496,21 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
502
496
|
profileGrounding?.parser !==
|
|
503
497
|
"packages/cli/src/analytics/personalGlossaryProfile.ts#personalProfileGrounding" ||
|
|
504
498
|
profileGrounding?.max_profile_utf8_bytes !== 65536 ||
|
|
505
|
-
!sameStrings(mapping(profileGrounding?.validity)?.statuses, [
|
|
506
|
-
|
|
499
|
+
!sameStrings(mapping(profileGrounding?.validity)?.statuses, [
|
|
500
|
+
"absent",
|
|
501
|
+
"valid",
|
|
502
|
+
"repair_needed",
|
|
503
|
+
]) ||
|
|
504
|
+
!sameStrings(mapping(profileGrounding?.validity)?.classes, [
|
|
505
|
+
"absent",
|
|
506
|
+
"valid",
|
|
507
|
+
"malformed",
|
|
508
|
+
"ambiguous",
|
|
509
|
+
"unreadable",
|
|
510
|
+
"unsafe",
|
|
511
|
+
"oversized",
|
|
512
|
+
"invalid_utf8",
|
|
513
|
+
]) ||
|
|
507
514
|
!sameStrings(mapping(profileGrounding?.freshness)?.states, ["current", "stale", "unknown"]) ||
|
|
508
515
|
!nonEmpty(mapping(profileGrounding?.recovery)?.repair) ||
|
|
509
516
|
!nonEmpty(mapping(profileGrounding?.recovery)?.absent) ||
|
|
@@ -532,15 +539,19 @@ export function validateGlossaryEntryContract(pathname = glossaryEntryAuthorityP
|
|
|
532
539
|
!sameStrings(profile?.capabilities, ["profile"]) ||
|
|
533
540
|
!sameStrings(profile?.active_behavior, [
|
|
534
541
|
"ownership_contracts.personal.admission",
|
|
535
|
-
"
|
|
542
|
+
"personal_mining_authority.profile_full",
|
|
536
543
|
]) ||
|
|
537
544
|
!sameStrings(profile?.inactive_behavior, ["lookup"]) ||
|
|
538
545
|
profileContracts?.admission !== "ownership_contracts.personal.input" ||
|
|
539
546
|
profileContracts?.provenance !== "ownership_contracts.personal.allowed_provenance" ||
|
|
540
547
|
profileContracts?.confidence !== "shared_primitive.fields.confidence" ||
|
|
541
548
|
profileContracts?.retention_and_decay !== "ownership_contracts.personal.retention_and_decay" ||
|
|
542
|
-
|
|
543
|
-
|
|
549
|
+
profileContracts?.profile_full !== "personal_mining_authority.profile_full" ||
|
|
550
|
+
!sameStrings(profile?.forbidden_current_claims, [
|
|
551
|
+
"lookup",
|
|
552
|
+
"project_glossary_consumption",
|
|
553
|
+
])) {
|
|
554
|
+
errors.push("profile glossary synthesis must reuse existing consented input and only canonical authorized personal publication");
|
|
544
555
|
}
|
|
545
556
|
const audit = mapping(capabilities?.audit);
|
|
546
557
|
const findingFamily = mapping(audit?.finding_family);
|
|
@@ -647,7 +658,7 @@ function requiredEntryShape(entry, authority) {
|
|
|
647
658
|
}
|
|
648
659
|
const temporal = mapping(entry.temporal);
|
|
649
660
|
for (const field of strings(mapping(fields?.temporal)?.required_fields)) {
|
|
650
|
-
if (!
|
|
661
|
+
if (!isGlossaryIsoCalendarDate(temporal?.[field])) {
|
|
651
662
|
errors.push(`temporal.${field} must be an ISO date`);
|
|
652
663
|
}
|
|
653
664
|
}
|
|
@@ -665,18 +676,6 @@ function evidenceShape(evidence, requiredFields, kind, index) {
|
|
|
665
676
|
}
|
|
666
677
|
return errors;
|
|
667
678
|
}
|
|
668
|
-
function validateHistoryEvidence(evidence, context, index) {
|
|
669
|
-
const errors = [];
|
|
670
|
-
const sourceId = typeof evidence.source_id === "string" ? evidence.source_id : "";
|
|
671
|
-
const anchor = typeof evidence.evidence_anchor === "string" ? evidence.evidence_anchor : "";
|
|
672
|
-
const retained = context.retainedHistory.get(anchor);
|
|
673
|
-
if (!sourceId || !anchor)
|
|
674
|
-
errors.push(`provenance.evidence[${index}] requires source_id and evidence_anchor`);
|
|
675
|
-
if (!retained || retained.sourceId !== sourceId) {
|
|
676
|
-
errors.push(`provenance.evidence[${index}].evidence_anchor must resolve to its retained source_id`);
|
|
677
|
-
}
|
|
678
|
-
return errors;
|
|
679
|
-
}
|
|
680
679
|
export function validateGlossaryEntry(entry, owner, context = { retainedHistory: new Map() }, pathname = glossaryEntryAuthorityPath()) {
|
|
681
680
|
const authorityErrors = validateGlossaryEntryContract(pathname);
|
|
682
681
|
if (authorityErrors.length > 0) {
|
|
@@ -738,6 +737,9 @@ export function validateGlossaryEntry(entry, owner, context = { retainedHistory:
|
|
|
738
737
|
}
|
|
739
738
|
}
|
|
740
739
|
}
|
|
740
|
+
if (kind === "personal_inferred_conversation") {
|
|
741
|
+
errors.push(...validateConversationProvenance(evidence, provenance, variant, context));
|
|
742
|
+
}
|
|
741
743
|
if (kind === "project_file") {
|
|
742
744
|
if (evidence.length !== evidenceCount || evidence[0] === null) {
|
|
743
745
|
errors.push("project file provenance requires exactly one source record");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Validate a calendar date without accepting normalized JavaScript date overflow. */
|
|
2
|
+
export function isGlossaryIsoCalendarDate(value) {
|
|
3
|
+
if (typeof value !== "string")
|
|
4
|
+
return false;
|
|
5
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/u.exec(value);
|
|
6
|
+
if (!match)
|
|
7
|
+
return false;
|
|
8
|
+
const [, year, month, day] = match.map(Number);
|
|
9
|
+
const date = new Date(`${value}T00:00:00.000Z`);
|
|
10
|
+
return !Number.isNaN(date.getTime()) && date.getUTCFullYear() === year &&
|
|
11
|
+
date.getUTCMonth() + 1 === month && date.getUTCDate() === day;
|
|
12
|
+
}
|