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.
Files changed (93) hide show
  1. package/README.md +111 -0
  2. package/bundle/.agentera-build-source.json +8 -0
  3. package/bundle/CHANGELOG.md +17 -17
  4. package/bundle/extract-corpus-parity.json +1 -1
  5. package/bundle/references/adapters/package-publication.json +49 -53
  6. package/bundle/references/adapters/package-registry.yaml +5 -1
  7. package/bundle/references/adapters/package-surface-characterization.md +6 -4
  8. package/bundle/references/analysis/evidence-tier-authority.yaml +45 -4
  9. package/bundle/references/analysis/personal-glossary-evaluation-authority.yaml +175 -0
  10. package/bundle/references/analysis/personal-glossary-evaluation-corpus.yaml +291 -0
  11. package/bundle/references/analysis/personal-glossary-holdout.yaml +192 -0
  12. package/bundle/references/analysis/verification-policy.yaml +8 -13
  13. package/bundle/references/artifacts/glossary-entry-contract.yaml +1533 -35
  14. package/bundle/references/cli/update-channels.yaml +2 -2
  15. package/bundle/references/cli/vocabulary.md +1 -1
  16. package/bundle/references/meta/retained-reference-authority.yaml +16 -1
  17. package/bundle/skills/agentera/capabilities/profile/schemas/artifacts.yaml +11 -7
  18. package/bundle/skills/agentera/capabilities/profile/schemas/exit.yaml +6 -3
  19. package/bundle/skills/agentera/capabilities/profile/schemas/validation.yaml +13 -7
  20. package/bundle/skills/agentera/schemas/artifacts/glossary.yaml +5 -0
  21. package/bundle/skills/agentera/schemas/artifacts/plan.yaml +7 -0
  22. package/dist/.agentera-build-source.json +8 -0
  23. package/dist/analytics/extractCorpus/copilotSessions.js +13 -4
  24. package/dist/analytics/extractCorpus/core.js +223 -3
  25. package/dist/analytics/extractCorpus/corpus.js +18 -1
  26. package/dist/analytics/extractCorpus/cursorSessions.js +22 -4
  27. package/dist/analytics/extractCorpus/evidenceTiers.js +123 -17
  28. package/dist/analytics/extractCorpus/filesystemSources.js +4 -0
  29. package/dist/analytics/extractCorpus/index.js +2 -2
  30. package/dist/analytics/extractCorpus/jsonlSessions.js +52 -3
  31. package/dist/analytics/extractCorpus/sqliteSessions.js +12 -3
  32. package/dist/analytics/personalGlossaryAdmission.js +26 -46
  33. package/dist/analytics/personalGlossaryCandidateProjection.js +692 -0
  34. package/dist/analytics/personalGlossaryCandidateProjectionExcerpts.js +144 -0
  35. package/dist/analytics/personalGlossaryCandidateReadView.js +23 -0
  36. package/dist/analytics/personalGlossaryCurrentGeneration.js +25 -0
  37. package/dist/analytics/personalGlossaryDecision.js +203 -0
  38. package/dist/analytics/personalGlossaryExplicit.js +788 -0
  39. package/dist/analytics/personalGlossaryExplicitMining.js +285 -0
  40. package/dist/analytics/personalGlossaryExplicitScope.js +41 -0
  41. package/dist/analytics/personalGlossaryExplicitSegments.js +418 -0
  42. package/dist/analytics/personalGlossaryExplicitTypes.js +26 -0
  43. package/dist/analytics/personalGlossaryLexicalClassifier.js +175 -0
  44. package/dist/analytics/personalGlossaryProfile.js +13 -3
  45. package/dist/analytics/personalGlossaryRecurrence.js +618 -0
  46. package/dist/analytics/personalGlossaryReviewRecordStorage.js +428 -0
  47. package/dist/analytics/personalGlossaryReviewRecords.js +332 -0
  48. package/dist/capabilities/index.js +5 -1
  49. package/dist/capabilities/profile/instructions.js +50 -15
  50. package/dist/cli/commands/personalGlossaryCandidateReads.js +744 -0
  51. package/dist/cli/commands/personalGlossaryDecision.js +349 -0
  52. package/dist/cli/commands/personalGlossaryPublish.js +484 -0
  53. package/dist/cli/commands/personalGlossaryReviewRecordReads.js +209 -0
  54. package/dist/cli/commands/personalGlossaryReviewRecords.js +623 -0
  55. package/dist/cli/commands/prime/briefOrientation.js +118 -19
  56. package/dist/cli/commands/report.js +18 -2
  57. package/dist/cli/commands/schema.js +179 -0
  58. package/dist/cli/commands/verify.js +51 -9
  59. package/dist/cli/dispatch/lifecycle.js +51 -6
  60. package/dist/cli/help.js +48 -2
  61. package/dist/cli/migrationRequired.js +4 -1
  62. package/dist/core/atomicWriter.js +4 -1
  63. package/dist/core/developmentInvocation.js +4 -1
  64. package/dist/core/yaml.js +53 -1
  65. package/dist/eval/glossaryEvaluation.js +751 -0
  66. package/dist/eval/glossaryEvaluationProcess.js +29 -0
  67. package/dist/eval/glossaryEvaluationRunner.js +571 -0
  68. package/dist/eval/glossaryEvaluationSuccessReport.js +297 -0
  69. package/dist/registries/activationTuples.js +31 -3
  70. package/dist/registries/evidenceTierContract.js +4 -0
  71. package/dist/registries/explicitSegmentGrammarContract.js +619 -0
  72. package/dist/registries/glossaryCandidateContractPaths.js +6 -0
  73. package/dist/registries/glossaryCandidateContracts.js +820 -0
  74. package/dist/registries/glossaryCandidateDecisionAuthority.js +119 -0
  75. package/dist/registries/glossaryCandidateDecisionContract.js +62 -0
  76. package/dist/registries/glossaryCandidateProjectionAuthority.js +197 -0
  77. package/dist/registries/glossaryCandidateProjectionContract.js +104 -0
  78. package/dist/registries/glossaryEntryContract.js +105 -103
  79. package/dist/registries/glossaryEntryTemporal.js +12 -0
  80. package/dist/registries/glossaryMiningAuthority.js +764 -0
  81. package/dist/registries/glossaryProfileFullContract.js +24 -0
  82. package/dist/registries/glossaryReviewRecordsAuthority.js +426 -0
  83. package/dist/registries/glossaryReviewRecordsContract.js +129 -0
  84. package/dist/registries/glossaryTermIdentity.js +122 -0
  85. package/dist/registries/packagePublication.js +3 -3
  86. package/dist/registries/personalGlossaryContracts.js +1 -0
  87. package/dist/release/releaseMetadata.js +15 -8
  88. package/dist/upgrade/npxPlatformStatus.js +2 -1
  89. package/dist/upgrade/projectIntegration.js +7 -1
  90. package/dist/validate/activationArtifactEvidence.js +18 -4
  91. package/dist/validate/activationEvidenceManifest.js +101 -22
  92. package/package.json +2 -4
  93. package/dist/cli/commands/personalGlossary.js +0 -176
