agentera 3.0.0-dev.51 → 3.0.0-dev.69

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 (45) hide show
  1. package/README.md +5 -5
  2. package/bundle/CHANGELOG.md +21 -11
  3. package/bundle/UPGRADE.md +23 -7
  4. package/bundle/references/adapters/package-publication.json +68 -17
  5. package/bundle/references/adapters/package-registry.yaml +145 -145
  6. package/bundle/references/analysis/verification-policy.yaml +93 -18
  7. package/bundle/references/artifacts/state-storage-authority.yaml +50 -11
  8. package/bundle/skills/agentera/SKILL.md +7 -5
  9. package/bundle/skills/agentera/capabilities/build/schemas/artifacts.yaml +7 -6
  10. package/bundle/skills/agentera/capabilities/build/schemas/exit.yaml +6 -5
  11. package/bundle/skills/agentera/capabilities/build/schemas/validation.yaml +18 -10
  12. package/bundle/skills/agentera/schemas/artifacts/plan.yaml +3 -0
  13. package/bundle/skills/agentera/schemas/artifacts/progress.yaml +8 -6
  14. package/dist/capabilities/build/instructions.js +8 -5
  15. package/dist/cli/capabilityContext/build.js +12 -3
  16. package/dist/cli/capabilityContext/planState.js +6 -2
  17. package/dist/cli/capabilityContext/startupAggregation.js +1 -1
  18. package/dist/cli/commands/doctor.js +1 -1
  19. package/dist/cli/commands/prime/briefOrientation.js +0 -1
  20. package/dist/cli/commands/prime/collectOrientationState.js +13 -6
  21. package/dist/cli/commands/prime/orientationOutput.js +27 -5
  22. package/dist/cli/commands/state/write.js +4 -1
  23. package/dist/cli/dispatch/index.js +1 -1
  24. package/dist/cli/help.js +1 -0
  25. package/dist/cli/migrationRequired.js +40 -5
  26. package/dist/registries/activationTuples.js +3 -2
  27. package/dist/registries/packagePublication.js +51 -7
  28. package/dist/state/entityMigrationPreview.js +3 -9
  29. package/dist/state/entityPublicationContext.js +56 -3
  30. package/dist/state/planEntities.js +49 -4
  31. package/dist/state/progressWritePolicy.js +33 -0
  32. package/dist/state/stateMode.js +138 -1
  33. package/dist/state/todoDocsEntities.js +62 -7
  34. package/dist/state/todoReconciliationActivation.js +46 -4
  35. package/dist/state/todoReconciliationInspection.js +5 -3
  36. package/dist/state/todoReconciliationRepair.js +149 -1
  37. package/dist/state/todoReconciliationTransaction.js +20 -7
  38. package/dist/state/write/explain.js +17 -3
  39. package/dist/state/write/input.js +25 -1
  40. package/dist/state/write/runtimeOperations.js +4 -2
  41. package/dist/state/write/transaction.js +6 -1
  42. package/dist/validate/activationArtifactEvidence.js +49 -41
  43. package/dist/validate/activationArtifactEvidenceTypes.js +12 -0
  44. package/dist/validate/activationEvidenceManifest.js +26 -10
  45. package/package.json +11 -6
