@kungfu-tech/buildchain 4.0.1-alpha.8 → 4.0.1
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 -6
- package/actions/v4-release-candidate-promote/README.md +3 -0
- package/architecture/agent-change-map.md +1015 -0
- package/architecture/ci-lane-change-budget.json +70 -1
- package/architecture/decisions/0004-v4-declarative-release-tail.md +47 -0
- package/architecture/internal-capabilities.json +156 -11
- package/architecture/maintainability-debt.json +3229 -0
- package/architecture/maintainability-policy.json +480 -129
- package/architecture/v3-core-mechanism-inventory.json +4 -3
- package/architecture/v3-v4-capability-closure.md +59 -0
- package/architecture/v3-v4-live-capability-inventory.json +102404 -0
- package/architecture/v4-cross-platform-adopter-qualification.json +52 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.json +3 -3
- package/architecture/v4-runtime-semantic-closure.json +710 -0
- package/bin/internal/trust-release-release-handlers.mjs +5 -0
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
- package/contracts/v4-publication-qualification-v1.schema.json +51 -0
- package/dist/site/agent-index.json +1 -0
- package/dist/site/artifact-schemas.json +2 -0
- package/dist/site/buildchain-contract.json +123 -32
- package/dist/site/buildchain-site.json +96 -28
- package/dist/site/capability-registry.json +6 -6
- package/dist/site/cli-registry.json +5 -2
- package/dist/site/controller-registry.json +41 -5
- package/dist/site/kfd-claims.json +170 -21
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +6 -6
- package/dist/site/node-api-registry.json +1474 -215
- package/dist/site/page-registry.json +85 -17
- package/dist/site/public-surface-audit.json +85 -20
- package/dist/site/publication-authority-registry.json +28 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +5 -0
- package/dist/site/schemas/v4-publication-qualification-v1.schema.json +51 -0
- package/dist/site/site-manifest.json +10 -10
- package/dist/site/workflow-registry.json +94 -18
- package/docs/MAP.md +1 -1
- package/docs/cli-reference.md +4 -4
- package/docs/dev-delivery-warrant.md +12 -9
- package/docs/node-api-reference.md +291 -206
- package/docs/publish-transaction.md +11 -4
- package/docs/release-candidate.md +7 -0
- package/docs/v4-adopter-delivery.md +23 -4
- package/docs/v4-declarative-release-tail-migration.md +43 -0
- package/package.json +8 -3
- package/packages/core/adopter-delivery-passport.js +36 -0
- package/packages/core/buildchain-contract.js +31 -1
- package/packages/core/buildchain-publication-authority.js +1 -0
- package/packages/core/dev-delivery-warrant-settlement.js +239 -3
- package/packages/core/dev-delivery-warrant-state.js +15 -2
- package/packages/core/dev-delivery-warrant.js +21 -4
- package/packages/core/github-governance-authority.js +4 -4
- package/packages/core/index.js +1 -0
- package/packages/core/paper-scaffold-content.js +401 -0
- package/packages/core/paper.js +12 -378
- package/packages/core/publication-control-plane-audit.js +135 -111
- package/packages/core/publication-rehearsal-projection.js +104 -0
- package/packages/core/publication-rehearsal-runtime.js +190 -0
- package/packages/core/release-candidate-recovery.js +6 -5
- package/packages/core/release-passport.js +82 -184
- package/packages/core/v4-cross-platform-adopter-qualification.js +343 -0
- package/packages/core/v4-floating-consumer-policy.js +3 -2
- package/packages/core/v4-floating-consumer-release-passport.js +134 -15
- package/packages/core/v4-publication-qualification.js +222 -0
- package/scripts/artifact-signing-controller-core.mjs +1 -1
- package/scripts/audit-publication-control-plane.mjs +17 -17
- package/scripts/buildchain-cli-help.mjs +3 -0
- package/scripts/check-internal-architecture.mjs +23 -3
- package/scripts/check-inventory.mjs +23 -5
- package/scripts/check-maintainability.mjs +145 -4
- package/scripts/check-project-cut-merge-queue-admission.mjs +87 -0
- package/scripts/check-v3-v4-capability-inventory.mjs +574 -0
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +10 -3
- package/scripts/check-v4-runtime-semantic-closure.mjs +266 -0
- package/scripts/dev-delivery-warrant-options.mjs +27 -11
- package/scripts/dev-delivery-warrant.mjs +45 -5
- package/scripts/dev-pr-auto-merge.mjs +25 -11
- package/scripts/dev-pr-delivery-warrant.mjs +44 -0
- package/scripts/dev-pr-prequeue-guard.mjs +0 -18
- package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
- package/scripts/generate-agent-change-map.mjs +118 -0
- package/scripts/generate-release-candidate-passport.mjs +26 -1
- package/scripts/generate-site-bundle.mjs +6 -0
- package/scripts/maintainability-domain-metrics.mjs +237 -0
- package/scripts/maintainability-governance.mjs +473 -0
- package/scripts/maintainability-metrics.mjs +28 -6
- package/scripts/project-cut-merge-queue-admission.mjs +394 -0
- package/scripts/promotion-routing-evidence.mjs +35 -6
- package/scripts/release-candidate-resolver.mjs +44 -0
- package/scripts/release-line-policy.mjs +25 -15
- package/scripts/release-tail.mjs +19 -2
- package/scripts/resume-from-candidate-run.mjs +106 -103
- package/scripts/run-lifecycle-core.mjs +341 -376
- package/scripts/site-capability-metadata.mjs +4 -0
- package/scripts/stable-candidate-qualification.mjs +9 -10
- package/scripts/v3-v4-capability-catalog.mjs +439 -0
- package/scripts/v4-cross-platform-adopter-qualification.mjs +228 -0
- package/scripts/v4-declarative-promotion-admission.mjs +42 -0
package/packages/core/paper.js
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
resolvePaperBuildchainSha,
|
|
39
39
|
} from "./paper-agent-entry.js";
|
|
40
40
|
import {
|
|
41
|
+
createPaperScaffoldOperations,
|
|
41
42
|
managedPaperPackageJson,
|
|
42
43
|
scaffoldMainTex,
|
|
43
44
|
scaffoldMakefile,
|
|
@@ -704,207 +705,6 @@ function scaffoldFiles({
|
|
|
704
705
|
]);
|
|
705
706
|
}
|
|
706
707
|
|
|
707
|
-
export function planPaperScaffold({
|
|
708
|
-
cwd = process.cwd(),
|
|
709
|
-
buildchainRoot = process.cwd(),
|
|
710
|
-
buildchainVersion = "",
|
|
711
|
-
buildchainRef = "v3",
|
|
712
|
-
buildchainSha = "",
|
|
713
|
-
name = path.basename(path.resolve(cwd)),
|
|
714
|
-
title = "",
|
|
715
|
-
packageName = "",
|
|
716
|
-
repository = "",
|
|
717
|
-
version = "0.1.0-alpha.0",
|
|
718
|
-
siteBaseUrl = "",
|
|
719
|
-
} = {}) {
|
|
720
|
-
const resolvedCwd = path.resolve(cwd);
|
|
721
|
-
const normalizedName = String(name || "").trim();
|
|
722
|
-
if (!normalizedName) throw new Error("paper scaffold requires --name");
|
|
723
|
-
const normalizedPackage = normalizePackageName(packageName);
|
|
724
|
-
const normalizedRepository = normalizeRepository(repository);
|
|
725
|
-
if (!normalizedRepository) {
|
|
726
|
-
throw new Error("paper scaffold requires --repository <owner/repo>");
|
|
727
|
-
}
|
|
728
|
-
const normalizedVersion = String(version || "")
|
|
729
|
-
.trim()
|
|
730
|
-
.replace(/^v/, "");
|
|
731
|
-
if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(normalizedVersion)) {
|
|
732
|
-
throw new Error("paper scaffold --version must be semver");
|
|
733
|
-
}
|
|
734
|
-
const runtimeIdentity = buildchainPackageIdentity(
|
|
735
|
-
buildchainRoot,
|
|
736
|
-
buildchainVersion,
|
|
737
|
-
);
|
|
738
|
-
const runtimeSha =
|
|
739
|
-
buildchainSha ||
|
|
740
|
-
resolvePaperRuntimeGitSha(buildchainRoot, runtimeIdentity.version);
|
|
741
|
-
if (!GIT_SHA_PATTERN.test(runtimeSha)) {
|
|
742
|
-
throw new Error(
|
|
743
|
-
"paper scaffold cannot resolve the exact Buildchain runtime SHA; pass buildchainSha or use a published Buildchain package with npm gitHead provenance",
|
|
744
|
-
);
|
|
745
|
-
}
|
|
746
|
-
const files = scaffoldFiles({
|
|
747
|
-
buildchainRoot,
|
|
748
|
-
buildchainVersion: runtimeIdentity.version,
|
|
749
|
-
buildchainRef,
|
|
750
|
-
buildchainSha: runtimeSha,
|
|
751
|
-
cwd: resolvedCwd,
|
|
752
|
-
name: normalizedName,
|
|
753
|
-
title: title || normalizedName,
|
|
754
|
-
packageName: normalizedPackage,
|
|
755
|
-
repository: normalizedRepository,
|
|
756
|
-
version: normalizedVersion,
|
|
757
|
-
siteBaseUrl,
|
|
758
|
-
});
|
|
759
|
-
const changes = [...files.entries()].map(([relativePath, content]) => {
|
|
760
|
-
const filePath = path.resolve(resolvedCwd, relativePath);
|
|
761
|
-
const exists = fs.existsSync(filePath);
|
|
762
|
-
if (!exists) {
|
|
763
|
-
return {
|
|
764
|
-
path: relativePath,
|
|
765
|
-
action: "create",
|
|
766
|
-
sha256: sha256Text(content),
|
|
767
|
-
content,
|
|
768
|
-
};
|
|
769
|
-
}
|
|
770
|
-
if (!fs.statSync(filePath).isFile()) {
|
|
771
|
-
return {
|
|
772
|
-
path: relativePath,
|
|
773
|
-
action: "conflict",
|
|
774
|
-
reason: "path-exists-and-is-not-a-file",
|
|
775
|
-
sha256: sha256Text(content),
|
|
776
|
-
content,
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
const current = fs.readFileSync(filePath, "utf8");
|
|
780
|
-
return current === content
|
|
781
|
-
? {
|
|
782
|
-
path: relativePath,
|
|
783
|
-
action: "unchanged",
|
|
784
|
-
sha256: sha256Text(content),
|
|
785
|
-
content,
|
|
786
|
-
}
|
|
787
|
-
: {
|
|
788
|
-
path: relativePath,
|
|
789
|
-
action: "conflict",
|
|
790
|
-
reason: "existing-content-differs",
|
|
791
|
-
currentSha256: sha256Text(current),
|
|
792
|
-
sha256: sha256Text(content),
|
|
793
|
-
content,
|
|
794
|
-
};
|
|
795
|
-
});
|
|
796
|
-
const publicChanges = changes.map(({ content: _content, ...entry }) => entry);
|
|
797
|
-
const conflicts = publicChanges.filter(
|
|
798
|
-
(entry) => entry.action === "conflict",
|
|
799
|
-
);
|
|
800
|
-
const result = {
|
|
801
|
-
schemaVersion: 1,
|
|
802
|
-
contract: PAPER_SCAFFOLD_CONTRACT,
|
|
803
|
-
ok: conflicts.length === 0,
|
|
804
|
-
cwd: resolvedCwd,
|
|
805
|
-
dryRun: true,
|
|
806
|
-
identity: {
|
|
807
|
-
project: normalizedName,
|
|
808
|
-
title: title || normalizedName,
|
|
809
|
-
package: normalizedPackage,
|
|
810
|
-
repository: normalizedRepository,
|
|
811
|
-
version: normalizedVersion,
|
|
812
|
-
},
|
|
813
|
-
buildchain: {
|
|
814
|
-
version: runtimeIdentity.version,
|
|
815
|
-
ref: runtimeSha,
|
|
816
|
-
resolvedSha: runtimeSha,
|
|
817
|
-
},
|
|
818
|
-
summary: {
|
|
819
|
-
create: publicChanges.filter((entry) => entry.action === "create").length,
|
|
820
|
-
unchanged: publicChanges.filter((entry) => entry.action === "unchanged")
|
|
821
|
-
.length,
|
|
822
|
-
conflict: conflicts.length,
|
|
823
|
-
},
|
|
824
|
-
changes: publicChanges,
|
|
825
|
-
conflicts,
|
|
826
|
-
nextActions:
|
|
827
|
-
conflicts.length > 0
|
|
828
|
-
? [
|
|
829
|
-
{
|
|
830
|
-
id: "resolve-scaffold-conflicts",
|
|
831
|
-
command: "",
|
|
832
|
-
description:
|
|
833
|
-
"Resolve the listed semantic conflicts; scaffold never overwrites them.",
|
|
834
|
-
},
|
|
835
|
-
]
|
|
836
|
-
: [
|
|
837
|
-
{
|
|
838
|
-
id: "write-scaffold",
|
|
839
|
-
command: "buildchain paper scaffold --write <same arguments>",
|
|
840
|
-
description:
|
|
841
|
-
"Write only missing files after the conflict-free plan is reviewed.",
|
|
842
|
-
},
|
|
843
|
-
],
|
|
844
|
-
};
|
|
845
|
-
Object.defineProperty(result, "_plannedFiles", {
|
|
846
|
-
value: changes,
|
|
847
|
-
enumerable: false,
|
|
848
|
-
});
|
|
849
|
-
return result;
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
export function writePaperScaffold(plan) {
|
|
853
|
-
if (!plan || plan.contract !== PAPER_SCAFFOLD_CONTRACT) {
|
|
854
|
-
throw new Error("paper scaffold plan contract mismatch");
|
|
855
|
-
}
|
|
856
|
-
if (!plan.ok || plan.conflicts.length > 0) {
|
|
857
|
-
return {
|
|
858
|
-
...plan,
|
|
859
|
-
dryRun: false,
|
|
860
|
-
written: [],
|
|
861
|
-
ok: false,
|
|
862
|
-
errorCode: "paper-scaffold-conflict",
|
|
863
|
-
};
|
|
864
|
-
}
|
|
865
|
-
const resolvedCwd = path.resolve(plan.cwd);
|
|
866
|
-
const creates = plan._plannedFiles.filter(
|
|
867
|
-
(entry) => entry.action === "create",
|
|
868
|
-
);
|
|
869
|
-
for (const entry of creates) {
|
|
870
|
-
const target = path.resolve(resolvedCwd, entry.path);
|
|
871
|
-
if (fs.existsSync(target)) {
|
|
872
|
-
const current = fs.statSync(target).isFile()
|
|
873
|
-
? fs.readFileSync(target, "utf8")
|
|
874
|
-
: undefined;
|
|
875
|
-
if (current !== entry.content) {
|
|
876
|
-
throw new Error(
|
|
877
|
-
`paper scaffold race detected at ${entry.path}; no file was overwritten`,
|
|
878
|
-
);
|
|
879
|
-
}
|
|
880
|
-
continue;
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
const written = [];
|
|
884
|
-
for (const entry of creates) {
|
|
885
|
-
const target = path.resolve(resolvedCwd, entry.path);
|
|
886
|
-
if (fs.existsSync(target)) continue;
|
|
887
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
888
|
-
fs.writeFileSync(target, entry.content, { flag: "wx" });
|
|
889
|
-
written.push(entry.path);
|
|
890
|
-
}
|
|
891
|
-
return {
|
|
892
|
-
...plan,
|
|
893
|
-
ok: true,
|
|
894
|
-
dryRun: false,
|
|
895
|
-
written,
|
|
896
|
-
idempotent: written.length === 0,
|
|
897
|
-
nextActions: [
|
|
898
|
-
{
|
|
899
|
-
id: "paper-preflight",
|
|
900
|
-
command: `buildchain paper preflight --cwd ${JSON.stringify(resolvedCwd)} --json`,
|
|
901
|
-
description:
|
|
902
|
-
"Verify the generated repository before any external mutation.",
|
|
903
|
-
},
|
|
904
|
-
],
|
|
905
|
-
};
|
|
906
|
-
}
|
|
907
|
-
|
|
908
708
|
function migrationFiles({
|
|
909
709
|
cwd,
|
|
910
710
|
buildchainRoot,
|
|
@@ -1021,183 +821,17 @@ function migrationFiles({
|
|
|
1021
821
|
return files;
|
|
1022
822
|
}
|
|
1023
823
|
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
} = {
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
const repositoryPrefix = gitValue(resolvedCwd, [
|
|
1036
|
-
"rev-parse",
|
|
1037
|
-
"--show-prefix",
|
|
1038
|
-
]).replace(/\/+$/u, "");
|
|
1039
|
-
if (!repositoryRoot || repositoryPrefix) {
|
|
1040
|
-
throw new Error("paper migration must target the exact repository root");
|
|
1041
|
-
}
|
|
1042
|
-
const source = {
|
|
1043
|
-
head: gitValue(resolvedCwd, ["rev-parse", "HEAD"]),
|
|
1044
|
-
clean: gitResult(resolvedCwd, ["status", "--porcelain"]).stdout === "",
|
|
1045
|
-
};
|
|
1046
|
-
if (!GIT_SHA_PATTERN.test(source.head)) {
|
|
1047
|
-
throw new Error("paper migration requires a committed Git source");
|
|
1048
|
-
}
|
|
1049
|
-
const plannedFiles = [
|
|
1050
|
-
...migrationFiles({
|
|
1051
|
-
cwd: resolvedCwd,
|
|
1052
|
-
buildchainRoot,
|
|
1053
|
-
buildchainVersion,
|
|
1054
|
-
buildchainSha,
|
|
1055
|
-
}),
|
|
1056
|
-
].map(([relativePath, content]) => {
|
|
1057
|
-
const target = path.resolve(resolvedCwd, relativePath);
|
|
1058
|
-
if (fs.existsSync(target) && !fs.statSync(target).isFile()) {
|
|
1059
|
-
return {
|
|
1060
|
-
path: relativePath,
|
|
1061
|
-
action: "conflict",
|
|
1062
|
-
currentSha256: "",
|
|
1063
|
-
sha256: sha256Text(content),
|
|
1064
|
-
content,
|
|
1065
|
-
};
|
|
1066
|
-
}
|
|
1067
|
-
const current = fs.existsSync(target)
|
|
1068
|
-
? fs.readFileSync(target, "utf8")
|
|
1069
|
-
: undefined;
|
|
1070
|
-
return {
|
|
1071
|
-
path: relativePath,
|
|
1072
|
-
action:
|
|
1073
|
-
current === undefined
|
|
1074
|
-
? "create"
|
|
1075
|
-
: current === content
|
|
1076
|
-
? "unchanged"
|
|
1077
|
-
: "update",
|
|
1078
|
-
currentSha256: current === undefined ? "" : sha256Text(current),
|
|
1079
|
-
sha256: sha256Text(content),
|
|
1080
|
-
content,
|
|
1081
|
-
};
|
|
1082
|
-
});
|
|
1083
|
-
const changes = plannedFiles.map(({ content: _content, ...entry }) => entry);
|
|
1084
|
-
const conflicts = changes.filter((entry) => entry.action === "conflict");
|
|
1085
|
-
const ok = source.clean && conflicts.length === 0;
|
|
1086
|
-
const result = {
|
|
1087
|
-
schemaVersion: 1,
|
|
1088
|
-
contract: PAPER_MIGRATION_CONTRACT,
|
|
1089
|
-
ok,
|
|
1090
|
-
cwd: resolvedCwd,
|
|
1091
|
-
dryRun: true,
|
|
1092
|
-
source,
|
|
1093
|
-
summary: {
|
|
1094
|
-
create: changes.filter((entry) => entry.action === "create").length,
|
|
1095
|
-
update: changes.filter((entry) => entry.action === "update").length,
|
|
1096
|
-
unchanged: changes.filter((entry) => entry.action === "unchanged").length,
|
|
1097
|
-
conflict: conflicts.length,
|
|
1098
|
-
},
|
|
1099
|
-
changes,
|
|
1100
|
-
conflicts,
|
|
1101
|
-
nextActions: !source.clean
|
|
1102
|
-
? [
|
|
1103
|
-
{
|
|
1104
|
-
id: "commit-source",
|
|
1105
|
-
command: "git status --short",
|
|
1106
|
-
description:
|
|
1107
|
-
"Migration only rewrites Buildchain-owned control files from a clean committed source.",
|
|
1108
|
-
},
|
|
1109
|
-
]
|
|
1110
|
-
: conflicts.length > 0
|
|
1111
|
-
? [
|
|
1112
|
-
{
|
|
1113
|
-
id: "resolve-migration-conflicts",
|
|
1114
|
-
command: "",
|
|
1115
|
-
description:
|
|
1116
|
-
"Resolve non-file targets; migration never replaces a directory or special path.",
|
|
1117
|
-
},
|
|
1118
|
-
]
|
|
1119
|
-
: [
|
|
1120
|
-
{
|
|
1121
|
-
id: "write-migration",
|
|
1122
|
-
command: "buildchain paper migrate --write --json",
|
|
1123
|
-
description:
|
|
1124
|
-
"Write the reviewed Buildchain-owned control files without changing paper content or publication configuration.",
|
|
1125
|
-
},
|
|
1126
|
-
{
|
|
1127
|
-
id: "refresh-pnpm-lock",
|
|
1128
|
-
command: "pnpm install --lockfile-only",
|
|
1129
|
-
description:
|
|
1130
|
-
"Bind the exact Buildchain semantic dependency into pnpm-lock.yaml after the reviewed package update.",
|
|
1131
|
-
},
|
|
1132
|
-
],
|
|
1133
|
-
};
|
|
1134
|
-
Object.defineProperty(result, "_plannedFiles", {
|
|
1135
|
-
value: plannedFiles,
|
|
1136
|
-
enumerable: false,
|
|
1137
|
-
});
|
|
1138
|
-
return result;
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
export function writePaperMigration(plan) {
|
|
1142
|
-
if (!plan || plan.contract !== PAPER_MIGRATION_CONTRACT) {
|
|
1143
|
-
throw new Error("paper migration plan contract mismatch");
|
|
1144
|
-
}
|
|
1145
|
-
if (!plan.ok) {
|
|
1146
|
-
return {
|
|
1147
|
-
...plan,
|
|
1148
|
-
dryRun: false,
|
|
1149
|
-
written: [],
|
|
1150
|
-
updated: [],
|
|
1151
|
-
ok: false,
|
|
1152
|
-
errorCode: "paper-migration-blocked",
|
|
1153
|
-
};
|
|
1154
|
-
}
|
|
1155
|
-
const written = [];
|
|
1156
|
-
const updated = [];
|
|
1157
|
-
for (const entry of plan._plannedFiles) {
|
|
1158
|
-
if (entry.action === "unchanged") continue;
|
|
1159
|
-
const target = path.resolve(plan.cwd, entry.path);
|
|
1160
|
-
const exists = fs.existsSync(target);
|
|
1161
|
-
const current =
|
|
1162
|
-
exists && fs.statSync(target).isFile()
|
|
1163
|
-
? fs.readFileSync(target, "utf8")
|
|
1164
|
-
: undefined;
|
|
1165
|
-
const currentSha256 = current === undefined ? "" : sha256Text(current);
|
|
1166
|
-
if (
|
|
1167
|
-
(entry.action === "create" && exists) ||
|
|
1168
|
-
(entry.action === "update" && currentSha256 !== entry.currentSha256)
|
|
1169
|
-
) {
|
|
1170
|
-
throw new Error(
|
|
1171
|
-
`paper migration race detected at ${entry.path}; no stale plan was applied`,
|
|
1172
|
-
);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
for (const entry of plan._plannedFiles) {
|
|
1176
|
-
if (entry.action === "unchanged") continue;
|
|
1177
|
-
const target = path.resolve(plan.cwd, entry.path);
|
|
1178
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
1179
|
-
fs.writeFileSync(target, entry.content, {
|
|
1180
|
-
flag: entry.action === "create" ? "wx" : "w",
|
|
1181
|
-
});
|
|
1182
|
-
(entry.action === "create" ? written : updated).push(entry.path);
|
|
1183
|
-
}
|
|
1184
|
-
return {
|
|
1185
|
-
...plan,
|
|
1186
|
-
ok: true,
|
|
1187
|
-
dryRun: false,
|
|
1188
|
-
written,
|
|
1189
|
-
updated,
|
|
1190
|
-
idempotent: written.length === 0 && updated.length === 0,
|
|
1191
|
-
nextActions: [
|
|
1192
|
-
{
|
|
1193
|
-
id: "paper-preflight",
|
|
1194
|
-
command: `buildchain paper preflight --cwd ${JSON.stringify(plan.cwd)} --offline --json`,
|
|
1195
|
-
description:
|
|
1196
|
-
"Verify the migrated repository before any external mutation.",
|
|
1197
|
-
},
|
|
1198
|
-
],
|
|
1199
|
-
};
|
|
1200
|
-
}
|
|
824
|
+
const {
|
|
825
|
+
planPaperMigration,
|
|
826
|
+
planPaperScaffold,
|
|
827
|
+
writePaperMigration,
|
|
828
|
+
writePaperScaffold,
|
|
829
|
+
} = createPaperScaffoldOperations({
|
|
830
|
+
PAPER_MIGRATION_CONTRACT, PAPER_SCAFFOLD_CONTRACT, GIT_SHA_PATTERN,
|
|
831
|
+
buildchainPackageIdentity, migrationFiles, normalizePackageName,
|
|
832
|
+
resolvePaperRuntimeGitSha, scaffoldFiles,
|
|
833
|
+
});
|
|
834
|
+
export { planPaperMigration, planPaperScaffold, writePaperMigration, writePaperScaffold };
|
|
1201
835
|
|
|
1202
836
|
function state(id, status, reason, evidence = []) {
|
|
1203
837
|
return {
|