@kungfu-tech/buildchain 3.0.3 → 3.0.4-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/AGENTS.md +13 -0
- package/dist/site/buildchain-contract.json +5 -5
- package/dist/site/buildchain-site.json +7 -7
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/cli-registry.json +18 -0
- package/dist/site/kfd-claims.json +19 -7
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +1 -1
- package/dist/site/node-api-registry.json +2 -2
- package/dist/site/page-registry.json +2 -2
- package/dist/site/public-surface-audit.json +14 -4
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +5 -5
- package/docs/cli.md +22 -7
- package/package.json +1 -1
- package/packages/core/paper-agent-entry.js +361 -0
- package/packages/core/paper-repository.js +2 -0
- package/packages/core/paper-scaffold-content.js +163 -0
- package/packages/core/paper-work.js +35 -0
- package/packages/core/paper.js +139 -170
- package/scripts/buildchain-cli-help.mjs +1 -0
- package/scripts/paper-agent-cli.mjs +35 -0
- package/scripts/paper-work-fleet-cli.mjs +14 -4
- package/scripts/paper.mjs +15 -2
- package/scripts/site-capability-metadata.mjs +1 -1
package/packages/core/paper.js
CHANGED
|
@@ -31,8 +31,33 @@ import {
|
|
|
31
31
|
sha256Text,
|
|
32
32
|
stableJson,
|
|
33
33
|
} from "./paper-repository.js";
|
|
34
|
+
import {
|
|
35
|
+
PAPER_AGENT_ENTRY_CONTRACT,
|
|
36
|
+
collectPaperAgentEntry,
|
|
37
|
+
paperAgentEntryFiles,
|
|
38
|
+
} from "./paper-agent-entry.js";
|
|
39
|
+
import {
|
|
40
|
+
managedPaperPackageJson,
|
|
41
|
+
scaffoldMainTex,
|
|
42
|
+
scaffoldMakefile,
|
|
43
|
+
scaffoldMap,
|
|
44
|
+
scaffoldPackageJson,
|
|
45
|
+
scaffoldReadme,
|
|
46
|
+
} from "./paper-scaffold-content.js";
|
|
34
47
|
|
|
35
48
|
export { PAPER_PATHS, resolvePaperRepository } from "./paper-repository.js";
|
|
49
|
+
export {
|
|
50
|
+
PAPER_AGENT_ENTRY_CONTRACT,
|
|
51
|
+
PAPER_AGENT_ENTRY_SCHEMA_VERSION,
|
|
52
|
+
PAPER_AGENT_ENTRY_SECTION_END,
|
|
53
|
+
PAPER_AGENT_ENTRY_SECTION_START,
|
|
54
|
+
collectPaperAgentEntry,
|
|
55
|
+
createPaperAgentEntry,
|
|
56
|
+
mergePaperAgentEntryInstructions,
|
|
57
|
+
paperAgentEntryFiles,
|
|
58
|
+
paperAgentEntryInstructions,
|
|
59
|
+
resolvePaperBuildchainSha,
|
|
60
|
+
} from "./paper-agent-entry.js";
|
|
36
61
|
export {
|
|
37
62
|
PAPER_WORK_START_PLAN_CONTRACT,
|
|
38
63
|
PAPER_WORK_SUBMIT_PLAN_CONTRACT,
|
|
@@ -79,9 +104,12 @@ export const PAPER_STATE_ORDER = Object.freeze([
|
|
|
79
104
|
|
|
80
105
|
const PAPER_SCAFFOLD_PATHS = Object.freeze([
|
|
81
106
|
PAPER_PATHS.config,
|
|
107
|
+
PAPER_PATHS.agentEntry,
|
|
108
|
+
PAPER_PATHS.agentInstructions,
|
|
82
109
|
PAPER_PATHS.contractLock,
|
|
83
110
|
PAPER_PATHS.versionPin,
|
|
84
111
|
PAPER_PATHS.buildWorkflow,
|
|
112
|
+
PAPER_PATHS.verifyWorkflow,
|
|
85
113
|
PAPER_PATHS.releaseWorkflow,
|
|
86
114
|
PAPER_PATHS.provisioningAuthority,
|
|
87
115
|
"Makefile",
|
|
@@ -227,18 +255,6 @@ function tomlString(value) {
|
|
|
227
255
|
return JSON.stringify(String(value || ""));
|
|
228
256
|
}
|
|
229
257
|
|
|
230
|
-
function texEscape(value) {
|
|
231
|
-
return String(value || "")
|
|
232
|
-
.replaceAll("\\", "\\textbackslash{}")
|
|
233
|
-
.replaceAll("&", "\\&")
|
|
234
|
-
.replaceAll("%", "\\%")
|
|
235
|
-
.replaceAll("$", "\\$")
|
|
236
|
-
.replaceAll("#", "\\#")
|
|
237
|
-
.replaceAll("_", "\\_")
|
|
238
|
-
.replaceAll("{", "\\{")
|
|
239
|
-
.replaceAll("}", "\\}");
|
|
240
|
-
}
|
|
241
|
-
|
|
242
258
|
function joinUrl(base, suffix = "") {
|
|
243
259
|
const normalizedBase = String(base || "")
|
|
244
260
|
.trim()
|
|
@@ -334,6 +350,31 @@ jobs:
|
|
|
334
350
|
`;
|
|
335
351
|
}
|
|
336
352
|
|
|
353
|
+
function scaffoldVerifyWorkflow(buildchainSha) {
|
|
354
|
+
return `name: Verify
|
|
355
|
+
|
|
356
|
+
on:
|
|
357
|
+
pull_request:
|
|
358
|
+
push:
|
|
359
|
+
branches:
|
|
360
|
+
- "dev/v*/v*"
|
|
361
|
+
- "alpha/v*/v*"
|
|
362
|
+
- "release/v*/v*"
|
|
363
|
+
workflow_dispatch:
|
|
364
|
+
|
|
365
|
+
permissions:
|
|
366
|
+
contents: read
|
|
367
|
+
|
|
368
|
+
jobs:
|
|
369
|
+
check:
|
|
370
|
+
uses: kungfu-systems/buildchain/.github/workflows/check.yml@${buildchainSha}
|
|
371
|
+
with:
|
|
372
|
+
buildchain-ref: ${buildchainSha}
|
|
373
|
+
require-version-state: true
|
|
374
|
+
upload-artifacts: true
|
|
375
|
+
`;
|
|
376
|
+
}
|
|
377
|
+
|
|
337
378
|
function scaffoldReleaseWorkflow(
|
|
338
379
|
buildchainSha,
|
|
339
380
|
{ artifactPaths = "_build/main.pdf", releasePassportProductName = "" } = {},
|
|
@@ -413,7 +454,10 @@ export function createPaperProvisioningAuthority({
|
|
|
413
454
|
buildchainSha,
|
|
414
455
|
contractLock,
|
|
415
456
|
buildWorkflow,
|
|
457
|
+
verifyWorkflow,
|
|
416
458
|
releaseWorkflow,
|
|
459
|
+
agentEntry,
|
|
460
|
+
agentInstructions,
|
|
417
461
|
environment = "",
|
|
418
462
|
}) {
|
|
419
463
|
const policy = paperProvisioningPolicy();
|
|
@@ -439,6 +483,12 @@ export function createPaperProvisioningAuthority({
|
|
|
439
483
|
reusablePath: ".github/workflows/publication-artifact.yml",
|
|
440
484
|
reusableRef: buildchainSha,
|
|
441
485
|
},
|
|
486
|
+
verify: {
|
|
487
|
+
path: PAPER_PATHS.verifyWorkflow,
|
|
488
|
+
sourceDigest: sha256Text(verifyWorkflow),
|
|
489
|
+
reusablePath: ".github/workflows/check.yml",
|
|
490
|
+
reusableRef: buildchainSha,
|
|
491
|
+
},
|
|
442
492
|
release: {
|
|
443
493
|
path: PAPER_PATHS.releaseWorkflow,
|
|
444
494
|
sourceDigest: sha256Text(releaseWorkflow),
|
|
@@ -446,6 +496,13 @@ export function createPaperProvisioningAuthority({
|
|
|
446
496
|
reusableRef: buildchainSha,
|
|
447
497
|
},
|
|
448
498
|
},
|
|
499
|
+
agentEntry: {
|
|
500
|
+
contract: PAPER_AGENT_ENTRY_CONTRACT,
|
|
501
|
+
policyPath: PAPER_PATHS.agentEntry,
|
|
502
|
+
policyDigest: sha256Text(agentEntry),
|
|
503
|
+
instructionsPath: PAPER_PATHS.agentInstructions,
|
|
504
|
+
instructionsDigest: sha256Text(agentInstructions),
|
|
505
|
+
},
|
|
449
506
|
admission: {
|
|
450
507
|
contractLockPath: PAPER_PATHS.contractLock,
|
|
451
508
|
contractLockDigest: sha256Text(contractLock),
|
|
@@ -469,150 +526,6 @@ export function createPaperProvisioningAuthority({
|
|
|
469
526
|
};
|
|
470
527
|
}
|
|
471
528
|
|
|
472
|
-
function scaffoldMakefile() {
|
|
473
|
-
const image = `${DEFAULT_TOOLCHAIN_IMAGE}@${DEFAULT_TOOLCHAIN_DIGEST}`;
|
|
474
|
-
return `.PHONY: check pdf clean
|
|
475
|
-
|
|
476
|
-
BUILDER_IMAGE := ${image}
|
|
477
|
-
SOURCE_DATE_EPOCH ?= 0
|
|
478
|
-
|
|
479
|
-
check:
|
|
480
|
-
\t@test -f paper/main.tex
|
|
481
|
-
\t@test -f paper/references.bib
|
|
482
|
-
\t@git diff --check
|
|
483
|
-
|
|
484
|
-
pdf:
|
|
485
|
-
\t@mkdir -p _build
|
|
486
|
-
\tdocker run --rm --network=none \\
|
|
487
|
-
\t\t-e SOURCE_DATE_EPOCH="$(SOURCE_DATE_EPOCH)" \\
|
|
488
|
-
\t\t-e TZ=UTC -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -e HOME=/tmp \\
|
|
489
|
-
\t\t-v "$(CURDIR):/workspace" -w /workspace \\
|
|
490
|
-
\t\t"$(BUILDER_IMAGE)" bash -lc '${DEFAULT_TOOLCHAIN_COMMAND}'
|
|
491
|
-
|
|
492
|
-
clean:
|
|
493
|
-
\trm -rf _build
|
|
494
|
-
`;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
function paperPackageScripts(current = {}) {
|
|
498
|
-
return {
|
|
499
|
-
...current,
|
|
500
|
-
"buildchain:paper": "buildchain paper",
|
|
501
|
-
"paper:preflight": "buildchain paper preflight --json",
|
|
502
|
-
"paper:work:start": "buildchain paper work start",
|
|
503
|
-
"paper:work:submit": "buildchain paper work submit",
|
|
504
|
-
"paper:status": "buildchain paper status --json",
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
function managedPaperPackageJson(current, buildchainVersion) {
|
|
509
|
-
if (!/^3\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(buildchainVersion)) {
|
|
510
|
-
throw new Error(
|
|
511
|
-
"paper repositories require an exact Buildchain v3 version",
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
const packageManager = current.packageManager || "pnpm@11.7.0";
|
|
515
|
-
if (!packageManager.startsWith("pnpm@")) {
|
|
516
|
-
throw new Error("paper repositories require a pnpm packageManager");
|
|
517
|
-
}
|
|
518
|
-
return {
|
|
519
|
-
...current,
|
|
520
|
-
private: true,
|
|
521
|
-
scripts: paperPackageScripts(current.scripts),
|
|
522
|
-
devDependencies: {
|
|
523
|
-
...(current.devDependencies || {}),
|
|
524
|
-
"@kungfu-tech/buildchain": buildchainVersion,
|
|
525
|
-
},
|
|
526
|
-
packageManager,
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
function scaffoldPackageJson({
|
|
531
|
-
name,
|
|
532
|
-
packageName,
|
|
533
|
-
repository,
|
|
534
|
-
buildchainVersion,
|
|
535
|
-
}) {
|
|
536
|
-
return jsonText({
|
|
537
|
-
...managedPaperPackageJson(
|
|
538
|
-
{
|
|
539
|
-
name: packageName,
|
|
540
|
-
description: `${name} publication source repository.`,
|
|
541
|
-
repository: {
|
|
542
|
-
type: "git",
|
|
543
|
-
url: `git+https://github.com/${repository}.git`,
|
|
544
|
-
},
|
|
545
|
-
license: "Apache-2.0",
|
|
546
|
-
},
|
|
547
|
-
buildchainVersion,
|
|
548
|
-
),
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
function scaffoldReadme({ title, packageName }) {
|
|
553
|
-
return `# ${title}
|
|
554
|
-
|
|
555
|
-
This repository is a Buildchain-governed publication artifact source.
|
|
556
|
-
|
|
557
|
-
## Local workflow
|
|
558
|
-
|
|
559
|
-
\`\`\`sh
|
|
560
|
-
pnpm paper:preflight
|
|
561
|
-
pnpm paper:work:start -- <topic>
|
|
562
|
-
pnpm paper:work:submit
|
|
563
|
-
make pdf
|
|
564
|
-
\`\`\`
|
|
565
|
-
|
|
566
|
-
The public package identity is \`${packageName}\`. Buildchain owns reproducible
|
|
567
|
-
artifact generation, sealed publication, npm Trusted Publishing, and recovery;
|
|
568
|
-
this repository owns the paper source and review history.
|
|
569
|
-
|
|
570
|
-
See [docs/MAP.md](docs/MAP.md) for the repository map.
|
|
571
|
-
`;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
function scaffoldMap() {
|
|
575
|
-
return `# Repository Map
|
|
576
|
-
|
|
577
|
-
- \`paper/main.tex\`: paper source entrypoint.
|
|
578
|
-
- \`paper/references.bib\`: bibliography source.
|
|
579
|
-
- \`.buildchain/buildchain.toml\`: publication identity, toolchain, package, and lifecycle contract.
|
|
580
|
-
- \`.buildchain/contract-lock.json\`: accepted Buildchain runtime contract.
|
|
581
|
-
- \`.github/workflows/build.yml\`: thin read-only build and reproducibility caller.
|
|
582
|
-
- \`.github/workflows/paper-release.yml\`: thin protected sealed-release caller.
|
|
583
|
-
|
|
584
|
-
The repository does not own npm transaction logic, publication authority,
|
|
585
|
-
release-state recovery, or site deployment mechanics. Those remain Buildchain,
|
|
586
|
-
npm/GitHub, and downstream site responsibilities respectively.
|
|
587
|
-
`;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
function scaffoldMainTex(title) {
|
|
591
|
-
return `\\documentclass[11pt]{article}
|
|
592
|
-
\\usepackage[T1]{fontenc}
|
|
593
|
-
\\usepackage{lmodern}
|
|
594
|
-
\\usepackage{hyperref}
|
|
595
|
-
|
|
596
|
-
\\title{${texEscape(title)}}
|
|
597
|
-
\\author{}
|
|
598
|
-
\\date{}
|
|
599
|
-
|
|
600
|
-
\\begin{document}
|
|
601
|
-
\\maketitle
|
|
602
|
-
|
|
603
|
-
\\begin{abstract}
|
|
604
|
-
Replace this paragraph with the paper abstract.
|
|
605
|
-
\\end{abstract}
|
|
606
|
-
|
|
607
|
-
\\section{Introduction}
|
|
608
|
-
Replace this section with the reviewed paper content.
|
|
609
|
-
|
|
610
|
-
\\bibliographystyle{plain}
|
|
611
|
-
\\bibliography{paper/references}
|
|
612
|
-
\\end{document}
|
|
613
|
-
`;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
529
|
function scaffoldFiles({
|
|
617
530
|
buildchainRoot,
|
|
618
531
|
buildchainVersion,
|
|
@@ -647,6 +560,15 @@ function scaffoldFiles({
|
|
|
647
560
|
artifactPaths: "_build/main.pdf",
|
|
648
561
|
releasePassportProductName: title,
|
|
649
562
|
});
|
|
563
|
+
const verifyWorkflow = scaffoldVerifyWorkflow(buildchainSha);
|
|
564
|
+
const agentEntry = paperAgentEntryFiles({
|
|
565
|
+
cwd,
|
|
566
|
+
buildchainVersion,
|
|
567
|
+
buildchainSha,
|
|
568
|
+
developmentRef: `dev/v${parsePaperVersion(version).major}/v${
|
|
569
|
+
parsePaperVersion(version).major
|
|
570
|
+
}.${parsePaperVersion(version).minor}`,
|
|
571
|
+
});
|
|
650
572
|
const provisioningAuthority = createPaperProvisioningAuthority({
|
|
651
573
|
repository,
|
|
652
574
|
packageName,
|
|
@@ -654,7 +576,10 @@ function scaffoldFiles({
|
|
|
654
576
|
buildchainSha,
|
|
655
577
|
contractLock: contractLockText,
|
|
656
578
|
buildWorkflow,
|
|
579
|
+
verifyWorkflow,
|
|
657
580
|
releaseWorkflow,
|
|
581
|
+
agentEntry: agentEntry.get(PAPER_PATHS.agentEntry),
|
|
582
|
+
agentInstructions: agentEntry.get(PAPER_PATHS.agentInstructions),
|
|
658
583
|
});
|
|
659
584
|
const licenseText = runtimeLicenseText(buildchainRoot);
|
|
660
585
|
return new Map([
|
|
@@ -671,9 +596,18 @@ function scaffoldFiles({
|
|
|
671
596
|
[PAPER_PATHS.contractLock, contractLockText],
|
|
672
597
|
[PAPER_PATHS.versionPin, `${buildchainVersion}\n`],
|
|
673
598
|
[PAPER_PATHS.buildWorkflow, buildWorkflow],
|
|
599
|
+
[PAPER_PATHS.verifyWorkflow, verifyWorkflow],
|
|
674
600
|
[PAPER_PATHS.releaseWorkflow, releaseWorkflow],
|
|
675
601
|
[PAPER_PATHS.provisioningAuthority, jsonText(provisioningAuthority)],
|
|
676
|
-
|
|
602
|
+
...agentEntry,
|
|
603
|
+
[
|
|
604
|
+
"Makefile",
|
|
605
|
+
scaffoldMakefile({
|
|
606
|
+
image: DEFAULT_TOOLCHAIN_IMAGE,
|
|
607
|
+
digest: DEFAULT_TOOLCHAIN_DIGEST,
|
|
608
|
+
command: DEFAULT_TOOLCHAIN_COMMAND,
|
|
609
|
+
}),
|
|
610
|
+
],
|
|
677
611
|
[
|
|
678
612
|
"package.json",
|
|
679
613
|
scaffoldPackageJson({
|
|
@@ -957,6 +891,12 @@ function migrationFiles({
|
|
|
957
891
|
artifactPaths: config.publication.artifactPaths.join(","),
|
|
958
892
|
releasePassportProductName: config.publication.title,
|
|
959
893
|
});
|
|
894
|
+
const verifyWorkflow = scaffoldVerifyWorkflow(runtimeSha);
|
|
895
|
+
const agentEntry = paperAgentEntryFiles({
|
|
896
|
+
cwd,
|
|
897
|
+
buildchainVersion: runtimeIdentity.version,
|
|
898
|
+
buildchainSha: runtimeSha,
|
|
899
|
+
});
|
|
960
900
|
const provisioningAuthority = createPaperProvisioningAuthority({
|
|
961
901
|
repository,
|
|
962
902
|
packageName,
|
|
@@ -964,7 +904,10 @@ function migrationFiles({
|
|
|
964
904
|
buildchainSha: runtimeSha,
|
|
965
905
|
contractLock: contractLockText,
|
|
966
906
|
buildWorkflow,
|
|
907
|
+
verifyWorkflow,
|
|
967
908
|
releaseWorkflow,
|
|
909
|
+
agentEntry: agentEntry.get(PAPER_PATHS.agentEntry),
|
|
910
|
+
agentInstructions: agentEntry.get(PAPER_PATHS.agentInstructions),
|
|
968
911
|
});
|
|
969
912
|
const currentPackage = readJson(path.resolve(cwd, "package.json"));
|
|
970
913
|
if (!currentPackage.exists || currentPackage.error || !currentPackage.value) {
|
|
@@ -978,21 +921,12 @@ function migrationFiles({
|
|
|
978
921
|
[PAPER_PATHS.contractLock, contractLockText],
|
|
979
922
|
[PAPER_PATHS.versionPin, `${runtimeIdentity.version}\n`],
|
|
980
923
|
[PAPER_PATHS.buildWorkflow, buildWorkflow],
|
|
924
|
+
[PAPER_PATHS.verifyWorkflow, verifyWorkflow],
|
|
981
925
|
[PAPER_PATHS.releaseWorkflow, releaseWorkflow],
|
|
982
926
|
[PAPER_PATHS.provisioningAuthority, jsonText(provisioningAuthority)],
|
|
927
|
+
...agentEntry,
|
|
983
928
|
["package.json", jsonText(packageJson)],
|
|
984
929
|
]);
|
|
985
|
-
const verifyWorkflowPath = path.resolve(cwd, PAPER_PATHS.verifyWorkflow);
|
|
986
|
-
if (fs.existsSync(verifyWorkflowPath)) {
|
|
987
|
-
const currentVerifyWorkflow = fs.readFileSync(verifyWorkflowPath, "utf8");
|
|
988
|
-
const migratedVerifyWorkflow = currentVerifyWorkflow.replace(
|
|
989
|
-
/(uses:\s*kungfu-systems\/buildchain\/\.github\/workflows\/check\.yml@)[^\s]+/g,
|
|
990
|
-
`$1${runtimeSha}`,
|
|
991
|
-
);
|
|
992
|
-
if (migratedVerifyWorkflow !== currentVerifyWorkflow) {
|
|
993
|
-
files.set(PAPER_PATHS.verifyWorkflow, migratedVerifyWorkflow);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
930
|
return files;
|
|
997
931
|
}
|
|
998
932
|
|
|
@@ -1687,7 +1621,27 @@ function validatePaperProvisioningAuthority(cwd) {
|
|
|
1687
1621
|
"paper release policy permits avoidable bookkeeping pull requests",
|
|
1688
1622
|
);
|
|
1689
1623
|
}
|
|
1690
|
-
|
|
1624
|
+
if (value.agentEntry?.contract !== PAPER_AGENT_ENTRY_CONTRACT) {
|
|
1625
|
+
errors.push("paper agent-entry authority contract mismatch");
|
|
1626
|
+
}
|
|
1627
|
+
for (const [entryPath, expectedDigest] of [
|
|
1628
|
+
[value.agentEntry?.policyPath, value.agentEntry?.policyDigest],
|
|
1629
|
+
[value.agentEntry?.instructionsPath, value.agentEntry?.instructionsDigest],
|
|
1630
|
+
]) {
|
|
1631
|
+
if (!entryPath || !SHA256_PATTERN.test(String(expectedDigest || ""))) {
|
|
1632
|
+
errors.push("paper agent-entry authority is incomplete");
|
|
1633
|
+
continue;
|
|
1634
|
+
}
|
|
1635
|
+
const absolute = path.resolve(cwd, entryPath);
|
|
1636
|
+
if (!fs.existsSync(absolute) || sha256File(absolute) !== expectedDigest) {
|
|
1637
|
+
errors.push(`paper agent-entry source digest mismatch: ${entryPath}`);
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
for (const workflow of [
|
|
1641
|
+
value.workflows?.build,
|
|
1642
|
+
value.workflows?.verify,
|
|
1643
|
+
value.workflows?.release,
|
|
1644
|
+
]) {
|
|
1691
1645
|
if (!workflow?.path || !workflow?.sourceDigest) {
|
|
1692
1646
|
errors.push("paper workflow authority is incomplete");
|
|
1693
1647
|
continue;
|
|
@@ -1707,7 +1661,10 @@ function validatePaperProvisioningAuthority(cwd) {
|
|
|
1707
1661
|
`paper workflow reusable source is not exact: ${workflow.path}`,
|
|
1708
1662
|
);
|
|
1709
1663
|
}
|
|
1710
|
-
if (
|
|
1664
|
+
if (
|
|
1665
|
+
workflow.reusablePath !== ".github/workflows/check.yml" &&
|
|
1666
|
+
!text.includes(`buildchain-ref: ${value.runtime.resolvedSha}`)
|
|
1667
|
+
) {
|
|
1711
1668
|
errors.push(
|
|
1712
1669
|
`paper workflow runtime input is not exact: ${workflow.path}`,
|
|
1713
1670
|
);
|
|
@@ -2094,6 +2051,7 @@ export function collectPaperPreflight({
|
|
|
2094
2051
|
buildchainSha = "",
|
|
2095
2052
|
registry = NPM_REGISTRY,
|
|
2096
2053
|
offline = false,
|
|
2054
|
+
agentEntryMode = "contract",
|
|
2097
2055
|
} = {}) {
|
|
2098
2056
|
const resolvedCwd = path.resolve(cwd);
|
|
2099
2057
|
const status = collectPaperStatus({ cwd: resolvedCwd });
|
|
@@ -2114,6 +2072,11 @@ export function collectPaperPreflight({
|
|
|
2114
2072
|
buildchainRef: provisioning.value?.runtime?.ref || buildchainRef,
|
|
2115
2073
|
buildchainSha,
|
|
2116
2074
|
});
|
|
2075
|
+
const agentEntry = collectPaperAgentEntry({
|
|
2076
|
+
cwd: resolvedCwd,
|
|
2077
|
+
buildchainSha: runtime.resolvedSha,
|
|
2078
|
+
mode: agentEntryMode,
|
|
2079
|
+
});
|
|
2117
2080
|
const lockPath = path.resolve(resolvedCwd, PAPER_PATHS.contractLock);
|
|
2118
2081
|
let lockEvaluation = {
|
|
2119
2082
|
status: "missing-lock",
|
|
@@ -2220,6 +2183,11 @@ export function collectPaperPreflight({
|
|
|
2220
2183
|
configResult.loaded?.config?.publication,
|
|
2221
2184
|
);
|
|
2222
2185
|
const checks = [
|
|
2186
|
+
...agentEntry.checks.map((entry) => ({
|
|
2187
|
+
...entry,
|
|
2188
|
+
blocking: true,
|
|
2189
|
+
scope: "local",
|
|
2190
|
+
})),
|
|
2223
2191
|
{
|
|
2224
2192
|
id: "provisioning.authority",
|
|
2225
2193
|
status: provisioning.valid ? "pass" : "fail",
|
|
@@ -2486,6 +2454,7 @@ export function collectPaperPreflight({
|
|
|
2486
2454
|
policyDigest: provisioning.value?.policy?.policyDigest || "",
|
|
2487
2455
|
errors: provisioning.errors,
|
|
2488
2456
|
},
|
|
2457
|
+
agentEntry,
|
|
2489
2458
|
repositoryPermissions,
|
|
2490
2459
|
repositoryActions,
|
|
2491
2460
|
generatedWriteAuthority,
|
|
@@ -199,6 +199,7 @@ export const BUILDCHAIN_USAGE = `Usage:
|
|
|
199
199
|
buildchain paper work submit [--cwd <dir>] [--title <title>] [--body <body>] [--execute] [--json]
|
|
200
200
|
buildchain paper fleet audit [--root <dir>] [--offline] [--json]
|
|
201
201
|
buildchain paper fleet update [--root <dir>] [--write] [--json]
|
|
202
|
+
buildchain paper agent verify [--cwd <dir>] [--offline] [--json]
|
|
202
203
|
buildchain paper preflight [--cwd <dir>] [--offline] [--json]
|
|
203
204
|
buildchain paper bootstrap npm [--cwd <dir>] [--execute]
|
|
204
205
|
[--confirm-public-package <name>] [--json]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { collectPaperPreflight } from "../packages/core/paper.js";
|
|
2
|
+
|
|
3
|
+
function readFlag(args, name, fallback = "") {
|
|
4
|
+
const index = args.indexOf(`--${name}`);
|
|
5
|
+
if (index === -1) return fallback;
|
|
6
|
+
return args[index + 1] || "";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function runPaperAgentCli({
|
|
10
|
+
command,
|
|
11
|
+
subcommand,
|
|
12
|
+
args,
|
|
13
|
+
cwd,
|
|
14
|
+
buildchainRoot,
|
|
15
|
+
buildchainVersion,
|
|
16
|
+
buildchainRef,
|
|
17
|
+
buildchainSha,
|
|
18
|
+
}) {
|
|
19
|
+
if (command !== "agent" || subcommand !== "verify") {
|
|
20
|
+
return { handled: false, result: null };
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
handled: true,
|
|
24
|
+
result: collectPaperPreflight({
|
|
25
|
+
cwd,
|
|
26
|
+
buildchainRoot,
|
|
27
|
+
buildchainVersion,
|
|
28
|
+
buildchainRef: readFlag(args, "buildchain-ref", buildchainRef),
|
|
29
|
+
buildchainSha,
|
|
30
|
+
registry: readFlag(args, "registry", "https://registry.npmjs.org/"),
|
|
31
|
+
offline: args.includes("--offline"),
|
|
32
|
+
agentEntryMode: "local",
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -368,12 +368,13 @@ function githubGovernance(cwd, repository) {
|
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
370
|
|
|
371
|
-
function runWorkStart({ args, cwd }) {
|
|
371
|
+
function runWorkStart({ args, cwd, buildchainSha }) {
|
|
372
372
|
const topic = args[0]?.startsWith("--") ? "" : args[0] || "";
|
|
373
373
|
const plan = createPaperWorkStartPlan({
|
|
374
374
|
cwd,
|
|
375
375
|
topic,
|
|
376
376
|
branch: readFlag(args, "branch"),
|
|
377
|
+
buildchainSha,
|
|
377
378
|
});
|
|
378
379
|
return args.includes("--execute") ? executePaperWorkStart(plan) : plan;
|
|
379
380
|
}
|
|
@@ -382,7 +383,11 @@ function runScaffold(options) {
|
|
|
382
383
|
const plan = planPaperScaffold({
|
|
383
384
|
cwd: options.cwd,
|
|
384
385
|
buildchainRoot: options.buildchainRoot,
|
|
385
|
-
buildchainVersion:
|
|
386
|
+
buildchainVersion: readFlag(
|
|
387
|
+
options.args,
|
|
388
|
+
"buildchain-version",
|
|
389
|
+
options.buildchainVersion,
|
|
390
|
+
),
|
|
386
391
|
buildchainRef: readFlag(
|
|
387
392
|
options.args,
|
|
388
393
|
"buildchain-ref",
|
|
@@ -405,7 +410,11 @@ function runMigration(options) {
|
|
|
405
410
|
const plan = planPaperMigration({
|
|
406
411
|
cwd: options.cwd,
|
|
407
412
|
buildchainRoot: options.buildchainRoot,
|
|
408
|
-
buildchainVersion:
|
|
413
|
+
buildchainVersion: readFlag(
|
|
414
|
+
options.args,
|
|
415
|
+
"buildchain-version",
|
|
416
|
+
options.buildchainVersion,
|
|
417
|
+
),
|
|
409
418
|
buildchainSha: options.buildchainSha,
|
|
410
419
|
});
|
|
411
420
|
return options.args.some((entry) => ["--write", "--execute"].includes(entry))
|
|
@@ -413,7 +422,7 @@ function runMigration(options) {
|
|
|
413
422
|
: plan;
|
|
414
423
|
}
|
|
415
424
|
|
|
416
|
-
function runWorkSubmit({ args, cwd }) {
|
|
425
|
+
function runWorkSubmit({ args, cwd, buildchainSha }) {
|
|
417
426
|
const repository = collectPaperStatus({ cwd }).identity.repository;
|
|
418
427
|
const branch = commandResult("git", ["branch", "--show-current"], {
|
|
419
428
|
cwd,
|
|
@@ -426,6 +435,7 @@ function runWorkSubmit({ args, cwd }) {
|
|
|
426
435
|
cwd,
|
|
427
436
|
pullRequests: observation.rows,
|
|
428
437
|
pullRequestObservation: observation,
|
|
438
|
+
buildchainSha,
|
|
429
439
|
});
|
|
430
440
|
return args.includes("--execute") ? executeWorkSubmit(plan, args) : plan;
|
|
431
441
|
}
|
package/scripts/paper.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
PAPER_SCAFFOLD_CONTRACT,
|
|
14
14
|
PAPER_STATUS_CONTRACT,
|
|
15
15
|
collectPaperPreflight,
|
|
16
|
+
resolvePaperBuildchainSha,
|
|
16
17
|
collectPaperStatus,
|
|
17
18
|
createPaperAlphaPlan,
|
|
18
19
|
createPaperBuildPlan,
|
|
@@ -24,6 +25,7 @@ import {
|
|
|
24
25
|
printPaperWorkFleetSummary,
|
|
25
26
|
runPaperWorkFleetCli,
|
|
26
27
|
} from "./paper-work-fleet-cli.mjs";
|
|
28
|
+
import { runPaperAgentCli } from "./paper-agent-cli.mjs";
|
|
27
29
|
|
|
28
30
|
function usage() {
|
|
29
31
|
return `Usage:
|
|
@@ -38,6 +40,7 @@ function usage() {
|
|
|
38
40
|
[--execute] [--json]
|
|
39
41
|
buildchain paper fleet audit [--root <dir>] [--offline] [--json]
|
|
40
42
|
buildchain paper fleet update [--root <dir>] [--write] [--json]
|
|
43
|
+
buildchain paper agent verify [--cwd <dir>] [--offline] [--json]
|
|
41
44
|
buildchain paper preflight [--cwd <dir>] [--offline] [--json]
|
|
42
45
|
buildchain paper bootstrap npm [--cwd <dir>] [--package <name>]
|
|
43
46
|
[--repository <owner/repo>] [--workflow <filename>]
|
|
@@ -455,6 +458,7 @@ export async function runPaperCli(
|
|
|
455
458
|
buildchainSha = "",
|
|
456
459
|
} = {},
|
|
457
460
|
) {
|
|
461
|
+
buildchainSha = resolvePaperBuildchainSha(buildchainRoot, buildchainSha);
|
|
458
462
|
const [command = "", maybeSubcommand = "", ...rest] = args;
|
|
459
463
|
const json = hasFlag(args, "json");
|
|
460
464
|
try {
|
|
@@ -476,8 +480,12 @@ export async function runPaperCli(
|
|
|
476
480
|
buildchainRef,
|
|
477
481
|
buildchainSha,
|
|
478
482
|
});
|
|
483
|
+
// prettier-ignore
|
|
484
|
+
const paperAgent = runPaperAgentCli({ command, subcommand: maybeSubcommand, args: effectiveArgs, cwd, buildchainRoot, buildchainVersion, buildchainRef, buildchainSha });
|
|
479
485
|
let result;
|
|
480
|
-
if (
|
|
486
|
+
if (paperAgent.handled) {
|
|
487
|
+
result = paperAgent.result;
|
|
488
|
+
} else if (workFleet.handled) {
|
|
481
489
|
result = workFleet.result;
|
|
482
490
|
} else if (command === "preflight") {
|
|
483
491
|
result = collectPaperPreflight({
|
|
@@ -492,6 +500,11 @@ export async function runPaperCli(
|
|
|
492
500
|
"https://registry.npmjs.org/",
|
|
493
501
|
),
|
|
494
502
|
offline: hasFlag(effectiveArgs, "offline"),
|
|
503
|
+
agentEntryMode: hasFlag(effectiveArgs, "ci")
|
|
504
|
+
? "ci"
|
|
505
|
+
: hasFlag(effectiveArgs, "agent-entry")
|
|
506
|
+
? "local"
|
|
507
|
+
: "contract",
|
|
495
508
|
});
|
|
496
509
|
} else if (command === "bootstrap" && maybeSubcommand === "npm") {
|
|
497
510
|
result = executePaperNpmBootstrap({
|
|
@@ -577,7 +590,7 @@ export async function runPaperCli(
|
|
|
577
590
|
: plan;
|
|
578
591
|
} else {
|
|
579
592
|
throw new Error(
|
|
580
|
-
"usage: buildchain paper <scaffold|migrate|work start|work submit|fleet audit|fleet update|preflight|bootstrap npm|build|alpha|status|resume> ...",
|
|
593
|
+
"usage: buildchain paper <scaffold|migrate|work start|work submit|fleet audit|fleet update|agent verify|preflight|bootstrap npm|build|alpha|status|resume> ...",
|
|
581
594
|
);
|
|
582
595
|
}
|
|
583
596
|
printResult(result, json);
|
|
@@ -97,6 +97,7 @@ export function cliCommandMeta(id) {
|
|
|
97
97
|
"portable-cache-receipt": { group: "observability-diagnostics", purpose: "Seal exact, compatible, miss, or corrupt provider evidence against one cache plan." },
|
|
98
98
|
"npm-dry-run": { group: "release-passport-trust", purpose: "Verify npm publish shape before a release transaction." },
|
|
99
99
|
paper: { group: "reusable-build", purpose: "Inspect the unified paper repository and publication command families." },
|
|
100
|
+
"paper-agent": { group: "getting-started", purpose: "Verify the mandatory managed Paper agent entry contract on an existing work branch." },
|
|
100
101
|
"paper-alpha": { group: "release-passport-trust", purpose: "Plan or open the protected dev-to-alpha paper publication PR without direct publication." },
|
|
101
102
|
"paper-bootstrap-npm": { group: "release-passport-trust", purpose: "Dry-run or explicitly bootstrap the public npm package and bind GitHub Trusted Publishing." },
|
|
102
103
|
"paper-build": { group: "reusable-build", purpose: "Plan or execute the existing two-clean-build reproducibility gate for a paper." },
|
|
@@ -199,4 +200,3 @@ export function nodeApiMeta(exportName) {
|
|
|
199
200
|
}
|
|
200
201
|
return { capabilityGroup: capabilityGroup(meta.group), summary: meta.summary, audience: ["developer", "agent"], maturity: "stable" };
|
|
201
202
|
}
|
|
202
|
-
|