@kungfu-tech/buildchain 4.1.3 → 4.1.4
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/AGENTS.md +11 -13
- package/CONTRIBUTING.md +32 -9
- package/README.md +56 -140
- package/actions/release/promotion/ref/README.md +1 -1
- package/architecture/action-taxonomy.json +1 -1
- package/architecture/agent-change-map.md +32 -45
- package/architecture/build-orchestration.json +1 -1
- package/architecture/capability-state-machine-manifest.json +5 -5
- package/architecture/ci-lane-change-budget.json +92 -92
- package/architecture/code-layout.json +2 -12
- package/architecture/core-mechanisms.json +38 -39
- package/architecture/cross-platform-adopter-qualification.json +1 -1
- package/architecture/dev-delivery-orchestration.json +2 -2
- package/architecture/floating-consumer-policy.json +3 -3
- package/architecture/internal-capabilities.json +27 -28
- package/architecture/maintainability-debt.json +60 -94
- package/architecture/maintainability-policy.json +7 -13
- package/architecture/minimal-consumer-migration.json +43 -5014
- package/architecture/platform-stage-checkpoints.json +1 -1
- package/architecture/release-tail-contract.json +2 -2
- package/architecture/release-topology.json +31 -25
- package/architecture/stage-capsule-qualification.json +1 -1
- package/architecture/universal-workflow-bootstrap.json +60 -60
- package/architecture/universal-workflow-capability-policy.json +3 -3
- package/architecture/universal-workflow-fault-campaign.json +7 -7
- package/architecture/workflow-taxonomy.json +59 -60
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
- package/dist/site/buildchain-contract.json +138 -66
- package/dist/site/buildchain-site.json +257 -331
- package/dist/site/capability-registry.json +4 -4
- package/dist/site/cli-registry.json +6 -142
- package/dist/site/controller-registry.json +19 -19
- package/dist/site/kfd-claims.json +481 -529
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +22 -22
- package/dist/site/node-api-registry.json +82 -339
- package/dist/site/page-registry.json +229 -304
- package/dist/site/public-surface-audit.json +544 -754
- package/dist/site/publication-authority-registry.json +316 -316
- package/dist/site/publication-registry.json +1 -1
- package/dist/site/site-manifest.json +23 -23
- package/dist/site/workflow-registry.json +1071 -1027
- package/docs/MAP.md +28 -20
- package/docs/auditable-demo.md +17 -49
- package/docs/bootstrap-recovery.md +46 -37
- package/docs/cli-reference.md +2 -46
- package/docs/cli.md +97 -186
- package/docs/code-organization.md +7 -5
- package/docs/dev-alpha-candidate-patrol.md +19 -42
- package/docs/dev-delivery-orchestration.md +15 -11
- package/docs/dev-delivery-qualification-landing-adr.md +10 -9
- package/docs/dev-delivery-warrant.md +17 -16
- package/docs/dev-qualification-patrol.md +25 -20
- package/docs/getting-started.md +80 -139
- package/docs/github-artifact-attestation.md +31 -81
- package/docs/install.md +66 -30
- package/docs/lifecycle-protocol.md +19 -57
- package/docs/migration-inventory.md +17 -45
- package/docs/next-development-transition.md +13 -13
- package/docs/node-api-reference.md +122 -138
- package/docs/oci-publication.md +13 -10
- package/docs/publication-artifacts.md +128 -486
- package/docs/publication-authority.md +15 -45
- package/docs/publish-transaction.md +13 -11
- package/docs/release-candidate.md +126 -355
- package/docs/release-discussions.md +36 -67
- package/docs/release-flow.md +80 -339
- package/docs/release-governance.md +114 -962
- package/docs/release-promotion-request.md +45 -43
- package/docs/release-propagation.md +13 -27
- package/docs/release-tail-provider-plane.md +38 -65
- package/docs/reusable-build-surface.md +78 -196
- package/docs/runtime-train-validation.md +8 -6
- package/docs/stable-candidate-patrol.md +13 -66
- package/docs/v4-adopter-delivery.md +15 -15
- package/docs/v4-declarative-release-tail-migration.md +19 -17
- package/docs/v4-production-release.md +11 -6
- package/docs/v4-publication-rehearsal.md +12 -27
- package/docs/v4-stage-capsule.md +14 -20
- package/docs/v4-tail-reseal.md +34 -20
- package/docs/web-surface-deployments.md +26 -264
- package/docs/workflow-catalog.md +31 -31
- package/docs/workflow-path-migration.md +10 -4
- package/package.json +5 -4
- package/packages/core/adoption/buildchain-kfd-claims.js +7 -7
- package/packages/core/adoption/cli/output.mjs +1 -9
- package/packages/core/adoption/cli/product-gate.mjs +1 -15
- package/packages/core/adoption/cli/project.mjs +9 -10
- package/packages/core/adoption/cli/standards.mjs +1 -14
- package/packages/core/adoption/cli/support.mjs +0 -2
- package/packages/core/adoption/cli/surface-register.mjs +0 -2
- package/packages/core/adoption/commands/init-repo.mjs +77 -485
- package/packages/core/adoption/consumer-init.js +279 -0
- package/packages/core/adoption/qualification/admission.js +1 -1
- package/packages/core/build/cli/cache.mjs +0 -2
- package/packages/core/build/cli/facts.mjs +0 -3
- package/packages/core/build/cli/homebrew.mjs +0 -4
- package/packages/core/build/cli/lifecycle.mjs +0 -3
- package/packages/core/build/github-artifact-attestation.js +2 -2
- package/packages/core/build/platform-stage-checkpoints.js +1 -1
- package/packages/core/build/signing/dispatch.js +1 -1
- package/packages/core/consumer/buildchain-config.js +9 -0
- package/packages/core/consumer/contract/inspection.js +351 -9
- package/packages/core/consumer/contract/javascript-syntax.js +439 -0
- package/packages/core/consumer/contract/javascript-values.js +61 -0
- package/packages/core/consumer/contract/javascript.js +555 -0
- package/packages/core/consumer/contract/local-validation.js +84 -0
- package/packages/core/contracts/buildchain-contract.js +39 -8
- package/packages/core/contracts/cli/introspection.mjs +1 -9
- package/packages/core/contracts/public-surface-cli.js +0 -1
- package/packages/core/dev-delivery/dev-delivery-contract-surface.js +2 -2
- package/packages/core/governance/buildchain-publication-authority.js +24 -24
- package/packages/core/governance/cli/doctor.mjs +58 -42
- package/packages/core/governance/commands/architecture.mjs +6 -1
- package/packages/core/governance/commands/audit-publication-control-plane.mjs +1 -1
- package/packages/core/governance/commands/workflow-friction-report.mjs +1 -1
- package/packages/core/governance/github-governance-authority.js +2 -2
- package/packages/core/governance/publication/collection.js +1 -1
- package/packages/core/index.js +1 -3
- package/packages/core/observability/cli/candidate.mjs +0 -2
- package/packages/core/observability/cli/context.mjs +0 -5
- package/packages/core/observability/cli/diagnostics.mjs +0 -7
- package/packages/core/observability/cli/events.mjs +2 -10
- package/packages/core/paper/commands/paper-work-fleet-cli.mjs +1 -1
- package/packages/core/paper/commands/paper.mjs +33 -422
- package/packages/core/paper/consumer-status.js +72 -0
- package/packages/core/paper/operations/identity.js +0 -3
- package/packages/core/paper/operations/migration.js +460 -0
- package/packages/core/paper/operations/preflight-checks.js +8 -68
- package/packages/core/paper/operations/scaffold.js +16 -326
- package/packages/core/paper/operations/status.js +27 -53
- package/packages/core/paper/paper-agent-entry.js +36 -147
- package/packages/core/paper/paper-fleet.js +24 -39
- package/packages/core/paper/paper-repository.js +16 -0
- package/packages/core/paper/paper-runtime-channels.js +1 -1
- package/packages/core/paper/paper-scaffold-content.js +153 -162
- package/packages/core/paper/paper-work.js +3 -10
- package/packages/core/paper/paper.js +43 -5
- package/packages/core/providers/github/artifact-attestation.js +1 -1
- package/packages/core/providers/github/pipeline-context-artifacts.js +172 -0
- package/packages/core/publication/authority/control-plane.js +2 -2
- package/packages/core/publication/authority/seal.js +1 -1
- package/packages/core/publication/cli/dispatch.mjs +1 -12
- package/packages/core/publication/pipeline/actions.js +16 -9
- package/packages/core/publication/pipeline/apply.js +17 -9
- package/packages/core/publication/pipeline/context.js +29 -0
- package/packages/core/publication/pipeline/prepare.js +15 -6
- package/packages/core/publication/pipeline/recovery-materials.js +63 -1
- package/packages/core/publication/pipeline/recovery-prepare.js +21 -9
- package/packages/core/publication/pipeline/stable-entry.js +12 -7
- package/packages/core/publication/pipeline/stable-products.js +21 -19
- package/packages/core/publication/pipeline/version-actions.js +15 -6
- package/packages/core/publication/publication-rehearsal-projection.js +0 -9
- package/packages/core/release/cli/dispatch.mjs +1 -4
- package/packages/core/release/cli/inspection-handlers.mjs +1 -33
- package/packages/core/release/cli/release-handlers.mjs +2 -19
- package/packages/core/release/cli/verification-handlers.mjs +4 -25
- package/packages/core/release/next-development-projection.js +13 -13
- package/packages/core/release/passport/locations.js +13 -8
- package/packages/core/release/release-passport.js +70 -5
- package/packages/core/web/cli/badges.mjs +0 -4
- package/packages/core/web/publication-admission.js +1 -1
- package/packages/core/web/publication-capability.js +1 -1
- package/packages/core/web/readme-badges.js +1 -1
- package/packages/core/workflow/cli/main.mjs +1 -4
- package/packages/core/workflow/cli/process.mjs +1 -1
- package/packages/core/workflow/commands/buildchain-cli-help.mjs +2 -8
- package/packages/core/workflow/engine/conformance.js +1 -1
- package/packages/core/workflow/pipeline/build.js +21 -1
- package/packages/core/workflow/pipeline/delivery-observation.js +6 -2
- package/packages/core/workflow/workflow-taxonomy.mjs +61 -17
- package/scripts/check-code-layout.mjs +2 -0
- package/scripts/check-core-mechanism-inventory.mjs +29 -13
- package/scripts/check-floating-consumer-policy-contract.mjs +3 -3
- package/scripts/check-inventory.mjs +27 -27
- package/scripts/check-maintainability.mjs +28 -5
- package/scripts/check-public-dogfood-contract.mjs +3 -3
- package/scripts/check-release-topology.mjs +1 -1
- package/scripts/check-self-consumer-contract.mjs +7 -7
- package/scripts/check-universal-workflow-bootstrap.mjs +1 -1
- package/scripts/generate-channel-promotion-workflow.mjs +1 -1
- package/scripts/generate-minimal-consumer-contract.mjs +21 -1
- package/scripts/generate-site-bundle.mjs +2 -1
- package/scripts/generate-tail-reseal-fixture.mjs +3 -3
- package/scripts/inventory/promotion.mjs +1 -1
- package/scripts/next-development-self-dogfood-harness.mjs +1 -1
- package/scripts/next-development-self-dogfood.mjs +4 -4
- package/scripts/site-capability-metadata.mjs +2 -6
- package/scripts/source-metric-lineage.mjs +62 -7
- package/scripts/verify-golden-path.mjs +31 -35
- package/templates/native-dev-delivery.yml +1 -1
- package/templates/universal-buildchain-bootstrap.yml +1 -1
- package/packages/core/paper/operations/bootstrap.js +0 -75
- package/packages/core/paper/operations/plans.js +0 -213
- package/packages/core/paper/operations/provisioning.js +0 -113
- package/packages/core/paper/operations/scaffold-config.js +0 -77
- package/packages/core/paper/operations/scaffold-workflows.js +0 -116
- package/packages/core/paper/operations/workspace.js +0 -60
- package/packages/core/paper/paper-npm-bootstrap.js +0 -492
|
@@ -113,16 +113,21 @@ async function inspectEntryRun(listed, plan, source, host) {
|
|
|
113
113
|
const { run, jobs } = await host.runs.read(listed.id, listed.run_attempt);
|
|
114
114
|
const consumer = await pipelineEntryRun(run, plan, source, host);
|
|
115
115
|
if (!consumer) return null;
|
|
116
|
+
const productJobs = jobs.filter((job) =>
|
|
117
|
+
/(?:^| \/ )Build product \([^)]+\)$/u.test(job.name),
|
|
118
|
+
);
|
|
119
|
+
const check = await pipelineEntryCheck(run, host);
|
|
120
|
+
// Controller-only PR notifications are not new product qualifications. A
|
|
121
|
+
// failed controller must not displace an earlier actual build. Conversely,
|
|
122
|
+
// any admitted native receipt or product job (even cancelled/skipped setup)
|
|
123
|
+
// keeps the execution in scope and must qualify its original full evidence.
|
|
116
124
|
if (
|
|
117
|
-
!
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
) &&
|
|
122
|
-
run.conclusion === "success"
|
|
125
|
+
!check &&
|
|
126
|
+
(!productJobs.length ||
|
|
127
|
+
(run.conclusion === "success" &&
|
|
128
|
+
productJobs.every((job) => job.conclusion === "skipped")))
|
|
123
129
|
)
|
|
124
130
|
return null;
|
|
125
|
-
const check = await pipelineEntryCheck(run, host);
|
|
126
131
|
if (!check)
|
|
127
132
|
return {
|
|
128
133
|
status: "missing",
|
|
@@ -17,7 +17,6 @@ function assertPublishedPlan(stablePlan, source, values) {
|
|
|
17
17
|
const { plan, qualification: qualified, release } = values;
|
|
18
18
|
verifyPipelinePublicationPlan(plan);
|
|
19
19
|
if (
|
|
20
|
-
plan.evidenceVersion !== 1 ||
|
|
21
20
|
plan.channel !== "alpha" ||
|
|
22
21
|
plan.version !== stablePlan.candidateVersion ||
|
|
23
22
|
plan.tag !== source.candidate.tag ||
|
|
@@ -32,17 +31,6 @@ function assertPublishedPlan(stablePlan, source, values) {
|
|
|
32
31
|
throw new Error(
|
|
33
32
|
"Published product evidence differs from the exact Alpha contract or source",
|
|
34
33
|
);
|
|
35
|
-
if (
|
|
36
|
-
plan.publisher.repository !== "kungfu-systems/buildchain" ||
|
|
37
|
-
plan.publisher.workflow !==
|
|
38
|
-
".github/workflows/.release-pipeline-products.yml" ||
|
|
39
|
-
plan.publisher.job !== "apply" ||
|
|
40
|
-
!/^[0-9a-f]{40}$/u.test(plan.publisher.workflowSha || "") ||
|
|
41
|
-
plan.runtime.repository !== "kungfu-systems/buildchain"
|
|
42
|
-
)
|
|
43
|
-
throw new Error(
|
|
44
|
-
"Published product evidence requires the central publisher",
|
|
45
|
-
);
|
|
46
34
|
const issued = Date.parse(qualified.qualification?.issuedAt);
|
|
47
35
|
if (
|
|
48
36
|
!Number.isFinite(issued) ||
|
|
@@ -200,7 +188,11 @@ function completionTime(jobs, qualified, candidate) {
|
|
|
200
188
|
return new Date(Math.max(...values)).toISOString();
|
|
201
189
|
}
|
|
202
190
|
|
|
203
|
-
function verifyPublishedDocuments(
|
|
191
|
+
export function verifyPublishedDocuments(
|
|
192
|
+
values,
|
|
193
|
+
bundle,
|
|
194
|
+
{ directory, token, execute },
|
|
195
|
+
) {
|
|
204
196
|
const {
|
|
205
197
|
plan,
|
|
206
198
|
qualification: qualified,
|
|
@@ -208,6 +200,18 @@ function verifyPublishedDocuments(values, bundle, directory, host, execute) {
|
|
|
208
200
|
release,
|
|
209
201
|
invocation,
|
|
210
202
|
} = values;
|
|
203
|
+
if (
|
|
204
|
+
plan.evidenceVersion !== 1 ||
|
|
205
|
+
plan.publisher.repository !== "kungfu-systems/buildchain" ||
|
|
206
|
+
plan.publisher.workflow !==
|
|
207
|
+
".github/workflows/.release-pipeline-products.yml" ||
|
|
208
|
+
plan.publisher.job !== "apply" ||
|
|
209
|
+
!/^[0-9a-f]{40}$/u.test(plan.publisher.workflowSha || "") ||
|
|
210
|
+
plan.runtime.repository !== "kungfu-systems/buildchain"
|
|
211
|
+
)
|
|
212
|
+
throw new Error(
|
|
213
|
+
"Published product evidence requires the central publisher",
|
|
214
|
+
);
|
|
211
215
|
const materialization = release.versionMaterialization;
|
|
212
216
|
const signing = verifyPipelineSigning({
|
|
213
217
|
plan,
|
|
@@ -218,7 +222,7 @@ function verifyPublishedDocuments(values, bundle, directory, host, execute) {
|
|
|
218
222
|
bundle,
|
|
219
223
|
),
|
|
220
224
|
directory: path.join(directory, "signature"),
|
|
221
|
-
token
|
|
225
|
+
token,
|
|
222
226
|
// Historical evidence is checked at issue time. It never supplies fresh
|
|
223
227
|
// Stable publisher admission or extends the original receipt's lifetime.
|
|
224
228
|
evaluatedAt: qualified.qualification.issuedAt,
|
|
@@ -274,13 +278,11 @@ export async function readPipelineStableProducts(
|
|
|
274
278
|
path.join(fs.realpathSync(os.tmpdir()), "buildchain-stable-products-"),
|
|
275
279
|
);
|
|
276
280
|
try {
|
|
277
|
-
const signing = verifyPublishedDocuments(
|
|
278
|
-
evidence.values,
|
|
279
|
-
evidence.bundle,
|
|
281
|
+
const signing = verifyPublishedDocuments(evidence.values, evidence.bundle, {
|
|
280
282
|
directory,
|
|
281
|
-
host,
|
|
283
|
+
token: host.token,
|
|
282
284
|
execute,
|
|
283
|
-
);
|
|
285
|
+
});
|
|
284
286
|
await reobservePublicationBuild(qualified.build, qualified.source, host);
|
|
285
287
|
const signer = await signingRun(plan, qualified, host);
|
|
286
288
|
const completedAt = completionTime(
|
|
@@ -6,14 +6,18 @@ import { buildPipelineVersionMaterial } from "./version-build.js";
|
|
|
6
6
|
import { qualifyPipelineVersionContext } from "./version-context.js";
|
|
7
7
|
import { preparePipelinePublication } from "./prepare.js";
|
|
8
8
|
import { settlePipelinePublication } from "./settle.js";
|
|
9
|
+
import {
|
|
10
|
+
readPipelineContext,
|
|
11
|
+
writePipelineContext,
|
|
12
|
+
} from "../../providers/github/pipeline-context-artifacts.js";
|
|
9
13
|
|
|
10
|
-
const contextInput = (core) =>
|
|
11
|
-
|
|
14
|
+
const contextInput = (core, env) =>
|
|
15
|
+
readPipelineContext(core.getInput("context", { required: true }), env);
|
|
12
16
|
const directory = (env) =>
|
|
13
17
|
path.join(env.GITHUB_WORKSPACE, ".buildchain/version-material");
|
|
14
18
|
|
|
15
19
|
export async function buildPipelineVersionAction(core, env) {
|
|
16
|
-
const context = contextInput(core);
|
|
20
|
+
const context = await contextInput(core, env);
|
|
17
21
|
if (
|
|
18
22
|
context.schema !== "buildchain.pipeline-version-context/v1" ||
|
|
19
23
|
context.runId !== Number(env.GITHUB_RUN_ID) ||
|
|
@@ -36,7 +40,7 @@ export async function buildPipelineVersionAction(core, env) {
|
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
export async function materializePipelinePublicationAction(core, env) {
|
|
39
|
-
const context = contextInput(core);
|
|
43
|
+
const context = await contextInput(core, env);
|
|
40
44
|
const operation = core.getInput("operation", { required: true });
|
|
41
45
|
let result = { operation, context };
|
|
42
46
|
if (operation === "regenerate") {
|
|
@@ -58,7 +62,12 @@ export async function materializePipelinePublicationAction(core, env) {
|
|
|
58
62
|
}
|
|
59
63
|
core.setOutput("operation", result.operation);
|
|
60
64
|
core.setOutput("stable-wait", result.wait ? JSON.stringify(result.wait) : "");
|
|
61
|
-
core.setOutput(
|
|
65
|
+
core.setOutput(
|
|
66
|
+
"context",
|
|
67
|
+
operation === "regenerate"
|
|
68
|
+
? await writePipelineContext(result.context || {}, env)
|
|
69
|
+
: core.getInput("context", { required: true }),
|
|
70
|
+
);
|
|
62
71
|
core.setOutput(
|
|
63
72
|
"matrix",
|
|
64
73
|
JSON.stringify({ include: result.context?.platforms || [] }),
|
|
@@ -66,7 +75,7 @@ export async function materializePipelinePublicationAction(core, env) {
|
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
export async function materializePipelineDevelopmentAction(core, env) {
|
|
69
|
-
const context = contextInput(core);
|
|
78
|
+
const context = await contextInput(core, env);
|
|
70
79
|
if (context.preparation.purpose !== "development")
|
|
71
80
|
throw new Error(
|
|
72
81
|
"Development materialization received a different version purpose",
|
|
@@ -9,8 +9,6 @@ export const PUBLICATION_REHEARSAL_AGENT_SECTION_START =
|
|
|
9
9
|
"<!-- buildchain:publication-rehearsal:start -->";
|
|
10
10
|
export const PUBLICATION_REHEARSAL_AGENT_SECTION_END =
|
|
11
11
|
"<!-- buildchain:publication-rehearsal:end -->";
|
|
12
|
-
export const PUBLICATION_REHEARSAL_WORKFLOW_PATH =
|
|
13
|
-
".github/workflows/publication-rehearsal.yml";
|
|
14
12
|
|
|
15
13
|
export function publicationRehearsalToml() {
|
|
16
14
|
return `[publication_rehearsal]\ncontract = ${JSON.stringify(PUBLICATION_REHEARSAL_CAPSULE_CONTRACT)}\nadr = ${JSON.stringify(RELEASE_LOCAL_CONSTRUCTIBILITY_ADR)}\ninvariant = ${JSON.stringify(RELEASE_LOCAL_CONSTRUCTIBILITY_INVARIANT)}\ncommand = ${JSON.stringify(PUBLICATION_REHEARSAL_COMMAND)}\ncapsule = ".buildchain/publication-rehearsal/capsule.json"\ncandidate_root = ".buildchain/publication-rehearsal/candidate"\nstate = ".buildchain/publication-rehearsal/state.json"\nevidence = ".buildchain/publication-rehearsal/evidence.json"\n`;
|
|
@@ -95,10 +93,3 @@ export function mergePublicationRehearsalAgentInstructions(current = "") {
|
|
|
95
93
|
end + PUBLICATION_REHEARSAL_AGENT_SECTION_END.length,
|
|
96
94
|
)}`;
|
|
97
95
|
}
|
|
98
|
-
|
|
99
|
-
export function publicationRehearsalWorkflow(buildchainRef) {
|
|
100
|
-
const ref = String(buildchainRef || "").trim();
|
|
101
|
-
if (!/^v4(?:-alpha)?$/u.test(ref))
|
|
102
|
-
throw new Error("publication rehearsal workflow requires a floating public entry");
|
|
103
|
-
return `name: Publication Rehearsal\n\non:\n workflow_dispatch:\n inputs:\n capsule-path:\n description: "Source-bound v4 publication rehearsal capsule"\n required: true\n default: ".buildchain/publication-rehearsal/capsule.json"\n candidate-root:\n description: "Repository-relative candidate root"\n required: true\n default: ".buildchain/publication-rehearsal/candidate"\n\npermissions:\n contents: read\n\njobs:\n rehearsal:\n uses: kungfu-systems/buildchain/.github/workflows/public-release-tail.yml@${ref}\n with:\n rehearsal-capsule-path: \${{ inputs.capsule-path }}\n candidate-root: \${{ inputs.candidate-root }}\n rehearsal-mode: simulate\n state-path: ".buildchain/publication-rehearsal/state.json"\n rehearsal-evidence-path: ".buildchain/publication-rehearsal/evidence.json"\n`;
|
|
104
|
-
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { runReleasePropagationCli } from "../commands/release-propagation.mjs";
|
|
2
2
|
import { runReleaseTailCli } from "../commands/release-tail.mjs";
|
|
3
3
|
import { runTailResealCli } from "../commands/tail-reseal.mjs";
|
|
4
|
-
import {
|
|
5
|
-
TRUST_RELEASE_COMMANDS,
|
|
6
|
-
dispatchTrustReleaseCommand,
|
|
7
|
-
} from "./trust-release.mjs";
|
|
4
|
+
import { dispatchTrustReleaseCommand } from "./trust-release.mjs";
|
|
8
5
|
import { packageVersion } from "../../contracts/cli/context.mjs";
|
|
9
6
|
import { runScript } from "../../workflow/cli/process.mjs";
|
|
10
7
|
|
|
@@ -1,44 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { spawnSync } from "node:child_process";
|
|
4
|
-
import { verifyInfraContractEvidenceBundle } from "../../providers/commands/infra-contract-core.mjs";
|
|
5
|
-
import { verifyBuildchainLogEvents } from "../../observability/logging.js";
|
|
6
|
-
import {
|
|
7
|
-
explainReleaseLineDryRun,
|
|
8
|
-
formatReleaseLineDryRun,
|
|
9
|
-
} from "../release-line-dry-run.js";
|
|
10
|
-
import {
|
|
11
|
-
planReleaseLineBootstrap,
|
|
12
|
-
writeReleaseLineBootstrapVersionState,
|
|
13
|
-
} from "../release-line-bootstrap.js";
|
|
14
|
-
import { collectGitHubReleasePassport } from "../passport/collection.js";
|
|
15
|
-
import { explainReleasePassport, verifyReleasePassport } from "../release-passport.js";
|
|
16
|
-
import {
|
|
17
|
-
createPublicationAdmission,
|
|
18
|
-
createRunnerProvenance,
|
|
19
|
-
verifyPublicationAdmission,
|
|
20
|
-
} from "../../publication/publication-authority.js";
|
|
21
|
-
import {
|
|
22
|
-
createGitHubArtifactAttestationPolicy,
|
|
23
|
-
createGitHubArtifactAttestationVerificationPlan,
|
|
24
|
-
verifyGitHubArtifactAttestationEvidence,
|
|
25
|
-
} from "../../build/github-artifact-attestation.js";
|
|
1
|
+
import { explainReleasePassport } from "../release-passport.js";
|
|
26
2
|
import {
|
|
27
3
|
explainArtifactPassport,
|
|
28
4
|
verifyArtifactPassport,
|
|
29
5
|
} from "../../build/artifact-passport.js";
|
|
30
6
|
import {
|
|
31
|
-
projectArtifactVerificationEnvelopeToKfx,
|
|
32
|
-
verifyArtifactVerificationEnvelope,
|
|
33
|
-
} from "../../build/artifact-verification-envelope.js";
|
|
34
|
-
import {
|
|
35
|
-
artifactEnvelopeOptions,
|
|
36
7
|
printJson,
|
|
37
8
|
readBooleanFlag,
|
|
38
9
|
readFlag,
|
|
39
|
-
readJsonInput,
|
|
40
|
-
readRepeatedFlag,
|
|
41
|
-
writeJsonFile,
|
|
42
10
|
} from "../../contracts/cli/options.mjs";
|
|
43
11
|
|
|
44
12
|
async function handleAuditCommand({ args, runScript, packageVersion }) {
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
1
|
import path from "node:path";
|
|
3
|
-
import { spawnSync } from "node:child_process";
|
|
4
|
-
import { verifyInfraContractEvidenceBundle } from "../../providers/commands/infra-contract-core.mjs";
|
|
5
|
-
import { verifyBuildchainLogEvents } from "../../observability/logging.js";
|
|
6
2
|
import {
|
|
7
3
|
explainReleaseLineDryRun,
|
|
8
4
|
formatReleaseLineDryRun,
|
|
@@ -12,25 +8,12 @@ import {
|
|
|
12
8
|
writeReleaseLineBootstrapVersionState,
|
|
13
9
|
} from "../release-line-bootstrap.js";
|
|
14
10
|
import { collectGitHubReleasePassport } from "../passport/collection.js";
|
|
15
|
-
import { explainReleasePassport, verifyReleasePassport } from "../release-passport.js";
|
|
16
11
|
import {
|
|
17
12
|
createPublicationAdmission,
|
|
18
13
|
createRunnerProvenance,
|
|
19
|
-
verifyPublicationAdmission,
|
|
20
14
|
} from "../../publication/publication-authority.js";
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
createGitHubArtifactAttestationVerificationPlan,
|
|
24
|
-
verifyGitHubArtifactAttestationEvidence,
|
|
25
|
-
} from "../../build/github-artifact-attestation.js";
|
|
26
|
-
import {
|
|
27
|
-
explainArtifactPassport,
|
|
28
|
-
verifyArtifactPassport,
|
|
29
|
-
} from "../../build/artifact-passport.js";
|
|
30
|
-
import {
|
|
31
|
-
projectArtifactVerificationEnvelopeToKfx,
|
|
32
|
-
verifyArtifactVerificationEnvelope,
|
|
33
|
-
} from "../../build/artifact-verification-envelope.js";
|
|
15
|
+
import { createGitHubArtifactAttestationPolicy } from "../../build/github-artifact-attestation.js";
|
|
16
|
+
import { projectArtifactVerificationEnvelopeToKfx } from "../../build/artifact-verification-envelope.js";
|
|
34
17
|
import {
|
|
35
18
|
artifactEnvelopeOptions,
|
|
36
19
|
printJson,
|
|
@@ -3,34 +3,14 @@ import path from "node:path";
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import { verifyInfraContractEvidenceBundle } from "../../providers/commands/infra-contract-core.mjs";
|
|
5
5
|
import { verifyBuildchainLogEvents } from "../../observability/logging.js";
|
|
6
|
+
import { verifyReleasePassport } from "../release-passport.js";
|
|
7
|
+
import { verifyPublicationAdmission } from "../../publication/publication-authority.js";
|
|
6
8
|
import {
|
|
7
|
-
explainReleaseLineDryRun,
|
|
8
|
-
formatReleaseLineDryRun,
|
|
9
|
-
} from "../release-line-dry-run.js";
|
|
10
|
-
import {
|
|
11
|
-
planReleaseLineBootstrap,
|
|
12
|
-
writeReleaseLineBootstrapVersionState,
|
|
13
|
-
} from "../release-line-bootstrap.js";
|
|
14
|
-
import { collectGitHubReleasePassport } from "../passport/collection.js";
|
|
15
|
-
import { explainReleasePassport, verifyReleasePassport } from "../release-passport.js";
|
|
16
|
-
import {
|
|
17
|
-
createPublicationAdmission,
|
|
18
|
-
createRunnerProvenance,
|
|
19
|
-
verifyPublicationAdmission,
|
|
20
|
-
} from "../../publication/publication-authority.js";
|
|
21
|
-
import {
|
|
22
|
-
createGitHubArtifactAttestationPolicy,
|
|
23
9
|
createGitHubArtifactAttestationVerificationPlan,
|
|
24
10
|
verifyGitHubArtifactAttestationEvidence,
|
|
25
11
|
} from "../../build/github-artifact-attestation.js";
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
verifyArtifactPassport,
|
|
29
|
-
} from "../../build/artifact-passport.js";
|
|
30
|
-
import {
|
|
31
|
-
projectArtifactVerificationEnvelopeToKfx,
|
|
32
|
-
verifyArtifactVerificationEnvelope,
|
|
33
|
-
} from "../../build/artifact-verification-envelope.js";
|
|
12
|
+
import { verifyArtifactPassport } from "../../build/artifact-passport.js";
|
|
13
|
+
import { verifyArtifactVerificationEnvelope } from "../../build/artifact-verification-envelope.js";
|
|
34
14
|
import {
|
|
35
15
|
artifactEnvelopeOptions,
|
|
36
16
|
printJson,
|
|
@@ -38,7 +18,6 @@ import {
|
|
|
38
18
|
readFlag,
|
|
39
19
|
readJsonInput,
|
|
40
20
|
readRepeatedFlag,
|
|
41
|
-
writeJsonFile,
|
|
42
21
|
} from "../../contracts/cli/options.mjs";
|
|
43
22
|
|
|
44
23
|
async function verifyGitHubArtifactAttestationCommand({
|
|
@@ -266,19 +266,19 @@ invalid.
|
|
|
266
266
|
|
|
267
267
|
## Public self-dogfood and adoption
|
|
268
268
|
|
|
269
|
-
\`.github/workflows/
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
269
|
+
\`.github/workflows/buildchain.yml\` calls the published
|
|
270
|
+
\`public-ops-pipeline.yml@v4\` entry. Products declare their verification commands
|
|
271
|
+
in schema-2 TOML, including the full repository check on each required platform.
|
|
272
|
+
Next-development preparation, independent review, protected merge and settlement
|
|
273
|
+
remain runtime responsibilities.
|
|
274
|
+
|
|
275
|
+
\`.github/workflows/buildchain-recover.yml\` calls
|
|
276
|
+
\`public-ops-recover.yml@v4\` with one exact attempt and an optional temporary
|
|
277
|
+
repaired runtime. It preserves completed publication evidence while continuing
|
|
278
|
+
unfinished follow-ups. Both callers use the same generated bytes as external
|
|
279
|
+
consumers. Tool-maintained locks and retained receipts bind exact runtime SHAs.
|
|
280
|
+
Earlier Stage Capsule and channel-build proofs retain their historical source
|
|
281
|
+
identities; they do not define additional current consumer entrypoints.
|
|
282
282
|
|
|
283
283
|
## Local adapter
|
|
284
284
|
|
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import { readJsonFile } from "./files.js";
|
|
4
3
|
import https from "node:https";
|
|
5
4
|
import http from "node:http";
|
|
6
5
|
import { nonEmptyString } from "./identity.js";
|
|
7
|
-
export async function resolveSiblingJson(basePath, relativePath) {
|
|
6
|
+
export async function resolveSiblingJson(basePath, relativePath, options) {
|
|
8
7
|
if (!basePath || !relativePath) {
|
|
9
8
|
return undefined;
|
|
10
9
|
}
|
|
11
10
|
if (/^https?:\/\//.test(relativePath)) {
|
|
12
|
-
return readJsonFromLocation(relativePath);
|
|
11
|
+
return readJsonFromLocation(relativePath, 0, options);
|
|
13
12
|
}
|
|
14
13
|
if (/^https?:\/\//.test(basePath)) {
|
|
15
|
-
return readJsonFromLocation(
|
|
14
|
+
return readJsonFromLocation(
|
|
15
|
+
new URL(relativePath, basePath).toString(),
|
|
16
|
+
0,
|
|
17
|
+
options,
|
|
18
|
+
);
|
|
16
19
|
}
|
|
17
20
|
const candidate = path.resolve(path.dirname(basePath), relativePath);
|
|
18
21
|
if (!fs.existsSync(candidate)) {
|
|
19
22
|
return undefined;
|
|
20
23
|
}
|
|
21
|
-
return
|
|
24
|
+
return readJsonFromLocation(candidate, 0, options);
|
|
22
25
|
}
|
|
23
26
|
export async function readJsonFromLocation(
|
|
24
27
|
location,
|
|
25
28
|
redirectCount = 0,
|
|
26
|
-
{ timeoutMs = 15_000 } = {},
|
|
29
|
+
{ timeoutMs = 15_000, raw = false } = {},
|
|
27
30
|
) {
|
|
28
31
|
const input = nonEmptyString(location, "location");
|
|
29
32
|
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
|
|
@@ -47,6 +50,7 @@ export async function readJsonFromLocation(
|
|
|
47
50
|
response.resume();
|
|
48
51
|
readJsonFromLocation(nextLocation, redirectCount + 1, {
|
|
49
52
|
timeoutMs,
|
|
53
|
+
raw,
|
|
50
54
|
}).then(resolve, reject);
|
|
51
55
|
return;
|
|
52
56
|
}
|
|
@@ -64,7 +68,7 @@ export async function readJsonFromLocation(
|
|
|
64
68
|
});
|
|
65
69
|
response.on("end", () => {
|
|
66
70
|
try {
|
|
67
|
-
resolve(JSON.parse(body));
|
|
71
|
+
resolve(raw ? body : JSON.parse(body));
|
|
68
72
|
} catch (error) {
|
|
69
73
|
reject(error);
|
|
70
74
|
}
|
|
@@ -78,5 +82,6 @@ export async function readJsonFromLocation(
|
|
|
78
82
|
request.on("error", reject);
|
|
79
83
|
});
|
|
80
84
|
}
|
|
81
|
-
|
|
85
|
+
const bytes = fs.readFileSync(input, "utf8");
|
|
86
|
+
return raw ? bytes : JSON.parse(bytes);
|
|
82
87
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { verifyPublishedDocuments } from "../publication/pipeline/stable-products.js";
|
|
1
5
|
import { resolveReleasePassportVerificationInputs } from "./release-passport-contract.js";
|
|
2
6
|
import { nowIso } from "./passport/identity.js";
|
|
3
7
|
import {
|
|
@@ -5,6 +9,56 @@ import {
|
|
|
5
9
|
resolveSiblingJson,
|
|
6
10
|
} from "./passport/locations.js";
|
|
7
11
|
import { createReleaseCheckReport } from "./passport/report.js";
|
|
12
|
+
|
|
13
|
+
async function verifyPipelinePassport(location, release, checkedAt, execute) {
|
|
14
|
+
const directory = fs.mkdtempSync(
|
|
15
|
+
path.join(fs.realpathSync(os.tmpdir()), "buildchain-passport-"),
|
|
16
|
+
);
|
|
17
|
+
const report = {
|
|
18
|
+
schemaVersion: 1,
|
|
19
|
+
contract: "kungfu-buildchain-release-check-report",
|
|
20
|
+
checkedAt,
|
|
21
|
+
verificationScope: "signed-release-metadata",
|
|
22
|
+
artifactBytesVerified: false,
|
|
23
|
+
providerStateVerified: false,
|
|
24
|
+
completeness: { artifactCount: 0 },
|
|
25
|
+
issues: [],
|
|
26
|
+
};
|
|
27
|
+
try {
|
|
28
|
+
const values = { release };
|
|
29
|
+
for (const name of ["plan", "qualification", "capsules", "invocation"])
|
|
30
|
+
values[name] = await resolveSiblingJson(
|
|
31
|
+
location,
|
|
32
|
+
`buildchain.${name}.json`,
|
|
33
|
+
);
|
|
34
|
+
const bundle = await resolveSiblingJson(
|
|
35
|
+
location,
|
|
36
|
+
"buildchain.attestation.json",
|
|
37
|
+
{ raw: true },
|
|
38
|
+
);
|
|
39
|
+
verifyPublishedDocuments(values, bundle, {
|
|
40
|
+
directory,
|
|
41
|
+
token: process.env.GH_TOKEN || process.env.GITHUB_TOKEN,
|
|
42
|
+
execute,
|
|
43
|
+
});
|
|
44
|
+
report.completeness.artifactCount = values.qualification.artifacts.length;
|
|
45
|
+
report.source = release.source;
|
|
46
|
+
report.release = release.release;
|
|
47
|
+
} catch {
|
|
48
|
+
report.issues.push({
|
|
49
|
+
level: "error",
|
|
50
|
+
code: "pipeline.evidence",
|
|
51
|
+
message:
|
|
52
|
+
"Signed release metadata verification failed. Supply all five unchanged companion files and GitHub CLI with attestation verification support.",
|
|
53
|
+
});
|
|
54
|
+
} finally {
|
|
55
|
+
fs.rmSync(directory, { recursive: true, force: true });
|
|
56
|
+
}
|
|
57
|
+
report.ok = report.issues.length === 0;
|
|
58
|
+
report.trust = report.ok ? "pass" : "fail";
|
|
59
|
+
return report;
|
|
60
|
+
}
|
|
61
|
+
|
|
8
62
|
export async function verifyReleasePassport({
|
|
9
63
|
passportLocation,
|
|
10
64
|
artifactEvidenceLocation = "",
|
|
@@ -17,7 +71,16 @@ export async function verifyReleasePassport({
|
|
|
17
71
|
kfdAdopterManifestGateLocation = "",
|
|
18
72
|
kfdSupportEvidenceLocation = "",
|
|
19
73
|
checkedAt = nowIso(),
|
|
74
|
+
execute,
|
|
20
75
|
} = {}) {
|
|
76
|
+
const passport = await readJsonFromLocation(passportLocation);
|
|
77
|
+
if (passport?.schema === "kungfu.buildchain.release-passport/v4")
|
|
78
|
+
return verifyPipelinePassport(
|
|
79
|
+
passportLocation,
|
|
80
|
+
passport,
|
|
81
|
+
checkedAt,
|
|
82
|
+
execute,
|
|
83
|
+
);
|
|
21
84
|
const evidence = await resolveReleasePassportVerificationInputs({
|
|
22
85
|
passportLocation,
|
|
23
86
|
locations: {
|
|
@@ -34,10 +97,7 @@ export async function verifyReleasePassport({
|
|
|
34
97
|
readJson: readJsonFromLocation,
|
|
35
98
|
resolveSibling: resolveSiblingJson,
|
|
36
99
|
});
|
|
37
|
-
return createReleaseCheckReport({
|
|
38
|
-
...evidence,
|
|
39
|
-
checkedAt,
|
|
40
|
-
});
|
|
100
|
+
return createReleaseCheckReport({ ...evidence, checkedAt });
|
|
41
101
|
}
|
|
42
102
|
export async function explainReleasePassport({
|
|
43
103
|
passportLocation,
|
|
@@ -46,7 +106,9 @@ export async function explainReleasePassport({
|
|
|
46
106
|
const report = await verifyReleasePassport({ passportLocation });
|
|
47
107
|
const passport = await readJsonFromLocation(passportLocation);
|
|
48
108
|
const nextAction = report.ok
|
|
49
|
-
? "
|
|
109
|
+
? report.verificationScope === "signed-release-metadata"
|
|
110
|
+
? "verify-artifact-bytes-and-review-policy"
|
|
111
|
+
: "install-or-upgrade-after-policy-review"
|
|
50
112
|
: "block-release-and-report-verification-failure";
|
|
51
113
|
return {
|
|
52
114
|
schemaVersion: 1,
|
|
@@ -54,6 +116,9 @@ export async function explainReleasePassport({
|
|
|
54
116
|
audience: forAudience,
|
|
55
117
|
release: passport.release,
|
|
56
118
|
trust: report.trust,
|
|
119
|
+
verificationScope: report.verificationScope,
|
|
120
|
+
artifactBytesVerified: report.artifactBytesVerified,
|
|
121
|
+
providerStateVerified: report.providerStateVerified,
|
|
57
122
|
complete: report.ok,
|
|
58
123
|
artifactCount: report.completeness.artifactCount,
|
|
59
124
|
runnerPolicy: passport.runnerPolicy,
|
|
@@ -56,7 +56,7 @@ export function assembleWebPublicationAdmission({
|
|
|
56
56
|
"managed web-surface publication requires an ephemeral GitHub-hosted Actions runner",
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
|
-
const workflowPath = ".github/workflows
|
|
59
|
+
const workflowPath = ".github/workflows/.release-web.yml";
|
|
60
60
|
const publisherWorkflowPath = workflowPath;
|
|
61
61
|
const controlPlaneAudit = createPublicationControlPlaneAudit({
|
|
62
62
|
repository,
|
|
@@ -36,7 +36,7 @@ export function verifyWebPublicationCapability(request, now = Date.now()) {
|
|
|
36
36
|
}
|
|
37
37
|
const roleArn = required(request, "roleArn");
|
|
38
38
|
const exact = {
|
|
39
|
-
workflowPath: ".github/workflows
|
|
39
|
+
workflowPath: ".github/workflows/.release-web.yml",
|
|
40
40
|
repository: required(request, "repository"),
|
|
41
41
|
sourceSha: required(request, "sourceSha").toLowerCase(),
|
|
42
42
|
runtimeSha: required(request, "runtimeSha").toLowerCase(),
|
|
@@ -457,7 +457,7 @@ function normalizePackageRepository(repository) {
|
|
|
457
457
|
function discoverWorkflowFacts({ cwd, repository, badgeConfig = {} }) {
|
|
458
458
|
const workflowDir = path.join(cwd, ".github", "workflows");
|
|
459
459
|
const configured = normalizeStringArray(badgeConfig.workflows);
|
|
460
|
-
const defaults = ["verify.yml", "build.yml", "buildchain-ref-promotion.yml"];
|
|
460
|
+
const defaults = ["verify.yml", ".build-candidate.yml", "buildchain-ref-promotion.yml"];
|
|
461
461
|
const names = configured.length > 0 ? configured : defaults;
|
|
462
462
|
if (!fs.existsSync(workflowDir)) {
|
|
463
463
|
return [];
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { initializeCliRuntime } from "../../contracts/cli/context.mjs";
|
|
2
2
|
import { BUILDCHAIN_USAGE } from "../commands/buildchain-cli-help.mjs";
|
|
3
3
|
import { formatCliHelp } from "../../contracts/cli-reference.js";
|
|
4
|
-
import {
|
|
5
|
-
TRUST_RELEASE_COMMANDS,
|
|
6
|
-
dispatchTrustReleaseCommand,
|
|
7
|
-
} from "../../release/cli/trust-release.mjs";
|
|
4
|
+
import { TRUST_RELEASE_COMMANDS } from "../../release/cli/trust-release.mjs";
|
|
8
5
|
import { dispatchRegisteredCommand } from "../../contracts/command-registry.mjs";
|
|
9
6
|
import { handleAdopterDeliveryCommand } from "../../adoption/cli/dispatch.mjs";
|
|
10
7
|
import { handleKfdCommand } from "../../adoption/cli/kfd.mjs";
|
|
@@ -20,7 +20,7 @@ export const BUILDCHAIN_USAGE = `Usage:
|
|
|
20
20
|
[--cold-fallback-status not-run|passed|failed]
|
|
21
21
|
[--output <file>] [--json]
|
|
22
22
|
buildchain candidate timeline --input <file-or-json> [--output <file>] [--json]
|
|
23
|
-
buildchain init [--cwd <dir>] [--type package|native|
|
|
23
|
+
buildchain init [--cwd <dir>] [--type npm|binary|paper|package|native|publication-artifact|anchored-package] [--force]
|
|
24
24
|
[--package-manager pnpm|npm|yarn] [--runner-preset <preset>]
|
|
25
25
|
[--artifact-name <name>]
|
|
26
26
|
buildchain validate [--cwd <dir>] [--require-version-state]
|
|
@@ -253,7 +253,7 @@ export const BUILDCHAIN_USAGE = `Usage:
|
|
|
253
253
|
[--output <file>] [--promote]
|
|
254
254
|
[--no-toolchain-pull]
|
|
255
255
|
[--allow-unpinned-toolchain] [--json]
|
|
256
|
-
buildchain paper scaffold --
|
|
256
|
+
buildchain paper scaffold --repository <owner/repo> [--package <name>] [--write] [--json]
|
|
257
257
|
buildchain paper migrate [--cwd <dir>] [--write] [--json]
|
|
258
258
|
buildchain paper work start <topic> [--cwd <dir>] [--branch <branch>] [--execute] [--json]
|
|
259
259
|
buildchain paper work submit [--cwd <dir>] [--title <title>] [--body <body>] [--execute] [--json]
|
|
@@ -261,13 +261,7 @@ export const BUILDCHAIN_USAGE = `Usage:
|
|
|
261
261
|
buildchain paper fleet update [--root <dir>] [--write] [--json]
|
|
262
262
|
buildchain paper agent verify [--cwd <dir>] [--offline] [--json]
|
|
263
263
|
buildchain paper preflight [--cwd <dir>] [--offline] [--json]
|
|
264
|
-
buildchain paper bootstrap npm [--cwd <dir>] [--execute]
|
|
265
|
-
[--confirm-public-package <name>] [--json]
|
|
266
|
-
buildchain paper build [--cwd <dir>] [--execute] [--json]
|
|
267
|
-
buildchain paper alpha [--cwd <dir>] [--source-ref <ref>] [--target-ref <ref>]
|
|
268
|
-
[--execute] [--json]
|
|
269
264
|
buildchain paper status [--cwd <dir>] [--json]
|
|
270
|
-
buildchain paper resume [--cwd <dir>] [--runtime-ref <ref>] [--execute] [--json]
|
|
271
265
|
buildchain release-propagation <plan|write-lock|work|entry|pickup> ...
|
|
272
266
|
buildchain badges readme [--cwd <dir>] [--readme <path>] [--check] [--write] [--json]
|
|
273
267
|
buildchain badges bundle [--cwd <dir>] [--readme <path>] [--claims <csv>] [--check] [--write] [--json]
|
|
@@ -52,7 +52,7 @@ export function executeBootstrapConformance(
|
|
|
52
52
|
const source = fs.readFileSync(path.join(runtimeRoot, relative), "utf8");
|
|
53
53
|
if (
|
|
54
54
|
relative !== architecture.bootstrap.publicWorkflow &&
|
|
55
|
-
!/(?:\.\/)?\.github\/workflows
|
|
55
|
+
!/(?:\.\/)?\.github\/workflows\/\.ops-bootstrap\.yml/u.test(source)
|
|
56
56
|
)
|
|
57
57
|
fail(`candidate Bootstrap facade is not governed: ${relative}`);
|
|
58
58
|
}
|