@kungfu-tech/buildchain 4.0.1-alpha.3 → 4.0.1-alpha.30
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/actions/release-tail/README.md +8 -0
- package/architecture/ci-lane-change-budget.json +187 -0
- package/architecture/decisions/0002-next-development-transition.md +101 -0
- package/architecture/internal-capabilities.json +117 -8
- package/architecture/maintainability-policy.json +43 -25
- package/architecture/release-tail-contract-inventory.json +5 -2
- package/architecture/v3-core-mechanism-inventory.json +89 -0
- package/architecture/v4-adopter-delivery-parity.json +32 -5
- package/architecture/v4-capability-state-machine-manifest.json +73 -0
- package/architecture/v4-compatibility-facts-parity.json +77 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.json +15 -6
- package/architecture/v4-floating-consumer-policy.json +6 -0
- package/architecture/v4-next-development-parity.json +192 -0
- package/architecture/v4-publication-rehearsal-parity.json +84 -0
- package/architecture/v4-release-train-parity.json +1 -0
- package/architecture/v4-tail-reseal-parity.json +150 -0
- package/bin/buildchain.mjs +23 -2
- package/bin/internal/adopter-delivery-cli.mjs +70 -0
- package/bin/internal/command-registry.mjs +3 -0
- package/bin/internal/compatibility-facts-cli.mjs +101 -0
- package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +47 -0
- package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +47 -0
- package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +40 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/archive-template.json +19 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/bootstrap-positive.json +93 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/gate-positive.json +29 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/gate-unknown-selector.json +26 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/offline-vectors.json +50 -0
- package/contracts/fixtures/v4-compatibility-facts-v1/shared.json +1129 -0
- package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +7 -1
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/artifacts/product.bin +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/config/buildchain.toml +5 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/release-activation.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/signed-channel.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/evidence/qualification.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/candidate.json +5 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/release-passport.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/capsule.json +707 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/offline-vectors.json +27 -0
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +229 -0
- package/contracts/next-development-request-v1.schema.json +66 -0
- package/contracts/next-development-transition-v1.schema.json +292 -0
- package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
- package/contracts/v4-compatibility-facts-v1.schema.json +230 -0
- package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +4 -2
- package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/contracts/v4-tail-reseal-v1.schema.json +276 -0
- package/dist/site/agent-index.json +4 -0
- package/dist/site/artifact-schemas.json +8 -0
- package/dist/site/buildchain-contract.json +1393 -28
- package/dist/site/buildchain-site.json +477 -32
- package/dist/site/capability-registry.json +17 -14
- package/dist/site/cli-registry.json +159 -1
- package/dist/site/kfd-claims.json +455 -15
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +53 -7
- package/dist/site/node-api-registry.json +13921 -9565
- package/dist/site/page-registry.json +442 -21
- package/dist/site/public-surface-audit.json +440 -11
- package/dist/site/publication-authority-registry.json +44 -8
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +22 -0
- package/dist/site/schemas/release-tail-capabilities-v1.schema.json +199 -0
- package/dist/site/schemas/v4-adopter-delivery-v1.schema.json +81 -0
- package/dist/site/schemas/v4-compatibility-facts-v1.schema.json +230 -0
- package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/dist/site/site-manifest.json +35 -11
- package/dist/site/workflow-registry.json +142 -8
- package/docs/MAP.md +7 -2
- package/docs/cli-reference.md +193 -0
- package/docs/cli.md +8 -0
- package/docs/dev-alpha-candidate-patrol.md +8 -0
- package/docs/dev-delivery-warrant.md +30 -5
- package/docs/next-development-transition.md +118 -0
- package/docs/node-api-reference.md +578 -285
- package/docs/release-candidate.md +7 -0
- package/docs/release-tail-provider-plane.md +30 -0
- package/docs/v4-adopter-delivery.md +133 -0
- package/docs/v4-compatibility-facts.md +91 -0
- package/docs/v4-publication-rehearsal.md +130 -0
- package/docs/v4-tail-reseal.md +73 -0
- package/docs/versioning.md +4 -3
- package/package.json +30 -6
- package/packages/core/adopter-delivery-passport.js +259 -0
- package/packages/core/adopter-delivery-vectors.js +158 -0
- package/packages/core/adopter-delivery-vectors.json +77 -0
- package/packages/core/buildchain-agent-manuals.js +3 -0
- package/packages/core/buildchain-compatibility-authority.js +336 -0
- package/packages/core/buildchain-compatibility-fact.js +394 -0
- package/packages/core/buildchain-compatibility-facts.json +217 -0
- package/packages/core/buildchain-compatibility-proof.js +566 -0
- package/packages/core/buildchain-config.js +84 -0
- package/packages/core/buildchain-contract.js +93 -141
- package/packages/core/buildchain-delivery-bootstrap.js +240 -0
- package/packages/core/buildchain-delivery-infrastructure.js +164 -0
- package/packages/core/buildchain-delivery-self-dogfood.js +395 -0
- package/packages/core/buildchain-publication-authority.js +1 -0
- package/packages/core/channel-candidate.js +8 -0
- package/packages/core/channel-promotion-baseline.js +55 -0
- package/packages/core/ci-lane-change-budget.js +247 -0
- package/packages/core/dev-alpha-candidate-selection.js +10 -2
- package/packages/core/dev-delivery-execution-transfer.js +21 -1
- package/packages/core/dev-delivery-native-proof.js +43 -27
- package/packages/core/dev-delivery-process-boundary.js +19 -7
- package/packages/core/dev-delivery-provider-heartbeat.js +18 -6
- package/packages/core/dev-delivery-warrant-state.js +32 -10
- package/packages/core/dev-delivery-warrant.js +9 -3
- package/packages/core/github-governance-authority.js +1 -0
- package/packages/core/index.js +5 -0
- package/packages/core/kungfu-temporal-fact.js +557 -0
- package/packages/core/legacy-kfd-adopter-driver.js +167 -0
- package/packages/core/next-development-candidate-reservation.js +186 -0
- package/packages/core/next-development-controller.js +728 -0
- package/packages/core/next-development-projection.js +287 -0
- package/packages/core/next-development-transition.js +738 -0
- package/packages/core/paper-agent-entry.js +11 -5
- package/packages/core/paper.js +16 -5
- package/packages/core/published-delivery-authority.js +266 -0
- package/packages/core/release-candidate-recovery.js +70 -15
- package/packages/core/release-candidate.js +2 -2
- package/packages/core/release-passport.js +36 -9
- package/packages/core/v4-adopter-delivery-parity.js +3 -3
- package/packages/core/v4-adopter-delivery.js +359 -0
- package/packages/core/v4-canonical-contracts.js +5 -0
- package/packages/core/v4-delivery-warrant-read-candidate.js +10 -3
- package/packages/core/v4-floating-consumer-evidence.js +18 -4
- package/packages/core/v4-floating-consumer-policy.js +143 -20
- package/packages/core/v4-floating-consumer-release-passport.js +35 -8
- package/packages/core/v4-publication-rehearsal-capsule.js +468 -0
- package/packages/core/v4-publication-rehearsal-provider-bindings.js +212 -0
- package/packages/core/v4-publication-rehearsal.js +481 -0
- package/packages/core/v4-tail-reseal-contract.js +26 -0
- package/packages/core/v4-tail-reseal-github.js +178 -0
- package/packages/core/v4-tail-reseal-receipt.js +225 -0
- package/packages/core/v4-tail-reseal.js +594 -0
- package/packages/core/workflow-yaml-contract.js +24 -2
- package/scripts/artifact-signing-controller-core.mjs +1 -1
- package/scripts/buildchain-cli-help.mjs +30 -0
- package/scripts/check-ci-lane-change-budget.mjs +100 -0
- package/scripts/check-inventory.mjs +14 -3
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +23 -4
- package/scripts/dev-alpha-candidate-patrol.mjs +22 -1
- package/scripts/dev-delivery-source-proof-replay.mjs +153 -0
- package/scripts/dev-delivery-source-proof-reuse.mjs +13 -97
- package/scripts/dev-delivery-warrant-store.mjs +10 -6
- package/scripts/dev-delivery-warrant.mjs +5 -1
- package/scripts/dev-pr-auto-merge.mjs +1 -1
- package/scripts/dev-pr-delivery-warrant.mjs +1 -0
- package/scripts/dev-pr-prequeue-guard.mjs +0 -18
- package/scripts/dev-qualification-patrol.mjs +9 -9
- package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
- package/scripts/generate-channel-promotion-workflow.mjs +2 -2
- package/scripts/generate-next-development-guidance.mjs +49 -0
- package/scripts/generate-release-candidate-passport.mjs +152 -0
- package/scripts/generate-site-bundle.mjs +46 -3
- package/scripts/init-repo.mjs +22 -4
- package/scripts/next-development-self-dogfood-harness.mjs +460 -0
- package/scripts/next-development-self-dogfood.mjs +597 -0
- package/scripts/next-development-transition.mjs +47 -0
- package/scripts/promotion-channel-router.mjs +4 -4
- package/scripts/release-candidate-anchor-provenance.mjs +99 -0
- package/scripts/release-tail.mjs +51 -3
- package/scripts/release-train-self-dogfood.mjs +94 -92
- package/scripts/resume-from-candidate-run.mjs +560 -30
- package/scripts/site-capability-metadata.mjs +29 -0
- package/scripts/stable-candidate-qualification.mjs +9 -10
- package/scripts/v4-consumer-policy.mjs +5 -5
- package/scripts/v4-publication-rehearsal-fixture.mjs +144 -0
- package/scripts/v4-tail-reseal-macos-rehearsal.mjs +134 -0
- package/scripts/v4-tail-reseal.mjs +416 -0
- package/templates/native-dev-delivery.yml +2 -0
|
@@ -46,7 +46,7 @@ function decodeBlob(blob) {
|
|
|
46
46
|
).toString("utf8");
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function validateStoredState(queue) {
|
|
49
|
+
function validateStoredState(queue, { allowLegacyV3Readback = false } = {}) {
|
|
50
50
|
const body = structuredClone(queue || {});
|
|
51
51
|
const embeddedStateRoot = body.stateRoot;
|
|
52
52
|
delete body.stateRoot;
|
|
@@ -59,7 +59,7 @@ function validateStoredState(queue) {
|
|
|
59
59
|
) {
|
|
60
60
|
normalizeDevDeliveryAuthorityState(queue);
|
|
61
61
|
} else {
|
|
62
|
-
normalizeDevDeliveryQueue(queue);
|
|
62
|
+
normalizeDevDeliveryQueue(queue, { allowLegacyV3Readback });
|
|
63
63
|
}
|
|
64
64
|
return queue;
|
|
65
65
|
}
|
|
@@ -108,7 +108,7 @@ export class GitHubDevDeliveryStore {
|
|
|
108
108
|
return data;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
async read({ stateRef, protectedBase, now }) {
|
|
111
|
+
async read({ stateRef, protectedBase, now, allowLegacyV3Readback = false }) {
|
|
112
112
|
let ref;
|
|
113
113
|
try {
|
|
114
114
|
ref = await this.request(
|
|
@@ -128,11 +128,13 @@ export class GitHubDevDeliveryStore {
|
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
130
|
const commitSha = exactSha(ref?.object?.sha, "state ref commit");
|
|
131
|
-
const readback = await this.readCommit(commitSha
|
|
131
|
+
const readback = await this.readCommit(commitSha, {
|
|
132
|
+
allowLegacyV3Readback,
|
|
133
|
+
});
|
|
132
134
|
return { exists: true, ...readback };
|
|
133
135
|
}
|
|
134
136
|
|
|
135
|
-
async readCommit(commitShaInput) {
|
|
137
|
+
async readCommit(commitShaInput, { allowLegacyV3Readback = false } = {}) {
|
|
136
138
|
const commitSha = exactSha(commitShaInput, "state commit");
|
|
137
139
|
const commit = await this.request(
|
|
138
140
|
"GET",
|
|
@@ -152,7 +154,9 @@ export class GitHubDevDeliveryStore {
|
|
|
152
154
|
`/repos/${this.repository.fullName}/git/blobs/${entry.sha}`,
|
|
153
155
|
);
|
|
154
156
|
const bytes = decodeBlob(blob);
|
|
155
|
-
const queue = validateStoredState(JSON.parse(bytes)
|
|
157
|
+
const queue = validateStoredState(JSON.parse(bytes), {
|
|
158
|
+
allowLegacyV3Readback,
|
|
159
|
+
});
|
|
156
160
|
return { commitSha, queue, bytes };
|
|
157
161
|
}
|
|
158
162
|
|
|
@@ -295,7 +295,10 @@ async function observeQueue(loaded, options) {
|
|
|
295
295
|
const readMode = text(options.readMode || "v3").toLowerCase();
|
|
296
296
|
if (!["v3", "v4"].includes(readMode))
|
|
297
297
|
throw new Error("readMode must be v3 or v4");
|
|
298
|
-
let observation = observeDevDeliveryQueue(loaded.queue, {
|
|
298
|
+
let observation = observeDevDeliveryQueue(loaded.queue, {
|
|
299
|
+
now: options.now,
|
|
300
|
+
allowLegacyV3Readback: true,
|
|
301
|
+
});
|
|
299
302
|
let readCandidate;
|
|
300
303
|
if (readMode === "v4") {
|
|
301
304
|
const qualification =
|
|
@@ -374,6 +377,7 @@ export async function runDevDeliveryCommand(optionsInput = {}, clientInput) {
|
|
|
374
377
|
stateRef: options.stateRef,
|
|
375
378
|
protectedBase: options.branch,
|
|
376
379
|
now: options.now,
|
|
380
|
+
allowLegacyV3Readback: options.command === "observe",
|
|
377
381
|
});
|
|
378
382
|
if (
|
|
379
383
|
options.expectedOldStateRoot &&
|
|
@@ -70,7 +70,7 @@ function normalizeOptions(options = {}) {
|
|
|
70
70
|
allowedHeadPrefixes: splitList(options.allowedHeadPrefixes, DEFAULT_ALLOWED_HEAD_PREFIXES),
|
|
71
71
|
requiredChecks: splitList(options.requiredChecks, DEFAULT_REQUIRED_CHECKS),
|
|
72
72
|
queueAdmissionContext: String(options.queueAdmissionContext || "").trim(),
|
|
73
|
-
activeLeaseContext: String(options.activeLeaseContext || "").trim(),
|
|
73
|
+
activeLeaseContext: String(options.activeLeaseContext || (choiceOption(options.warrantMode, VALID_WARRANT_MODES, "off", "delivery Warrant mode") === "required" ? "Queue family lease/exact" : "")).trim(),
|
|
74
74
|
requireApproval: boolOption(options.requireApproval, true),
|
|
75
75
|
sameRepositoryOnly: boolOption(options.sameRepositoryOnly, true),
|
|
76
76
|
maxMerges: intOption(options.maxMerges, 1),
|
|
@@ -143,6 +143,7 @@ export async function readCurrentDeliveryQueueState(client, repository, targetBr
|
|
|
143
143
|
const { queue } = await store.read({
|
|
144
144
|
stateRef: defaultDevDeliveryStateRef(targetBranch),
|
|
145
145
|
protectedBase: targetBranch,
|
|
146
|
+
allowLegacyV3Readback: true,
|
|
146
147
|
});
|
|
147
148
|
return queue;
|
|
148
149
|
}
|
|
@@ -164,15 +164,6 @@ async function qualifyProjectCut({
|
|
|
164
164
|
|
|
165
165
|
let reuseDecision = null;
|
|
166
166
|
if (currentBaseSha !== previousBaseSha) {
|
|
167
|
-
const observedPullRequestBase = String(
|
|
168
|
-
observedPullRequest.base?.sha || "",
|
|
169
|
-
).toLowerCase();
|
|
170
|
-
if (observedPullRequestBase !== currentBaseSha) {
|
|
171
|
-
mismatch("pre-enqueue-project-cut-base-stale", {
|
|
172
|
-
observedPullRequestBase,
|
|
173
|
-
currentBaseSha,
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
167
|
const proof = readOptionalJson(options.sourceProofPath);
|
|
177
168
|
if (!proof) mismatch("pre-enqueue-base-attribution-unknown");
|
|
178
169
|
if (
|
|
@@ -342,15 +333,6 @@ export async function qualifyPreEnqueueReadback({
|
|
|
342
333
|
) {
|
|
343
334
|
mismatch("head-sha-drift-after-project-cut");
|
|
344
335
|
}
|
|
345
|
-
const casPullRequestBase = String(
|
|
346
|
-
casPullRequest.base?.sha || "",
|
|
347
|
-
).toLowerCase();
|
|
348
|
-
if (casPullRequestBase && casPullRequestBase !== casBaseSha) {
|
|
349
|
-
mismatch("pre-enqueue-project-cut-base-stale", {
|
|
350
|
-
observedPullRequestBase: casPullRequestBase,
|
|
351
|
-
currentBaseSha: casBaseSha,
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
336
|
if (casPullRequest.mergeable === false) {
|
|
355
337
|
mismatch("pre-enqueue-merge-conflict-after-project-cut");
|
|
356
338
|
}
|
|
@@ -501,16 +501,16 @@ export function createGitHubDevQualificationClient({
|
|
|
501
501
|
sourceBranch,
|
|
502
502
|
{ activeOnly = false } = {},
|
|
503
503
|
) {
|
|
504
|
-
const query = sourceBranch
|
|
505
|
-
|
|
506
|
-
: ""
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
504
|
+
const query = sourceBranch ? `branch=${encodeRef(sourceBranch)}&` : "";
|
|
505
|
+
const runs = await Promise.all(
|
|
506
|
+
[...(activeOnly ? ACTIVE_STATUSES : [""])].map((status) =>
|
|
507
|
+
paged(
|
|
508
|
+
`/repos/${owner}/${repo}/actions/workflows/${encodeURIComponent(workflow)}/runs?${query}${status ? `status=${status}` : ""}`,
|
|
509
|
+
"workflow_runs",
|
|
510
|
+
),
|
|
511
|
+
),
|
|
510
512
|
);
|
|
511
|
-
return
|
|
512
|
-
? runs.filter((run) => ACTIVE_STATUSES.has(text(run.status)))
|
|
513
|
-
: runs;
|
|
513
|
+
return runs.flat();
|
|
514
514
|
},
|
|
515
515
|
async listRunJobs(runId, runAttempt) {
|
|
516
516
|
return paged(
|
|
@@ -24,7 +24,7 @@ const AUTHORITY_WORKFLOW = "artifact-signing-authority.yml";
|
|
|
24
24
|
|
|
25
25
|
export function resolveAuthorityDispatchRef(value) {
|
|
26
26
|
const ref = required(value, "authority ref");
|
|
27
|
-
return /^[0-9a-f]{40}$/u.test(ref)
|
|
27
|
+
return /^[0-9a-f]{40}$/u.test(ref) || /^v\d+(?:\.\d+)?(?:-alpha)?$/u.test(ref)
|
|
28
28
|
? DEFAULT_ARTIFACT_SIGNING_AUTHORITY_REF
|
|
29
29
|
: ref;
|
|
30
30
|
}
|
|
@@ -159,8 +159,8 @@ function validateWorkflowRoute(name, route, expectedLogicalRef) {
|
|
|
159
159
|
if (!/^\.github\/workflows\/[.a-z0-9-]+\.ya?ml$/.test(route.workflowPath || "")) {
|
|
160
160
|
throw new Error(`promotion shell ${name} workflowPath must name a reusable workflow`);
|
|
161
161
|
}
|
|
162
|
-
if (!/^(?:v[0-9]+(?:-alpha)?|train\/[A-Za-z0-9._+\/-]+|[0-9a-f]{40})$/.test(route.callRef || "")) {
|
|
163
|
-
throw new Error(`promotion shell ${name} callRef must be an official channel ref, trusted train, or exact SHA`);
|
|
162
|
+
if (!/^(?:v[0-9]+(?:-alpha)?|(?:train|alpha|release)\/[A-Za-z0-9._+\/-]+|[0-9a-f]{40})$/.test(route.callRef || "")) {
|
|
163
|
+
throw new Error(`promotion shell ${name} callRef must be an official tag, protected channel ref, trusted train, or exact SHA`);
|
|
164
164
|
}
|
|
165
165
|
if (typeof route.forwardInternalInputs !== "boolean") {
|
|
166
166
|
throw new Error(`promotion shell ${name} forwardInternalInputs must be boolean`);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
|
|
7
|
+
import { nextDevelopmentManual } from "../packages/core/next-development-projection.js";
|
|
8
|
+
|
|
9
|
+
export const NEXT_DEVELOPMENT_MANUAL_PATH =
|
|
10
|
+
"docs/next-development-transition.md";
|
|
11
|
+
|
|
12
|
+
export function generateNextDevelopmentGuidance({
|
|
13
|
+
cwd = process.cwd(),
|
|
14
|
+
check = false,
|
|
15
|
+
} = {}) {
|
|
16
|
+
const target = path.resolve(cwd, NEXT_DEVELOPMENT_MANUAL_PATH);
|
|
17
|
+
const expected = nextDevelopmentManual();
|
|
18
|
+
const current = fs.existsSync(target) ? fs.readFileSync(target, "utf8") : "";
|
|
19
|
+
if (check) {
|
|
20
|
+
if (current !== expected) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`${NEXT_DEVELOPMENT_MANUAL_PATH} drifted from its contract source`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return { ok: true, changed: false, path: NEXT_DEVELOPMENT_MANUAL_PATH };
|
|
26
|
+
}
|
|
27
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
28
|
+
if (current !== expected) fs.writeFileSync(target, expected);
|
|
29
|
+
return {
|
|
30
|
+
ok: true,
|
|
31
|
+
changed: current !== expected,
|
|
32
|
+
path: NEXT_DEVELOPMENT_MANUAL_PATH,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (
|
|
37
|
+
process.argv[1] &&
|
|
38
|
+
import.meta.url === pathToFileURL(process.argv[1]).href
|
|
39
|
+
) {
|
|
40
|
+
try {
|
|
41
|
+
const result = generateNextDevelopmentGuidance({
|
|
42
|
+
check: process.argv.includes("--check"),
|
|
43
|
+
});
|
|
44
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
process.stderr.write(`next-development guidance: ${error.message}\n`);
|
|
47
|
+
process.exitCode = 1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -5,11 +5,160 @@ import { execFileSync } from "node:child_process";
|
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
6
|
import { createReleaseCandidatePassport, validateReleaseCandidatePassport } from "../packages/core/release-candidate.js";
|
|
7
7
|
import { scanV4FloatingConsumerPolicy, v4ConsumerPolicyScannerRoot } from "../packages/core/v4-floating-consumer-policy.js";
|
|
8
|
+
import { v4ContentRoot } from "../packages/core/v4-canonical-contracts.js";
|
|
9
|
+
import { V4_STAGE_CAPSULE_CONTRACT, V4_STAGE_CAPSULE_IDENTITY_CONTRACT, v4StageCapsuleIdentityRoot, v4StageCapsuleRoot, validateV4StageCapsule } from "../packages/core/v4-stage-capsule.js";
|
|
10
|
+
import { v4RuntimeResumeDocumentRoot } from "../packages/core/v4-runtime-ref-resume-authority.js";
|
|
8
11
|
import { writeGitHubOutputs } from "./build-contract-core.mjs";
|
|
9
12
|
|
|
10
13
|
const env = (name, fallback = "") => process.env[name] || fallback;
|
|
11
14
|
const readJsonFile = (filePath) => JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
12
15
|
|
|
16
|
+
export function createReleaseCandidateStageCapsules({
|
|
17
|
+
passport,
|
|
18
|
+
buildSummary,
|
|
19
|
+
coordinates,
|
|
20
|
+
}) {
|
|
21
|
+
if (!passport.consumerPolicy?.receiptRoot) return undefined;
|
|
22
|
+
if (
|
|
23
|
+
coordinates.repository !== passport.repository ||
|
|
24
|
+
String(coordinates.runId) !== String(passport.workflow.runId) ||
|
|
25
|
+
String(coordinates.runAttempt) !== String(passport.workflow.runAttempt) ||
|
|
26
|
+
coordinates.sourceSha !== passport.source.headSha
|
|
27
|
+
) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
"Stage Capsule coordinate set does not bind the candidate run",
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
const coordinateByPlatform = new Map(
|
|
33
|
+
coordinates.artifacts.map((entry) => [entry.platformId, entry]),
|
|
34
|
+
);
|
|
35
|
+
const qualificationRoot = passport.controllerReceipts?.[0]?.receiptDigest;
|
|
36
|
+
const entries = passport.platformMatrix
|
|
37
|
+
.map((platform) => {
|
|
38
|
+
const coordinate = coordinateByPlatform.get(platform.platformId);
|
|
39
|
+
if (!coordinate || coordinate.name !== platform.artifactName) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Stage Capsule coordinate missing for ${platform.platformId}`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
const manifest = readJsonFile(platform.manifestPath);
|
|
45
|
+
const identity = {
|
|
46
|
+
schema: V4_STAGE_CAPSULE_IDENTITY_CONTRACT,
|
|
47
|
+
sourceRoot: v4ContentRoot("candidate-identity", passport.source),
|
|
48
|
+
platform: platform.platformId,
|
|
49
|
+
platformRoot: v4ContentRoot("candidate-identity", manifest.platform),
|
|
50
|
+
stage: "verify",
|
|
51
|
+
toolchainRoots: [],
|
|
52
|
+
runtimeRoot: v4ContentRoot("candidate-identity", {
|
|
53
|
+
sha: passport.buildchain.sha,
|
|
54
|
+
}),
|
|
55
|
+
policyRoot: passport.consumerPolicy.receiptRoot,
|
|
56
|
+
declaredInputs: [
|
|
57
|
+
{
|
|
58
|
+
name: "release-candidate",
|
|
59
|
+
root: `sha256:${passport.candidateHash}`,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
transformationRoot: v4ContentRoot("candidate-identity", {
|
|
63
|
+
lifecycle: manifest.lifecycle,
|
|
64
|
+
summary: platform.summary,
|
|
65
|
+
}),
|
|
66
|
+
outputManifestRoot: v4ContentRoot(
|
|
67
|
+
"stage-capsule-artifact-manifest",
|
|
68
|
+
{ artifact: coordinate, manifest },
|
|
69
|
+
),
|
|
70
|
+
qualificationRoot,
|
|
71
|
+
observationRoots: [
|
|
72
|
+
{
|
|
73
|
+
name: "provider-coordinate",
|
|
74
|
+
root: v4ContentRoot("provider-readback-sample", coordinate),
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
const capsule = {
|
|
79
|
+
schema: V4_STAGE_CAPSULE_CONTRACT,
|
|
80
|
+
writerAuthority: "typescript-v3",
|
|
81
|
+
rustAuthority: "validation-only",
|
|
82
|
+
identity,
|
|
83
|
+
identityRoot: v4StageCapsuleIdentityRoot(identity),
|
|
84
|
+
retentionPromise: {
|
|
85
|
+
class: "github-artifact",
|
|
86
|
+
retainUntil: coordinate.expiresAt,
|
|
87
|
+
},
|
|
88
|
+
capsuleRoot: `sha256:${"0".repeat(64)}`,
|
|
89
|
+
};
|
|
90
|
+
capsule.capsuleRoot = v4StageCapsuleRoot(capsule);
|
|
91
|
+
validateV4StageCapsule(capsule);
|
|
92
|
+
return {
|
|
93
|
+
platform: platform.platformId,
|
|
94
|
+
artifactName: coordinate.name,
|
|
95
|
+
artifactDigest: coordinate.digest,
|
|
96
|
+
artifact: coordinate,
|
|
97
|
+
capsule,
|
|
98
|
+
};
|
|
99
|
+
})
|
|
100
|
+
.sort((left, right) => left.platform.localeCompare(right.platform));
|
|
101
|
+
const body = {
|
|
102
|
+
schemaVersion: 1,
|
|
103
|
+
contract: "kungfu-buildchain-v4-release-candidate-stage-capsules/v1",
|
|
104
|
+
status: "sealed",
|
|
105
|
+
repository: passport.repository,
|
|
106
|
+
buildAttempt: {
|
|
107
|
+
id: `github-run:${passport.workflow.runId}:attempt:${passport.workflow.runAttempt}`,
|
|
108
|
+
runtimeSha: passport.buildchain.sha,
|
|
109
|
+
},
|
|
110
|
+
source: {
|
|
111
|
+
sha: passport.source.headSha,
|
|
112
|
+
treeSha: passport.source.treeHash,
|
|
113
|
+
},
|
|
114
|
+
consumerPolicyReceiptRoot: passport.consumerPolicy.receiptRoot,
|
|
115
|
+
capsules: entries,
|
|
116
|
+
};
|
|
117
|
+
return { ...body, root: v4RuntimeResumeDocumentRoot(body) };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function writeReleaseCandidateStageCapsules({
|
|
121
|
+
passport,
|
|
122
|
+
buildSummary,
|
|
123
|
+
outputPath,
|
|
124
|
+
}) {
|
|
125
|
+
const coordinatesPath = path.resolve(
|
|
126
|
+
env(
|
|
127
|
+
"BUILDCHAIN_ARTIFACT_COORDINATES_PATH",
|
|
128
|
+
".buildchain/artifacts/artifact-coordinates.json",
|
|
129
|
+
),
|
|
130
|
+
);
|
|
131
|
+
if (!fs.existsSync(coordinatesPath)) {
|
|
132
|
+
if (passport.consumerPolicy?.receiptRoot) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
"v4 release candidate Stage Capsules require exact artifact coordinates",
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
return { path: "", root: "" };
|
|
138
|
+
}
|
|
139
|
+
const stageCapsules = createReleaseCandidateStageCapsules({
|
|
140
|
+
passport,
|
|
141
|
+
buildSummary,
|
|
142
|
+
coordinates: readJsonFile(coordinatesPath),
|
|
143
|
+
});
|
|
144
|
+
if (!stageCapsules) return { path: "", root: "" };
|
|
145
|
+
const stageCapsulesPath = path.join(
|
|
146
|
+
path.dirname(outputPath),
|
|
147
|
+
"release-candidate-stage-capsules.json",
|
|
148
|
+
);
|
|
149
|
+
fs.writeFileSync(
|
|
150
|
+
stageCapsulesPath,
|
|
151
|
+
`${JSON.stringify(stageCapsules, null, 2)}\n`,
|
|
152
|
+
);
|
|
153
|
+
return {
|
|
154
|
+
path: path
|
|
155
|
+
.relative(process.cwd(), stageCapsulesPath)
|
|
156
|
+
.split(path.sep)
|
|
157
|
+
.join("/"),
|
|
158
|
+
root: stageCapsules.root,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
13
162
|
export function resolveLegacyConsumerPolicyReceipt(options = {}) {
|
|
14
163
|
if (options.json) return { receipt: JSON.parse(options.json), receiptRoot: options.receiptRoot };
|
|
15
164
|
if (options.repository !== "kungfu-systems/buildchain" || options.targetChannel !== "alpha" || options.workflowShellRef !== "v4-alpha" || options.runtimeOverride !== true) return undefined;
|
|
@@ -80,6 +229,7 @@ export function generateReleaseCandidatePassportCli() {
|
|
|
80
229
|
if (!validation.ok) throw new Error(`release candidate passport invalid: ${validation.errors.join("; ")}`);
|
|
81
230
|
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
82
231
|
fs.writeFileSync(outputPath, `${JSON.stringify(passport, null, 2)}\n`);
|
|
232
|
+
const stageCapsules = writeReleaseCandidateStageCapsules({ passport, buildSummary, outputPath });
|
|
83
233
|
writeGitHubOutputs({
|
|
84
234
|
"release-candidate-passport-path": path.relative(process.cwd(), outputPath).split(path.sep).join("/"),
|
|
85
235
|
"release-candidate-passport-json": JSON.stringify({
|
|
@@ -94,6 +244,8 @@ export function generateReleaseCandidatePassportCli() {
|
|
|
94
244
|
consumerPolicy: passport.consumerPolicy,
|
|
95
245
|
controllerReceipts: passport.controllerReceipts || [],
|
|
96
246
|
}),
|
|
247
|
+
"release-candidate-stage-capsules-path": stageCapsules.path,
|
|
248
|
+
"release-candidate-stage-capsules-root": stageCapsules.root,
|
|
97
249
|
});
|
|
98
250
|
return passport;
|
|
99
251
|
}
|
|
@@ -50,6 +50,27 @@ const DEV_DELIVERY_AUTHORITY_SCHEMA =
|
|
|
50
50
|
"schemas/dev-delivery-authority-v2.schema.json";
|
|
51
51
|
const DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE =
|
|
52
52
|
"contracts/dev-delivery-authority-v2.schema.json";
|
|
53
|
+
const V4_COMPATIBILITY_FACTS_SCHEMA =
|
|
54
|
+
"schemas/v4-compatibility-facts-v1.schema.json";
|
|
55
|
+
const V4_COMPATIBILITY_FACTS_SCHEMA_SOURCE =
|
|
56
|
+
"contracts/v4-compatibility-facts-v1.schema.json";
|
|
57
|
+
const V4_PUBLICATION_REHEARSAL_SCHEMA =
|
|
58
|
+
"schemas/v4-publication-rehearsal-capsule-v1.schema.json";
|
|
59
|
+
const V4_PUBLICATION_REHEARSAL_SCHEMA_SOURCE =
|
|
60
|
+
"contracts/v4-publication-rehearsal-capsule-v1.schema.json";
|
|
61
|
+
const V4_ADOPTER_DELIVERY_SCHEMA =
|
|
62
|
+
"schemas/v4-adopter-delivery-v1.schema.json";
|
|
63
|
+
const V4_ADOPTER_DELIVERY_SCHEMA_SOURCE =
|
|
64
|
+
"contracts/v4-adopter-delivery-v1.schema.json";
|
|
65
|
+
const RELEASE_TAIL_CAPABILITIES_SCHEMA =
|
|
66
|
+
"schemas/release-tail-capabilities-v1.schema.json";
|
|
67
|
+
const RELEASE_TAIL_CAPABILITIES_SCHEMA_SOURCE =
|
|
68
|
+
"contracts/release-tail-capabilities-v1.schema.json";
|
|
69
|
+
const PUBLICATION_REHEARSAL_SITE_SCHEMAS = [
|
|
70
|
+
V4_PUBLICATION_REHEARSAL_SCHEMA,
|
|
71
|
+
V4_ADOPTER_DELIVERY_SCHEMA,
|
|
72
|
+
RELEASE_TAIL_CAPABILITIES_SCHEMA,
|
|
73
|
+
];
|
|
53
74
|
const root = path.resolve(import.meta.dirname, "..");
|
|
54
75
|
const outputDir = path.join(root, "dist", "site");
|
|
55
76
|
const requireFromHere = createRequire(import.meta.url);
|
|
@@ -78,9 +99,12 @@ function stableJson(value) {
|
|
|
78
99
|
}
|
|
79
100
|
|
|
80
101
|
function siteFileBytes(name, value) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
102
|
+
if (name === DEV_DELIVERY_AUTHORITY_SCHEMA) return readText(DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE);
|
|
103
|
+
if (name === V4_COMPATIBILITY_FACTS_SCHEMA) return readText(V4_COMPATIBILITY_FACTS_SCHEMA_SOURCE);
|
|
104
|
+
if (name === V4_PUBLICATION_REHEARSAL_SCHEMA) return readText(V4_PUBLICATION_REHEARSAL_SCHEMA_SOURCE);
|
|
105
|
+
if (name === V4_ADOPTER_DELIVERY_SCHEMA) return readText(V4_ADOPTER_DELIVERY_SCHEMA_SOURCE);
|
|
106
|
+
if (name === RELEASE_TAIL_CAPABILITIES_SCHEMA) return readText(RELEASE_TAIL_CAPABILITIES_SCHEMA_SOURCE);
|
|
107
|
+
return stableJson(value);
|
|
84
108
|
}
|
|
85
109
|
|
|
86
110
|
function writeSiteFile(name, value) {
|
|
@@ -383,13 +407,16 @@ const manualMetaById = new Map(Object.entries({
|
|
|
383
407
|
"release-activation-transaction": { capabilityGroup: "release-passport-trust", audience: ["release-operator", "agent"], maturity: "preview", order: 125 },
|
|
384
408
|
"release-candidate": { capabilityGroup: "reusable-build", audience: ["release-operator", "consumer"], maturity: "stable", order: 130 },
|
|
385
409
|
"release-train": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 132 },
|
|
410
|
+
"next-development-transition": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 133 },
|
|
386
411
|
"stable-candidate-patrol": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer"], maturity: "preview", order: 135 },
|
|
387
412
|
"dev-qualification-patrol": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 136 },
|
|
388
413
|
"dev-alpha-candidate-patrol": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 137 },
|
|
389
414
|
"v4-canonical-contracts": { capabilityGroup: "governance-versioning", audience: ["developer", "maintainer", "agent"], maturity: "preview", order: 138 },
|
|
415
|
+
"v4-compatibility-facts": { capabilityGroup: "governance-versioning", audience: ["developer", "maintainer", "agent"], maturity: "preview", order: 139 },
|
|
390
416
|
"observed-evidence-patrol": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 140 },
|
|
391
417
|
"engineering-housekeeper": { capabilityGroup: "governance-versioning", audience: ["maintainer", "consumer", "agent"], maturity: "preview", order: 145 },
|
|
392
418
|
"reusable-build-surface": { capabilityGroup: "reusable-build", audience: ["consumer", "release-operator"], maturity: "stable", order: 200 },
|
|
419
|
+
"v4-adopter-delivery": { capabilityGroup: "reusable-build", audience: ["consumer", "developer", "agent"], maturity: "preview", order: 205 },
|
|
393
420
|
"lifecycle-protocol": { capabilityGroup: "reusable-build", audience: ["consumer", "developer"], maturity: "stable", order: 210 },
|
|
394
421
|
"runtime-train-validation": { capabilityGroup: "governance-versioning", audience: ["maintainer", "consumer"], maturity: "stable", order: 220 },
|
|
395
422
|
"kfd-support": { capabilityGroup: "kfd-trust", audience: ["agent", "maintainer"], maturity: "stable", order: 300 },
|
|
@@ -753,6 +780,7 @@ function buildSiteBundle() {
|
|
|
753
780
|
"docs/reusable-build-surface.md",
|
|
754
781
|
"docs/release-candidate.md",
|
|
755
782
|
"docs/release-train.md",
|
|
783
|
+
"docs/next-development-transition.md",
|
|
756
784
|
"docs/stable-candidate-patrol.md",
|
|
757
785
|
"docs/dev-qualification-patrol.md",
|
|
758
786
|
"docs/dev-alpha-candidate-patrol.md",
|
|
@@ -948,6 +976,8 @@ function buildSiteBundle() {
|
|
|
948
976
|
"schemas/kfd-agent-hub-adoption.schema.json",
|
|
949
977
|
"schemas/kfd-product-gate-input-v1.schema.json",
|
|
950
978
|
"schemas/dev-delivery-authority-v2.schema.json",
|
|
979
|
+
"schemas/v4-compatibility-facts-v1.schema.json",
|
|
980
|
+
...PUBLICATION_REHEARSAL_SITE_SCHEMAS,
|
|
951
981
|
"kfd-support.json",
|
|
952
982
|
"artifact-evidence.json",
|
|
953
983
|
"product-mechanism.json",
|
|
@@ -983,6 +1013,8 @@ function buildSiteBundle() {
|
|
|
983
1013
|
"schemas/kfd-agent-hub-adoption.schema.json",
|
|
984
1014
|
"schemas/kfd-product-gate-input-v1.schema.json",
|
|
985
1015
|
"schemas/dev-delivery-authority-v2.schema.json",
|
|
1016
|
+
"schemas/v4-compatibility-facts-v1.schema.json",
|
|
1017
|
+
...PUBLICATION_REHEARSAL_SITE_SCHEMAS,
|
|
986
1018
|
"buildchain-contract.json",
|
|
987
1019
|
"kfd-claims.json",
|
|
988
1020
|
"product-mechanism.json",
|
|
@@ -1114,6 +1146,8 @@ function buildSiteBundle() {
|
|
|
1114
1146
|
"schemas/kfd-agent-hub-adoption.schema.json",
|
|
1115
1147
|
"schemas/kfd-product-gate-input-v1.schema.json",
|
|
1116
1148
|
"schemas/dev-delivery-authority-v2.schema.json",
|
|
1149
|
+
"schemas/v4-compatibility-facts-v1.schema.json",
|
|
1150
|
+
...PUBLICATION_REHEARSAL_SITE_SCHEMAS,
|
|
1117
1151
|
"buildchain-contract.json",
|
|
1118
1152
|
"kfd-upstream-aggregate.json",
|
|
1119
1153
|
"kfd-claims.json",
|
|
@@ -1291,6 +1325,15 @@ function buildSiteBundle() {
|
|
|
1291
1325
|
[DEV_DELIVERY_AUTHORITY_SCHEMA]: readJson(
|
|
1292
1326
|
DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE,
|
|
1293
1327
|
),
|
|
1328
|
+
[V4_COMPATIBILITY_FACTS_SCHEMA]: readJson(
|
|
1329
|
+
V4_COMPATIBILITY_FACTS_SCHEMA_SOURCE,
|
|
1330
|
+
),
|
|
1331
|
+
...Object.fromEntries(
|
|
1332
|
+
PUBLICATION_REHEARSAL_SITE_SCHEMAS.map((name) => [
|
|
1333
|
+
name,
|
|
1334
|
+
JSON.parse(siteFileBytes(name)),
|
|
1335
|
+
]),
|
|
1336
|
+
),
|
|
1294
1337
|
"badge-endpoint-registry.json": badgeEndpointRegistry,
|
|
1295
1338
|
"publication-registry.json": publicationRegistry,
|
|
1296
1339
|
"buildchain-contract.json": createBuildchainContractWorld({ root, controllerRegistry }),
|
package/scripts/init-repo.mjs
CHANGED
|
@@ -4,6 +4,11 @@ import path from "node:path";
|
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
import { BUILDCHAIN_CONFIG_PATH } from "../packages/core/buildchain-layout.js";
|
|
6
6
|
import { detectPackageManager, assertPackageManager } from "../packages/core/package-manager.js";
|
|
7
|
+
import {
|
|
8
|
+
appendNextDevelopmentToml,
|
|
9
|
+
mergeNextDevelopmentAgentInstructions,
|
|
10
|
+
nextDevelopmentWorkflowHeader,
|
|
11
|
+
} from "../packages/core/next-development-projection.js";
|
|
7
12
|
|
|
8
13
|
const BUILDCHAIN_WORKFLOW_REF = "kungfu-systems/buildchain/.github/workflows/.build.yml@v4";
|
|
9
14
|
const DEFAULT_PUBLICATION_LATEX_IMAGE = "ghcr.io/kungfu-systems/build-images/latex-pdf-builder";
|
|
@@ -327,7 +332,7 @@ function workflowArtifactPaths(type) {
|
|
|
327
332
|
}
|
|
328
333
|
|
|
329
334
|
function publicationWorkflowYaml() {
|
|
330
|
-
return
|
|
335
|
+
return `${nextDevelopmentWorkflowHeader()}# Commit both .buildchain/contract-lock.json and .buildchain/alpha-contract-lock.json.
|
|
331
336
|
# Persist only @v4 or @v4-alpha; pass temporary train/SHA runtimes through workflow_dispatch.
|
|
332
337
|
name: Build
|
|
333
338
|
|
|
@@ -361,7 +366,7 @@ jobs:
|
|
|
361
366
|
}
|
|
362
367
|
|
|
363
368
|
function workflowYaml({ type, runnerPreset, artifactName }) {
|
|
364
|
-
return
|
|
369
|
+
return `${nextDevelopmentWorkflowHeader()}# Buildchain v4 lifecycle checkpoints are governed by architecture/v4-platform-stage-checkpoints.json.
|
|
365
370
|
# Do not add undeclared runner-only inputs, outputs, environment, or provider effects.
|
|
366
371
|
# Commit both .buildchain/contract-lock.json and .buildchain/alpha-contract-lock.json.
|
|
367
372
|
# Persist only @v4 or @v4-alpha; pass temporary train/SHA runtimes through workflow_dispatch.
|
|
@@ -407,6 +412,13 @@ function writeIfAllowed(filePath, content, { force }) {
|
|
|
407
412
|
return filePath;
|
|
408
413
|
}
|
|
409
414
|
|
|
415
|
+
function writeManagedAgentEntry(filePath, current) {
|
|
416
|
+
const content = mergeNextDevelopmentAgentInstructions(current);
|
|
417
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
418
|
+
fs.writeFileSync(filePath, content);
|
|
419
|
+
return filePath;
|
|
420
|
+
}
|
|
421
|
+
|
|
410
422
|
export function initBuildchainRepo({
|
|
411
423
|
cwd = process.cwd(),
|
|
412
424
|
type = "package",
|
|
@@ -417,7 +429,7 @@ export function initBuildchainRepo({
|
|
|
417
429
|
} = {}) {
|
|
418
430
|
const resolvedCwd = path.resolve(cwd);
|
|
419
431
|
const manager = detectOrDefaultPackageManager(resolvedCwd, packageManager);
|
|
420
|
-
const toml = (() => {
|
|
432
|
+
const toml = appendNextDevelopmentToml((() => {
|
|
421
433
|
if (type === "package") {
|
|
422
434
|
return packageToml(resolvedCwd, manager);
|
|
423
435
|
}
|
|
@@ -437,7 +449,12 @@ export function initBuildchainRepo({
|
|
|
437
449
|
return anchoredPackageToml(resolvedCwd, manager);
|
|
438
450
|
}
|
|
439
451
|
throw new Error("init --type must be one of package, native, web-surface, infra-contract, publication-artifact, or anchored-package");
|
|
440
|
-
})();
|
|
452
|
+
})());
|
|
453
|
+
|
|
454
|
+
const agentsPath = path.join(resolvedCwd, "AGENTS.md");
|
|
455
|
+
const currentAgents = fs.existsSync(agentsPath)
|
|
456
|
+
? fs.readFileSync(agentsPath, "utf8")
|
|
457
|
+
: "";
|
|
441
458
|
|
|
442
459
|
const written = [
|
|
443
460
|
writeIfAllowed(path.join(resolvedCwd, BUILDCHAIN_CONFIG_PATH), toml, { force }),
|
|
@@ -452,6 +469,7 @@ export function initBuildchainRepo({
|
|
|
452
469
|
}),
|
|
453
470
|
{ force },
|
|
454
471
|
),
|
|
472
|
+
writeManagedAgentEntry(agentsPath, currentAgents),
|
|
455
473
|
];
|
|
456
474
|
|
|
457
475
|
if (type === "anchored-package" && !fs.existsSync(path.join(resolvedCwd, "release.json"))) {
|