agentera 3.0.0-dev.22 → 3.0.0-dev.25
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 +9 -5
- package/bundle/.cursor/agents/agentera.md +1 -1
- package/bundle/.opencode/agents/agentera.md +1 -1
- package/bundle/CHANGELOG.md +15 -5
- package/bundle/README.md +9 -8
- package/bundle/UPGRADE.md +10 -24
- package/bundle/agents/openai.yaml +1 -1
- package/bundle/references/adapters/package-manifest-interface-model.yaml +2 -0
- package/bundle/references/adapters/package-registry.yaml +9 -0
- package/bundle/references/artifacts/state-storage-authority.yaml +842 -15
- package/bundle/references/cli/agent-ready-state-contract.yaml +25 -17
- package/bundle/references/cli/prime-consumer-compatibility.yaml +676 -0
- package/bundle/references/cli/update-channels.yaml +4 -2
- package/bundle/references/cli/vocabulary-index.yaml +3 -3
- package/bundle/references/cli/vocabulary.md +14 -7
- package/bundle/skills/agentera/SKILL.md +35 -20
- package/bundle/skills/agentera/agents/audit.toml +1 -1
- package/bundle/skills/agentera/agents/build.toml +1 -1
- package/bundle/skills/agentera/agents/design.toml +1 -1
- package/bundle/skills/agentera/agents/discuss.toml +1 -1
- package/bundle/skills/agentera/agents/document.toml +1 -1
- package/bundle/skills/agentera/agents/optimize.toml +1 -1
- package/bundle/skills/agentera/agents/orchestrate.toml +1 -1
- package/bundle/skills/agentera/agents/plan.toml +1 -1
- package/bundle/skills/agentera/agents/profile.toml +1 -1
- package/bundle/skills/agentera/agents/research.toml +1 -1
- package/bundle/skills/agentera/agents/status.toml +1 -1
- package/bundle/skills/agentera/agents/vision.toml +1 -1
- package/bundle/skills/agentera/capabilities/audit/schemas/artifacts.yaml +12 -12
- package/bundle/skills/agentera/capabilities/audit/schemas/validation.yaml +2 -2
- package/bundle/skills/agentera/capabilities/build/schemas/artifacts.yaml +12 -12
- package/bundle/skills/agentera/capabilities/build/schemas/validation.yaml +8 -8
- package/bundle/skills/agentera/capabilities/design/schemas/artifacts.yaml +6 -6
- package/bundle/skills/agentera/capabilities/discuss/schemas/artifacts.yaml +7 -7
- package/bundle/skills/agentera/capabilities/document/schemas/artifacts.yaml +12 -12
- package/bundle/skills/agentera/capabilities/optimize/schemas/artifacts.yaml +9 -9
- package/bundle/skills/agentera/capabilities/orchestrate/schemas/artifacts.yaml +11 -11
- package/bundle/skills/agentera/capabilities/plan/schemas/artifacts.yaml +9 -9
- package/bundle/skills/agentera/capabilities/profile/schemas/artifacts.yaml +2 -2
- package/bundle/skills/agentera/capabilities/research/schemas/artifacts.yaml +3 -3
- package/bundle/skills/agentera/capabilities/status/schemas/artifacts.yaml +11 -11
- package/bundle/skills/agentera/capabilities/vision/schemas/artifacts.yaml +8 -8
- package/bundle/skills/agentera/schemas/artifacts/decisions.yaml +15 -2
- package/bundle/skills/agentera/schemas/artifacts/docs.yaml +4 -1
- package/bundle/skills/agentera/schemas/artifacts/experiments.yaml +21 -21
- package/bundle/skills/agentera/schemas/artifacts/health.yaml +15 -2
- package/bundle/skills/agentera/schemas/artifacts/plan.yaml +36 -15
- package/bundle/skills/agentera/schemas/artifacts/progress.yaml +15 -2
- package/bundle/skills/agentera/schemas/artifacts/todo.yaml +4 -4
- package/dist/capabilities/audit/instructions.js +13 -1
- package/dist/capabilities/audit/instructions.js.map +1 -1
- package/dist/capabilities/build/instructions.js +14 -1
- package/dist/capabilities/build/instructions.js.map +1 -1
- package/dist/capabilities/discuss/instructions.js +11 -1
- package/dist/capabilities/discuss/instructions.js.map +1 -1
- package/dist/capabilities/document/instructions.js +9 -1
- package/dist/capabilities/document/instructions.js.map +1 -1
- package/dist/capabilities/index.js +9 -8
- package/dist/capabilities/index.js.map +1 -1
- package/dist/capabilities/optimize/instructions.js +10 -1
- package/dist/capabilities/optimize/instructions.js.map +1 -1
- package/dist/capabilities/orchestrate/instructions.js +13 -2
- package/dist/capabilities/orchestrate/instructions.js.map +1 -1
- package/dist/capabilities/plan/instructions.js +10 -1
- package/dist/capabilities/plan/instructions.js.map +1 -1
- package/dist/capabilities/status/startupInstructions.js +35 -0
- package/dist/capabilities/status/startupInstructions.js.map +1 -0
- package/dist/cli/capabilityContext/build.js +3 -3
- package/dist/cli/capabilityContext/build.js.map +1 -1
- package/dist/cli/capabilityContext/closeout.js +5 -5
- package/dist/cli/capabilityContext/closeout.js.map +1 -1
- package/dist/cli/capabilityContext/contract.js +14 -19
- package/dist/cli/capabilityContext/contract.js.map +1 -1
- package/dist/cli/capabilityContext/evidence.js +7 -7
- package/dist/cli/capabilityContext/evidence.js.map +1 -1
- package/dist/cli/capabilityContext/planState.js +12 -11
- package/dist/cli/capabilityContext/planState.js.map +1 -1
- package/dist/cli/capabilityContext/progress.js +1 -1
- package/dist/cli/capabilityContext/progress.js.map +1 -1
- package/dist/cli/capabilityContext/shared.js +8 -2
- package/dist/cli/capabilityContext/shared.js.map +1 -1
- package/dist/cli/capabilityContext/slim.js +2 -1
- package/dist/cli/capabilityContext/slim.js.map +1 -1
- package/dist/cli/capabilityContext/startup.js +22 -11
- package/dist/cli/capabilityContext/startup.js.map +1 -1
- package/dist/cli/capabilityContext/types.js +4 -4
- package/dist/cli/capabilityContext/types.js.map +1 -1
- package/dist/cli/commands/backfill.js +39 -2
- package/dist/cli/commands/backfill.js.map +1 -1
- package/dist/cli/commands/durability.js +34 -1
- package/dist/cli/commands/durability.js.map +1 -1
- package/dist/cli/commands/entityMigrate.js +128 -0
- package/dist/cli/commands/entityMigrate.js.map +1 -0
- package/dist/cli/commands/migrate.js +4 -0
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands/prime/briefOrientation.js +584 -0
- package/dist/cli/commands/prime/briefOrientation.js.map +1 -0
- package/dist/cli/commands/prime/collectEntityOrientation.js +148 -0
- package/dist/cli/commands/prime/collectEntityOrientation.js.map +1 -0
- package/dist/cli/commands/prime/collectOrientationState.js +21 -27
- package/dist/cli/commands/prime/collectOrientationState.js.map +1 -1
- package/dist/cli/commands/prime/orientationOutput.js +118 -24
- package/dist/cli/commands/prime/orientationOutput.js.map +1 -1
- package/dist/cli/commands/prime.js +32 -3
- package/dist/cli/commands/prime.js.map +1 -1
- package/dist/cli/commands/query.js +41 -15
- package/dist/cli/commands/query.js.map +1 -1
- package/dist/cli/commands/schema.js +10 -34
- package/dist/cli/commands/schema.js.map +1 -1
- package/dist/cli/commands/state/decisions.js +13 -0
- package/dist/cli/commands/state/decisions.js.map +1 -1
- package/dist/cli/commands/state/docs.js +38 -0
- package/dist/cli/commands/state/docs.js.map +1 -1
- package/dist/cli/commands/state/experimentRecords.js +82 -0
- package/dist/cli/commands/state/experimentRecords.js.map +1 -1
- package/dist/cli/commands/state/experiments.js +13 -0
- package/dist/cli/commands/state/experiments.js.map +1 -1
- package/dist/cli/commands/state/get.js +69 -2
- package/dist/cli/commands/state/get.js.map +1 -1
- package/dist/cli/commands/state/health.js +13 -0
- package/dist/cli/commands/state/health.js.map +1 -1
- package/dist/cli/commands/state/index.js +9 -0
- package/dist/cli/commands/state/index.js.map +1 -1
- package/dist/cli/commands/state/list.js +40 -7
- package/dist/cli/commands/state/list.js.map +1 -1
- package/dist/cli/commands/state/objective.js +24 -0
- package/dist/cli/commands/state/objective.js.map +1 -1
- package/dist/cli/commands/state/plan.js +17 -2
- package/dist/cli/commands/state/plan.js.map +1 -1
- package/dist/cli/commands/state/planTasks.js +38 -25
- package/dist/cli/commands/state/planTasks.js.map +1 -1
- package/dist/cli/commands/state/plans.js +32 -16
- package/dist/cli/commands/state/plans.js.map +1 -1
- package/dist/cli/commands/state/progress.js +12 -0
- package/dist/cli/commands/state/progress.js.map +1 -1
- package/dist/cli/commands/state/shared.js.map +1 -1
- package/dist/cli/commands/state/todo.js +30 -0
- package/dist/cli/commands/state/todo.js.map +1 -1
- package/dist/cli/commands/state/write.js +79 -4
- package/dist/cli/commands/state/write.js.map +1 -1
- package/dist/cli/commands/upgrade.js +65 -31
- package/dist/cli/commands/upgrade.js.map +1 -1
- package/dist/cli/commands/upgradeVerify.js +46 -14
- package/dist/cli/commands/upgradeVerify.js.map +1 -1
- package/dist/cli/commands/validate.js +65 -0
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/dispatch/check.js +8 -1
- package/dist/cli/dispatch/check.js.map +1 -1
- package/dist/cli/dispatch/index.js +6 -0
- package/dist/cli/dispatch/index.js.map +1 -1
- package/dist/cli/dispatch/lifecycle.js +2 -5
- package/dist/cli/dispatch/lifecycle.js.map +1 -1
- package/dist/cli/dispatch/prime.js +15 -0
- package/dist/cli/dispatch/prime.js.map +1 -1
- package/dist/cli/dispatch/state.js +7 -1
- package/dist/cli/dispatch/state.js.map +1 -1
- package/dist/cli/help.js +79 -21
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/migrationRequired.js +84 -0
- package/dist/cli/migrationRequired.js.map +1 -0
- package/dist/cli/orientation/attention.js +2 -2
- package/dist/cli/orientation/attention.js.map +1 -1
- package/dist/cli/orientation.js +13 -10
- package/dist/cli/orientation.js.map +1 -1
- package/dist/cli/planArtifacts.js +192 -42
- package/dist/cli/planArtifacts.js.map +1 -1
- package/dist/cli/prime-blob.js +5 -5
- package/dist/cli/prime-blob.js.map +1 -1
- package/dist/cli/startupCompletenessContract.js +3 -3
- package/dist/cli/startupCompletenessContract.js.map +1 -1
- package/dist/cli/stateQuery.js +42 -5
- package/dist/cli/stateQuery.js.map +1 -1
- package/dist/hooks/compaction/status.js +25 -1
- package/dist/hooks/compaction/status.js.map +1 -1
- package/dist/hooks/cursorSessionStart.js +6 -0
- package/dist/hooks/cursorSessionStart.js.map +1 -1
- package/dist/hooks/sessionStart.js +62 -0
- package/dist/hooks/sessionStart.js.map +1 -1
- package/dist/registries/artifactRegistry.js +23 -14
- package/dist/registries/artifactRegistry.js.map +1 -1
- package/dist/registries/packageRegistry.js +1 -1
- package/dist/registries/packageRegistry.js.map +1 -1
- package/dist/state/archivePublication.js +3 -2
- package/dist/state/archivePublication.js.map +1 -1
- package/dist/state/decisionEntities.js +279 -0
- package/dist/state/decisionEntities.js.map +1 -0
- package/dist/state/decisionLegacyValidation.js +185 -0
- package/dist/state/decisionLegacyValidation.js.map +1 -0
- package/dist/state/decisionOverlay.js +26 -3
- package/dist/state/decisionOverlay.js.map +1 -1
- package/dist/state/decisionRevision.js +632 -0
- package/dist/state/decisionRevision.js.map +1 -0
- package/dist/state/decisionRevisionPublication.js +532 -0
- package/dist/state/decisionRevisionPublication.js.map +1 -0
- package/dist/state/directRetrieval.js +55 -4
- package/dist/state/directRetrieval.js.map +1 -1
- package/dist/state/durability.js +92 -1
- package/dist/state/durability.js.map +1 -1
- package/dist/state/entityCutover.js +390 -0
- package/dist/state/entityCutover.js.map +1 -0
- package/dist/state/entityCutoverGit.js +128 -0
- package/dist/state/entityCutoverGit.js.map +1 -0
- package/dist/state/entityMigrationPreview.js +803 -0
- package/dist/state/entityMigrationPreview.js.map +1 -0
- package/dist/state/entityPublicationContext.js +612 -0
- package/dist/state/entityPublicationContext.js.map +1 -0
- package/dist/state/entityStorage.js +807 -0
- package/dist/state/entityStorage.js.map +1 -0
- package/dist/state/experimentIdentity.js +23 -11
- package/dist/state/experimentIdentity.js.map +1 -1
- package/dist/state/gitBackfill.js.map +1 -1
- package/dist/state/healthEntities.js +227 -0
- package/dist/state/healthEntities.js.map +1 -0
- package/dist/state/healthEntityValidation.js +6 -0
- package/dist/state/healthEntityValidation.js.map +1 -0
- package/dist/state/legacyEntityCutoverEvidence.js +66 -0
- package/dist/state/legacyEntityCutoverEvidence.js.map +1 -0
- package/dist/state/listRetrieval.js +42 -11
- package/dist/state/listRetrieval.js.map +1 -1
- package/dist/state/objectiveExperimentEntities.js +321 -0
- package/dist/state/objectiveExperimentEntities.js.map +1 -0
- package/dist/state/planEntities.js +358 -0
- package/dist/state/planEntities.js.map +1 -0
- package/dist/state/progressEntities.js +382 -0
- package/dist/state/progressEntities.js.map +1 -0
- package/dist/state/projectRoot.js +63 -0
- package/dist/state/projectRoot.js.map +1 -0
- package/dist/state/projectionRecovery.js +458 -0
- package/dist/state/projectionRecovery.js.map +1 -0
- package/dist/state/retrievalAuthority.js +13 -6
- package/dist/state/retrievalAuthority.js.map +1 -1
- package/dist/state/safeProjectFile.js +153 -0
- package/dist/state/safeProjectFile.js.map +1 -0
- package/dist/state/startupProjection.js +68 -1
- package/dist/state/startupProjection.js.map +1 -1
- package/dist/state/stateMode.js +76 -0
- package/dist/state/stateMode.js.map +1 -0
- package/dist/state/todoDocsEntities.js +223 -0
- package/dist/state/todoDocsEntities.js.map +1 -0
- package/dist/state/todoDocsEntityValidation.js +26 -0
- package/dist/state/todoDocsEntityValidation.js.map +1 -0
- package/dist/state/write/candidateMutation.js +281 -0
- package/dist/state/write/candidateMutation.js.map +1 -0
- package/dist/state/write/explain.js +156 -33
- package/dist/state/write/explain.js.map +1 -1
- package/dist/state/write/helpers.js +22 -0
- package/dist/state/write/helpers.js.map +1 -1
- package/dist/state/write/lock.js +794 -87
- package/dist/state/write/lock.js.map +1 -1
- package/dist/state/write/mutation.js +47 -2
- package/dist/state/write/mutation.js.map +1 -1
- package/dist/state/write/operations.js +99 -6
- package/dist/state/write/operations.js.map +1 -1
- package/dist/state/write/planEvaluation.js +107 -0
- package/dist/state/write/planEvaluation.js.map +1 -0
- package/dist/state/write/planPublication.js +11 -55
- package/dist/state/write/planPublication.js.map +1 -1
- package/dist/state/write/transaction.js +111 -358
- package/dist/state/write/transaction.js.map +1 -1
- package/dist/upgrade/compatibility.js +4 -4
- package/dist/upgrade/compatibility.js.map +1 -1
- package/dist/upgrade/migrateArtifactsV2ToV3.js +13 -14
- package/dist/upgrade/migrateArtifactsV2ToV3.js.map +1 -1
- package/dist/upgrade/upgradeOrchestrator.js +126 -23
- package/dist/upgrade/upgradeOrchestrator.js.map +1 -1
- package/dist/validate/crossCapability.js +2 -2
- package/dist/validate/crossCapability.js.map +1 -1
- package/dist/validate/lifecycleAdapters/lifecycleMain.js +154 -0
- package/dist/validate/lifecycleAdapters/lifecycleMain.js.map +1 -0
- package/dist/validate/lifecycleAdapters.js +5 -156
- package/dist/validate/lifecycleAdapters.js.map +1 -1
- package/package.json +3 -3
- package/dist/upgrade/upgradeSnapshot.js +0 -93
- package/dist/upgrade/upgradeSnapshot.js.map +0 -1
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { dumpYamlMapping, loadYamlMapping } from "../core/yaml.js";
|
|
5
|
+
import { writeFileAtomic } from "../upgrade/atomicWriter.js";
|
|
6
|
+
import { canonicalRecordJson } from "./archiveDiscovery.js";
|
|
7
|
+
import { verifyEntityCutoverGitSource } from "./entityCutoverGit.js";
|
|
8
|
+
import { canonicalEntityEnvelopeBytes, validateEntityState } from "./entityStorage.js";
|
|
9
|
+
import { planEntityMigration, validateEntityMigrationTargets } from "./entityMigrationPreview.js";
|
|
10
|
+
import { loadLegacyEntityCutoverTargets } from "./legacyEntityCutoverEvidence.js";
|
|
11
|
+
import { validateRealProjectRoot } from "./projectRoot.js";
|
|
12
|
+
import { readProjectFileSnapshot } from "./safeProjectFile.js";
|
|
13
|
+
import { acquireWriterLock } from "./write/lock.js";
|
|
14
|
+
export const MIGRATION_ROOT = ".agentera/migrations/entities";
|
|
15
|
+
export const MIGRATION_STAGING = `${MIGRATION_ROOT}/staging`;
|
|
16
|
+
export const FORWARD_MANIFEST = `${MIGRATION_ROOT}/forward.yaml`;
|
|
17
|
+
export const ENTITY_MODE_MARKER = ".agentera/state-mode.yaml";
|
|
18
|
+
const STAGING_PROJECT = `${MIGRATION_STAGING}/project`;
|
|
19
|
+
const MANIFEST_SCHEMA = "agentera.entityCutoverManifest.v1";
|
|
20
|
+
const MARKER_BYTES = dumpYamlMapping({ schemaVersion: "agentera.stateMode.v1", mode: "entities", cutover: "one_way_git" });
|
|
21
|
+
const SHA256 = /^[a-f0-9]{64}$/;
|
|
22
|
+
export class EntityCutoverError extends Error {
|
|
23
|
+
constructor(message) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.name = "EntityCutoverError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function hash(bytes) {
|
|
29
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
30
|
+
}
|
|
31
|
+
function mapping(value) {
|
|
32
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
33
|
+
}
|
|
34
|
+
function exactKeys(value, expected) {
|
|
35
|
+
return canonicalRecordJson(Object.keys(value).sort()) === canonicalRecordJson([...expected].sort());
|
|
36
|
+
}
|
|
37
|
+
function safeTarget(value) {
|
|
38
|
+
return value.startsWith(".agentera/entities/")
|
|
39
|
+
&& !path.isAbsolute(value)
|
|
40
|
+
&& !value.includes("\\")
|
|
41
|
+
&& value.split("/").every((part) => part !== "" && part !== "." && part !== "..");
|
|
42
|
+
}
|
|
43
|
+
function markerSnapshot(project) {
|
|
44
|
+
return readProjectFileSnapshot(validateRealProjectRoot(project), ENTITY_MODE_MARKER);
|
|
45
|
+
}
|
|
46
|
+
function manifestBytes(manifest) {
|
|
47
|
+
return dumpYamlMapping(manifest);
|
|
48
|
+
}
|
|
49
|
+
function parseForwardManifest(bytes) {
|
|
50
|
+
const value = loadYamlMapping(bytes.toString("utf8"));
|
|
51
|
+
if (!exactKeys(value, ["schemaVersion", "phase", "source", "targets", "marker"])
|
|
52
|
+
|| value.schemaVersion !== MANIFEST_SCHEMA
|
|
53
|
+
|| !["publishing_entities", "entities_published"].includes(String(value.phase))
|
|
54
|
+
|| !mapping(value.source)
|
|
55
|
+
|| !exactKeys(value.source, ["head", "source_fingerprint", "preview_digest"])
|
|
56
|
+
|| typeof value.source.head !== "string"
|
|
57
|
+
|| !/^[a-f0-9]{40,64}$/.test(value.source.head)
|
|
58
|
+
|| typeof value.source.source_fingerprint !== "string"
|
|
59
|
+
|| !SHA256.test(value.source.source_fingerprint)
|
|
60
|
+
|| typeof value.source.preview_digest !== "string"
|
|
61
|
+
|| !SHA256.test(value.source.preview_digest)
|
|
62
|
+
|| !mapping(value.marker)
|
|
63
|
+
|| !exactKeys(value.marker, ["path", "sha256"])
|
|
64
|
+
|| value.marker.path !== ENTITY_MODE_MARKER
|
|
65
|
+
|| value.marker.sha256 !== hash(MARKER_BYTES)
|
|
66
|
+
|| !Array.isArray(value.targets)) {
|
|
67
|
+
throw new EntityCutoverError(`forward cutover manifest '${FORWARD_MANIFEST}' is invalid`);
|
|
68
|
+
}
|
|
69
|
+
const targets = value.targets.map((raw) => {
|
|
70
|
+
if (!mapping(raw) || !exactKeys(raw, ["path", "sha256"]) || typeof raw.path !== "string" || !safeTarget(raw.path) || typeof raw.sha256 !== "string" || !SHA256.test(raw.sha256)) {
|
|
71
|
+
throw new EntityCutoverError(`forward cutover manifest '${FORWARD_MANIFEST}' has an invalid target`);
|
|
72
|
+
}
|
|
73
|
+
return { path: raw.path, sha256: raw.sha256 };
|
|
74
|
+
});
|
|
75
|
+
if (new Set(targets.map(({ path: target }) => target)).size !== targets.length
|
|
76
|
+
|| canonicalRecordJson([...targets].sort((a, b) => a.path.localeCompare(b.path))) !== canonicalRecordJson(targets)) {
|
|
77
|
+
throw new EntityCutoverError(`forward cutover manifest '${FORWARD_MANIFEST}' targets must be unique and sorted`);
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
schemaVersion: MANIFEST_SCHEMA,
|
|
81
|
+
phase: value.phase,
|
|
82
|
+
source: value.source,
|
|
83
|
+
targets,
|
|
84
|
+
marker: value.marker,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function loadForwardManifest(project) {
|
|
88
|
+
const observed = readProjectFileSnapshot(validateRealProjectRoot(project), FORWARD_MANIFEST);
|
|
89
|
+
if (observed.kind === "missing")
|
|
90
|
+
return null;
|
|
91
|
+
if (observed.kind !== "file")
|
|
92
|
+
throw new EntityCutoverError(`forward cutover manifest '${FORWARD_MANIFEST}' is unsafe`);
|
|
93
|
+
return parseForwardManifest(observed.bytes);
|
|
94
|
+
}
|
|
95
|
+
function targetsForPlan(plan) {
|
|
96
|
+
const targets = plan.entries.map((entry) => {
|
|
97
|
+
const target = entry.proposed_target;
|
|
98
|
+
if (!target || typeof target.id !== "string" || typeof entry.artifact !== "string" || !safeTarget(target.path))
|
|
99
|
+
throw new EntityCutoverError(`migration source '${entry.source_identity}' has no safe canonical target`);
|
|
100
|
+
const id = target.id;
|
|
101
|
+
const artifact = entry.artifact;
|
|
102
|
+
const bytes = canonicalEntityEnvelopeBytes({ id, artifact, record: entry.record });
|
|
103
|
+
const sha256 = hash(bytes);
|
|
104
|
+
if (entry.target_sha256 !== sha256)
|
|
105
|
+
throw new EntityCutoverError(`migration source '${entry.source_identity}' target digest is not deterministic`);
|
|
106
|
+
return { path: target.path, sha256 };
|
|
107
|
+
}).sort((a, b) => a.path.localeCompare(b.path));
|
|
108
|
+
if (new Set(targets.map(({ path: target }) => target)).size !== targets.length)
|
|
109
|
+
throw new EntityCutoverError("entity cutover target paths are not unique");
|
|
110
|
+
return targets;
|
|
111
|
+
}
|
|
112
|
+
function assertPlanReady(plan, sourceRoot) {
|
|
113
|
+
if (plan.counts.blockers > 0)
|
|
114
|
+
throw new EntityCutoverError(`entity migration inventory has ${plan.counts.blockers} blocker(s); repair the read-only preview before upgrade`);
|
|
115
|
+
const invalid = validateEntityMigrationTargets(plan.project, plan.entries, sourceRoot)[0];
|
|
116
|
+
if (invalid)
|
|
117
|
+
throw new EntityCutoverError(`mapped record '${invalid.sourceIdentity}' is invalid: ${invalid.message}`);
|
|
118
|
+
}
|
|
119
|
+
function listFiles(project, relativeRoot) {
|
|
120
|
+
const absoluteRoot = path.join(project, relativeRoot);
|
|
121
|
+
if (!fs.existsSync(absoluteRoot))
|
|
122
|
+
return [];
|
|
123
|
+
const rootStat = fs.lstatSync(absoluteRoot);
|
|
124
|
+
if (!rootStat.isDirectory() || rootStat.isSymbolicLink() || fs.realpathSync(absoluteRoot) !== absoluteRoot)
|
|
125
|
+
throw new EntityCutoverError(`cutover path '${relativeRoot}' must be a real project directory`);
|
|
126
|
+
const found = [];
|
|
127
|
+
const visit = (directory) => {
|
|
128
|
+
for (const entry of fs.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
129
|
+
const absolute = path.join(directory, entry.name);
|
|
130
|
+
const relative = path.relative(project, absolute).split(path.sep).join("/");
|
|
131
|
+
if (entry.isSymbolicLink())
|
|
132
|
+
throw new EntityCutoverError(`cutover path '${relative}' must not be a symbolic link`);
|
|
133
|
+
if (entry.isDirectory()) {
|
|
134
|
+
if (fs.realpathSync(absolute) !== absolute)
|
|
135
|
+
throw new EntityCutoverError(`cutover directory '${relative}' is unsafe`);
|
|
136
|
+
visit(absolute);
|
|
137
|
+
}
|
|
138
|
+
else if (entry.isFile())
|
|
139
|
+
found.push(relative);
|
|
140
|
+
else
|
|
141
|
+
throw new EntityCutoverError(`cutover path '${relative}' must be a regular file or directory`);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
visit(absoluteRoot);
|
|
145
|
+
return found.sort();
|
|
146
|
+
}
|
|
147
|
+
function validateExistingCanonicalTargets(project, targets, requireAll) {
|
|
148
|
+
const expected = new Map(targets.map((target) => [target.path, target]));
|
|
149
|
+
for (const relative of listFiles(project, ".agentera/entities")) {
|
|
150
|
+
const target = expected.get(relative);
|
|
151
|
+
if (!target)
|
|
152
|
+
throw new EntityCutoverError(`canonical entity '${relative}' is outside the bounded forward manifest`);
|
|
153
|
+
}
|
|
154
|
+
for (const target of targets) {
|
|
155
|
+
const observed = readProjectFileSnapshot(validateRealProjectRoot(project), target.path);
|
|
156
|
+
if (observed.kind === "missing") {
|
|
157
|
+
if (requireAll)
|
|
158
|
+
throw new EntityCutoverError(`canonical entity '${target.path}' is missing after entity publication`);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (observed.kind !== "file" || hash(observed.bytes) !== target.sha256)
|
|
162
|
+
throw new EntityCutoverError(`canonical entity '${target.path}' diverges from the bounded forward manifest`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function assertManifestMatchesPlan(manifest, plan, head, targets) {
|
|
166
|
+
if ((head !== null && manifest.source.head !== head)
|
|
167
|
+
|| manifest.source.source_fingerprint !== plan.source_fingerprint
|
|
168
|
+
|| manifest.source.preview_digest !== plan.preview_digest
|
|
169
|
+
|| canonicalRecordJson(manifest.targets) !== canonicalRecordJson(targets)) {
|
|
170
|
+
throw new EntityCutoverError("forward cutover manifest does not match the current Git-pinned migration source");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function validateActiveEntityCutover(project, markerBytes, sourceRoot) {
|
|
174
|
+
const targets = loadEntityCutoverTargetsForMarker(project, markerBytes);
|
|
175
|
+
const result = validateEntityState(project, sourceRoot);
|
|
176
|
+
if (!result.valid)
|
|
177
|
+
throw new EntityCutoverError(`active entity state is invalid: ${result.issues.map(({ message }) => message).join("; ")}`);
|
|
178
|
+
const byPath = new Map(result.entities.map((entity) => [entity.relativePath, entity]));
|
|
179
|
+
for (const target of targets) {
|
|
180
|
+
const entity = byPath.get(target.path);
|
|
181
|
+
if (!entity || entity.classification !== "valid" || (target.id && entity.id !== target.id) || (target.artifact && entity.artifact !== target.artifact)) {
|
|
182
|
+
throw new EntityCutoverError(`active entity target '${target.path}' is missing or invalid`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return result.entityCount;
|
|
186
|
+
}
|
|
187
|
+
export function loadEntityCutoverTargetsForMarker(projectRoot, bytes) {
|
|
188
|
+
const project = validateRealProjectRoot(projectRoot).path;
|
|
189
|
+
const marker = loadYamlMapping(bytes.toString("utf8"));
|
|
190
|
+
if (marker.schemaVersion !== "agentera.stateMode.v1" || marker.mode !== "entities")
|
|
191
|
+
throw new EntityCutoverError("state marker is not valid entity authority");
|
|
192
|
+
if (marker.cutover === "one_way_git") {
|
|
193
|
+
const manifest = loadForwardManifest(project);
|
|
194
|
+
if (!manifest || manifest.phase !== "entities_published" || manifest.marker.sha256 !== hash(bytes))
|
|
195
|
+
throw new EntityCutoverError("one-way entity marker has no matching completed forward manifest");
|
|
196
|
+
return manifest.targets;
|
|
197
|
+
}
|
|
198
|
+
if (typeof marker.migration_id === "string")
|
|
199
|
+
return loadLegacyEntityCutoverTargets(project, bytes);
|
|
200
|
+
throw new EntityCutoverError("entity marker has no supported one-way or historical cutover binding");
|
|
201
|
+
}
|
|
202
|
+
function inspect(projectRoot, sourceRoot, requireGit, writerLockHeld = false) {
|
|
203
|
+
const project = validateRealProjectRoot(projectRoot).path;
|
|
204
|
+
const marker = markerSnapshot(project);
|
|
205
|
+
if (marker.kind === "file")
|
|
206
|
+
return { inspection: { phase: "active", entityCount: validateActiveEntityCutover(project, marker.bytes, sourceRoot) } };
|
|
207
|
+
if (marker.kind !== "missing")
|
|
208
|
+
throw new EntityCutoverError(`state marker '${ENTITY_MODE_MARKER}' is unsafe`);
|
|
209
|
+
const plan = planEntityMigration(project, sourceRoot);
|
|
210
|
+
assertPlanReady(plan, sourceRoot);
|
|
211
|
+
const targets = targetsForPlan(plan);
|
|
212
|
+
const manifest = loadForwardManifest(project);
|
|
213
|
+
if (manifest)
|
|
214
|
+
assertManifestMatchesPlan(manifest, plan, null, targets);
|
|
215
|
+
validateExistingCanonicalTargets(project, targets, manifest?.phase === "entities_published");
|
|
216
|
+
if (!manifest && listFiles(project, ".agentera/entities").length > 0)
|
|
217
|
+
throw new EntityCutoverError("canonical entity state exists without the bounded forward manifest");
|
|
218
|
+
let head;
|
|
219
|
+
if (requireGit) {
|
|
220
|
+
const allowedPaths = new Set([FORWARD_MANIFEST, ENTITY_MODE_MARKER]);
|
|
221
|
+
if (manifest)
|
|
222
|
+
for (const target of targets)
|
|
223
|
+
allowedPaths.add(target.path);
|
|
224
|
+
const binding = verifyEntityCutoverGitSource(project, plan, { paths: allowedPaths, prefixes: [MIGRATION_STAGING, ...(writerLockHeld ? [".agentera/.writer.lock"] : [])] });
|
|
225
|
+
head = binding.head;
|
|
226
|
+
if (manifest)
|
|
227
|
+
assertManifestMatchesPlan(manifest, plan, head, targets);
|
|
228
|
+
}
|
|
229
|
+
return { inspection: { phase: manifest?.phase ?? "ready", entityCount: targets.length }, plan, ...(head ? { head } : {}) };
|
|
230
|
+
}
|
|
231
|
+
export function inspectEntityCutoverForUpgrade(projectRoot, sourceRoot, requireGit = false) {
|
|
232
|
+
return inspect(projectRoot, sourceRoot, requireGit).inspection;
|
|
233
|
+
}
|
|
234
|
+
export function prepareEntityCutoverForUpgrade(projectRoot, sourceRoot) {
|
|
235
|
+
const current = inspect(projectRoot, sourceRoot, true);
|
|
236
|
+
if (current.inspection.phase === "active" || !current.plan || !current.head)
|
|
237
|
+
throw new EntityCutoverError("entity authority is already active; no cutover preparation is available");
|
|
238
|
+
return { project: current.plan.project, sourceRoot, head: current.head, sourceFingerprint: current.plan.source_fingerprint, previewDigest: current.plan.preview_digest };
|
|
239
|
+
}
|
|
240
|
+
function ensureDirectory(project, relativeDirectory) {
|
|
241
|
+
let current = project;
|
|
242
|
+
for (const segment of relativeDirectory.split("/").filter(Boolean)) {
|
|
243
|
+
current = path.join(current, segment);
|
|
244
|
+
if (!fs.existsSync(current))
|
|
245
|
+
fs.mkdirSync(current, { mode: 0o700 });
|
|
246
|
+
const stat = fs.lstatSync(current);
|
|
247
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || fs.realpathSync(current) !== current)
|
|
248
|
+
throw new EntityCutoverError(`cutover directory '${path.relative(project, current)}' is unsafe`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function removeStaging(project) {
|
|
252
|
+
const staging = path.join(project, MIGRATION_STAGING);
|
|
253
|
+
if (!fs.existsSync(staging))
|
|
254
|
+
return;
|
|
255
|
+
const stat = fs.lstatSync(staging);
|
|
256
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || fs.realpathSync(staging) !== staging)
|
|
257
|
+
throw new EntityCutoverError(`known cutover staging '${MIGRATION_STAGING}' is unsafe and was not removed`);
|
|
258
|
+
fs.rmSync(staging, { recursive: true });
|
|
259
|
+
}
|
|
260
|
+
function writeDurable(file, bytes) {
|
|
261
|
+
const fd = fs.openSync(file, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | (fs.constants.O_NOFOLLOW ?? 0), 0o600);
|
|
262
|
+
try {
|
|
263
|
+
fs.writeFileSync(fd, bytes);
|
|
264
|
+
fs.fsyncSync(fd);
|
|
265
|
+
}
|
|
266
|
+
finally {
|
|
267
|
+
fs.closeSync(fd);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function buildStaging(project, sourceRoot, plan, manifest) {
|
|
271
|
+
removeStaging(project);
|
|
272
|
+
ensureDirectory(project, STAGING_PROJECT);
|
|
273
|
+
for (const entry of plan.entries) {
|
|
274
|
+
const target = entry.proposed_target;
|
|
275
|
+
if (typeof target.id !== "string" || typeof entry.artifact !== "string")
|
|
276
|
+
throw new EntityCutoverError(`migration source '${entry.source_identity}' has no canonical identity`);
|
|
277
|
+
const id = target.id;
|
|
278
|
+
const artifact = entry.artifact;
|
|
279
|
+
const staged = path.join(project, STAGING_PROJECT, target.path);
|
|
280
|
+
ensureDirectory(project, path.relative(project, path.dirname(staged)).split(path.sep).join("/"));
|
|
281
|
+
writeDurable(staged, canonicalEntityEnvelopeBytes({ id, artifact, record: entry.record }));
|
|
282
|
+
}
|
|
283
|
+
const validation = validateEntityState(path.join(project, STAGING_PROJECT), sourceRoot);
|
|
284
|
+
if (!validation.valid || validation.entityCount !== manifest.targets.length)
|
|
285
|
+
throw new EntityCutoverError(`staged entity graph is invalid (${validation.entityCount}/${manifest.targets.length})`);
|
|
286
|
+
writeDurable(path.join(project, MIGRATION_STAGING, "forward.yaml"), manifestBytes(manifest));
|
|
287
|
+
fault("staging_built");
|
|
288
|
+
}
|
|
289
|
+
function publishForwardManifest(project) {
|
|
290
|
+
ensureDirectory(project, MIGRATION_ROOT);
|
|
291
|
+
const target = path.join(project, FORWARD_MANIFEST);
|
|
292
|
+
if (fs.existsSync(target))
|
|
293
|
+
throw new EntityCutoverError(`forward cutover manifest '${FORWARD_MANIFEST}' already exists`);
|
|
294
|
+
fs.renameSync(path.join(project, MIGRATION_STAGING, "forward.yaml"), target);
|
|
295
|
+
fault("manifest_published");
|
|
296
|
+
}
|
|
297
|
+
function publishCanonicalTargets(project, manifest) {
|
|
298
|
+
for (const target of manifest.targets) {
|
|
299
|
+
const canonical = path.join(project, target.path);
|
|
300
|
+
const observed = readProjectFileSnapshot(validateRealProjectRoot(project), target.path);
|
|
301
|
+
if (observed.kind === "file") {
|
|
302
|
+
if (hash(observed.bytes) !== target.sha256)
|
|
303
|
+
throw new EntityCutoverError(`canonical entity '${target.path}' diverges from the bounded forward manifest`);
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if (observed.kind !== "missing")
|
|
307
|
+
throw new EntityCutoverError(`canonical entity '${target.path}' is unsafe`);
|
|
308
|
+
ensureDirectory(project, path.relative(project, path.dirname(canonical)).split(path.sep).join("/"));
|
|
309
|
+
fs.renameSync(path.join(project, STAGING_PROJECT, target.path), canonical);
|
|
310
|
+
fault("entity_published");
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function validatePublishedGraph(project, sourceRoot, manifest) {
|
|
314
|
+
validateExistingCanonicalTargets(project, manifest.targets, true);
|
|
315
|
+
const validation = validateEntityState(project, sourceRoot);
|
|
316
|
+
if (!validation.valid || validation.entityCount !== manifest.targets.length)
|
|
317
|
+
throw new EntityCutoverError(`published entity graph is invalid (${validation.entityCount}/${manifest.targets.length})`);
|
|
318
|
+
}
|
|
319
|
+
function publishMarker(project) {
|
|
320
|
+
const existing = markerSnapshot(project);
|
|
321
|
+
if (existing.kind === "file") {
|
|
322
|
+
if (!existing.bytes.equals(Buffer.from(MARKER_BYTES)))
|
|
323
|
+
throw new EntityCutoverError(`state marker '${ENTITY_MODE_MARKER}' has unexpected bytes`);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (existing.kind !== "missing")
|
|
327
|
+
throw new EntityCutoverError(`state marker '${ENTITY_MODE_MARKER}' is unsafe`);
|
|
328
|
+
ensureDirectory(project, ".agentera");
|
|
329
|
+
const temporary = path.join(project, `.agentera/.state-mode-${randomUUID()}.tmp`);
|
|
330
|
+
try {
|
|
331
|
+
writeDurable(temporary, MARKER_BYTES);
|
|
332
|
+
if (fs.existsSync(path.join(project, ENTITY_MODE_MARKER)))
|
|
333
|
+
throw new EntityCutoverError(`state marker '${ENTITY_MODE_MARKER}' appeared during publication`);
|
|
334
|
+
fs.renameSync(temporary, path.join(project, ENTITY_MODE_MARKER));
|
|
335
|
+
}
|
|
336
|
+
finally {
|
|
337
|
+
fs.rmSync(temporary, { force: true });
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function fault(phase) {
|
|
341
|
+
if (process.env.NODE_ENV === "test" && process.env.AGENTERA_FAULT_INJECT_ENTITY_MIGRATION_AFTER_PHASE === phase)
|
|
342
|
+
throw new EntityCutoverError(`simulated entity cutover interruption after ${phase}`);
|
|
343
|
+
}
|
|
344
|
+
export function applyPreparedEntityCutover(prepared) {
|
|
345
|
+
const before = inspect(prepared.project, prepared.sourceRoot, true);
|
|
346
|
+
if (before.inspection.phase === "active")
|
|
347
|
+
return { status: "complete", phase: "active", idempotent: true, mutation_performed: false, entity_count: before.inspection.entityCount };
|
|
348
|
+
if (!before.plan || before.head !== prepared.head || before.plan.source_fingerprint !== prepared.sourceFingerprint || before.plan.preview_digest !== prepared.previewDigest)
|
|
349
|
+
throw new EntityCutoverError("Git-pinned entity cutover preparation changed before apply");
|
|
350
|
+
const lock = acquireWriterLock(prepared.project, 2000);
|
|
351
|
+
try {
|
|
352
|
+
const current = inspect(prepared.project, prepared.sourceRoot, true, true);
|
|
353
|
+
if (current.inspection.phase === "active")
|
|
354
|
+
return { status: "complete", phase: "active", idempotent: true, mutation_performed: false, entity_count: current.inspection.entityCount };
|
|
355
|
+
const plan = current.plan;
|
|
356
|
+
if (current.head !== prepared.head || plan.source_fingerprint !== prepared.sourceFingerprint || plan.preview_digest !== prepared.previewDigest)
|
|
357
|
+
throw new EntityCutoverError("Git-pinned entity cutover source changed before its first publication effect");
|
|
358
|
+
const targets = targetsForPlan(plan);
|
|
359
|
+
let manifest = loadForwardManifest(prepared.project);
|
|
360
|
+
if (!manifest) {
|
|
361
|
+
manifest = { schemaVersion: MANIFEST_SCHEMA, phase: "publishing_entities", source: { head: current.head, source_fingerprint: plan.source_fingerprint, preview_digest: plan.preview_digest }, targets, marker: { path: ENTITY_MODE_MARKER, sha256: hash(MARKER_BYTES) } };
|
|
362
|
+
buildStaging(prepared.project, prepared.sourceRoot, plan, manifest);
|
|
363
|
+
publishForwardManifest(prepared.project);
|
|
364
|
+
}
|
|
365
|
+
else if (manifest.phase === "publishing_entities") {
|
|
366
|
+
buildStaging(prepared.project, prepared.sourceRoot, plan, manifest);
|
|
367
|
+
}
|
|
368
|
+
if (manifest.phase === "publishing_entities") {
|
|
369
|
+
publishCanonicalTargets(prepared.project, manifest);
|
|
370
|
+
validatePublishedGraph(prepared.project, prepared.sourceRoot, manifest);
|
|
371
|
+
manifest = { ...manifest, phase: "entities_published" };
|
|
372
|
+
writeFileAtomic(path.join(prepared.project, FORWARD_MANIFEST), manifestBytes(manifest));
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
validatePublishedGraph(prepared.project, prepared.sourceRoot, manifest);
|
|
376
|
+
}
|
|
377
|
+
removeStaging(prepared.project);
|
|
378
|
+
fault("entities_published");
|
|
379
|
+
publishMarker(prepared.project);
|
|
380
|
+
const marker = markerSnapshot(prepared.project);
|
|
381
|
+
if (marker.kind !== "file")
|
|
382
|
+
throw new EntityCutoverError("entity authority marker was not published");
|
|
383
|
+
const entityCount = validateActiveEntityCutover(prepared.project, marker.bytes, prepared.sourceRoot);
|
|
384
|
+
return { status: "complete", phase: "active", idempotent: false, mutation_performed: true, entity_count: entityCount };
|
|
385
|
+
}
|
|
386
|
+
finally {
|
|
387
|
+
lock.release();
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=entityCutover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entityCutover.js","sourceRoot":"","sources":["../../src/state/entityCutover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { validateRealProjectRoot } from "./projectRoot.js";
|
|
6
|
+
import { readProjectFileSnapshot } from "./safeProjectFile.js";
|
|
7
|
+
export class EntityCutoverGitError extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "EntityCutoverGitError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function hash(bytes) {
|
|
14
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
15
|
+
}
|
|
16
|
+
function gitEnvironment() {
|
|
17
|
+
const env = { ...process.env };
|
|
18
|
+
for (const name of ["GIT_INDEX_FILE", "GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR"])
|
|
19
|
+
delete env[name];
|
|
20
|
+
return env;
|
|
21
|
+
}
|
|
22
|
+
function git(project, args, encoding = "utf8") {
|
|
23
|
+
const result = spawnSync("git", args, { cwd: project, env: gitEnvironment(), encoding: encoding ?? "buffer" });
|
|
24
|
+
if (result.error)
|
|
25
|
+
throw new EntityCutoverGitError(`Git preflight failed: ${result.error.message}`);
|
|
26
|
+
return { status: result.status ?? 2, stdout: result.stdout ?? (encoding === null ? Buffer.alloc(0) : "") };
|
|
27
|
+
}
|
|
28
|
+
function gitText(project, args) {
|
|
29
|
+
const result = git(project, args);
|
|
30
|
+
if (result.status !== 0)
|
|
31
|
+
throw new EntityCutoverGitError(`Git preflight command failed: git ${args.join(" ")}`);
|
|
32
|
+
return String(result.stdout).trim();
|
|
33
|
+
}
|
|
34
|
+
function safeRelative(value) {
|
|
35
|
+
return value.length > 0
|
|
36
|
+
&& !value.includes("\0")
|
|
37
|
+
&& !value.includes("\\")
|
|
38
|
+
&& !path.isAbsolute(value)
|
|
39
|
+
&& value.split("/").every((part) => part !== "" && part !== "." && part !== "..");
|
|
40
|
+
}
|
|
41
|
+
function assertCleanTrackedState(project) {
|
|
42
|
+
const working = git(project, ["diff", "--quiet", "--no-ext-diff", "--"]);
|
|
43
|
+
if (working.status === 1)
|
|
44
|
+
throw new EntityCutoverGitError("Git worktree has modified or renamed tracked paths; commit or restore them before v2-to-v3 upgrade");
|
|
45
|
+
if (working.status !== 0)
|
|
46
|
+
throw new EntityCutoverGitError("Git could not verify the working tree before v2-to-v3 upgrade");
|
|
47
|
+
const staged = git(project, ["diff", "--cached", "--quiet", "--no-ext-diff", "HEAD", "--"]);
|
|
48
|
+
if (staged.status === 1)
|
|
49
|
+
throw new EntityCutoverGitError("Git index has staged or renamed paths; commit or restore them before v2-to-v3 upgrade");
|
|
50
|
+
if (staged.status !== 0)
|
|
51
|
+
throw new EntityCutoverGitError("Git could not verify the index before v2-to-v3 upgrade");
|
|
52
|
+
}
|
|
53
|
+
function assertNoUnapprovedUntracked(project, allowlist) {
|
|
54
|
+
const result = git(project, ["ls-files", "--others", "--exclude-standard", "-z"]);
|
|
55
|
+
if (result.status !== 0)
|
|
56
|
+
throw new EntityCutoverGitError("Git could not inventory untracked paths before v2-to-v3 upgrade");
|
|
57
|
+
const paths = new Set(allowlist.paths ?? []);
|
|
58
|
+
const prefixes = [...(allowlist.prefixes ?? [])].map((prefix) => prefix.endsWith("/") ? prefix : `${prefix}/`);
|
|
59
|
+
const unexpected = String(result.stdout).split("\0").filter(Boolean).find((candidate) => !paths.has(candidate) && !prefixes.some((prefix) => candidate.startsWith(prefix)));
|
|
60
|
+
if (unexpected)
|
|
61
|
+
throw new EntityCutoverGitError(`Git worktree has untracked path '${unexpected}'; commit, ignore, or remove it before v2-to-v3 upgrade`);
|
|
62
|
+
}
|
|
63
|
+
function headEntry(project, relativePath) {
|
|
64
|
+
const result = git(project, ["ls-tree", "-z", "HEAD", "--", relativePath]);
|
|
65
|
+
if (result.status !== 0)
|
|
66
|
+
throw new EntityCutoverGitError(`Git could not inspect HEAD path '${relativePath}'`);
|
|
67
|
+
const records = String(result.stdout).split("\0").filter(Boolean);
|
|
68
|
+
if (records.length === 0)
|
|
69
|
+
return null;
|
|
70
|
+
if (records.length !== 1)
|
|
71
|
+
throw new EntityCutoverGitError(`Git HEAD path '${relativePath}' is ambiguous`);
|
|
72
|
+
const match = /^([0-7]{6}) (blob|commit) ([a-f0-9]+)\t(.+)$/.exec(records[0]);
|
|
73
|
+
if (!match || match[4] !== relativePath || match[2] !== "blob" || !["100644", "100755"].includes(match[1])) {
|
|
74
|
+
throw new EntityCutoverGitError(`migration input '${relativePath}' must be a regular tracked file in HEAD`);
|
|
75
|
+
}
|
|
76
|
+
return { mode: match[1], oid: match[3] };
|
|
77
|
+
}
|
|
78
|
+
function assertSourceMatchesHead(project, source) {
|
|
79
|
+
const lookupPath = source.path.endsWith("/") ? source.path.slice(0, -1) : source.path;
|
|
80
|
+
if (!safeRelative(lookupPath))
|
|
81
|
+
throw new EntityCutoverGitError(`migration input path '${source.path}' is unsafe`);
|
|
82
|
+
if (source.presence === "missing") {
|
|
83
|
+
const tracked = source.path.endsWith("/")
|
|
84
|
+
? gitText(project, ["ls-tree", "-r", "--name-only", "HEAD", "--", `${lookupPath}/`]) !== ""
|
|
85
|
+
: headEntry(project, lookupPath) !== null;
|
|
86
|
+
if (tracked)
|
|
87
|
+
throw new EntityCutoverGitError(`migration input '${source.path}' is tracked in HEAD but absent from the worktree`);
|
|
88
|
+
const observed = readProjectFileSnapshot(validateRealProjectRoot(project), lookupPath);
|
|
89
|
+
if (observed.kind !== "missing")
|
|
90
|
+
throw new EntityCutoverGitError(`migration input '${source.path}' is absent from HEAD but present or unsafe in the worktree`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const tracked = headEntry(project, lookupPath);
|
|
94
|
+
if (!tracked)
|
|
95
|
+
throw new EntityCutoverGitError(`migration input '${source.path}' is ignored or untracked; v2-to-v3 upgrade consumes only HEAD`);
|
|
96
|
+
const observed = readProjectFileSnapshot(validateRealProjectRoot(project), lookupPath);
|
|
97
|
+
if (observed.kind !== "file")
|
|
98
|
+
throw new EntityCutoverGitError(`migration input '${source.path}' must be a safe regular tracked file`);
|
|
99
|
+
const blob = git(project, ["cat-file", "blob", tracked.oid], null);
|
|
100
|
+
if (blob.status !== 0 || !Buffer.isBuffer(blob.stdout))
|
|
101
|
+
throw new EntityCutoverGitError(`Git could not read HEAD bytes for migration input '${source.path}'`);
|
|
102
|
+
const executable = (observed.mode & 0o111) !== 0;
|
|
103
|
+
const expectedMode = executable ? "100755" : "100644";
|
|
104
|
+
if (tracked.mode !== expectedMode
|
|
105
|
+
|| source.mode !== observed.mode
|
|
106
|
+
|| source.type !== "file"
|
|
107
|
+
|| source.sha256 !== hash(observed.bytes)
|
|
108
|
+
|| !observed.bytes.equals(blob.stdout)) {
|
|
109
|
+
throw new EntityCutoverGitError(`migration input '${source.path}' differs from HEAD in bytes, type, mode, or symlink form`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export function verifyEntityCutoverGitSource(projectRoot, plan, allowlist = {}) {
|
|
113
|
+
const project = validateRealProjectRoot(projectRoot).path;
|
|
114
|
+
const top = fs.realpathSync(gitText(project, ["rev-parse", "--show-toplevel"]));
|
|
115
|
+
if (top !== project)
|
|
116
|
+
throw new EntityCutoverGitError(`project '${project}' must be the Git worktree root for v2-to-v3 upgrade`);
|
|
117
|
+
const head = gitText(project, ["rev-parse", "--verify", "HEAD^{commit}"]);
|
|
118
|
+
if (!/^[a-f0-9]{40,64}$/.test(head))
|
|
119
|
+
throw new EntityCutoverGitError("Git HEAD is missing or invalid; commit the v2 project before upgrade");
|
|
120
|
+
assertCleanTrackedState(project);
|
|
121
|
+
assertNoUnapprovedUntracked(project, allowlist);
|
|
122
|
+
for (const source of plan.sources)
|
|
123
|
+
assertSourceMatchesHead(project, source);
|
|
124
|
+
if (gitText(project, ["rev-parse", "--verify", "HEAD^{commit}"]) !== head)
|
|
125
|
+
throw new EntityCutoverGitError("Git HEAD changed during v2-to-v3 preflight");
|
|
126
|
+
return { head };
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=entityCutoverGit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entityCutoverGit.js","sourceRoot":"","sources":["../../src/state/entityCutoverGit.ts"],"names":[],"mappings":"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"}
|