package/dist/cli/help.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import { CAPABILITY_ROUTING_NAMES } from "./commands/capability.js";
2
2
  import { verbsForArtifact, WRITABLE_ARTIFACTS } from "../state/write/operations.js";
3
3
  import { personalGlossaryOutputContract } from "../registries/glossaryEntryContract.js";
4
+ import { personalGlossaryCandidateProjectionContract } from "../registries/glossaryCandidateProjectionContract.js";
5
+ import { personalGlossaryCandidateDecisionContract } from "../registries/glossaryCandidateDecisionContract.js";
6
+ import { personalGlossaryReviewRecordsContract } from "../registries/glossaryReviewRecordsContract.js";
4
7
  import { describeRouteReceipt } from "../registries/hybridRoute.js";
5
8
  import { advertisedValidateFamilyNames } from "./commands/validate.js";
6
9
  import { entityListFamilies, entityRetrievalFamilyForHelpArgs } from "../state/entityRetrievalHelp.js";
@@ -346,7 +349,7 @@ export function stateCommandNames() {
346
349
  export function printCheckHelp(sub) {
347
350
  if (sub === "verify") {
348
351
  return [
349
- "usage: agentera check verify [-h] eval {skills,semantic,routing} [--format text|json] [options]",
352
+ "usage: agentera check verify [-h] eval {skills,semantic,routing,glossary} [--format text|json] [options]",
350
353
  "",
351
354
  "Evaluation verify gates. Smoke verify is retired on the npm self-contained CLI;",
352
355
  "use the stable Python line for smoke maintainer harnesses.",
@@ -397,6 +400,9 @@ export function printCheckHelp(sub) {
397
400
  }
398
401
  export function printReportHelp() {
399
402
  const profileGlossary = personalGlossaryOutputContract();
403
+ const candidateReads = personalGlossaryCandidateProjectionContract();
404
+ const candidateDecision = personalGlossaryCandidateDecisionContract();
405
+ const reviewRecords = personalGlossaryReviewRecordsContract();
400
406
  return [
401
407
  "usage: agentera report [-h] [--format {text,json}] [--project VALUE] [--sources {active,all}]",
402
408
  " | agentera report refresh [--dry-run|--consent local-history]",
@@ -405,13 +411,53 @@ export function printReportHelp() {
405
411
  ` | ${profileGlossary.command} --input <file|-> [--dry-run] --format json`,
406
412
  " | agentera report glossary-advice --input <file|-> --format json",
407
413
  " | agentera report profile-grounding --format json",
414
+ ` | ${candidateReads.candidateReadCommand} list [--source-family explicit|recurring]`,
415
+ " [--provenance-kind KIND] [--scope personal|ambiguous] [--limit N] [--cursor TOKEN] --format json",
416
+ ` | ${candidateReads.candidateReadCommand} get --candidate-id ID --candidate-revision REVISION`,
417
+ " --generation GENERATION --policy-version POLICY --format json",
418
+ ` | ${candidateDecision.command} --input <file|-> --format json`,
419
+ ` | ${reviewRecords.command} queue --input <file|-> --format json`,
420
+ ` | ${reviewRecords.command} disposition --input <file|-> --format json`,
421
+ ` | ${reviewRecords.command} list [--status pending|terminal] [--limit N] [--cursor TOKEN] --format json`,
422
+ ` | ${reviewRecords.command} get --review-id ID --candidate-id ID --candidate-revision REVISION`,
423
+ " --generation GENERATION --policy-version POLICY --format json",
408
424
  "",
409
425
  "Privacy-gated usage analytics over an existing corpus.",
410
426
  "Default analytics use --sources active and exclude historical imports.",
411
427
  "Use --sources all to include historical records with visible provenance.",
412
- `Profile Full sends ${profileGlossary.requestSchemaVersion} to the exact profile path returned by prime; this subcommand requires no project checkout.`,
428
+ `Personal glossary publication accepts one ${profileGlossary.requestSchemaVersion} mapping with a prior CLI decision and its host receipt; this subcommand requires no project checkout.`,
413
429
  "Profile grounding reports one bounded validity object (valid, absent, or repair_needed); only valid responses include non-glossary content.",
414
430
  "Build requests bounded glossary advice through structured input; the command is read-only and does not publish or refresh state.",
431
+ "Personal glossary candidate reads are private, user-local, non-interactive, and read-only. They require a readable current bounded",
432
+ "evidence-tier generation and a projection bound to it. They never read a project glossary, refresh evidence, acquire consent,",
433
+ "record review state, or alter the candidate projection. List emits only summaries and bounded",
434
+ "projection-local abstention and coverage counts. Safe context becomes unavailable at its 30-day expiry without changing projection bytes.",
435
+ "Exact read returns only opaque validated occurrences and a currently available safe context.",
436
+ "Both forms emit JSON on stdout. Exit 0 reports a current page or exact candidate, exit 1 reports unavailable/stale state, and exit 2",
437
+ "reports malformed arguments. Copy a returned next_cursor exactly; it binds the collection, generation, policy, filters, limit, order,",
438
+ "and expiry-aware safe-context availability snapshot.",
439
+ `Personal glossary decisions accept either a ${candidateDecision.requestSchemaVersion} host receipt or a ${candidateDecision.receiptConstructionRequestSchemaVersion}`,
440
+ "classification with exact candidate bindings. The CLI binds it to the current private projection, current evidence, and quality",
441
+ "gate, then emits automatic_admission, review_required, or abstain. The classification form constructs and returns its receipt.",
442
+ "It never writes a review, profile, project glossary, candidate projection, or project state. Host confidence cannot enable",
443
+ "inferred automatic admission.",
444
+ "Personal glossary publication consumes a current explicit automatic admission, or one current accepted/corrected review authorization.",
445
+ "Immediately before changing the owned PROFILE.md Glossary section, it revalidates the current candidate, projection, receipt,",
446
+ "decision, explicit user-authored evidence, policy, quality gate, scope, meaning, and revision. It never accepts a profile path,",
447
+ "reads a project glossary, or echoes candidate content. Accepted/corrected review publication revalidates the same current",
448
+ "projection, receipt, decision, evidence, policy, scope, meaning, and revision before the profile effect.",
449
+ "Personal glossary reviews queue only a current review_required decision. Disposition accepts only a fresh signed current-user",
450
+ "agentera-local-host IPC approval verified by the configured user-local Ed25519 public key. It records accept, correct, reject,",
451
+ "or defer without changing a profile entry, project state, candidate projection, or publication. Accept/correct returns only an",
452
+ "opaque authorization for the separate publish command. Exact approval replay is idempotent and conflicting nonce reuse fails.",
453
+ "Canonical v1 pending stores remain readable without mutation; only disposition revalidates and migrates one valid v1 record",
454
+ "to v2, deriving its missing scope from the current validated host receipt. Invalid or ambiguous v1 input has no effects.",
455
+ "Rejected and deferred records suppress a recurrence with the same stable identity, semantic fingerprint, scope, and policy.",
456
+ "Meaning, scope, or policy changes requeue with a visible reopening reason. List and exact reads emit only opaque bindings,",
457
+ "a stable reason, lifecycle dates, status, disposition, and reopening reason. They require the configured",
458
+ "current-user owner and current candidate-projection binding, use opaque snapshot cursors, and never return terms, meanings,",
459
+ "evidence, source, session, project, path, tool, or approval material. Terminal review metadata expires after 90 days through",
460
+ "separate authenticated owner maintenance; reads never perform maintenance.",
415
461
  "",
416
462
  "Corpus extraction flags (report refresh with --consent local-history):",
417
463
  " These flags deselect runtimes that would otherwise be included when their",
@@ -20,7 +20,10 @@ export function requiresCompletedEntityCutover(argv) {
20
20
  const [command, subcommand, verb] = argv;
21
21
  if (["--version", "version", "app-home", "doctor", "schema", "route", "upgrade"].includes(command))
22
22
  return false;
23
- if (command === "report" && ["profile-glossary", "profile-grounding"].includes(subcommand))
23
+ if (command === "report" &&
24
+ ["personal-glossary-publish", "profile-grounding", "personal-glossary-candidates", "personal-glossary-decision", "personal-glossary-reviews"].includes(subcommand))
25
+ return false;
26
+ if (command === "check" && subcommand === "verify" && verb === "eval" && argv[3] === "glossary")
24
27
  return false;
25
28
  if (command === "prime" && (argv.includes("--guidance") || !argv.includes("--context") || value(argv, "--context") === "status"))
26
29
  return false;
@@ -1,11 +1,14 @@
1
1
  import fs from "node:fs";
2
- export function writeFileAtomic(target, data, encoding = "utf8") {
2
+ export function writeFileAtomic(target, data, encoding = "utf8", options = {}) {
3
+ const targetMode = options.preserveTargetMode ? fs.statSync(target).mode & 0o777 : undefined;
3
4
  const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
4
5
  try {
5
6
  if (Buffer.isBuffer(data))
6
7
  fs.writeFileSync(tmp, data);
7
8
  else
8
9
  fs.writeFileSync(tmp, data, encoding);
10
+ if (targetMode !== undefined)
11
+ fs.chmodSync(tmp, targetMode);
9
12
  fs.renameSync(tmp, target);
10
13
  }
11
14
  catch (err) {
@@ -46,11 +46,14 @@ function developmentCommand(argumentsText) {
46
46
  }
47
47
  const profileGroundingCommand = developmentCommand("report profile-grounding --format json");
48
48
  const GLOSSARY_PROJECTIONS = {
49
- "profile_output.command": developmentCommand("report profile-glossary"),
49
+ "profile_output.command": developmentCommand("report personal-glossary-publish"),
50
50
  "profile_grounding.command": profileGroundingCommand,
51
51
  "profile_grounding.repair": `Use the Profile capability to repair or regenerate PROFILE.md, then retry \`${profileGroundingCommand}\`; no profile bytes were changed.`,
52
52
  "profile_grounding.absent": `Use the Profile capability to generate PROFILE.md, then retry ${profileGroundingCommand}.`,
53
53
  "advice.command": developmentCommand("report glossary-advice --input REQUEST --format json"),
54
+ "candidate_retrieval.command": developmentCommand("report personal-glossary-candidates"),
55
+ "candidate_decision.command": developmentCommand("report personal-glossary-decision"),
56
+ "review_records.command": developmentCommand("report personal-glossary-reviews"),
54
57
  };
55
58
  function invalid(reason) {
56
59
  throw new Error(`invalid development command projection: ${reason}`);
package/dist/core/yaml.js CHANGED
@@ -1,5 +1,34 @@
1
+ import crypto from "node:crypto";
1
2
  import fs from "node:fs";
2
3
  import YAML from "yaml";
4
+ const MAX_MAPPING_CACHE_ENTRIES = 64;
5
+ let activeMappingCache = null;
6
+ /** Run synchronous work with a bounded, content-invalidated YAML mapping cache. */
7
+ export function withYamlMappingCache(run) {
8
+ return withActiveYamlMappingCache(run, false);
9
+ }
10
+ /** Share frozen YAML mappings only inside one trusted read-only operation. */
11
+ export function withReadOnlyYamlMappingCache(run) {
12
+ return withActiveYamlMappingCache(run, true);
13
+ }
14
+ function withActiveYamlMappingCache(run, readOnly) {
15
+ const previous = activeMappingCache;
16
+ activeMappingCache = { entries: new Map(), readOnly };
17
+ try {
18
+ return run();
19
+ }
20
+ finally {
21
+ activeMappingCache = previous;
22
+ }
23
+ }
24
+ function freezeYamlValue(value, seen = new WeakSet()) {
25
+ if (value === null || typeof value !== "object" || seen.has(value))
26
+ return;
27
+ seen.add(value);
28
+ for (const child of Object.values(value))
29
+ freezeYamlValue(child, seen);
30
+ Object.freeze(value);
31
+ }
3
32
  /**
4
33
  * Parse YAML text as a mapping. Empty/whitespace-only documents return `{}`.
5
34
  * Non-mapping roots throw. Faithful port of `scripts/yaml_mapping.py`.
@@ -16,7 +45,30 @@ export function loadYamlMapping(text) {
16
45
  }
17
46
  /** Read `path` and parse it with {@link loadYamlMapping}. */
18
47
  export function loadYamlMappingFile(path) {
19
- return loadYamlMapping(fs.readFileSync(path, "utf8"));
48
+ const cache = activeMappingCache;
49
+ if (cache === null)
50
+ return loadYamlMapping(fs.readFileSync(path, "utf8"));
51
+ // One synchronous operation sees a stable frozen authority snapshot.
52
+ // A fresh scope still fingerprints its current bytes before reuse.
53
+ if (cache.readOnly) {
54
+ const cached = cache.entries.get(path);
55
+ if (cached)
56
+ return cached.value;
57
+ }
58
+ const text = fs.readFileSync(path, "utf8");
59
+ const digest = crypto.createHash("sha256").update(text).digest("hex");
60
+ // A digest check preserves fresh authority reads while avoiding repeated parses.
61
+ const cached = cache.entries.get(path);
62
+ if (cached?.digest === digest)
63
+ return cache.readOnly ? cached.value : structuredClone(cached.value);
64
+ const value = loadYamlMapping(text);
65
+ if (cache.readOnly)
66
+ freezeYamlValue(value);
67
+ cache.entries.set(path, { digest, value });
68
+ if (cache.entries.size > MAX_MAPPING_CACHE_ENTRIES) {
69
+ cache.entries.delete(cache.entries.keys().next().value);
70
+ }
71
+ return cache.readOnly ? value : structuredClone(value);
20
72
  }
21
73
  /** Parse arbitrary YAML (any root type). */
22
74
  export function parseYaml(text) {