@kungfu-tech/buildchain 3.0.6 → 3.0.7-alpha.0
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 +4 -2
- package/actions/release-tail/README.md +17 -0
- package/bin/buildchain.mjs +11 -0
- package/bin/internal/command-registry.mjs +2 -0
- package/contracts/fixtures/release-tail-capabilities-v1/kungfu-alpha.json +273 -0
- package/contracts/publication-rehearsal-capsule-v1.schema.json +173 -0
- package/contracts/release-tail-capabilities-v1.schema.json +199 -0
- package/contracts/release-tail-provider-bindings-v1.schema.json +56 -0
- package/dist/site/agent-index.json +3 -0
- package/dist/site/artifact-schemas.json +6 -0
- package/dist/site/buildchain-contract.json +35 -20
- package/dist/site/buildchain-site.json +307 -17
- package/dist/site/capability-registry.json +12 -9
- package/dist/site/cli-registry.json +102 -0
- package/dist/site/controller-registry.json +14 -2
- package/dist/site/kfd-claims.json +247 -16
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +48 -3
- package/dist/site/node-api-registry.json +3108 -1409
- package/dist/site/page-registry.json +275 -9
- package/dist/site/public-surface-audit.json +304 -15
- package/dist/site/publication-authority-registry.json +26 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +5 -0
- package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +269 -0
- package/dist/site/schemas/release-tail-capabilities-v1.schema.json +353 -0
- package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +94 -0
- package/dist/site/site-manifest.json +31 -7
- package/dist/site/workflow-registry.json +86 -9
- package/docs/MAP.md +5 -2
- package/docs/cli-reference.md +136 -0
- package/docs/node-api-reference.md +233 -84
- package/docs/publication-rehearsal.md +94 -0
- package/docs/release-tail-contract.md +160 -0
- package/docs/release-tail-provider-plane.md +120 -0
- package/package.json +8 -3
- package/packages/core/buildchain-agent-manuals.js +3 -0
- package/packages/core/buildchain-kfd-claims.js +1 -1
- package/packages/core/buildchain-publication-authority.js +1 -0
- package/packages/core/index.js +39 -0
- package/packages/core/paper-agent-entry.js +11 -5
- package/packages/core/paper-repository.js +1 -0
- package/packages/core/paper-scaffold-content.js +21 -0
- package/packages/core/paper.js +28 -2
- package/packages/core/publication-rehearsal-projection.js +173 -0
- package/packages/core/publication-rehearsal-runtime.js +909 -0
- package/packages/core/release-tail-compatibility.js +60 -0
- package/packages/core/release-tail-provider-adapters.js +461 -0
- package/packages/core/release-tail-provider-plane.js +1228 -0
- package/scripts/assemble-publication-artifact-admission.mjs +1 -1
- package/scripts/assemble-self-publication-admission.mjs +1 -1
- package/scripts/buildchain-cli-help.mjs +13 -0
- package/scripts/check-core-mechanism-inventory.mjs +347 -0
- package/scripts/check-inventory.mjs +8 -8
- package/scripts/check-maintainability.mjs +9 -2
- package/scripts/check-release-tail-contract.mjs +435 -0
- package/scripts/generate-channel-promotion-workflow.mjs +10 -8
- package/scripts/generate-site-bundle.mjs +24 -0
- package/scripts/init-repo.mjs +26 -2
- package/scripts/materialize-self-release-candidate-version.mjs +131 -0
- package/scripts/release-tail.mjs +159 -0
- package/scripts/site-capability-metadata.mjs +11 -0
- package/scripts/v4-architecture.mjs +600 -0
- package/scripts/workflow-call-contract.mjs +184 -5
package/packages/core/paper.js
CHANGED
|
@@ -46,6 +46,11 @@ import {
|
|
|
46
46
|
scaffoldReadme,
|
|
47
47
|
} from "./paper-scaffold-content.js";
|
|
48
48
|
import { executePaperNpmBootstrap as executePaperNpmBootstrapOperation } from "./paper-npm-bootstrap.js";
|
|
49
|
+
import {
|
|
50
|
+
appendPublicationRehearsalToml,
|
|
51
|
+
projectPublicationRehearsalToml,
|
|
52
|
+
publicationRehearsalWorkflow,
|
|
53
|
+
} from "./publication-rehearsal-projection.js";
|
|
49
54
|
|
|
50
55
|
export { PAPER_PATHS, resolvePaperRepository } from "./paper-repository.js";
|
|
51
56
|
export {
|
|
@@ -114,6 +119,7 @@ const PAPER_SCAFFOLD_PATHS = Object.freeze([
|
|
|
114
119
|
PAPER_PATHS.buildWorkflow,
|
|
115
120
|
PAPER_PATHS.verifyWorkflow,
|
|
116
121
|
PAPER_PATHS.releaseWorkflow,
|
|
122
|
+
PAPER_PATHS.rehearsalWorkflow,
|
|
117
123
|
PAPER_PATHS.pnpmWorkspace,
|
|
118
124
|
PAPER_PATHS.provisioningAuthority,
|
|
119
125
|
"Makefile",
|
|
@@ -350,7 +356,7 @@ immutable_base_url = ${tomlString(joinUrl(siteBaseUrl, "archive").replace(/\/$/,
|
|
|
350
356
|
registry_path = ".buildchain/publication/publication-registry.json"
|
|
351
357
|
`
|
|
352
358
|
: "";
|
|
353
|
-
return `schema = 1
|
|
359
|
+
return appendPublicationRehearsalToml(`schema = 1
|
|
354
360
|
|
|
355
361
|
[project]
|
|
356
362
|
type = "publication-artifact"
|
|
@@ -384,7 +390,7 @@ command = "make pdf"
|
|
|
384
390
|
|
|
385
391
|
[lifecycle.verify]
|
|
386
392
|
command = "make check"
|
|
387
|
-
|
|
393
|
+
`);
|
|
388
394
|
}
|
|
389
395
|
|
|
390
396
|
function scaffoldBuildWorkflow(
|
|
@@ -525,6 +531,7 @@ export function createPaperProvisioningAuthority({
|
|
|
525
531
|
buildWorkflow,
|
|
526
532
|
verifyWorkflow,
|
|
527
533
|
releaseWorkflow,
|
|
534
|
+
rehearsalWorkflow,
|
|
528
535
|
agentEntry,
|
|
529
536
|
agentInstructions,
|
|
530
537
|
environment = "",
|
|
@@ -564,6 +571,12 @@ export function createPaperProvisioningAuthority({
|
|
|
564
571
|
reusablePath: ".github/workflows/paper-release-sealed.yml",
|
|
565
572
|
reusableRef: buildchainSha,
|
|
566
573
|
},
|
|
574
|
+
rehearsal: {
|
|
575
|
+
path: PAPER_PATHS.rehearsalWorkflow,
|
|
576
|
+
sourceDigest: sha256Text(rehearsalWorkflow),
|
|
577
|
+
reusablePath: ".github/workflows/release-tail.yml",
|
|
578
|
+
reusableRef: buildchainSha,
|
|
579
|
+
},
|
|
567
580
|
},
|
|
568
581
|
agentEntry: {
|
|
569
582
|
contract: PAPER_AGENT_ENTRY_CONTRACT,
|
|
@@ -630,6 +643,7 @@ function scaffoldFiles({
|
|
|
630
643
|
releasePassportProductName: title,
|
|
631
644
|
});
|
|
632
645
|
const verifyWorkflow = scaffoldVerifyWorkflow(buildchainSha);
|
|
646
|
+
const rehearsalWorkflow = publicationRehearsalWorkflow(buildchainSha);
|
|
633
647
|
const agentEntry = paperAgentEntryFiles({
|
|
634
648
|
cwd,
|
|
635
649
|
buildchainVersion,
|
|
@@ -647,6 +661,7 @@ function scaffoldFiles({
|
|
|
647
661
|
buildWorkflow,
|
|
648
662
|
verifyWorkflow,
|
|
649
663
|
releaseWorkflow,
|
|
664
|
+
rehearsalWorkflow,
|
|
650
665
|
agentEntry: agentEntry.get(PAPER_PATHS.agentEntry),
|
|
651
666
|
agentInstructions: agentEntry.get(PAPER_PATHS.agentInstructions),
|
|
652
667
|
});
|
|
@@ -667,6 +682,7 @@ function scaffoldFiles({
|
|
|
667
682
|
[PAPER_PATHS.buildWorkflow, buildWorkflow],
|
|
668
683
|
[PAPER_PATHS.verifyWorkflow, verifyWorkflow],
|
|
669
684
|
[PAPER_PATHS.releaseWorkflow, releaseWorkflow],
|
|
685
|
+
[PAPER_PATHS.rehearsalWorkflow, rehearsalWorkflow],
|
|
670
686
|
[PAPER_PATHS.pnpmWorkspace, paperPnpmWorkspace("", buildchainVersion)],
|
|
671
687
|
[PAPER_PATHS.provisioningAuthority, jsonText(provisioningAuthority)],
|
|
672
688
|
...agentEntry,
|
|
@@ -964,6 +980,7 @@ function migrationFiles({
|
|
|
964
980
|
releasePassportProductName: config.publication.title,
|
|
965
981
|
});
|
|
966
982
|
const verifyWorkflow = scaffoldVerifyWorkflow(runtimeSha);
|
|
983
|
+
const rehearsalWorkflow = publicationRehearsalWorkflow(runtimeSha);
|
|
967
984
|
const agentEntry = paperAgentEntryFiles({
|
|
968
985
|
cwd,
|
|
969
986
|
buildchainVersion: runtimeIdentity.version,
|
|
@@ -978,6 +995,7 @@ function migrationFiles({
|
|
|
978
995
|
buildWorkflow,
|
|
979
996
|
verifyWorkflow,
|
|
980
997
|
releaseWorkflow,
|
|
998
|
+
rehearsalWorkflow,
|
|
981
999
|
agentEntry: agentEntry.get(PAPER_PATHS.agentEntry),
|
|
982
1000
|
agentInstructions: agentEntry.get(PAPER_PATHS.agentInstructions),
|
|
983
1001
|
});
|
|
@@ -997,11 +1015,18 @@ function migrationFiles({
|
|
|
997
1015
|
runtimeIdentity.version,
|
|
998
1016
|
);
|
|
999
1017
|
const files = new Map([
|
|
1018
|
+
[
|
|
1019
|
+
PAPER_PATHS.config,
|
|
1020
|
+
projectPublicationRehearsalToml(
|
|
1021
|
+
fs.readFileSync(path.resolve(cwd, PAPER_PATHS.config), "utf8"),
|
|
1022
|
+
),
|
|
1023
|
+
],
|
|
1000
1024
|
[PAPER_PATHS.contractLock, contractLockText],
|
|
1001
1025
|
[PAPER_PATHS.versionPin, `${runtimeIdentity.version}\n`],
|
|
1002
1026
|
[PAPER_PATHS.buildWorkflow, buildWorkflow],
|
|
1003
1027
|
[PAPER_PATHS.verifyWorkflow, verifyWorkflow],
|
|
1004
1028
|
[PAPER_PATHS.releaseWorkflow, releaseWorkflow],
|
|
1029
|
+
[PAPER_PATHS.rehearsalWorkflow, rehearsalWorkflow],
|
|
1005
1030
|
[PAPER_PATHS.pnpmWorkspace, pnpmWorkspace],
|
|
1006
1031
|
[PAPER_PATHS.provisioningAuthority, jsonText(provisioningAuthority)],
|
|
1007
1032
|
...agentEntry,
|
|
@@ -1755,6 +1780,7 @@ function validatePaperProvisioningAuthority(cwd) {
|
|
|
1755
1780
|
value.workflows?.build,
|
|
1756
1781
|
value.workflows?.verify,
|
|
1757
1782
|
value.workflows?.release,
|
|
1783
|
+
value.workflows?.rehearsal,
|
|
1758
1784
|
]) {
|
|
1759
1785
|
if (!workflow?.path || !workflow?.sourceDigest) {
|
|
1760
1786
|
errors.push("paper workflow authority is incomplete");
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PUBLICATION_REHEARSAL_CAPSULE_CONTRACT,
|
|
3
|
+
PUBLICATION_REHEARSAL_COMMAND,
|
|
4
|
+
RELEASE_LOCAL_CONSTRUCTIBILITY_ADR,
|
|
5
|
+
RELEASE_LOCAL_CONSTRUCTIBILITY_INVARIANT,
|
|
6
|
+
} from "./publication-rehearsal-runtime.js";
|
|
7
|
+
|
|
8
|
+
export const PUBLICATION_REHEARSAL_AGENT_SECTION_START =
|
|
9
|
+
"<!-- buildchain:publication-rehearsal:v1:start -->";
|
|
10
|
+
export const PUBLICATION_REHEARSAL_AGENT_SECTION_END =
|
|
11
|
+
"<!-- buildchain:publication-rehearsal:v1:end -->";
|
|
12
|
+
export const PUBLICATION_REHEARSAL_WORKFLOW_PATH =
|
|
13
|
+
".github/workflows/publication-rehearsal.yml";
|
|
14
|
+
|
|
15
|
+
function tomlString(value) {
|
|
16
|
+
return JSON.stringify(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function publicationRehearsalToml() {
|
|
20
|
+
return `[publication_rehearsal]
|
|
21
|
+
contract = ${tomlString(PUBLICATION_REHEARSAL_CAPSULE_CONTRACT)}
|
|
22
|
+
adr = ${tomlString(RELEASE_LOCAL_CONSTRUCTIBILITY_ADR)}
|
|
23
|
+
invariant = ${tomlString(RELEASE_LOCAL_CONSTRUCTIBILITY_INVARIANT)}
|
|
24
|
+
command = ${tomlString(PUBLICATION_REHEARSAL_COMMAND)}
|
|
25
|
+
capsule = ".buildchain/publication/rehearsal-capsule.json"
|
|
26
|
+
capsule_root = ".buildchain/publication/candidate"
|
|
27
|
+
state = ".buildchain/publication/rehearsal-state.json"
|
|
28
|
+
evidence = ".buildchain/publication/rehearsal-evidence.json"
|
|
29
|
+
`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function assertPublicationRehearsalConfig(config) {
|
|
33
|
+
const section = config?.publication_rehearsal;
|
|
34
|
+
if (!section || typeof section !== "object" || Array.isArray(section)) {
|
|
35
|
+
throw new Error("publication_rehearsal table is missing");
|
|
36
|
+
}
|
|
37
|
+
const expected = {
|
|
38
|
+
contract: PUBLICATION_REHEARSAL_CAPSULE_CONTRACT,
|
|
39
|
+
adr: RELEASE_LOCAL_CONSTRUCTIBILITY_ADR,
|
|
40
|
+
invariant: RELEASE_LOCAL_CONSTRUCTIBILITY_INVARIANT,
|
|
41
|
+
command: PUBLICATION_REHEARSAL_COMMAND,
|
|
42
|
+
capsule: ".buildchain/publication/rehearsal-capsule.json",
|
|
43
|
+
capsule_root: ".buildchain/publication/candidate",
|
|
44
|
+
state: ".buildchain/publication/rehearsal-state.json",
|
|
45
|
+
evidence: ".buildchain/publication/rehearsal-evidence.json",
|
|
46
|
+
};
|
|
47
|
+
const actualKeys = Object.keys(section).sort();
|
|
48
|
+
const expectedKeys = Object.keys(expected).sort();
|
|
49
|
+
if (actualKeys.join("\n") !== expectedKeys.join("\n")) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`publication_rehearsal fields must be exactly: ${expectedKeys.join(", ")}`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
for (const [key, value] of Object.entries(expected)) {
|
|
55
|
+
if (section[key] !== value) {
|
|
56
|
+
throw new Error(`publication_rehearsal.${key} is stale or unsupported`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return structuredClone(section);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function appendPublicationRehearsalToml(source) {
|
|
63
|
+
const current = String(source || "").trimEnd();
|
|
64
|
+
if (/^\[publication_rehearsal\]$/mu.test(current)) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
"buildchain config already contains a publication_rehearsal table",
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return `${current}\n\n${publicationRehearsalToml()}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function projectPublicationRehearsalToml(source) {
|
|
73
|
+
const current = String(source || "");
|
|
74
|
+
const start = current.search(/^\[publication_rehearsal\]\s*$/mu);
|
|
75
|
+
if (start === -1) return appendPublicationRehearsalToml(current);
|
|
76
|
+
const remainder = current.slice(start);
|
|
77
|
+
const nextTable = remainder
|
|
78
|
+
.slice(remainder.indexOf("\n") + 1)
|
|
79
|
+
.search(/^\[[^\n]+\]\s*$/mu);
|
|
80
|
+
const end =
|
|
81
|
+
nextTable === -1
|
|
82
|
+
? current.length
|
|
83
|
+
: start + remainder.indexOf("\n") + 1 + nextTable;
|
|
84
|
+
const prefix = current.slice(0, start).trimEnd();
|
|
85
|
+
const suffix = current.slice(end).trimStart();
|
|
86
|
+
return `${prefix}\n\n${publicationRehearsalToml()}${suffix ? `\n${suffix}` : ""}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function publicationRehearsalAgentInstructions() {
|
|
90
|
+
return `${PUBLICATION_REHEARSAL_AGENT_SECTION_START}
|
|
91
|
+
## Publication rehearsal (required)
|
|
92
|
+
|
|
93
|
+
Buildchain release behavior follows
|
|
94
|
+
\`${RELEASE_LOCAL_CONSTRUCTIBILITY_ADR}\`. ${RELEASE_LOCAL_CONSTRUCTIBILITY_INVARIANT}
|
|
95
|
+
|
|
96
|
+
Before hosted publication, restore the explicit
|
|
97
|
+
\`${PUBLICATION_REHEARSAL_CAPSULE_CONTRACT}\` capsule and run exactly:
|
|
98
|
+
|
|
99
|
+
\`\`\`sh
|
|
100
|
+
${PUBLICATION_REHEARSAL_COMMAND}
|
|
101
|
+
\`\`\`
|
|
102
|
+
|
|
103
|
+
Simulation and replay evidence never claim external publication truth. GitHub
|
|
104
|
+
Actions may add only declared credentials, transport, and unavoidable provider
|
|
105
|
+
effects; it may not add semantic inputs from runner environment or workspace.
|
|
106
|
+
${PUBLICATION_REHEARSAL_AGENT_SECTION_END}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function mergePublicationRehearsalAgentInstructions(current = "") {
|
|
110
|
+
const source = String(current || "");
|
|
111
|
+
const section = publicationRehearsalAgentInstructions();
|
|
112
|
+
const start = source.indexOf(PUBLICATION_REHEARSAL_AGENT_SECTION_START);
|
|
113
|
+
const end = source.indexOf(PUBLICATION_REHEARSAL_AGENT_SECTION_END);
|
|
114
|
+
if ((start === -1) !== (end === -1)) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
"AGENTS.md has an incomplete Buildchain publication rehearsal section",
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
if (start === -1) {
|
|
120
|
+
return source.trim()
|
|
121
|
+
? `${source.trimEnd()}\n\n${section}\n`
|
|
122
|
+
: `# AGENTS.md\n\n${section}\n`;
|
|
123
|
+
}
|
|
124
|
+
if (
|
|
125
|
+
source.indexOf(PUBLICATION_REHEARSAL_AGENT_SECTION_START, start + 1) !==
|
|
126
|
+
-1 ||
|
|
127
|
+
source.indexOf(PUBLICATION_REHEARSAL_AGENT_SECTION_END, end + 1) !== -1 ||
|
|
128
|
+
end < start
|
|
129
|
+
) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
"AGENTS.md has ambiguous Buildchain publication rehearsal sections",
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
return `${source.slice(0, start)}${section}${source.slice(
|
|
135
|
+
end + PUBLICATION_REHEARSAL_AGENT_SECTION_END.length,
|
|
136
|
+
)}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function publicationRehearsalWorkflow(buildchainRef) {
|
|
140
|
+
const ref = String(buildchainRef || "").trim();
|
|
141
|
+
if (!ref)
|
|
142
|
+
throw new Error("publication rehearsal workflow requires a Buildchain ref");
|
|
143
|
+
return `name: Publication Rehearsal
|
|
144
|
+
|
|
145
|
+
on:
|
|
146
|
+
workflow_dispatch:
|
|
147
|
+
inputs:
|
|
148
|
+
capsule-path:
|
|
149
|
+
description: "Content-addressed publication rehearsal capsule"
|
|
150
|
+
required: true
|
|
151
|
+
default: ".buildchain/publication/rehearsal-capsule.json"
|
|
152
|
+
capsule-root:
|
|
153
|
+
description: "Repository-relative capsule file root"
|
|
154
|
+
required: true
|
|
155
|
+
default: ".buildchain/publication/candidate"
|
|
156
|
+
|
|
157
|
+
permissions:
|
|
158
|
+
contents: write
|
|
159
|
+
|
|
160
|
+
jobs:
|
|
161
|
+
rehearsal:
|
|
162
|
+
uses: kungfu-systems/buildchain/.github/workflows/release-tail.yml@${ref}
|
|
163
|
+
with:
|
|
164
|
+
buildchain-ref: ${ref}
|
|
165
|
+
capsule-contract: ${JSON.stringify(PUBLICATION_REHEARSAL_CAPSULE_CONTRACT)}
|
|
166
|
+
capsule-path: \${{ inputs.capsule-path }}
|
|
167
|
+
capsule-root: \${{ inputs.capsule-root }}
|
|
168
|
+
state-path: ".buildchain/publication/rehearsal-state.json"
|
|
169
|
+
evidence-path: ".buildchain/publication/rehearsal-evidence.json"
|
|
170
|
+
secrets:
|
|
171
|
+
http-token: \${{ secrets.BUILDCHAIN_PUBLICATION_HTTP_TOKEN }}
|
|
172
|
+
`;
|
|
173
|
+
}
|