@@ -7,6 +7,7 @@ import { operationSpec, mutationParityMatrix, writerOwnedFields, verbsForArtifac
7
7
  import { reject } from "./errors.js";
8
8
  import { structuredInputDescriptor, structuredInputSchemaProjection } from "./input.js";
9
9
  import { artifactSchemaFieldsForOperation } from "../../registries/artifactSchemaProjection.js";
10
+ import { progressWriteGuidance } from "../progressWritePolicy.js";
10
11
  function defaultVerb(artifact) {
11
12
  const verb = verbsForArtifact(artifact).find((candidate) => candidate !== "explain");
12
13
  if (!verb)
@@ -148,7 +149,7 @@ export function buildExplain(artifact, projectRoot, requestedVerb) {
148
149
  : artifact === "experiments"
149
150
  ? ["EXPERIMENT"]
150
151
  : artifact === "todo"
151
- ? ["TODO_PUBLIC", "TODO_OPERATIONAL"]
152
+ ? verb === "correct-owners" ? ["OWNER_MAPPING"] : ["TODO_PUBLIC", "TODO_OPERATIONAL"]
152
153
  : artifact === "progress"
153
154
  ? ["CYCLE", "CONTEXT", "GLOSSARY_CAVEAT"]
154
155
  : artifact === "decisions"
@@ -183,7 +184,13 @@ export function buildExplain(artifact, projectRoot, requestedVerb) {
183
184
  result.input_schema = { ...result.input_schema, record_fields: ["name", "depends_on", "acceptance", "evidence", "blocked_reason"] };
184
185
  if (artifact === "plan" && verb === "update")
185
186
  result.input_schema = { ...result.input_schema, record_fields: ["name", "depends_on", "acceptance", "evidence", "blocked_reason", "surprise"], clearable_patch_fields: ["depends_on", "acceptance", "evidence", "blocked_reason"] };
186
- if (artifact === "todo") {
187
+ if (artifact === "todo" && verb === "correct-owners") {
188
+ result.input_schema = {
189
+ ...result.input_schema,
190
+ record_fields: ["schema_version", "owners", "owners.id", "owners.source_line"],
191
+ };
192
+ }
193
+ else if (artifact === "todo") {
187
194
  result.input_schema = {
188
195
  ...result.input_schema,
189
196
  typed_fields: ["kind", "target_version", "title", "requirements", "acceptance", "release_blocker", "severity", "readiness"],
@@ -304,6 +311,13 @@ function decisionsGuidance(artifact, verb, _entityHealth = false, entityArtifact
304
311
  "supply a reason and YYYY-MM-DD date; supersede additionally requires a distinct existing replacement ID",
305
312
  ...base,
306
313
  ];
314
+ if (entityArtifact && artifact === "todo" && verb === "correct-owners")
315
+ return [
316
+ "supply every canonical TODO ID with one current one-based Markdown source_line through --input",
317
+ "preview is read-only; apply requires the same owner mapping, its exact effect SHA-256, and --yes",
318
+ "the correction is available only for marker-absent unsafe-inactive state; exact replay validates the stored owner-mapping authorization",
319
+ ...base,
320
+ ];
307
321
  if (entityArtifact && artifact === "todo")
308
322
  return [
309
323
  "a bare ten-letter TODO item ID is assigned by the CLI; status starts open",
@@ -316,7 +330,7 @@ function decisionsGuidance(artifact, verb, _entityHealth = false, entityArtifact
316
330
  if (entityArtifact && artifact === "docs")
317
331
  return ["a bare ten-letter documentation inventory ID is assigned by the CLI; path remains record data", ...base];
318
332
  if (artifact === "progress" && verb === "append")
319
- return ["supply one progress cycle mapping with --input PATH or --input -; the writer assigns id, artifact, and publication_order", "record content flags are retired; inspect the structured record_fields in explain before writing", ...base];
333
+ return [...progressWriteGuidance(), "when the policy authorizes or requires progress, supply one cycle mapping with --input PATH or --input -; the writer assigns id, artifact, and publication_order", "record content flags are retired; inspect the structured record_fields in explain before writing", ...base];
320
334
  if (artifact === "decisions" && verb === "append")
321
335
  return ["a bare ten-letter ID is assigned by the CLI; do not pass an identity", "supply one decision record mapping with --input PATH or --input -; the writer assigns id and artifact", "record content flags are retired; satisfaction remains a separate flag-only transition", ...base];
322
336
  if (artifact === "decisions" && verb === "update")
@@ -1,6 +1,8 @@
1
1
  import fs from "node:fs";
2
2
  import { loadYamlMapping } from "../../core/yaml.js";
3
3
  import { glossaryCaveatContract } from "../../registries/glossaryCaveatContract.js";
4
+ import { progressWritePolicy } from "../progressWritePolicy.js";
5
+ import { todoOwnerCorrectionInputViolations } from "../todoReconciliationRepair.js";
4
6
  const caveat = glossaryCaveatContract();
5
7
  const field = (path, type, description, options = { required: false, update: "replace" }) => ({ path, type, description, ...options });
6
8
  const PROGRESS_INPUT_SCHEMA = {
@@ -31,6 +33,7 @@ const PROGRESS_INPUT_SCHEMA = {
31
33
  omitted_fields: "not present in the canonical record except writer-defaulted timestamp",
32
34
  writer_metadata: "id, artifact, and publication_order are assigned by the writer and excluded from logical replay comparison",
33
35
  glossary_caveat: "current events deduplicate by the existing caveat lifecycle contract; resolved and superseded events remain distinct",
36
+ progress_write_policy: progressWritePolicy(),
34
37
  },
35
38
  ownedFields: ["id", "artifact", "publication_order"],
36
39
  immutableFields: [],
@@ -120,12 +123,31 @@ const PLAN_TASK_UPDATE_INPUT_SCHEMA = {
120
123
  bounds: { max_input_utf8_bytes: 32768, max_collection_items: 1 },
121
124
  examples: ["agentera state plan update --id qjtrmnpvka --plan abcdefghij --input task-patch.yaml --format json"],
122
125
  };
126
+ const TODO_OWNER_CORRECTION_INPUT_SCHEMA = {
127
+ root: "one unsafe TODO owner mapping",
128
+ fields: [
129
+ field("schema_version", "string", "Exact owner-correction input schema version.", { required: true, enum: ["agentera.todoOwnerCorrection.v1"], update: "replace" }),
130
+ field("owners", "list", "Complete one-to-one canonical TODO ID to current Markdown source-line mapping.", { required: true, itemType: "mapping", shape: "id:string, source_line:integer", update: "replace" }),
131
+ field("owners.id", "string", "Canonical bare ten-letter TODO ID claimed by this row.", { required: true, update: "replace" }),
132
+ field("owners.source_line", "integer", "Current one-based Markdown line claimed by this TODO ID.", { required: true, update: "replace" }),
133
+ ],
134
+ semantics: {
135
+ mode: "exact_owner_mapping",
136
+ owners: "every canonical TODO entity and every managed TODO checkbox row must appear exactly once; input order is normalized by ID before effect authorization",
137
+ public_authority: "the current mapped Markdown row supplies public description, severity, status, and order; entity operational fields remain unchanged",
138
+ },
139
+ ownedFields: ["reconciliation", "public_document", "activation"],
140
+ immutableFields: ["id", "artifact", "readiness", "dependencies", "gates", "evidence", "lifecycle"],
141
+ bounds: { max_input_utf8_bytes: 32768, max_collection_items: 256 },
142
+ examples: ["agentera state todo correct-owners --input owner-mapping.yaml --dry-run --format json"],
143
+ };
123
144
  const STRUCTURED_INPUT_SCHEMAS = {
124
145
  "progress.append": PROGRESS_INPUT_SCHEMA,
125
146
  "decisions.append": DECISION_APPEND_INPUT_SCHEMA,
126
147
  "decisions.amend": DECISION_AMEND_INPUT_SCHEMA,
127
148
  "plan.append": PLAN_TASK_APPEND_INPUT_SCHEMA,
128
149
  "plan.update": PLAN_TASK_UPDATE_INPUT_SCHEMA,
150
+ "todo.correct-owners": TODO_OWNER_CORRECTION_INPUT_SCHEMA,
129
151
  };
130
152
  export function structuredInputDescriptor(artifact, verb) {
131
153
  return STRUCTURED_INPUT_SCHEMAS[`${artifact}.${verb}`] ?? null;
@@ -311,7 +333,7 @@ function planTaskInputViolations(input, verb) {
311
333
  return violations;
312
334
  }
313
335
  export function structuredRecordInputViolations(artifact, verb, input) {
314
- if (!input || (artifact !== "progress" && artifact !== "decisions" && artifact !== "plan"))
336
+ if (!input || (artifact !== "progress" && artifact !== "decisions" && artifact !== "plan" && artifact !== "todo"))
315
337
  return [];
316
338
  if (artifact === "progress" && verb === "append")
317
339
  return progressInputViolations(input);
@@ -319,6 +341,8 @@ export function structuredRecordInputViolations(artifact, verb, input) {
319
341
  return decisionInputViolations(input, verb);
320
342
  if (artifact === "plan" && (verb === "append" || verb === "update"))
321
343
  return planTaskInputViolations(input, verb);
344
+ if (artifact === "todo" && verb === "correct-owners")
345
+ return todoOwnerCorrectionInputViolations(input);
322
346
  return [];
323
347
  }
324
348
  export function normalizeDecisionRecordInput(input) {
@@ -5,7 +5,7 @@ export const RUNTIME_WRITABLE_ARTIFACTS = [
5
5
  ];
6
6
  export const RUNTIME_WRITE_VERBS = [
7
7
  "append", "update", "amend", "set-status", "supersede", "set-plan-status",
8
- "record-evaluation", "archive", "create", "replace", "publish", "activate", "repair", "set-severity", "resolve", "reopen", "explain",
8
+ "record-evaluation", "archive", "create", "replace", "publish", "activate", "repair", "correct-owners", "set-severity", "resolve", "reopen", "explain",
9
9
  ];
10
10
  const readiness = loadTodoReadinessContract();
11
11
  const f = (flag, field, kind, options = {}) => ({ flag, field, kind, required: false, ...options });
@@ -50,6 +50,7 @@ const RUNTIME_OPERATION_CORES = [
50
50
  op("experiments", "publish", [f("--objective", "objective", "string", { required: true }), f("--id", "id", "string")], { selectors: ["--objective", "--id"], ownedFields: ["id", "artifact", "objective", "archive_identity"], inputMode: "structured", inputRoot: "one experiment entry", inputSources: ["file", "stdin"], structuredInputSources: ["file", "stdin"], cliOwnedFields: ["id", "artifact", "objective"], inputMaxBytes: 32768, compacts: true }),
51
51
  op("todo", "activate", [f("--effect-sha256", "effect_sha256", "string"), f("--yes", "confirmed", "boolean")], { ownedFields: ["reconciliation", "public_document", "activation"], compacts: true }),
52
52
  op("todo", "repair", [f("--effect-sha256", "effect_sha256", "string"), f("--yes", "confirmed", "boolean")], { ownedFields: ["reconciliation", "public_document", "activation"], compacts: true }),
53
+ op("todo", "correct-owners", [f("--effect-sha256", "effect_sha256", "string"), f("--yes", "confirmed", "boolean")], { ownedFields: ["reconciliation", "public_document", "activation"], inputMode: "structured", inputRoot: "one unsafe TODO owner mapping", inputSources: ["file", "stdin"], structuredInputSources: ["file", "stdin"], inputMaxBytes: 32768, compacts: true }),
53
54
  op("todo", "create", [], { ownedFields: ["id", "artifact", "status", "public_order", "lifecycle"], inputMode: "structured", inputRoot: "full typed TODO record", inputSources: ["file", "stdin"], structuredInputSources: ["file", "stdin"], cliOwnedFields: ["id", "artifact", "status", "public_order", "lifecycle"], inputMaxBytes: 32768 }),
54
55
  op("todo", "update", [f("--id", "id", "string", { required: true })], { selectors: ["--id"], ownedFields: ["id", "artifact", "status", "public_order", "lifecycle"], inputMode: "structured", inputRoot: "TODO record patch", inputSources: ["file", "stdin"], structuredInputSources: ["file", "stdin"], cliOwnedFields: ["id", "artifact", "status", "public_order", "lifecycle"], inputMaxBytes: 32768 }),
55
56
  op("todo", "set-severity", [f("--id", "id", "string", { required: true }), f("--severity", "severity", "string", { required: true, validValues: ["critical", "degraded", "normal", "annoying"] }), f("--reason", "lifecycle.reason", "string", { required: true }), f("--date", "lifecycle.date", "date", { required: true })], { selectors: ["--id"], ownedFields: ["id", "artifact", "severity", "lifecycle"] }),
@@ -95,8 +96,9 @@ const RUNTIME_OPERATION_PROJECTIONS = {
95
96
  "objective.create": projection("Remove identity fields assigned by the CLI and retry with one schema-valid objective document.", developmentCommand("state objective create --input objective.yaml --format json")),
96
97
  "objective.update": projection("Reread the objective, copy its bare ID to --id, remove CLI-owned fields, and retry.", developmentCommand("state objective update --id qjtrmnpvka --input objective.yaml --format json")),
97
98
  "experiments.publish": projection("Use a bare objective ID, omit numeric legacy selectors, and retry the exact input; divergent immutable identities remain untouched.", developmentCommand("state experiments publish --objective qjtrmnpvka --input experiment.yaml --format json")),
98
- "todo.activate": projection("Preview and review every reported safe activation effect before explicit confirmed apply; unsafe inactive evidence requires non-mutating owner correction and replanning.", developmentCommand("state todo activate --dry-run --format json"), developmentCommand("state todo activate --effect-sha256 EFFECT_SHA256 --yes --format json")),
99
+ "todo.activate": projection("Preview and review every reported safe activation effect before explicit confirmed apply; unsafe inactive evidence requires the separate effect-bound owner-correction operation.", developmentCommand("state todo activate --dry-run --format json"), developmentCommand("state todo activate --effect-sha256 EFFECT_SHA256 --yes --format json")),
99
100
  "todo.repair": projection("Preview and review every diagnosed repair decision before explicit confirmed apply; ambiguous evidence is rejected without effects.", developmentCommand("state todo repair --dry-run --format json"), developmentCommand("state todo repair --effect-sha256 EFFECT_SHA256 --yes --format json")),
101
+ "todo.correct-owners": projection("Supply one complete id/source_line owner mapping, preview its bounded effect, then apply only the exact returned effect; malformed, ambiguous, unmatched, or stale evidence is rejected without effects.", developmentCommand("state todo correct-owners --input owner-mapping.yaml --dry-run --format json"), developmentCommand("state todo correct-owners --input owner-mapping.yaml --effect-sha256 EFFECT_SHA256 --yes --format json")),
100
102
  "todo.create": projection(`Run ${developmentCommand("state todo explain --verb create --format json")}, remove CLI-owned fields, provide the full typed TODO record, and retry.`, developmentCommand("state todo create --input todo.yaml --format json")),
101
103
  "todo.update": projection("Reread the TODO item, use its bare ID, supply only typed patch fields, and use null or an empty list only for declared clearable fields.", developmentCommand("state todo update --id qjtrmnpvka --input todo-patch.yaml --format json")),
102
104
  "todo.set-severity": projection("Use the bare TODO ID, one immediate-impact severity, a reason, and a YYYY-MM-DD date; no record input is accepted.", developmentCommand('state todo set-severity --id qjtrmnpvka --severity degraded --reason "Impact changed" --date 2026-07-31 --format json')),
@@ -1,7 +1,7 @@
1
1
  import { amendDecisionEntity, appendDecisionEntity, updateDecisionSatisfactionEntity } from "../decisionEntities.js";
2
2
  import { appendHealthEntity } from "../healthEntities.js";
3
3
  import { mutateObjectiveEntity, publishExperimentEntity } from "../objectiveExperimentEntities.js";
4
- import { mutatePlanEntities } from "../planEntities.js";
4
+ import { createFreshPlanEntities, mutatePlanEntities } from "../planEntities.js";
5
5
  import { withEntityWriterLock } from "../entityStorage.js";
6
6
  import { appendProgressEntity } from "../progressEntities.js";
7
7
  import { requireEntityStateBinding } from "../stateMode.js";
@@ -21,6 +21,11 @@ export function executeStateWrite(req, _options = {}) {
21
21
  syntax: `agentera state ${req.artifact} ${req.spec.verb} --input PATH --format json`,
22
22
  example: `agentera state ${req.artifact} ${req.spec.verb} --input - --format json`,
23
23
  });
24
+ if (req.artifact === "plan" && req.spec.verb === "create") {
25
+ const initialized = createFreshPlanEntities(req);
26
+ if (initialized)
27
+ return initialized;
28
+ }
24
29
  const binding = requireEntityStateBinding(req.projectRoot);
25
30
  const publicationContext = binding.publicationContext;
26
31
  try {
@@ -6,19 +6,9 @@ import path from "node:path";
6
6
  import { ACTIVATION_CANONICAL_TUPLES } from "../registries/activationTuples.js";
7
7
  import { loadRegistry } from "../registries/packageRegistry.js";
8
8
  import { packageCommandDeclarations, packageDescriptorSemantics, packageDescriptors, } from "./activationPackageSemantics.js";
9
+ import { GENERATED_OWNER_EVIDENCE_SCHEMA, OWNER_EVIDENCE_MAX_BYTES, PACKAGE_IDENTITY_MAX_BYTES, PACKAGE_IDENTITY_SCHEMA, PACKAGE_OWNER_EVIDENCE_SCHEMA, PACKAGE_SNAPSHOT_DIRECTORY, PACKAGE_SNAPSHOT_EXTRACTED_MAX_BYTES, PACKAGE_SNAPSHOT_MARKER_MAX_BYTES, PACKAGE_SNAPSHOT_MAX_ENTRIES, PACKAGE_SNAPSHOT_SCHEMA, PACKAGE_SNAPSHOT_TARBALL_MAX_BYTES, SOURCE_OWNER_EVIDENCE_SCHEMA, } from "./activationArtifactEvidenceTypes.js";
9
10
  import { bootstrapMatrixAuthority } from "./bootstrapAuthority.js";
10
- export const SOURCE_OWNER_EVIDENCE_SCHEMA = "agentera.activationSourceOwnerEvidence.v1";
11
- export const PACKAGE_OWNER_EVIDENCE_SCHEMA = "agentera.activationPackageOwnerEvidence.v1";
12
- export const GENERATED_OWNER_EVIDENCE_SCHEMA = "agentera.activationGeneratedOwnerEvidence.v1";
13
- export const PACKAGE_IDENTITY_SCHEMA = "agentera.activationPackageIdentity.v1";
14
- export const PACKAGE_SNAPSHOT_SCHEMA = "agentera.activationPackageSnapshot.v1";
15
- export const PACKAGE_SNAPSHOT_DIRECTORY = ".activation-package-snapshot";
16
- export const OWNER_EVIDENCE_MAX_BYTES = 262_144;
17
- export const PACKAGE_IDENTITY_MAX_BYTES = 16_384;
18
- export const PACKAGE_SNAPSHOT_MARKER_MAX_BYTES = 16_384;
19
- export const PACKAGE_SNAPSHOT_TARBALL_MAX_BYTES = 64 * 1024 * 1024;
20
- export const PACKAGE_SNAPSHOT_EXTRACTED_MAX_BYTES = 128 * 1024 * 1024;
21
- export const PACKAGE_SNAPSHOT_MAX_ENTRIES = 4_096;
11
+ export * from "./activationArtifactEvidenceTypes.js";
22
12
  const sourceCapabilityCache = new Map();
23
13
  const CAPABILITY_IDS = Object.freeze(ACTIVATION_CANONICAL_TUPLES
24
14
  .filter((tuple) => tuple.class === "capability")
@@ -409,9 +399,9 @@ function sourceProjection(root) {
409
399
  },
410
400
  };
411
401
  }
412
- function runtimeArtifactObservation(runtimeRoot, projectRoot, sourceRoot) {
402
+ function runtimeArtifactObservation(runtimeRoot, projectRoot, sourceRoot, mode = "full") {
413
403
  const script = path.join(sourceRoot, "packages/cli/scripts/observe-runtime-artifact.mjs");
414
- const result = spawnSync(process.execPath, [script, runtimeRoot, projectRoot], {
404
+ const result = spawnSync(process.execPath, [script, runtimeRoot, projectRoot, mode], {
415
405
  cwd: projectRoot,
416
406
  env: process.env,
417
407
  encoding: "utf8",
@@ -444,8 +434,8 @@ function runtimeArtifactObservation(runtimeRoot, projectRoot, sourceRoot) {
444
434
  },
445
435
  } };
446
436
  }
447
- function runtimeProjection(runtimeRoot, projectRoot, sourceRoot) {
448
- return runtimeArtifactObservation(runtimeRoot, projectRoot, sourceRoot).projection;
437
+ function runtimeProjection(runtimeRoot, projectRoot, sourceRoot, mode = "full") {
438
+ return runtimeArtifactObservation(runtimeRoot, projectRoot, sourceRoot, mode).projection;
449
439
  }
450
440
  function createRecord(producerKind, artifactClass, artifactIdentity, artifactContentDigest, content, generation, packageIntegrity) {
451
441
  return {
@@ -548,7 +538,7 @@ function genericDimensionObservation(classId, dimension, input) {
548
538
  return { help: input.helpFamilies, examples: writes.map((entry) => ({ id: `${entry.artifact}.${entry.verb}`, examples: entry.projection.examples })) };
549
539
  return { bounds: input.bounds, inputBounds: writes.map((entry) => ({ id: `${entry.artifact}.${entry.verb}`, bytes: entry.inputMaxBytes, formats: entry.projection.formatValues })) };
550
540
  }
551
- export function createSourceOwnerEvidence(root, productionInputs) {
541
+ export function createSourceOwnerEvidence(root, productionInputs, packageExecution) {
552
542
  const capabilities = sourceProjection(root);
553
543
  const record = packageRecord(root);
554
544
  const records = {
@@ -570,6 +560,37 @@ export function createSourceOwnerEvidence(root, productionInputs) {
570
560
  }
571
561
  }
572
562
  }
563
+ if (packageExecution) {
564
+ const { fixture, runtimeSummary, missingSurfaceResults } = packageExecution;
565
+ const capabilityProject = path.join(fixture.root, "activation-source-package-capability-project");
566
+ resetObservationProject(capabilityProject);
567
+ const packageCapabilities = runtimeProjection(fixture.packageRoot, capabilityProject, root);
568
+ const packageRows = runtimeSummary.rows.filter((row) => row.runtime === "package");
569
+ const rejectedRows = packageRows.filter((row) => !row.accepted);
570
+ const commandPolicy = {
571
+ rowCount: packageRows.length,
572
+ accepted: packageRows.filter((row) => row.accepted).length,
573
+ rejected: rejectedRows.length,
574
+ classifications: Object.fromEntries([...new Set(packageRows.map((row) => row.classification))].sort().map((classification) => [classification, packageRows.filter((row) => row.classification === classification).length])),
575
+ compositeIdentityDigest: observationDigest(packageRows.map((row) => `${row.runtime}/${row.projectState}/${row.id}`).sort()),
576
+ };
577
+ const adversarial = {
578
+ rowCount: rejectedRows.length,
579
+ allBlockedBeforeChildStart: rejectedRows.every((row) => row.childStarted === false),
580
+ classifications: Object.fromEntries([...new Set(rejectedRows.map((row) => row.classification))].sort().map((classification) => [classification, rejectedRows.filter((row) => row.classification === classification).length])),
581
+ };
582
+ records["capability.extracted-served"] = createRecord("source-owner", "capability-extracted-served", "package/dist/bin/agentera.js#prime-context", packageCapabilities.artifacts.served, packageCapabilities.served, null, null);
583
+ records["package.command-policy"] = createRecord("source-owner", "package-command-policy", "source-integration/runtime-matrix/classifications", observationDigest(packageRows), commandPolicy, null, null);
584
+ records["package.adversarial"] = createRecord("source-owner", "package-adversarial", "source-integration/runtime-matrix/rejections", observationDigest(rejectedRows), adversarial, null, null);
585
+ records["bootstrap.extracted-classifications"] = createRecord("source-owner", "bootstrap-extracted-classifications", "source-integration/runtime-matrix/rows", observationDigest(packageRows), packageRows, null, null);
586
+ records["bootstrap.extracted-diagnostics"] = createRecord("source-owner", "bootstrap-extracted-diagnostics", "source-integration/runtime-matrix/rejection-diagnostics", observationDigest(rejectedRows), rejectedRows, null, null);
587
+ const parity = {
588
+ ...(runtimeSummary.runtimeObservationDigests ?? {}),
589
+ packageArtifact: runtimeSummary.packageArtifact ?? null,
590
+ };
591
+ records["bootstrap.source-package-parity"] = createRecord("source-owner", "bootstrap-source-package-parity", "source-integration/runtime-matrix/parity", observationDigest(parity), parity, null, null);
592
+ records["bootstrap.missing-surface"] = createRecord("source-owner", "bootstrap-missing-surface", "source-integration/runtime-matrix/missing-required-surfaces", observationDigest(missingSurfaceResults), missingSurfaceResults, null, null);
593
+ }
573
594
  return finishEvidence({
574
595
  schemaVersion: SOURCE_OWNER_EVIDENCE_SCHEMA,
575
596
  producerKind: "source-owner",
@@ -605,16 +626,23 @@ function seedObservationProject(project) {
605
626
  fs.mkdirSync(path.join(project, ".agentera"), { recursive: true, mode: 0o700 });
606
627
  fs.writeFileSync(path.join(project, ".agentera/state-mode.yaml"), "schemaVersion: agentera.stateMode.v1\nmode: entities\n", { flag: "wx", mode: 0o600 });
607
628
  }
629
+ function resetObservationProject(project) {
630
+ fs.rmSync(project, { recursive: true, force: true });
631
+ seedObservationProject(project);
632
+ }
608
633
  export async function finalizePackageOwnerEvidence(options) {
609
- const { root, fixture, runtimeSummary } = options;
634
+ const { root, fixture } = options;
610
635
  const runtimeRoot = fixture.packageRoot;
611
636
  const capabilityProject = path.join(fixture.root, "activation-capability-project");
612
- seedObservationProject(capabilityProject);
613
- const capabilities = await runtimeProjection(runtimeRoot, capabilityProject, root);
637
+ resetObservationProject(capabilityProject);
638
+ const capabilities = runtimeProjection(runtimeRoot, capabilityProject, root, "package-smoke");
614
639
  const record = packageRecord(path.join(runtimeRoot, "bundle"));
615
640
  const packageArtifact = packageArtifactObservation(runtimeRoot, fixture, options.requiredFiles, options.snapshotDirectory);
616
641
  const integrity = packageArtifact.integrity;
617
642
  const portability = {
643
+ deterministicPackRuns: fixture.deterministicBytes.packRuns,
644
+ deterministicTarballSha256: fixture.deterministicBytes.sha256,
645
+ secondTarballSha256: fixture.deterministicBytes.secondSha256,
618
646
  constructionRootCount: fixture.pathIndependence.constructionRoots.length,
619
647
  constructionRootsDistinct: new Set(fixture.pathIndependence.constructionRoots).size === fixture.pathIndependence.constructionRoots.length,
620
648
  extractedRootCount: fixture.pathIndependence.extractedRoots.length,
@@ -630,38 +658,18 @@ export async function finalizePackageOwnerEvidence(options) {
630
658
  files: fixture.pathIndependence.secondManifest.files,
631
659
  },
632
660
  };
633
- const packageRows = runtimeSummary.rows.filter((row) => row.runtime === "package");
634
- const rejectedRows = packageRows.filter((row) => !row.accepted);
635
- const commandPolicy = {
636
- rowCount: packageRows.length,
637
- accepted: packageRows.filter((row) => row.accepted).length,
638
- rejected: rejectedRows.length,
639
- classifications: Object.fromEntries([...new Set(packageRows.map((row) => row.classification))].sort().map((classification) => [classification, packageRows.filter((row) => row.classification === classification).length])),
640
- compositeIdentityDigest: observationDigest(packageRows.map((row) => `${row.runtime}/${row.projectState}/${row.id}`).sort()),
641
- };
642
- const adversarial = {
643
- rowCount: rejectedRows.length,
644
- allBlockedBeforeChildStart: rejectedRows.every((row) => row.childStarted === false),
645
- classifications: Object.fromEntries([...new Set(rejectedRows.map((row) => row.classification))].sort().map((classification) => [classification, rejectedRows.filter((row) => row.classification === classification).length])),
646
- };
647
661
  const records = {
648
662
  "capability.extracted-modules": createRecord("package-owner", "capability-extracted-modules", "package/dist/capabilities/*/instructions.js", capabilities.artifacts.modules, capabilities.modules, null, integrity),
649
663
  "capability.extracted-runtime-registry": createRecord("package-owner", "capability-extracted-runtime-registry", "package/dist/capabilities/index.js#CAPABILITY_INSTRUCTIONS", capabilities.artifacts.runtimeRegistry, capabilities.runtimeRegistry, null, integrity),
650
- "capability.extracted-served": createRecord("package-owner", "capability-extracted-served", "package/dist/bin/agentera.js#prime-context", capabilities.artifacts.served, capabilities.served, null, integrity),
651
664
  "capability.extracted-registry": createRecord("package-owner", "capability-extracted-registry", "package/bundle/registry.json#skills[0].capabilities", capabilities.artifacts.registry, capabilities.registry, null, integrity),
652
665
  "capability.extracted-routes": createRecord("package-owner", "capability-extracted-routes", "package/dist/cli/commands/capability.js#CAPABILITY_ROUTING_NAMES", capabilities.artifacts.routes, capabilities.routes, null, integrity),
653
666
  "capability.extracted-schemas": createRecord("package-owner", "capability-extracted-schemas", "package/bundle/skills/agentera/capabilities/*/schemas", capabilities.artifacts.schemas, capabilities.schemas, null, integrity),
654
667
  "package.extracted-artifact": createRecord("package-owner", "package-extracted-artifact", "npm-tarball/extracted-package", observationDigest(packageArtifact), packageArtifact, null, integrity),
655
668
  "package.extracted-registry": createRecord("package-owner", "package-extracted-registry", "package/bundle/references/adapters/package-registry.yaml#records[agentera]", artifactDigest(runtimeRoot, ["bundle/references/adapters/package-registry.yaml"]), packageDescriptorSemantics(packageDescriptors(record)), null, integrity),
656
- "package.command-policy": createRecord("package-owner", "package-command-policy", "package/runtime-matrix/classifications", observationDigest(packageRows), commandPolicy, null, integrity),
669
+ "package.extracted-smoke": createRecord("package-owner", "package-extracted-smoke", "package/dist/bin/agentera.js#prime-context-status", capabilities.artifacts.served, capabilities.served, null, integrity),
657
670
  "package.portability": createRecord("package-owner", "package-portability", "npm-tarball/path-portability", fixture.pathIndependence.contentSha256, portability, null, integrity),
658
- "package.adversarial": createRecord("package-owner", "package-adversarial", "package/runtime-matrix/rejections", observationDigest(rejectedRows), adversarial, null, integrity),
659
- "bootstrap.extracted-classifications": createRecord("package-owner", "bootstrap-extracted-classifications", "package/runtime-matrix/rows", observationDigest(packageRows), packageRows, null, integrity),
660
- "bootstrap.extracted-diagnostics": createRecord("package-owner", "bootstrap-extracted-diagnostics", "package/runtime-matrix/rejection-diagnostics", observationDigest(rejectedRows), rejectedRows, null, integrity),
661
671
  "bootstrap.extracted-startup": createRecord("package-owner", "bootstrap-extracted-startup", "package/dist/bin/agentera.js#startup-producers", capabilities.artifacts.startupProducers, capabilities.startupProducers, null, integrity),
662
672
  "bootstrap.extracted-declarations": createRecord("package-owner", "bootstrap-extracted-declarations", "package/bundle/references/adapters/package-registry.yaml#bootstrap_command_authority", artifactDigest(runtimeRoot, ["bundle/references/adapters/package-registry.yaml"]), packageCommandDeclarations(record), null, integrity),
663
- "bootstrap.source-package-parity": createRecord("package-owner", "bootstrap-source-package-parity", "package/runtime-matrix/parity", observationDigest(runtimeSummary.runtimeObservationDigests ?? {}), runtimeSummary.runtimeObservationDigests ?? {}, null, integrity),
664
- "bootstrap.missing-surface": createRecord("package-owner", "bootstrap-missing-surface", "package/runtime-matrix/missing-required-surfaces", observationDigest(options.missingSurfaceResults), options.missingSurfaceResults, null, integrity),
665
673
  };
666
674
  for (const classId of ["runtime", "reference", "state"]) {
667
675
  const relative = classId === "runtime"
@@ -0,0 +1,12 @@
1
+ export const SOURCE_OWNER_EVIDENCE_SCHEMA = "agentera.activationSourceOwnerEvidence.v1";
2
+ export const PACKAGE_OWNER_EVIDENCE_SCHEMA = "agentera.activationPackageOwnerEvidence.v1";
3
+ export const GENERATED_OWNER_EVIDENCE_SCHEMA = "agentera.activationGeneratedOwnerEvidence.v1";
4
+ export const PACKAGE_IDENTITY_SCHEMA = "agentera.activationPackageIdentity.v1";
5
+ export const PACKAGE_SNAPSHOT_SCHEMA = "agentera.activationPackageSnapshot.v1";
6
+ export const PACKAGE_SNAPSHOT_DIRECTORY = ".activation-package-snapshot";
7
+ export const OWNER_EVIDENCE_MAX_BYTES = 262_144;
8
+ export const PACKAGE_IDENTITY_MAX_BYTES = 16_384;
9
+ export const PACKAGE_SNAPSHOT_MARKER_MAX_BYTES = 16_384;
10
+ export const PACKAGE_SNAPSHOT_TARBALL_MAX_BYTES = 64 * 1024 * 1024;
11
+ export const PACKAGE_SNAPSHOT_EXTRACTED_MAX_BYTES = 128 * 1024 * 1024;
12
+ export const PACKAGE_SNAPSHOT_MAX_ENTRIES = 4_096;
@@ -43,7 +43,7 @@ const CHECK_OBSERVATIONS = Object.freeze({
43
43
  "package.discovery": ["package.source-registry"],
44
44
  "package.behavior": ["package.source-construction", "package.generated-construction"],
45
45
  "package.diagnostics": ["package.command-policy"],
46
- "package.package_projection": ["package.generated-registry", "package.extracted-artifact", "package.extracted-registry"],
46
+ "package.package_projection": ["package.generated-registry", "package.extracted-artifact", "package.extracted-registry", "package.extracted-smoke"],
47
47
  "package.instructions": ["package.source-selectors", "package.generated-selectors"],
48
48
  "package.adversarial": ["package.portability", "package.adversarial"],
49
49
  "bootstrap.discovery": ["bootstrap.source-authority"],
@@ -63,6 +63,13 @@ const SOURCE_PROVENANCE = {
63
63
  "package.source-construction": ["package-source-construction", "references/adapters/package-registry.yaml#records[agentera].bundle_surfaces"],
64
64
  "package.source-selectors": ["package-source-selectors", "references/adapters/package-registry.yaml#records[agentera].semantic_fields"],
65
65
  "bootstrap.source-authority": ["bootstrap-source-authority", "packages/cli/src/validate/bootstrapAuthority.ts#bootstrapMatrixAuthority"],
66
+ "capability.extracted-served": ["capability-extracted-served", "package/dist/bin/agentera.js#prime-context"],
67
+ "package.command-policy": ["package-command-policy", "source-integration/runtime-matrix/classifications"],
68
+ "package.adversarial": ["package-adversarial", "source-integration/runtime-matrix/rejections"],
69
+ "bootstrap.extracted-classifications": ["bootstrap-extracted-classifications", "source-integration/runtime-matrix/rows"],
70
+ "bootstrap.extracted-diagnostics": ["bootstrap-extracted-diagnostics", "source-integration/runtime-matrix/rejection-diagnostics"],
71
+ "bootstrap.source-package-parity": ["bootstrap-source-package-parity", "source-integration/runtime-matrix/parity"],
72
+ "bootstrap.missing-surface": ["bootstrap-missing-surface", "source-integration/runtime-matrix/missing-required-surfaces"],
66
73
  };
67
74
  const GENERATED_PROVENANCE = {
68
75
  "capability.generated-modules": ["capability-generated-modules", "generation/dist/capabilities/*/instructions.js"],
@@ -83,21 +90,15 @@ const GENERATED_PROVENANCE = {
83
90
  const PACKAGE_PROVENANCE = {
84
91
  "capability.extracted-modules": ["capability-extracted-modules", "package/dist/capabilities/*/instructions.js"],
85
92
  "capability.extracted-runtime-registry": ["capability-extracted-runtime-registry", "package/dist/capabilities/index.js#CAPABILITY_INSTRUCTIONS"],
86
- "capability.extracted-served": ["capability-extracted-served", "package/dist/bin/agentera.js#prime-context"],
87
93
  "capability.extracted-registry": ["capability-extracted-registry", "package/bundle/registry.json#skills[0].capabilities"],
88
94
  "capability.extracted-routes": ["capability-extracted-routes", "package/dist/cli/commands/capability.js#CAPABILITY_ROUTING_NAMES"],
89
95
  "capability.extracted-schemas": ["capability-extracted-schemas", "package/bundle/skills/agentera/capabilities/*/schemas"],
90
96
  "package.extracted-artifact": ["package-extracted-artifact", "npm-tarball/extracted-package"],
91
97
  "package.extracted-registry": ["package-extracted-registry", "package/bundle/references/adapters/package-registry.yaml#records[agentera]"],
92
- "package.command-policy": ["package-command-policy", "package/runtime-matrix/classifications"],
98
+ "package.extracted-smoke": ["package-extracted-smoke", "package/dist/bin/agentera.js#prime-context-status"],
93
99
  "package.portability": ["package-portability", "npm-tarball/path-portability"],
94
- "package.adversarial": ["package-adversarial", "package/runtime-matrix/rejections"],
95
- "bootstrap.extracted-classifications": ["bootstrap-extracted-classifications", "package/runtime-matrix/rows"],
96
- "bootstrap.extracted-diagnostics": ["bootstrap-extracted-diagnostics", "package/runtime-matrix/rejection-diagnostics"],
97
100
  "bootstrap.extracted-startup": ["bootstrap-extracted-startup", "package/dist/bin/agentera.js#startup-producers"],
98
101
  "bootstrap.extracted-declarations": ["bootstrap-extracted-declarations", "package/bundle/references/adapters/package-registry.yaml#bootstrap_command_authority"],
99
- "bootstrap.source-package-parity": ["bootstrap-source-package-parity", "package/runtime-matrix/parity"],
100
- "bootstrap.missing-surface": ["bootstrap-missing-surface", "package/runtime-matrix/missing-required-surfaces"],
101
102
  };
102
103
  for (const classId of ["cli", "runtime", "reference", "state"]) {
103
104
  for (const dimension of ["discovery", "behavior", "diagnostics", "instructions", "adversarial"]) {
@@ -276,6 +277,12 @@ function validatePackageSemantics(manifest, violations) {
276
277
  }
277
278
  function validateExecutedArtifactSemantics(manifest, violations) {
278
279
  const records = allRecords(manifest.producers);
280
+ const smoke = records.get("package.extracted-smoke")?.content;
281
+ if (canonicalObservationJson(smoke?.identities) !== canonicalObservationJson(["status"])
282
+ || smoke?.bodies?.status?.bytes <= 0
283
+ || !/^[a-f0-9]{64}$/.test(smoke?.bodies?.status?.sha256 ?? "")) {
284
+ violations.push("extracted package smoke is missing or did not serve status");
285
+ }
279
286
  const artifact = records.get("package.extracted-artifact")?.content;
280
287
  if (!artifact || canonicalObservationJson({
281
288
  filename: artifact.filename,
@@ -319,8 +326,11 @@ function validateExecutedArtifactSemantics(manifest, violations) {
319
326
  violations.push("complete extracted package tree is not bound to the current tarball payload");
320
327
  }
321
328
  const portability = records.get("package.portability")?.content;
322
- if (portability?.constructionRootCount !== 2 || portability?.constructionRootsDistinct !== true
323
- || portability?.extractedRootCount !== 2 || portability?.extractedRootsDistinct !== true
329
+ if (portability?.deterministicPackRuns !== 2
330
+ || !/^[a-f0-9]{64}$/.test(portability?.deterministicTarballSha256 ?? "")
331
+ || portability?.secondTarballSha256 !== portability?.deterministicTarballSha256
332
+ || portability?.constructionRootCount !== 2 || portability?.constructionRootsDistinct !== true
333
+ || portability?.extractedRootCount !== 1 || portability?.extractedRootsDistinct !== true
324
334
  || portability?.forbiddenPathMatches?.length !== 0 || !/^[a-f0-9]{64}$/.test(portability?.contentSha256 ?? "")) {
325
335
  violations.push("extracted package portability evidence is incomplete or failed");
326
336
  }
@@ -390,6 +400,12 @@ function validateExecutedArtifactSemantics(manifest, violations) {
390
400
  || canonicalObservationJson(Object.keys(parity.source).sort()) !== canonicalObservationJson(["clean", "partial", "v2", "v3"])) {
391
401
  violations.push("source and extracted package runtime classification parity failed");
392
402
  }
403
+ if (parity?.packageArtifact?.filename !== manifest.packageArtifact?.filename
404
+ || parity?.packageArtifact?.integrity !== manifest.packageArtifact?.integrity
405
+ || parity?.packageArtifact?.shasum !== manifest.packageArtifact?.shasum
406
+ || parity?.packageArtifact?.tarballSha256 !== manifest.packageArtifact?.tarballSha256) {
407
+ violations.push("source integration package artifact differs from the package owner artifact");
408
+ }
393
409
  const missing = records.get("bootstrap.missing-surface")?.content;
394
410
  if (!Array.isArray(missing) || missing.length !== DEVELOPMENT_RUNTIME_REQUIRED_FILES.length * 2
395
411
  || new Set(missing.map((entry) => `${entry.runtime}/${entry.relative}`)).size !== missing.length
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentera",
3
- "version": "3.0.0-dev.51",
3
+ "version": "3.0.0-dev.69",
4
4
  "description": "One CLI, many capabilities: project state, artifact validation, and capability routing for AI coding agents",
5
5
  "keywords": [
6
6
  "agentera",
@@ -36,13 +36,17 @@
36
36
  "test:stress": "node scripts/verify-lane.mjs stress",
37
37
  "test:performance": "node scripts/verify-lane.mjs performance",
38
38
  "test:performance:integration": "node test/integration/performanceOwner.integration.mjs",
39
+ "test:capacity": "node scripts/verify-lane.mjs capacity",
39
40
  "test:watch": "vp test watch --config vite.config.ts",
40
41
  "verify:package": "node scripts/verify-lane.mjs package",
41
42
  "verify:generated-overlap": "node scripts/verify-generated-overlap.mjs",
42
43
  "generated:cleanup": "node scripts/build-package.mjs --cleanup",
43
44
  "pack:dry-run": "node scripts/pack-package.mjs --dry-run",
44
45
  "release:prepare": "node scripts/publication-transaction.mjs prepare development",
46
+ "release:prepare:push": "node scripts/publication-transaction.mjs prepare-push development",
47
+ "release:validate:push": "node scripts/publication-transaction.mjs validate-push development",
45
48
  "release:qualify:source": "node scripts/release-qualification.mjs source",
49
+ "release:ready": "node scripts/release-readiness.mjs development",
46
50
  "release:qualify:candidate": "node scripts/release-qualification.mjs candidate --adapter development",
47
51
  "release:approve": "node scripts/release-qualification.mjs approval --adapter development",
48
52
  "release:attest": "node scripts/release-qualification.mjs attest --adapter development",
@@ -63,20 +67,21 @@
63
67
  "bundle:data": "node scripts/build-package.mjs"
64
68
  },
65
69
  "dependencies": {
66
- "smol-toml": "^1.3.1",
70
+ "smol-toml": "^1.7.1",
67
71
  "yaml": "^2.8.3"
68
72
  },
69
73
  "devDependencies": {
70
74
  "@types/node": "^22.10.0",
71
- "typescript": "^5.7.2",
72
- "vite": "^6.3.5",
73
- "vite-plus": "^0.1.22"
75
+ "@typescript/typescript6": "6.0.2",
76
+ "typescript": "^7.0.2",
77
+ "vite": "^8.2.1",
78
+ "vite-plus": "^0.2.8"
74
79
  },
75
80
  "engines": {
76
81
  "node": ">=22"
77
82
  },
78
83
  "agentera": {
79
84
  "suiteVersion": "3.0.0",
80
- "gitRef": "a70ed56a72d633f3f11e94cede11fe4aadba2d2e"
85
+ "gitRef": "cb8746e8eaec765d3b7a0a82cc561656caca33e9"
81
86
  }
82
87
  }