@contextecf/guardian-cli 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -15
- package/dist/packages/guardian-cli/src/bin.js +1036 -43
- package/dist/packages/guardian-cli/src/index.js +882 -39
- package/dist/packages/guardian-cli/src/runtime.d.ts +214 -2
- package/package.json +2 -2
|
@@ -17052,6 +17052,8 @@ async function runGuardianCli(argv, options = {}) {
|
|
|
17052
17052
|
write(stdout, renderGuardianProductionReadiness(readiness, flags));
|
|
17053
17053
|
return flags.has("strict") && (readiness.npmPreview.status !== "ready" || readiness.fullProduction.status !== "ready") ? 1 : 0;
|
|
17054
17054
|
}
|
|
17055
|
+
case "release":
|
|
17056
|
+
return runReleaseCommand(argv.slice(1), flags, options);
|
|
17055
17057
|
case "open":
|
|
17056
17058
|
return runControlTowerOpenCommand(flags, options);
|
|
17057
17059
|
case "status":
|
|
@@ -17205,7 +17207,7 @@ async function installGuardian(flags, options = {}) {
|
|
|
17205
17207
|
`First run: ${GUARDIAN_FIRST_RUN_COMMAND}`,
|
|
17206
17208
|
`Open Control Tower: ${GUARDIAN_OPEN_CONTROL_TOWER_COMMAND}`,
|
|
17207
17209
|
`No global install: ${GUARDIAN_NPX_SETUP_COMMAND}`,
|
|
17208
|
-
"Next: guardian setup; guardian doctor; guardian readiness; guardian launch; guardian mcp install; guardian extension open-setup; guardian daemon pair --json; guardian extension native-host install --extension-id=<browser-extension-id>"
|
|
17210
|
+
"Next: guardian setup; guardian doctor; guardian readiness; guardian launch; guardian open; guardian mcp install; guardian extension open-setup; guardian daemon pair --json; guardian extension native-host install --extension-id=<browser-extension-id>"
|
|
17209
17211
|
].join("\n")}
|
|
17210
17212
|
`;
|
|
17211
17213
|
}
|
|
@@ -17252,7 +17254,7 @@ async function runSetupCommand(flags, options) {
|
|
|
17252
17254
|
["json", true],
|
|
17253
17255
|
...copyStringFlags(flags, ["host", "port"])
|
|
17254
17256
|
]);
|
|
17255
|
-
if (flags.has("print")) {
|
|
17257
|
+
if (!flags.has("open") || flags.has("print")) {
|
|
17256
17258
|
launchFlags.set("print", true);
|
|
17257
17259
|
}
|
|
17258
17260
|
const launchExitCode = await runLaunchCommand(launchFlags, {
|
|
@@ -17331,6 +17333,7 @@ async function runSetupCommand(flags, options) {
|
|
|
17331
17333
|
nextCommands: [
|
|
17332
17334
|
"guardian status",
|
|
17333
17335
|
"guardian readiness",
|
|
17336
|
+
"guardian open",
|
|
17334
17337
|
"guardian policy list",
|
|
17335
17338
|
"guardian posture list",
|
|
17336
17339
|
"guardian preferences show",
|
|
@@ -17408,10 +17411,761 @@ async function buildGuardianProductionReadinessStatus(home, profile, env = proce
|
|
|
17408
17411
|
productionGateEvidenceStatus: protectedEvidence.productionGateEvidence?.status ?? "not_recorded",
|
|
17409
17412
|
productionGateEvidencePath: protectedEvidence.productionGateEvidence?.evidencePath
|
|
17410
17413
|
},
|
|
17414
|
+
distribution: buildGuardianDistributionReadiness(npmPreviewReady),
|
|
17415
|
+
tokenPrinted: false,
|
|
17416
|
+
rawContentIncluded: false
|
|
17417
|
+
};
|
|
17418
|
+
}
|
|
17419
|
+
function buildGuardianDistributionReadiness(npmPreviewReady) {
|
|
17420
|
+
return {
|
|
17421
|
+
status: npmPreviewReady ? "preview_install_ready" : "setup_or_release_evidence_required",
|
|
17422
|
+
oneLineInstallCommand: GUARDIAN_GLOBAL_INSTALL_COMMAND,
|
|
17423
|
+
oneLineTryCommand: GUARDIAN_NPX_SETUP_COMMAND,
|
|
17424
|
+
openControlTowerCommand: GUARDIAN_OPEN_CONTROL_TOWER_COMMAND,
|
|
17425
|
+
localUserCommands: {
|
|
17426
|
+
setup: GUARDIAN_FIRST_RUN_COMMAND,
|
|
17427
|
+
launch: "guardian launch",
|
|
17428
|
+
open: "guardian open",
|
|
17429
|
+
status: "guardian status",
|
|
17430
|
+
readiness: "guardian readiness"
|
|
17431
|
+
},
|
|
17432
|
+
aiToolIntegration: {
|
|
17433
|
+
mcpInstallCommand: "guardian mcp install --client=all --write",
|
|
17434
|
+
browserSetupCommand: "guardian extension open-setup",
|
|
17435
|
+
nativeHostInstallCommand: "guardian extension native-host install --extension-id=<browser-extension-id>"
|
|
17436
|
+
},
|
|
17437
|
+
browserStoreHandoff: {
|
|
17438
|
+
status: npmPreviewReady ? "operator_handoff_ready_not_submitted" : "blocked_until_preview_ready",
|
|
17439
|
+
submissionPackCommand: "npm run guardian:browser-store:submission-pack",
|
|
17440
|
+
closeoutChecklistPath: "release/evidence/guardian-browser-store-submission-pack/browser-store-closeout-checklist.json",
|
|
17441
|
+
productionGateStatus: "not_proven"
|
|
17442
|
+
},
|
|
17443
|
+
enterpriseDeployment: {
|
|
17444
|
+
status: "managed_rollout_ready_for_customer_pack",
|
|
17445
|
+
note: "Use enterprise policy packs, managed browser deployment, and customer evidence as a separate company or school-district rollout lane; it does not prove public browser-store distribution."
|
|
17446
|
+
},
|
|
17447
|
+
releaseAutomation: {
|
|
17448
|
+
workflow: GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
|
|
17449
|
+
dryRunCommand: buildGuardianReleaseDispatchCommand(true),
|
|
17450
|
+
publishCommand: buildGuardianReleaseDispatchCommand(false),
|
|
17451
|
+
requiredPublishCredentialName: "NPM_TOKEN",
|
|
17452
|
+
channels: ["all", "npm", "browser", "evidence"],
|
|
17453
|
+
defaultDockerSmoke: true,
|
|
17454
|
+
provenance: "github_actions_oidc_supported",
|
|
17455
|
+
status: npmPreviewReady ? "ready_for_dispatch_after_preview_evidence" : "blocked_until_preview_release_evidence_passes",
|
|
17456
|
+
boundaries: [
|
|
17457
|
+
"Use dry_run=true before public publication.",
|
|
17458
|
+
"dry_run=false requires the repository secret NPM_TOKEN and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17459
|
+
"The workflow can publish the npm preview package, upload evidence, and run public install smokes; it does not sign native installers or approve future browser-store listings.",
|
|
17460
|
+
"GitHub Actions OIDC/provenance applies to CI release context; manual local publishes are recorded separately and should not claim CI provenance."
|
|
17461
|
+
]
|
|
17462
|
+
},
|
|
17463
|
+
boundaries: [
|
|
17464
|
+
"One-line npm install and Control Tower launch prove preview distribution only.",
|
|
17465
|
+
"Chrome Web Store distribution is proven for the evidenced ContextECF Halo listing; future store submissions still require fresh official review evidence.",
|
|
17466
|
+
"Enterprise managed deployment can support company or school-district rollout but remains a separate rollout lane.",
|
|
17467
|
+
"MCP and browser setup commands must not print runtime tokens, raw prompts, raw responses, source archives, source maps, credentials, or private policy packs."
|
|
17468
|
+
]
|
|
17469
|
+
};
|
|
17470
|
+
}
|
|
17471
|
+
function buildGuardianReleaseDispatchCommand(dryRun) {
|
|
17472
|
+
return buildGuardianReleaseDispatchCommandFor({
|
|
17473
|
+
dryRun,
|
|
17474
|
+
releaseVersion: "<version>",
|
|
17475
|
+
channels: "all",
|
|
17476
|
+
runDockerSmoke: true
|
|
17477
|
+
});
|
|
17478
|
+
}
|
|
17479
|
+
function buildGuardianReleaseDispatchCommandFor(input2) {
|
|
17480
|
+
return [
|
|
17481
|
+
`gh workflow run ${GUARDIAN_RELEASE_DISPATCH_WORKFLOW} \\`,
|
|
17482
|
+
` -f release_version=${input2.releaseVersion} \\`,
|
|
17483
|
+
` -f channels=${input2.channels} \\`,
|
|
17484
|
+
` -f dry_run=${input2.dryRun ? "true" : "false"} \\`,
|
|
17485
|
+
` -f run_docker_smoke=${input2.runDockerSmoke ? "true" : "false"}`
|
|
17486
|
+
].join("\n");
|
|
17487
|
+
}
|
|
17488
|
+
async function runReleaseCommand(argv, flags, options) {
|
|
17489
|
+
const subcommand = argv[0];
|
|
17490
|
+
const stdout = options.stdout ?? process.stdout;
|
|
17491
|
+
const stderr = options.stderr ?? process.stderr;
|
|
17492
|
+
if (!subcommand || subcommand === "help" || subcommand === "quickstart") {
|
|
17493
|
+
write(stdout, renderGuardianReleaseHelp(buildGuardianReleaseHelp(), flags));
|
|
17494
|
+
return 0;
|
|
17495
|
+
}
|
|
17496
|
+
if (subcommand === "browser-store" || subcommand === "browser-store-handoff" || subcommand === "store") {
|
|
17497
|
+
write(
|
|
17498
|
+
stdout,
|
|
17499
|
+
renderGuardianBrowserStoreHandoffCommand(
|
|
17500
|
+
buildGuardianBrowserStoreHandoffCommandResult(),
|
|
17501
|
+
flags
|
|
17502
|
+
)
|
|
17503
|
+
);
|
|
17504
|
+
return 0;
|
|
17505
|
+
}
|
|
17506
|
+
if (subcommand === "secrets" || subcommand === "secret-setup" || subcommand === "npm-token") {
|
|
17507
|
+
write(stdout, renderGuardianReleaseSecretSetup(buildGuardianReleaseSecretSetup(), flags));
|
|
17508
|
+
return 0;
|
|
17509
|
+
}
|
|
17510
|
+
if (subcommand === "checklist" || subcommand === "plan") {
|
|
17511
|
+
const releaseVersion2 = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17512
|
+
if (!releaseVersion2) {
|
|
17513
|
+
write(
|
|
17514
|
+
stderr,
|
|
17515
|
+
"Missing release version. Usage: guardian release checklist --version=<semver>\n"
|
|
17516
|
+
);
|
|
17517
|
+
return 1;
|
|
17518
|
+
}
|
|
17519
|
+
if (!isValidReleaseVersion(releaseVersion2)) {
|
|
17520
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17521
|
+
return 1;
|
|
17522
|
+
}
|
|
17523
|
+
write(
|
|
17524
|
+
stdout,
|
|
17525
|
+
renderGuardianReleaseChecklist(buildGuardianReleaseChecklist(releaseVersion2), flags)
|
|
17526
|
+
);
|
|
17527
|
+
return 0;
|
|
17528
|
+
}
|
|
17529
|
+
if (subcommand === "flow" || subcommand === "train" || subcommand === "next") {
|
|
17530
|
+
const releaseVersion2 = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17531
|
+
if (!releaseVersion2) {
|
|
17532
|
+
write(stderr, "Missing release version. Usage: guardian release flow --version=<semver>\n");
|
|
17533
|
+
return 1;
|
|
17534
|
+
}
|
|
17535
|
+
if (!isValidReleaseVersion(releaseVersion2)) {
|
|
17536
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17537
|
+
return 1;
|
|
17538
|
+
}
|
|
17539
|
+
write(stdout, renderGuardianReleaseFlow(buildGuardianReleaseFlow(releaseVersion2), flags));
|
|
17540
|
+
return 0;
|
|
17541
|
+
}
|
|
17542
|
+
if (subcommand === "verify" || subcommand === "post-release") {
|
|
17543
|
+
const releaseVersion2 = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17544
|
+
if (!releaseVersion2) {
|
|
17545
|
+
write(stderr, "Missing release version. Usage: guardian release verify --version=<semver>\n");
|
|
17546
|
+
return 1;
|
|
17547
|
+
}
|
|
17548
|
+
if (!isValidReleaseVersion(releaseVersion2)) {
|
|
17549
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17550
|
+
return 1;
|
|
17551
|
+
}
|
|
17552
|
+
write(stdout, renderGuardianReleaseVerify(buildGuardianReleaseVerify(releaseVersion2), flags));
|
|
17553
|
+
return 0;
|
|
17554
|
+
}
|
|
17555
|
+
if (subcommand === "paste" || subcommand === "smoke" || subcommand === "install-smoke") {
|
|
17556
|
+
const releaseVersion2 = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17557
|
+
if (!releaseVersion2) {
|
|
17558
|
+
write(stderr, "Missing release version. Usage: guardian release paste --version=<semver>\n");
|
|
17559
|
+
return 1;
|
|
17560
|
+
}
|
|
17561
|
+
if (!isValidReleaseVersion(releaseVersion2)) {
|
|
17562
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17563
|
+
return 1;
|
|
17564
|
+
}
|
|
17565
|
+
write(stdout, renderGuardianReleasePaste(buildGuardianReleasePaste(releaseVersion2), flags));
|
|
17566
|
+
return 0;
|
|
17567
|
+
}
|
|
17568
|
+
if (subcommand !== "command" && subcommand !== "dispatch") {
|
|
17569
|
+
write(stderr, `Unknown Guardian release command: ${subcommand}
|
|
17570
|
+
`);
|
|
17571
|
+
return 1;
|
|
17572
|
+
}
|
|
17573
|
+
const releaseVersion = stringFlag(flags, "version") ?? stringFlag(flags, "release-version");
|
|
17574
|
+
if (!releaseVersion) {
|
|
17575
|
+
write(
|
|
17576
|
+
stderr,
|
|
17577
|
+
"Missing release version. Usage: guardian release command --version=<semver> [--publish|--dry-run=false]\n"
|
|
17578
|
+
);
|
|
17579
|
+
return 1;
|
|
17580
|
+
}
|
|
17581
|
+
if (!isValidReleaseVersion(releaseVersion)) {
|
|
17582
|
+
write(stderr, "Invalid --version. Expected a semver value like 0.1.4 or 0.1.4-beta.1.\n");
|
|
17583
|
+
return 1;
|
|
17584
|
+
}
|
|
17585
|
+
const channels = stringFlag(flags, "channels") ?? "all";
|
|
17586
|
+
if (!isValidReleaseChannels(channels)) {
|
|
17587
|
+
write(stderr, "Invalid --channels. Expected one of: all, npm, browser, evidence.\n");
|
|
17588
|
+
return 1;
|
|
17589
|
+
}
|
|
17590
|
+
const dryRun = flags.has("publish") ? false : booleanFlag(flags, "dry-run", true);
|
|
17591
|
+
const runDockerSmoke = booleanFlag(flags, "run-docker-smoke", true);
|
|
17592
|
+
const result = buildGuardianReleaseDispatchCommandResult({
|
|
17593
|
+
releaseVersion,
|
|
17594
|
+
channels,
|
|
17595
|
+
dryRun,
|
|
17596
|
+
runDockerSmoke
|
|
17597
|
+
});
|
|
17598
|
+
write(stdout, renderGuardianReleaseDispatchCommand(result, flags));
|
|
17599
|
+
return 0;
|
|
17600
|
+
}
|
|
17601
|
+
function buildGuardianReleaseHelp() {
|
|
17602
|
+
return {
|
|
17603
|
+
schema_version: "contextecf/project-guardian-release-help/v1",
|
|
17604
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17605
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17606
|
+
status: "release_owner_quickstart",
|
|
17607
|
+
commands: {
|
|
17608
|
+
checklist: "guardian release checklist --version=<version>",
|
|
17609
|
+
flow: "guardian release flow --version=<version>",
|
|
17610
|
+
secrets: "guardian release secrets",
|
|
17611
|
+
dryRunDispatch: "guardian release command --version=<version>",
|
|
17612
|
+
publishDispatch: "guardian release command --version=<version> --publish",
|
|
17613
|
+
verifyPublishedVersion: "guardian release verify --version=<version>",
|
|
17614
|
+
pasteLocalSmoke: "guardian release paste --version=<version>",
|
|
17615
|
+
browserStoreHandoff: "guardian release browser-store",
|
|
17616
|
+
readiness: "guardian readiness"
|
|
17617
|
+
},
|
|
17618
|
+
suggestedOrder: [
|
|
17619
|
+
"Run the checklist for the target version.",
|
|
17620
|
+
"Set or verify the repository publish credential if this is a public npm release.",
|
|
17621
|
+
"Run the dry-run dispatch before any publish dispatch.",
|
|
17622
|
+
"Run the publish dispatch only after dry-run evidence passes.",
|
|
17623
|
+
"Verify the published version and refresh release evidence.",
|
|
17624
|
+
"Use browser-store handoff only for submission/review evidence; it does not upload or approve listings."
|
|
17625
|
+
],
|
|
17626
|
+
boundaries: [
|
|
17627
|
+
"Release quickstart output is operator guidance only, not release evidence or production-gate proof.",
|
|
17628
|
+
"Do not paste npm tokens, OTP values, .npmrc contents, signing keys, browser-store credentials, raw prompts, raw responses, private policy packs, or customer content into release commands, chat, PR bodies, or evidence.",
|
|
17629
|
+
"Public npm preview publication does not close signed-installer, browser-store, high-risk desktop action, or autonomous local app execution production gates.",
|
|
17630
|
+
"Full production claims remain blocked until every not-proven production gate has real validated external evidence."
|
|
17631
|
+
],
|
|
17632
|
+
tokenPrinted: false,
|
|
17633
|
+
rawContentIncluded: false
|
|
17634
|
+
};
|
|
17635
|
+
}
|
|
17636
|
+
function renderGuardianReleaseHelp(result, flags) {
|
|
17637
|
+
if (flags.has("json")) {
|
|
17638
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17639
|
+
`;
|
|
17640
|
+
}
|
|
17641
|
+
return `${[
|
|
17642
|
+
"Project Guardian Release Quickstart",
|
|
17643
|
+
`Repository: ${result.repository}`,
|
|
17644
|
+
`Status: ${result.status}`,
|
|
17645
|
+
"Commands:",
|
|
17646
|
+
`- Checklist: ${result.commands.checklist}`,
|
|
17647
|
+
`- Flow: ${result.commands.flow}`,
|
|
17648
|
+
`- Secrets: ${result.commands.secrets}`,
|
|
17649
|
+
`- Dry run: ${result.commands.dryRunDispatch}`,
|
|
17650
|
+
`- Publish: ${result.commands.publishDispatch}`,
|
|
17651
|
+
`- Verify published version: ${result.commands.verifyPublishedVersion}`,
|
|
17652
|
+
`- Copy-paste local smoke: ${result.commands.pasteLocalSmoke}`,
|
|
17653
|
+
`- Browser-store handoff: ${result.commands.browserStoreHandoff}`,
|
|
17654
|
+
`- Readiness: ${result.commands.readiness}`,
|
|
17655
|
+
"Suggested order:",
|
|
17656
|
+
...result.suggestedOrder.map((step, index) => `${index + 1}. ${step}`),
|
|
17657
|
+
"Boundaries:",
|
|
17658
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17659
|
+
"Token printed: no"
|
|
17660
|
+
].join("\n")}
|
|
17661
|
+
`;
|
|
17662
|
+
}
|
|
17663
|
+
function buildGuardianReleaseDispatchCommandResult(input2) {
|
|
17664
|
+
return {
|
|
17665
|
+
schema_version: "contextecf/project-guardian-release-dispatch-command/v1",
|
|
17666
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17667
|
+
workflow: GUARDIAN_RELEASE_DISPATCH_WORKFLOW,
|
|
17668
|
+
releaseVersion: input2.releaseVersion,
|
|
17669
|
+
channels: input2.channels,
|
|
17670
|
+
dryRun: input2.dryRun,
|
|
17671
|
+
runDockerSmoke: input2.runDockerSmoke,
|
|
17672
|
+
command: buildGuardianReleaseDispatchCommandFor(input2),
|
|
17673
|
+
...input2.dryRun ? {} : { requiredPublishCredentialName: "NPM_TOKEN" },
|
|
17674
|
+
provenance: "github_actions_oidc_supported",
|
|
17675
|
+
boundaries: [
|
|
17676
|
+
"Use dry_run=true before public publication.",
|
|
17677
|
+
"dry_run=false requires the repository secret NPM_TOKEN and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17678
|
+
"This dispatch can publish the npm preview package, upload evidence, and run public install smokes; it does not sign native installers or approve future browser-store listings.",
|
|
17679
|
+
"A release-dispatch command is operator guidance, not production-gate proof."
|
|
17680
|
+
],
|
|
17681
|
+
tokenPrinted: false,
|
|
17682
|
+
rawContentIncluded: false
|
|
17683
|
+
};
|
|
17684
|
+
}
|
|
17685
|
+
function renderGuardianReleaseDispatchCommand(result, flags) {
|
|
17686
|
+
if (flags.has("json")) {
|
|
17687
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17688
|
+
`;
|
|
17689
|
+
}
|
|
17690
|
+
return `${[
|
|
17691
|
+
"Project Guardian Release Dispatch Command",
|
|
17692
|
+
`Release: ${result.releaseVersion}`,
|
|
17693
|
+
`Mode: ${result.dryRun ? "dry run" : "publish"}`,
|
|
17694
|
+
`Workflow: ${result.workflow}`,
|
|
17695
|
+
`Channels: ${result.channels}`,
|
|
17696
|
+
`Docker smoke: ${result.runDockerSmoke ? "yes" : "no"}`,
|
|
17697
|
+
result.requiredPublishCredentialName ? `Required repository secret: ${result.requiredPublishCredentialName}` : "Required repository secret: not needed for dry run",
|
|
17698
|
+
"Command:",
|
|
17699
|
+
result.command,
|
|
17700
|
+
"Boundaries:",
|
|
17701
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17702
|
+
"Token printed: no"
|
|
17703
|
+
].join("\n")}
|
|
17704
|
+
`;
|
|
17705
|
+
}
|
|
17706
|
+
function buildGuardianBrowserStoreHandoffCommandResult() {
|
|
17707
|
+
return {
|
|
17708
|
+
schema_version: "contextecf/project-guardian-browser-store-handoff-command/v1",
|
|
17709
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17710
|
+
status: "chrome_distribution_proven_next_submission_pack_ready",
|
|
17711
|
+
primaryStore: "chrome_web_store",
|
|
17712
|
+
productionGate: {
|
|
17713
|
+
id: "browser-store-distribution",
|
|
17714
|
+
status: "proven",
|
|
17715
|
+
nextSubmissionRequiresFreshOfficialReviewEvidence: true
|
|
17716
|
+
},
|
|
17717
|
+
commands: {
|
|
17718
|
+
submissionPack: "npm run guardian:browser-store:submission-pack -- --json --output-dir release/evidence/guardian-browser-store-submission-pack",
|
|
17719
|
+
preSubmissionSmoke: "GUARDIAN_BROWSER_STORE_SMOKE_WORKSPACE=/tmp/guardian-browser-store-pre-submission-smoke bash release/evidence/guardian-browser-store-submission-pack/run-pre-submission-readiness-smoke.sh",
|
|
17720
|
+
preSubmissionReadiness: [
|
|
17721
|
+
"npm run guardian:browser-store:readiness:collect -- \\",
|
|
17722
|
+
" --package artifacts/guardian-browser-store/guardian-browser-extension-<version>.zip \\",
|
|
17723
|
+
" --assert-pre-submission-only \\",
|
|
17724
|
+
" --assert-mv3-validation-passed \\",
|
|
17725
|
+
" --assert-source-archive-excluded \\",
|
|
17726
|
+
" --assert-store-credentials-excluded \\",
|
|
17727
|
+
" --output release/evidence/guardian-browser-store-submission-pack/pre-submission-readiness.json"
|
|
17728
|
+
].join("\n"),
|
|
17729
|
+
reviewPreflightAfterApproval: [
|
|
17730
|
+
"npm run guardian:browser-store:review-preflight -- \\",
|
|
17731
|
+
" --store-evidence release/evidence/guardian-browser-store-submission-pack/browser-store-evidence-input.json \\",
|
|
17732
|
+
" --assert-metadata-only \\",
|
|
17733
|
+
" --assert-no-store-credentials \\",
|
|
17734
|
+
" --assert-approved-review-status \\",
|
|
17735
|
+
" --assert-public-listing-url \\",
|
|
17736
|
+
" --output release/evidence/guardian-browser-store-submission-pack/browser-store-review-preflight.json"
|
|
17737
|
+
].join("\n"),
|
|
17738
|
+
collectorAfterApproval: [
|
|
17739
|
+
"npm run guardian:production-gates:collect:browser-store -- \\",
|
|
17740
|
+
" --store-evidence release/evidence/guardian-browser-store-submission-pack/browser-store-evidence-input.json \\",
|
|
17741
|
+
" --review-preflight-summary release/evidence/guardian-browser-store-submission-pack/browser-store-review-preflight.json \\",
|
|
17742
|
+
" --assert-no-source-archives \\",
|
|
17743
|
+
" --assert-package-digest-matches-release \\",
|
|
17744
|
+
" --assert-listing-matches-release-boundary \\",
|
|
17745
|
+
" --assert-listing-names-not-proven-gates \\",
|
|
17746
|
+
" --assert-production-claim-absent \\",
|
|
17747
|
+
" --output release/evidence/guardian-production-gates/browser-store-distribution.json"
|
|
17748
|
+
].join("\n"),
|
|
17749
|
+
finalGateValidation: "npm run validate:guardian-production-gates -- --claim production"
|
|
17750
|
+
},
|
|
17751
|
+
evidence: {
|
|
17752
|
+
submissionPackDir: "release/evidence/guardian-browser-store-submission-pack",
|
|
17753
|
+
closeoutChecklistPath: "release/evidence/guardian-browser-store-submission-pack/browser-store-closeout-checklist.json",
|
|
17754
|
+
preSubmissionChecklistPath: "docs/project-guardian/browser-store-pre-submission-checklist.md",
|
|
17755
|
+
readinessOutput: "release/evidence/guardian-browser-store-submission-pack/pre-submission-readiness.json",
|
|
17756
|
+
reviewPreflightOutput: "release/evidence/guardian-browser-store-submission-pack/browser-store-review-preflight.json",
|
|
17757
|
+
productionGatePacket: "release/evidence/guardian-production-gates/browser-store-distribution.json"
|
|
17758
|
+
},
|
|
17759
|
+
boundaries: [
|
|
17760
|
+
"This command surface prepares browser-store submission handoff for future extension versions; it does not upload, submit, approve, or distribute the extension.",
|
|
17761
|
+
"Chrome Web Store distribution is proven for the evidenced ContextECF Halo listing; each future extension package still needs fresh review/submission evidence before updating that proof.",
|
|
17762
|
+
"Do not place browser-store credentials, dashboard cookies, source archives, source maps, runtime tokens, private policy packs, raw prompts, raw responses, or customer content in browser-store evidence.",
|
|
17763
|
+
"Enterprise managed browser deployment is a separate customer rollout lane and does not replace public store review evidence for public listings."
|
|
17764
|
+
],
|
|
17765
|
+
tokenPrinted: false,
|
|
17766
|
+
rawContentIncluded: false
|
|
17767
|
+
};
|
|
17768
|
+
}
|
|
17769
|
+
function renderGuardianBrowserStoreHandoffCommand(result, flags) {
|
|
17770
|
+
if (flags.has("json")) {
|
|
17771
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17772
|
+
`;
|
|
17773
|
+
}
|
|
17774
|
+
return `${[
|
|
17775
|
+
"Project Guardian Browser Store Handoff",
|
|
17776
|
+
`Status: ${result.status}`,
|
|
17777
|
+
`Primary store: ${result.primaryStore}`,
|
|
17778
|
+
`Production gate: ${result.productionGate.id} (${result.productionGate.status})`,
|
|
17779
|
+
"1. Build submission pack:",
|
|
17780
|
+
result.commands.submissionPack,
|
|
17781
|
+
"2. Run pre-submission smoke:",
|
|
17782
|
+
result.commands.preSubmissionSmoke,
|
|
17783
|
+
"3. Record pre-submission readiness:",
|
|
17784
|
+
result.commands.preSubmissionReadiness,
|
|
17785
|
+
"4. After official approval, run review preflight:",
|
|
17786
|
+
result.commands.reviewPreflightAfterApproval,
|
|
17787
|
+
"5. After official approval, collect production-gate evidence:",
|
|
17788
|
+
result.commands.collectorAfterApproval,
|
|
17789
|
+
`Closeout checklist: ${result.evidence.closeoutChecklistPath}`,
|
|
17790
|
+
`Pre-submission checklist: ${result.evidence.preSubmissionChecklistPath}`,
|
|
17791
|
+
"Boundaries:",
|
|
17792
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17793
|
+
"Token printed: no"
|
|
17794
|
+
].join("\n")}
|
|
17795
|
+
`;
|
|
17796
|
+
}
|
|
17797
|
+
function buildGuardianReleaseSecretSetup() {
|
|
17798
|
+
return {
|
|
17799
|
+
schema_version: "contextecf/project-guardian-release-secret-setup/v1",
|
|
17800
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17801
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17802
|
+
requiredForPublish: "NPM_TOKEN",
|
|
17803
|
+
githubActionsSecretUrl: `https://github.com/${GUARDIAN_RELEASE_REPOSITORY}/settings/secrets/actions/new`,
|
|
17804
|
+
commands: {
|
|
17805
|
+
setNpmToken: `gh secret set NPM_TOKEN --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions`,
|
|
17806
|
+
verifyNpmTokenPresence: `gh secret list --repo ${GUARDIAN_RELEASE_REPOSITORY} --app actions | rg '^NPM_TOKEN\\b'`,
|
|
17807
|
+
dryRunDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17808
|
+
dryRun: true,
|
|
17809
|
+
releaseVersion: "<version>",
|
|
17810
|
+
channels: "all",
|
|
17811
|
+
runDockerSmoke: true
|
|
17812
|
+
}),
|
|
17813
|
+
publishDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17814
|
+
dryRun: false,
|
|
17815
|
+
releaseVersion: "<version>",
|
|
17816
|
+
channels: "all",
|
|
17817
|
+
runDockerSmoke: true
|
|
17818
|
+
})
|
|
17819
|
+
},
|
|
17820
|
+
boundaries: [
|
|
17821
|
+
"NPM_TOKEN belongs only in GitHub Actions repository secrets for guarded dry_run=false npm publication.",
|
|
17822
|
+
"Do not paste npm tokens, OTP values, .npmrc contents, signing keys, browser-store credentials, raw prompts, raw responses, private policy packs, or customer content into chat, PR bodies, release evidence, or CLI output.",
|
|
17823
|
+
"Use dry_run=true before dry_run=false; dry-run dispatch does not require NPM_TOKEN.",
|
|
17824
|
+
"Adding NPM_TOKEN enables the npm preview publish lane only; it does not close signed-installer, browser-store, high-risk desktop, or autonomous app production gates."
|
|
17825
|
+
],
|
|
17826
|
+
tokenPrinted: false,
|
|
17827
|
+
rawContentIncluded: false
|
|
17828
|
+
};
|
|
17829
|
+
}
|
|
17830
|
+
function renderGuardianReleaseSecretSetup(result, flags) {
|
|
17831
|
+
if (flags.has("json")) {
|
|
17832
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17833
|
+
`;
|
|
17834
|
+
}
|
|
17835
|
+
return `${[
|
|
17836
|
+
"Project Guardian Release Secret Setup",
|
|
17837
|
+
`Repository: ${result.repository}`,
|
|
17838
|
+
`Required for publish: ${result.requiredForPublish}`,
|
|
17839
|
+
`GitHub Actions secret page: ${result.githubActionsSecretUrl}`,
|
|
17840
|
+
"Set secret:",
|
|
17841
|
+
result.commands.setNpmToken,
|
|
17842
|
+
"Verify secret presence:",
|
|
17843
|
+
result.commands.verifyNpmTokenPresence,
|
|
17844
|
+
"Dry-run release command:",
|
|
17845
|
+
result.commands.dryRunDispatch,
|
|
17846
|
+
"Publish release command:",
|
|
17847
|
+
result.commands.publishDispatch,
|
|
17848
|
+
"Boundaries:",
|
|
17849
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
17850
|
+
"Token printed: no"
|
|
17851
|
+
].join("\n")}
|
|
17852
|
+
`;
|
|
17853
|
+
}
|
|
17854
|
+
function buildGuardianReleaseChecklist(releaseVersion) {
|
|
17855
|
+
return {
|
|
17856
|
+
schema_version: "contextecf/project-guardian-release-checklist/v1",
|
|
17857
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17858
|
+
releaseVersion,
|
|
17859
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17860
|
+
status: "preview_release_operator_ready_full_production_blocked",
|
|
17861
|
+
operatorCommands: {
|
|
17862
|
+
secretSetup: "guardian release secrets",
|
|
17863
|
+
dryRunDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17864
|
+
dryRun: true,
|
|
17865
|
+
releaseVersion,
|
|
17866
|
+
channels: "all",
|
|
17867
|
+
runDockerSmoke: true
|
|
17868
|
+
}),
|
|
17869
|
+
publishDispatch: buildGuardianReleaseDispatchCommandFor({
|
|
17870
|
+
dryRun: false,
|
|
17871
|
+
releaseVersion,
|
|
17872
|
+
channels: "all",
|
|
17873
|
+
runDockerSmoke: true
|
|
17874
|
+
}),
|
|
17875
|
+
browserStoreHandoff: "guardian release browser-store",
|
|
17876
|
+
readiness: "guardian readiness"
|
|
17877
|
+
},
|
|
17878
|
+
requiredRepositoryCredentialName: "NPM_TOKEN",
|
|
17879
|
+
evidenceOutputs: [
|
|
17880
|
+
"release/evidence/guardian-release-dispatch-summary.json",
|
|
17881
|
+
"release/evidence/guardian-npm-publish-execution-summary.json",
|
|
17882
|
+
"release/evidence/guardian-npm-publish-status-verification.json",
|
|
17883
|
+
"release/evidence/guardian-browser-store-submission-pack/browser-store-closeout-checklist.json",
|
|
17884
|
+
"release/evidence/guardian-finish-line-status.json"
|
|
17885
|
+
],
|
|
17886
|
+
notProvenProductionGates: GUARDIAN_NOT_PROVEN_PRODUCTION_GATES.map((gate) => ({
|
|
17887
|
+
id: gate.id,
|
|
17888
|
+
label: gate.label,
|
|
17889
|
+
owner: gate.owner,
|
|
17890
|
+
releaseBoundary: gate.releaseBoundary
|
|
17891
|
+
})),
|
|
17892
|
+
boundaries: [
|
|
17893
|
+
"This checklist is an operator command surface for Guardian preview releases; it is not production-gate proof.",
|
|
17894
|
+
"Run the dry-run dispatch before any dry_run=false publish dispatch.",
|
|
17895
|
+
"dry_run=false requires NPM_TOKEN in GitHub Actions repository secrets and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17896
|
+
"The checklist does not sign native installers, submit browser-store packages, execute high-risk desktop actions, or enable autonomous local app execution.",
|
|
17897
|
+
"Full production claims remain blocked until every not-proven production gate has real validated external evidence."
|
|
17898
|
+
],
|
|
17899
|
+
tokenPrinted: false,
|
|
17900
|
+
rawContentIncluded: false
|
|
17901
|
+
};
|
|
17902
|
+
}
|
|
17903
|
+
function buildGuardianReleaseFlow(releaseVersion) {
|
|
17904
|
+
const checklist = buildGuardianReleaseChecklist(releaseVersion);
|
|
17905
|
+
const verify = buildGuardianReleaseVerify(releaseVersion);
|
|
17906
|
+
const dryRunDispatch = buildGuardianReleaseDispatchCommandFor({
|
|
17907
|
+
dryRun: true,
|
|
17908
|
+
releaseVersion,
|
|
17909
|
+
channels: "all",
|
|
17910
|
+
runDockerSmoke: true
|
|
17911
|
+
});
|
|
17912
|
+
const publishDispatch = buildGuardianReleaseDispatchCommandFor({
|
|
17913
|
+
dryRun: false,
|
|
17914
|
+
releaseVersion,
|
|
17915
|
+
channels: "all",
|
|
17916
|
+
runDockerSmoke: true
|
|
17917
|
+
});
|
|
17918
|
+
return {
|
|
17919
|
+
schema_version: "contextecf/project-guardian-release-flow/v1",
|
|
17920
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
17921
|
+
releaseVersion,
|
|
17922
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
17923
|
+
status: "release_owner_flow_ready_full_production_blocked",
|
|
17924
|
+
steps: [
|
|
17925
|
+
{
|
|
17926
|
+
id: "review-checklist",
|
|
17927
|
+
label: "Review the release checklist",
|
|
17928
|
+
command: `guardian release checklist --version=${releaseVersion}`,
|
|
17929
|
+
credentialRequired: false
|
|
17930
|
+
},
|
|
17931
|
+
{
|
|
17932
|
+
id: "verify-secrets",
|
|
17933
|
+
label: "Verify npm publish secret setup",
|
|
17934
|
+
command: "guardian release secrets",
|
|
17935
|
+
credentialRequired: false
|
|
17936
|
+
},
|
|
17937
|
+
{
|
|
17938
|
+
id: "dry-run-dispatch",
|
|
17939
|
+
label: "Run the GitHub Actions dry run",
|
|
17940
|
+
command: dryRunDispatch,
|
|
17941
|
+
credentialRequired: false
|
|
17942
|
+
},
|
|
17943
|
+
{
|
|
17944
|
+
id: "publish-dispatch",
|
|
17945
|
+
label: "Run the guarded publish dispatch after dry-run evidence passes",
|
|
17946
|
+
command: publishDispatch,
|
|
17947
|
+
credentialRequired: true
|
|
17948
|
+
},
|
|
17949
|
+
{
|
|
17950
|
+
id: "verify-public-release",
|
|
17951
|
+
label: "Verify the published package and local install smoke",
|
|
17952
|
+
command: `guardian release verify --version=${releaseVersion}`,
|
|
17953
|
+
credentialRequired: false
|
|
17954
|
+
},
|
|
17955
|
+
{
|
|
17956
|
+
id: "copy-paste-local-smoke",
|
|
17957
|
+
label: "Copy-paste the local end-user smoke block",
|
|
17958
|
+
command: `guardian release paste --version=${releaseVersion}`,
|
|
17959
|
+
credentialRequired: false
|
|
17960
|
+
},
|
|
17961
|
+
{
|
|
17962
|
+
id: "browser-store-handoff",
|
|
17963
|
+
label: "Prepare browser-store submission handoff",
|
|
17964
|
+
command: "guardian release browser-store",
|
|
17965
|
+
credentialRequired: false
|
|
17966
|
+
}
|
|
17967
|
+
],
|
|
17968
|
+
copyPasteLocalSmoke: verify.commands.copyPasteLocalSmoke,
|
|
17969
|
+
evidenceOutputs: Array.from(
|
|
17970
|
+
/* @__PURE__ */ new Set([
|
|
17971
|
+
...checklist.evidenceOutputs,
|
|
17972
|
+
...verify.evidenceOutputs,
|
|
17973
|
+
"release/evidence/guardian-browser-store-submission-pack/browser-store-closeout-checklist.json"
|
|
17974
|
+
])
|
|
17975
|
+
),
|
|
17976
|
+
notProvenProductionGates: checklist.notProvenProductionGates.map((gate) => ({
|
|
17977
|
+
id: gate.id,
|
|
17978
|
+
label: gate.label,
|
|
17979
|
+
releaseBoundary: gate.releaseBoundary
|
|
17980
|
+
})),
|
|
17981
|
+
boundaries: [
|
|
17982
|
+
"This release flow is copy-paste operator guidance only; it is not release evidence or production-gate proof.",
|
|
17983
|
+
"Publish dispatch requires NPM_TOKEN in GitHub Actions repository secrets and must not print npm tokens, OTP values, or .npmrc contents.",
|
|
17984
|
+
"Run the dry-run dispatch before the guarded dry_run=false publish dispatch.",
|
|
17985
|
+
"Public npm preview publication and local install smoke prove the CLI preview lane only.",
|
|
17986
|
+
"Signed native installers, high-risk desktop action execution, and autonomous local app execution remain separate not-proven production gates until real external evidence is collected and validated."
|
|
17987
|
+
],
|
|
17411
17988
|
tokenPrinted: false,
|
|
17412
17989
|
rawContentIncluded: false
|
|
17413
17990
|
};
|
|
17414
17991
|
}
|
|
17992
|
+
function renderGuardianReleaseFlow(result, flags) {
|
|
17993
|
+
if (flags.has("json")) {
|
|
17994
|
+
return `${JSON.stringify(result, null, 2)}
|
|
17995
|
+
`;
|
|
17996
|
+
}
|
|
17997
|
+
const lines = [
|
|
17998
|
+
"Project Guardian Release Flow",
|
|
17999
|
+
`Release: ${result.releaseVersion}`,
|
|
18000
|
+
`Repository: ${result.repository}`,
|
|
18001
|
+
`Status: ${result.status}`,
|
|
18002
|
+
"Steps:",
|
|
18003
|
+
...result.steps.flatMap((step, index) => [
|
|
18004
|
+
`${index + 1}. ${step.label}${step.credentialRequired ? " (requires NPM_TOKEN secret)" : ""}:`,
|
|
18005
|
+
step.command
|
|
18006
|
+
]),
|
|
18007
|
+
"Post-publish copy-paste local smoke:",
|
|
18008
|
+
result.copyPasteLocalSmoke,
|
|
18009
|
+
"Evidence outputs:",
|
|
18010
|
+
...result.evidenceOutputs.map((output2) => `- ${output2}`),
|
|
18011
|
+
"Not-proven production gates:",
|
|
18012
|
+
...result.notProvenProductionGates.map(
|
|
18013
|
+
(gate) => `- ${gate.label}: ${gate.releaseBoundary ?? "not proven"}`
|
|
18014
|
+
),
|
|
18015
|
+
"Boundaries:",
|
|
18016
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
18017
|
+
"Token printed: no"
|
|
18018
|
+
];
|
|
18019
|
+
return `${lines.join("\n")}
|
|
18020
|
+
`;
|
|
18021
|
+
}
|
|
18022
|
+
function renderGuardianReleaseChecklist(result, flags) {
|
|
18023
|
+
if (flags.has("json")) {
|
|
18024
|
+
return `${JSON.stringify(result, null, 2)}
|
|
18025
|
+
`;
|
|
18026
|
+
}
|
|
18027
|
+
return `${[
|
|
18028
|
+
"Project Guardian Release Checklist",
|
|
18029
|
+
`Release: ${result.releaseVersion}`,
|
|
18030
|
+
`Repository: ${result.repository}`,
|
|
18031
|
+
`Status: ${result.status}`,
|
|
18032
|
+
`Required repository credential: ${result.requiredRepositoryCredentialName}`,
|
|
18033
|
+
"1. Secret setup:",
|
|
18034
|
+
result.operatorCommands.secretSetup,
|
|
18035
|
+
"2. Dry-run dispatch:",
|
|
18036
|
+
result.operatorCommands.dryRunDispatch,
|
|
18037
|
+
"3. Publish dispatch:",
|
|
18038
|
+
result.operatorCommands.publishDispatch,
|
|
18039
|
+
"4. Browser-store handoff:",
|
|
18040
|
+
result.operatorCommands.browserStoreHandoff,
|
|
18041
|
+
"5. Readiness check:",
|
|
18042
|
+
result.operatorCommands.readiness,
|
|
18043
|
+
"Evidence outputs:",
|
|
18044
|
+
...result.evidenceOutputs.map((output2) => `- ${output2}`),
|
|
18045
|
+
"Not-proven production gates:",
|
|
18046
|
+
...result.notProvenProductionGates.map(
|
|
18047
|
+
(gate) => `- ${gate.label}: ${gate.releaseBoundary ?? "not proven"}`
|
|
18048
|
+
),
|
|
18049
|
+
"Boundaries:",
|
|
18050
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
18051
|
+
"Token printed: no"
|
|
18052
|
+
].join("\n")}
|
|
18053
|
+
`;
|
|
18054
|
+
}
|
|
18055
|
+
function buildGuardianReleaseVerify(releaseVersion) {
|
|
18056
|
+
const copyPasteLocalSmoke = buildGuardianReleasePaste(releaseVersion).command;
|
|
18057
|
+
return {
|
|
18058
|
+
schema_version: "contextecf/project-guardian-release-verify/v1",
|
|
18059
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
18060
|
+
releaseVersion,
|
|
18061
|
+
repository: GUARDIAN_RELEASE_REPOSITORY,
|
|
18062
|
+
packageName: GUARDIAN_NPM_PACKAGE_NAME,
|
|
18063
|
+
registry: GUARDIAN_NPM_REGISTRY,
|
|
18064
|
+
status: "post_release_verification_required",
|
|
18065
|
+
commands: {
|
|
18066
|
+
registryVersion: `npm view ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion} version --registry=${GUARDIAN_NPM_REGISTRY}`,
|
|
18067
|
+
publicInstall: `npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion}`,
|
|
18068
|
+
installedVersion: "guardian --version",
|
|
18069
|
+
setup: "guardian setup",
|
|
18070
|
+
launch: "guardian launch",
|
|
18071
|
+
status: "guardian status",
|
|
18072
|
+
openControlTower: "guardian open",
|
|
18073
|
+
copyPasteLocalSmoke,
|
|
18074
|
+
publishStatusVerification: "npm run guardian:npm:publish:verify-status -- --status release/evidence/guardian-npm-publish-status.json --assert-ready --verify-artifacts --output release/evidence/guardian-npm-publish-status-verification.json",
|
|
18075
|
+
finishLineStatus: "npm run guardian:finish-line:status -- --npm-publish-status release/evidence/guardian-npm-publish-status.json --json --output release/evidence/guardian-finish-line-status.json"
|
|
18076
|
+
},
|
|
18077
|
+
evidenceOutputs: [
|
|
18078
|
+
"release/evidence/guardian-npm-publish-status.json",
|
|
18079
|
+
"release/evidence/guardian-npm-publish-status-verification.json",
|
|
18080
|
+
"release/evidence/guardian-finish-line-status.json"
|
|
18081
|
+
],
|
|
18082
|
+
boundaries: [
|
|
18083
|
+
"This command surface verifies public preview release visibility and installability; it does not publish to npm.",
|
|
18084
|
+
"Do not print npm tokens, OTP values, .npmrc contents, signing keys, browser-store credentials, raw prompts, raw responses, private policy packs, or customer content in release verification evidence.",
|
|
18085
|
+
"A passing public npm install smoke proves the CLI preview lane only; signed installers, high-risk desktop action execution, and autonomous app execution remain separate production gates.",
|
|
18086
|
+
"Full production claims remain blocked until every not-proven production gate has real validated external evidence."
|
|
18087
|
+
],
|
|
18088
|
+
tokenPrinted: false,
|
|
18089
|
+
rawContentIncluded: false
|
|
18090
|
+
};
|
|
18091
|
+
}
|
|
18092
|
+
function buildGuardianReleasePaste(releaseVersion) {
|
|
18093
|
+
const commands = [
|
|
18094
|
+
`npm view ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion} version --registry=${GUARDIAN_NPM_REGISTRY}`,
|
|
18095
|
+
`npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}@${releaseVersion}`,
|
|
18096
|
+
"guardian --version",
|
|
18097
|
+
"guardian stop",
|
|
18098
|
+
"guardian setup",
|
|
18099
|
+
"guardian launch",
|
|
18100
|
+
"guardian open",
|
|
18101
|
+
"guardian status"
|
|
18102
|
+
];
|
|
18103
|
+
return {
|
|
18104
|
+
schema_version: "contextecf/project-guardian-release-paste/v1",
|
|
18105
|
+
cli_version: GUARDIAN_CLI_VERSION,
|
|
18106
|
+
releaseVersion,
|
|
18107
|
+
packageName: GUARDIAN_NPM_PACKAGE_NAME,
|
|
18108
|
+
registry: GUARDIAN_NPM_REGISTRY,
|
|
18109
|
+
command: commands.join("\n"),
|
|
18110
|
+
commands,
|
|
18111
|
+
boundaries: [
|
|
18112
|
+
"This paste block verifies public npm visibility, global install, first-run setup, daemon launch, Control Tower open, and status.",
|
|
18113
|
+
"It does not publish to npm and must not include npm tokens, OTP values, .npmrc contents, signing keys, browser-store credentials, raw prompts, raw responses, private policy packs, or customer content.",
|
|
18114
|
+
"guardian stop is included before setup so stale local daemons or local token mismatches are cleared before launch."
|
|
18115
|
+
],
|
|
18116
|
+
tokenPrinted: false,
|
|
18117
|
+
rawContentIncluded: false
|
|
18118
|
+
};
|
|
18119
|
+
}
|
|
18120
|
+
function renderGuardianReleasePaste(result, flags) {
|
|
18121
|
+
if (flags.has("json")) {
|
|
18122
|
+
return `${JSON.stringify(result, null, 2)}
|
|
18123
|
+
`;
|
|
18124
|
+
}
|
|
18125
|
+
return `${result.command}
|
|
18126
|
+
`;
|
|
18127
|
+
}
|
|
18128
|
+
function renderGuardianReleaseVerify(result, flags) {
|
|
18129
|
+
if (flags.has("json")) {
|
|
18130
|
+
return `${JSON.stringify(result, null, 2)}
|
|
18131
|
+
`;
|
|
18132
|
+
}
|
|
18133
|
+
return `${[
|
|
18134
|
+
"Project Guardian Release Verification",
|
|
18135
|
+
`Release: ${result.releaseVersion}`,
|
|
18136
|
+
`Package: ${result.packageName}`,
|
|
18137
|
+
`Registry: ${result.registry}`,
|
|
18138
|
+
`Status: ${result.status}`,
|
|
18139
|
+
"1. Confirm registry visibility:",
|
|
18140
|
+
result.commands.registryVersion,
|
|
18141
|
+
"2. Install the published version:",
|
|
18142
|
+
result.commands.publicInstall,
|
|
18143
|
+
"3. Confirm installed CLI version:",
|
|
18144
|
+
result.commands.installedVersion,
|
|
18145
|
+
"4. Run first-use smoke:",
|
|
18146
|
+
result.commands.setup,
|
|
18147
|
+
result.commands.launch,
|
|
18148
|
+
result.commands.status,
|
|
18149
|
+
result.commands.openControlTower,
|
|
18150
|
+
"5. Copy-paste local smoke block:",
|
|
18151
|
+
result.commands.copyPasteLocalSmoke,
|
|
18152
|
+
"6. Verify release evidence:",
|
|
18153
|
+
result.commands.publishStatusVerification,
|
|
18154
|
+
result.commands.finishLineStatus,
|
|
18155
|
+
"Evidence outputs:",
|
|
18156
|
+
...result.evidenceOutputs.map((output2) => `- ${output2}`),
|
|
18157
|
+
"Boundaries:",
|
|
18158
|
+
...result.boundaries.map((boundary) => `- ${boundary}`),
|
|
18159
|
+
"Token printed: no"
|
|
18160
|
+
].join("\n")}
|
|
18161
|
+
`;
|
|
18162
|
+
}
|
|
18163
|
+
function isValidReleaseVersion(value) {
|
|
18164
|
+
return /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(value);
|
|
18165
|
+
}
|
|
18166
|
+
function isValidReleaseChannels(value) {
|
|
18167
|
+
return ["all", "npm", "browser", "evidence"].includes(value);
|
|
18168
|
+
}
|
|
17415
18169
|
function renderGuardianProductionReadiness(result, flags) {
|
|
17416
18170
|
if (flags.has("json")) {
|
|
17417
18171
|
return `${JSON.stringify(result, null, 2)}
|
|
@@ -17424,6 +18178,18 @@ function renderGuardianProductionReadiness(result, flags) {
|
|
|
17424
18178
|
`Doctor: ${result.doctorOverall.toUpperCase()}`,
|
|
17425
18179
|
`NPM preview install: ${result.npmPreview.status.toUpperCase()} - ${result.npmPreview.reason}`,
|
|
17426
18180
|
result.npmPreview.publishCommand ? `NPM publish command: ${result.npmPreview.publishCommand}` : "NPM publish command: not available until publish dry-run evidence passes",
|
|
18181
|
+
`Distribution: ${result.distribution.status}`,
|
|
18182
|
+
`Install: ${result.distribution.oneLineInstallCommand}`,
|
|
18183
|
+
`Try without global install: ${result.distribution.oneLineTryCommand}`,
|
|
18184
|
+
`Open Control Tower: ${result.distribution.openControlTowerCommand}`,
|
|
18185
|
+
`AI tool setup: ${result.distribution.aiToolIntegration.mcpInstallCommand}; ${result.distribution.aiToolIntegration.browserSetupCommand}`,
|
|
18186
|
+
`Browser-store handoff: ${result.distribution.browserStoreHandoff.status}; gate ${result.distribution.browserStoreHandoff.productionGateStatus}`,
|
|
18187
|
+
`Browser-store checklist: ${result.distribution.browserStoreHandoff.closeoutChecklistPath}`,
|
|
18188
|
+
`Release workflow: ${result.distribution.releaseAutomation.workflow}; status=${result.distribution.releaseAutomation.status}`,
|
|
18189
|
+
`Release dry run:
|
|
18190
|
+
${result.distribution.releaseAutomation.dryRunCommand}`,
|
|
18191
|
+
`Release publish:
|
|
18192
|
+
${result.distribution.releaseAutomation.publishCommand}`,
|
|
17427
18193
|
`Full production release: ${result.fullProduction.status.toUpperCase()} - ${result.fullProduction.reason}`,
|
|
17428
18194
|
`Production gate evidence: ${result.fullProduction.productionGateEvidenceStatus}`,
|
|
17429
18195
|
`Blocked production gates: ${result.fullProduction.blockedGateCount}`,
|
|
@@ -17452,6 +18218,10 @@ async function statusGuardian(flags, options) {
|
|
|
17452
18218
|
installed: profile !== void 0,
|
|
17453
18219
|
daemonStatus: daemonHealth.daemon.status
|
|
17454
18220
|
});
|
|
18221
|
+
const daemonVersionMismatch = daemonHealth.daemon.status === "reachable" && daemonHealth.daemon.version !== void 0 && daemonHealth.daemon.version !== GUARDIAN_CLI_VERSION ? { cliVersion: GUARDIAN_CLI_VERSION, daemonVersion: daemonHealth.daemon.version } : null;
|
|
18222
|
+
if (daemonVersionMismatch) {
|
|
18223
|
+
nextCommands.push("guardian stop", "guardian launch");
|
|
18224
|
+
}
|
|
17455
18225
|
const result = {
|
|
17456
18226
|
schema_version: "contextecf/project-guardian-status/v1",
|
|
17457
18227
|
cli_version: GUARDIAN_CLI_VERSION,
|
|
@@ -17485,6 +18255,7 @@ async function statusGuardian(flags, options) {
|
|
|
17485
18255
|
serviceSupervision,
|
|
17486
18256
|
osKeyStorage,
|
|
17487
18257
|
notProvenProductionGates: GUARDIAN_NOT_PROVEN_PRODUCTION_GATES,
|
|
18258
|
+
daemonVersionMismatch,
|
|
17488
18259
|
nextCommands
|
|
17489
18260
|
};
|
|
17490
18261
|
if (flags.has("json")) {
|
|
@@ -17499,6 +18270,7 @@ async function statusGuardian(flags, options) {
|
|
|
17499
18270
|
`Control Tower: ${result.controlTowerUrl ?? "not configured"}`,
|
|
17500
18271
|
`Daemon health: ${result.daemon.status}${result.daemon.statusCode ? ` (HTTP ${result.daemon.statusCode})` : ""}`,
|
|
17501
18272
|
result.daemon.error ? `Daemon detail: ${result.daemon.error}` : void 0,
|
|
18273
|
+
result.daemonVersionMismatch ? `Daemon version: ${result.daemonVersionMismatch.daemonVersion} (this CLI is ${result.daemonVersionMismatch.cliVersion} \u2014 versions differ, likely because the CLI was reinstalled or changed version while this daemon kept running; run guardian stop && guardian launch to restart it on the current version)` : void 0,
|
|
17502
18274
|
`MCP stdio: ${result.runtime.mcpStdioAvailable ? "available" : "unavailable"}`,
|
|
17503
18275
|
`Posture Profile: ${result.postureProfile.selected}`,
|
|
17504
18276
|
`Prompt Coach: ${result.preferences.promptCoachMode}`,
|
|
@@ -17588,7 +18360,7 @@ async function runLaunchCommand(flags, options) {
|
|
|
17588
18360
|
return startExitCode;
|
|
17589
18361
|
}
|
|
17590
18362
|
const start = JSON.parse(startOutput);
|
|
17591
|
-
const shouldOpen = !flags.has("print");
|
|
18363
|
+
const shouldOpen = flags.has("open") && !flags.has("print");
|
|
17592
18364
|
if (shouldOpen) {
|
|
17593
18365
|
const opener = options.openUrl ?? ((url2) => openUrlInDefaultBrowser(url2, options));
|
|
17594
18366
|
await opener(start.controlTowerUrl);
|
|
@@ -17602,7 +18374,12 @@ async function runLaunchCommand(flags, options) {
|
|
|
17602
18374
|
controlTowerUrl: start.controlTowerUrl,
|
|
17603
18375
|
pid: start.pid,
|
|
17604
18376
|
healthStatus: start.healthStatus,
|
|
17605
|
-
nextCommands: [
|
|
18377
|
+
nextCommands: [
|
|
18378
|
+
"guardian open",
|
|
18379
|
+
"guardian status",
|
|
18380
|
+
"guardian daemon pair --json",
|
|
18381
|
+
"guardian policy list"
|
|
18382
|
+
]
|
|
17606
18383
|
};
|
|
17607
18384
|
write(
|
|
17608
18385
|
stdout,
|
|
@@ -17612,7 +18389,7 @@ async function runLaunchCommand(flags, options) {
|
|
|
17612
18389
|
`Daemon: ${result.daemonUrl}${result.reusedExistingDaemon ? " (already running)" : ""}`,
|
|
17613
18390
|
`Control Tower: ${result.controlTowerUrl}`,
|
|
17614
18391
|
shouldOpen ? `Opening: ${result.controlTowerUrl}` : void 0,
|
|
17615
|
-
"Next: guardian status"
|
|
18392
|
+
"Next: guardian open; guardian status"
|
|
17616
18393
|
].filter(Boolean).join("\n")}
|
|
17617
18394
|
`
|
|
17618
18395
|
);
|
|
@@ -18036,6 +18813,7 @@ function requestGuardianDaemonHealth(request) {
|
|
|
18036
18813
|
const parsedBody = parseJsonObject(body);
|
|
18037
18814
|
const service = typeof parsedBody?.service === "string" ? parsedBody.service : void 0;
|
|
18038
18815
|
const rawContentPersistence = typeof parsedBody?.rawContentPersistence === "boolean" ? parsedBody.rawContentPersistence : void 0;
|
|
18816
|
+
const version2 = typeof parsedBody?.version === "string" ? parsedBody.version : void 0;
|
|
18039
18817
|
const error51 = typeof parsedBody?.error === "string" ? parsedBody.error : void 0;
|
|
18040
18818
|
const ok = typeof statusCode === "number" && statusCode >= 200 && statusCode < 300;
|
|
18041
18819
|
resolve({
|
|
@@ -18044,6 +18822,7 @@ function requestGuardianDaemonHealth(request) {
|
|
|
18044
18822
|
statusCode,
|
|
18045
18823
|
service,
|
|
18046
18824
|
rawContentPersistence,
|
|
18825
|
+
version: version2,
|
|
18047
18826
|
error: ok ? void 0 : error51 ?? "daemon_health_failed"
|
|
18048
18827
|
});
|
|
18049
18828
|
});
|
|
@@ -19832,7 +20611,7 @@ function drainMessages() {
|
|
|
19832
20611
|
|
|
19833
20612
|
async function handleNativeMessage(raw) {
|
|
19834
20613
|
const message = JSON.parse(raw);
|
|
19835
|
-
if (!message || message.
|
|
20614
|
+
if (!message || message.adapter !== 'browser_mv3') {
|
|
19836
20615
|
sendNativeMessage({ ok: false, error: 'Unsupported Guardian native message.' });
|
|
19837
20616
|
return;
|
|
19838
20617
|
}
|
|
@@ -19843,12 +20622,44 @@ async function handleNativeMessage(raw) {
|
|
|
19843
20622
|
return;
|
|
19844
20623
|
}
|
|
19845
20624
|
const token = readRuntimeToken();
|
|
19846
|
-
|
|
19847
|
-
|
|
19848
|
-
|
|
19849
|
-
|
|
19850
|
-
|
|
19851
|
-
|
|
20625
|
+
|
|
20626
|
+
if (message.type === 'GUARDIAN_BRIDGE_DISCOVER') {
|
|
20627
|
+
sendNativeMessage({
|
|
20628
|
+
ok: true,
|
|
20629
|
+
bridgeConfig: {
|
|
20630
|
+
schema_version: 'contextecf/project-guardian-browser-bridge/v1',
|
|
20631
|
+
loopbackBaseUrl,
|
|
20632
|
+
token,
|
|
20633
|
+
pairedAt: new Date().toISOString(),
|
|
20634
|
+
source: 'native-host-discovery',
|
|
20635
|
+
transport: 'native_then_loopback',
|
|
20636
|
+
nativeHostName: 'com.contextecf.guardian',
|
|
20637
|
+
},
|
|
20638
|
+
});
|
|
20639
|
+
return;
|
|
20640
|
+
}
|
|
20641
|
+
|
|
20642
|
+
if (message.type === 'GUARDIAN_PROMPT_CHECK') {
|
|
20643
|
+
const response = await postJson(
|
|
20644
|
+
loopbackBaseUrl + '/v1/guardian/process-prompt',
|
|
20645
|
+
JSON.stringify({ adapter: 'browser_mv3', request: message.request }),
|
|
20646
|
+
token
|
|
20647
|
+
);
|
|
20648
|
+
sendNativeMessage(response);
|
|
20649
|
+
return;
|
|
20650
|
+
}
|
|
20651
|
+
|
|
20652
|
+
if (message.type === 'GUARDIAN_LIVE_COACH_EVENT') {
|
|
20653
|
+
const response = await postJson(
|
|
20654
|
+
loopbackBaseUrl + '/v1/guardian/live-coach-event',
|
|
20655
|
+
JSON.stringify({ adapter: 'browser_mv3', request: message.request }),
|
|
20656
|
+
token
|
|
20657
|
+
);
|
|
20658
|
+
sendNativeMessage(response);
|
|
20659
|
+
return;
|
|
20660
|
+
}
|
|
20661
|
+
|
|
20662
|
+
sendNativeMessage({ ok: false, error: 'Unsupported Guardian native message.' });
|
|
19852
20663
|
}
|
|
19853
20664
|
|
|
19854
20665
|
function readRuntimeToken() {
|
|
@@ -21742,6 +22553,7 @@ async function buildDaemonHealthStatus(home, flags, options, profile) {
|
|
|
21742
22553
|
statusCode: checked.statusCode,
|
|
21743
22554
|
service: checked.service,
|
|
21744
22555
|
rawContentPersistence: checked.rawContentPersistence,
|
|
22556
|
+
version: checked.version,
|
|
21745
22557
|
error: checked.error
|
|
21746
22558
|
}
|
|
21747
22559
|
};
|
|
@@ -22054,6 +22866,18 @@ async function buildGuardianDoctorStatus(home, profile, env = process.env) {
|
|
|
22054
22866
|
rawContentIncluded: false
|
|
22055
22867
|
};
|
|
22056
22868
|
}
|
|
22869
|
+
function isGuardianSupportedNodeVersion(nodeVersion) {
|
|
22870
|
+
const parts = nodeVersion.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10));
|
|
22871
|
+
const [major = 0, minor = 0, patch = 0] = parts;
|
|
22872
|
+
const [minMajor, minMinor, minPatch] = GUARDIAN_MIN_SUPPORTED_NODE_VERSION;
|
|
22873
|
+
if (major !== minMajor) {
|
|
22874
|
+
return major > minMajor;
|
|
22875
|
+
}
|
|
22876
|
+
if (minor !== minMinor) {
|
|
22877
|
+
return minor > minMinor;
|
|
22878
|
+
}
|
|
22879
|
+
return patch >= minPatch;
|
|
22880
|
+
}
|
|
22057
22881
|
async function buildDoctorChecks(home, profile, env = process.env) {
|
|
22058
22882
|
const encryption = buildGuardianLocalDataEncryptionStatus(
|
|
22059
22883
|
env,
|
|
@@ -22063,6 +22887,12 @@ async function buildDoctorChecks(home, profile, env = process.env) {
|
|
|
22063
22887
|
const serviceSupervision = await buildGuardianServiceSupervisionStatus(home);
|
|
22064
22888
|
const osKeyStorage = await buildGuardianOsKeyStorageStatus(home);
|
|
22065
22889
|
return [
|
|
22890
|
+
{
|
|
22891
|
+
id: "node-runtime",
|
|
22892
|
+
label: "Node.js runtime",
|
|
22893
|
+
status: isGuardianSupportedNodeVersion(process.version) ? "pass" : "warn",
|
|
22894
|
+
detail: isGuardianSupportedNodeVersion(process.version) ? `Node ${process.version} meets the >=20.20.0 floor` : `Node ${process.version} is below the supported >=20.20.0 floor; upgrade to Node 20.20+ or 22 LTS`
|
|
22895
|
+
},
|
|
22066
22896
|
{
|
|
22067
22897
|
id: "profile",
|
|
22068
22898
|
label: "Guardian profile",
|
|
@@ -22164,6 +22994,26 @@ function stringFlag(flags, key) {
|
|
|
22164
22994
|
const value = flags.get(key);
|
|
22165
22995
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
22166
22996
|
}
|
|
22997
|
+
function booleanFlag(flags, key, defaultValue) {
|
|
22998
|
+
const value = flags.get(key);
|
|
22999
|
+
if (value === void 0) {
|
|
23000
|
+
return defaultValue;
|
|
23001
|
+
}
|
|
23002
|
+
if (value === true) {
|
|
23003
|
+
return true;
|
|
23004
|
+
}
|
|
23005
|
+
if (typeof value !== "string") {
|
|
23006
|
+
return defaultValue;
|
|
23007
|
+
}
|
|
23008
|
+
const normalized = value.trim().toLowerCase();
|
|
23009
|
+
if (["1", "true", "yes", "on"].includes(normalized)) {
|
|
23010
|
+
return true;
|
|
23011
|
+
}
|
|
23012
|
+
if (["0", "false", "no", "off"].includes(normalized)) {
|
|
23013
|
+
return false;
|
|
23014
|
+
}
|
|
23015
|
+
return defaultValue;
|
|
23016
|
+
}
|
|
22167
23017
|
function copyStringFlags(flags, keys) {
|
|
22168
23018
|
return keys.flatMap((key) => {
|
|
22169
23019
|
const value = stringFlag(flags, key);
|
|
@@ -22311,19 +23161,22 @@ function openUrlInDefaultBrowser(url2, options = {}) {
|
|
|
22311
23161
|
});
|
|
22312
23162
|
});
|
|
22313
23163
|
}
|
|
22314
|
-
var GUARDIAN_CLI_VERSION, GUARDIAN_PROFILE_SCHEMA_VERSION, GUARDIAN_NPM_PACKAGE_NAME, GUARDIAN_GLOBAL_INSTALL_COMMAND, GUARDIAN_NPX_SETUP_COMMAND, GUARDIAN_FIRST_RUN_COMMAND, GUARDIAN_OPEN_CONTROL_TOWER_COMMAND, GUARDIAN_DEFAULT_CONTROL_TOWER_URL, GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ENV, GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ID_ENV, GUARDIAN_SQLITE_PAGE_ENCRYPTION_KEY_ENV, GUARDIAN_SQLITE_PAGE_ENCRYPTION_KEY_ID_ENV, GUARDIAN_DESKTOP_ADAPTER_SIMULATE_OPEN_ENV, GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_ID, GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_VERSION, GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_PROOF_SCHEMA_VERSION, GUARDIAN_SERVICE_PROOF_SCHEMA_VERSION, GUARDIAN_OS_KEY_STORAGE_PROOF_SCHEMA_VERSION, GUARDIAN_WINDOWS_NATIVE_HOST_REGISTRY_PROOF_SCHEMA_VERSION, PERSONAL_FABRIC_CONTRACTS_SCHEMA_VERSION2, PROMPT_COACH_MODES, DEFAULT_PROMPT_COACH_DAILY_SOFT_CARD_LIMIT, GUARDIAN_POSTURE_PROFILE_IDS, GUARDIAN_POSTURE_PROFILE_CATALOG, GUARDIAN_POLICY_PACK_MARKETPLACE_CATALOG, GUARDIAN_PROVIDER_IDS, GUARDIAN_SOURCE_TYPES, GUARDIAN_NOT_PROVEN_PRODUCTION_GATES, DEFAULT_POLICY_PACKS, GUARDIAN_BRIDGE_CONFIG_STORAGE_KEY, GUARDIAN_BRIDGE_TOKEN_STORAGE_KEY, GUARDIAN_BRIDGE_CONFIG_SCHEMA_VERSION, GUARDIAN_NATIVE_HOST_NAME, MCP_CLIENTS, NATIVE_HOST_BROWSERS, HELP_TEXT, normalizeGuardianPreferences, GUARDIAN_DATA_FILE_NAMES, GUARDIAN_DATA_DIR_NAMES;
|
|
23164
|
+
var GUARDIAN_CLI_VERSION, GUARDIAN_PROFILE_SCHEMA_VERSION, GUARDIAN_NPM_PACKAGE_NAME, GUARDIAN_NPM_REGISTRY, GUARDIAN_GLOBAL_INSTALL_COMMAND, GUARDIAN_NPX_SETUP_COMMAND, GUARDIAN_FIRST_RUN_COMMAND, GUARDIAN_OPEN_CONTROL_TOWER_COMMAND, GUARDIAN_RELEASE_DISPATCH_WORKFLOW, GUARDIAN_RELEASE_REPOSITORY, GUARDIAN_DEFAULT_CONTROL_TOWER_URL, GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ENV, GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ID_ENV, GUARDIAN_SQLITE_PAGE_ENCRYPTION_KEY_ENV, GUARDIAN_SQLITE_PAGE_ENCRYPTION_KEY_ID_ENV, GUARDIAN_DESKTOP_ADAPTER_SIMULATE_OPEN_ENV, GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_ID, GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_VERSION, GUARDIAN_DESKTOP_URL_OPEN_ADAPTER_PROOF_SCHEMA_VERSION, GUARDIAN_SERVICE_PROOF_SCHEMA_VERSION, GUARDIAN_OS_KEY_STORAGE_PROOF_SCHEMA_VERSION, GUARDIAN_WINDOWS_NATIVE_HOST_REGISTRY_PROOF_SCHEMA_VERSION, PERSONAL_FABRIC_CONTRACTS_SCHEMA_VERSION2, PROMPT_COACH_MODES, DEFAULT_PROMPT_COACH_DAILY_SOFT_CARD_LIMIT, GUARDIAN_POSTURE_PROFILE_IDS, GUARDIAN_POSTURE_PROFILE_CATALOG, GUARDIAN_POLICY_PACK_MARKETPLACE_CATALOG, GUARDIAN_PROVIDER_IDS, GUARDIAN_SOURCE_TYPES, GUARDIAN_NOT_PROVEN_PRODUCTION_GATES, DEFAULT_POLICY_PACKS, GUARDIAN_BRIDGE_CONFIG_STORAGE_KEY, GUARDIAN_BRIDGE_TOKEN_STORAGE_KEY, GUARDIAN_BRIDGE_CONFIG_SCHEMA_VERSION, GUARDIAN_NATIVE_HOST_NAME, MCP_CLIENTS, NATIVE_HOST_BROWSERS, HELP_TEXT, normalizeGuardianPreferences, GUARDIAN_DATA_FILE_NAMES, GUARDIAN_DATA_DIR_NAMES, GUARDIAN_MIN_SUPPORTED_NODE_VERSION;
|
|
22315
23165
|
var init_runtime = __esm({
|
|
22316
23166
|
"packages/guardian-cli/src/runtime.ts"() {
|
|
22317
23167
|
"use strict";
|
|
22318
23168
|
init_src();
|
|
22319
23169
|
init_src2();
|
|
22320
|
-
GUARDIAN_CLI_VERSION = "0.1.
|
|
23170
|
+
GUARDIAN_CLI_VERSION = "0.1.5";
|
|
22321
23171
|
GUARDIAN_PROFILE_SCHEMA_VERSION = "contextecf/project-guardian-profile/v1";
|
|
22322
23172
|
GUARDIAN_NPM_PACKAGE_NAME = "@contextecf/guardian-cli";
|
|
23173
|
+
GUARDIAN_NPM_REGISTRY = "https://registry.npmjs.org/";
|
|
22323
23174
|
GUARDIAN_GLOBAL_INSTALL_COMMAND = `npm install -g ${GUARDIAN_NPM_PACKAGE_NAME}`;
|
|
22324
23175
|
GUARDIAN_NPX_SETUP_COMMAND = `npx ${GUARDIAN_NPM_PACKAGE_NAME}@latest setup`;
|
|
22325
23176
|
GUARDIAN_FIRST_RUN_COMMAND = "guardian setup";
|
|
22326
|
-
GUARDIAN_OPEN_CONTROL_TOWER_COMMAND = "guardian
|
|
23177
|
+
GUARDIAN_OPEN_CONTROL_TOWER_COMMAND = "guardian open";
|
|
23178
|
+
GUARDIAN_RELEASE_DISPATCH_WORKFLOW = "guardian-release-dispatch.yml";
|
|
23179
|
+
GUARDIAN_RELEASE_REPOSITORY = "Intelligent-Context-AI-Inc/ContextECF-GITHUB";
|
|
22327
23180
|
GUARDIAN_DEFAULT_CONTROL_TOWER_URL = "http://127.0.0.1:4317/control-tower";
|
|
22328
23181
|
GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ENV = "GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY";
|
|
22329
23182
|
GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ID_ENV = "GUARDIAN_LOCAL_DATA_ENCRYPTION_KEY_ID";
|
|
@@ -22749,28 +23602,6 @@ var init_runtime = __esm({
|
|
|
22749
23602
|
"Release evidence includes artifact digests without signing secrets."
|
|
22750
23603
|
]
|
|
22751
23604
|
},
|
|
22752
|
-
{
|
|
22753
|
-
id: "browser-store-distribution",
|
|
22754
|
-
label: "Browser store distribution",
|
|
22755
|
-
boundary: "Pending store submission, review, and release evidence.",
|
|
22756
|
-
owner: "browser-release",
|
|
22757
|
-
runtimeBoundary: "Pending store submission, review, and release evidence.",
|
|
22758
|
-
releaseBoundary: "Browser store approval and listing evidence are not yet proven.",
|
|
22759
|
-
evidencePacket: "browser-store-distribution",
|
|
22760
|
-
evidenceRequiredFields: [
|
|
22761
|
-
"stores",
|
|
22762
|
-
"submitted_versions",
|
|
22763
|
-
"review_status",
|
|
22764
|
-
"package_digest_matches_release",
|
|
22765
|
-
"listing_boundary_proof"
|
|
22766
|
-
],
|
|
22767
|
-
closesWhen: [
|
|
22768
|
-
"Chrome Web Store package id, version, and approval state are recorded.",
|
|
22769
|
-
"Any claimed Edge or Firefox store distribution has matching approval evidence.",
|
|
22770
|
-
"Store package digest matches the validated MV3 release artifact.",
|
|
22771
|
-
"Store listing text uses the same proven/not-proven boundary."
|
|
22772
|
-
]
|
|
22773
|
-
},
|
|
22774
23605
|
{
|
|
22775
23606
|
id: "high-risk-desktop-action-execution",
|
|
22776
23607
|
label: "High-risk desktop action execution after authorization",
|
|
@@ -22851,19 +23682,26 @@ No global install:
|
|
|
22851
23682
|
|
|
22852
23683
|
Open Control Tower:
|
|
22853
23684
|
${GUARDIAN_OPEN_CONTROL_TOWER_COMMAND}
|
|
22854
|
-
aliases: guardian tower, guardian control-tower
|
|
23685
|
+
start aliases: guardian launch, guardian tower, guardian control-tower
|
|
22855
23686
|
|
|
22856
23687
|
Usage:
|
|
22857
23688
|
guardian --version
|
|
22858
23689
|
guardian version [--json]
|
|
22859
|
-
guardian setup [--json] [--print] [--host=127.0.0.1] [--port=4317] [--no-launch] [--no-mcp] [--extension-id=<chrome-extension-id>]
|
|
23690
|
+
guardian setup [--json] [--open] [--print] [--host=127.0.0.1] [--port=4317] [--no-launch] [--no-mcp] [--extension-id=<chrome-extension-id>]
|
|
22860
23691
|
guardian install [--json]
|
|
22861
23692
|
guardian doctor [--json]
|
|
22862
23693
|
guardian readiness [--json] [--strict]
|
|
23694
|
+
guardian release checklist --version=<semver> [--json]
|
|
23695
|
+
guardian release flow --version=<semver> [--json]
|
|
23696
|
+
guardian release verify --version=<semver> [--json]
|
|
23697
|
+
guardian release paste --version=<semver> [--json]
|
|
23698
|
+
guardian release command --version=<semver> [--publish|--dry-run=false] [--channels=all|npm|browser|evidence] [--run-docker-smoke=true|false] [--json]
|
|
23699
|
+
guardian release secrets [--json]
|
|
23700
|
+
guardian release browser-store [--json]
|
|
22863
23701
|
guardian open [--json] [--print] [--url=http://127.0.0.1:<port>]
|
|
22864
23702
|
guardian status [--json]
|
|
22865
23703
|
guardian start [--json] [--host=127.0.0.1] [--port=4317]
|
|
22866
|
-
guardian launch|tower|control-tower [--json] [--print] [--host=127.0.0.1] [--port=4317]
|
|
23704
|
+
guardian launch|tower|control-tower [--json] [--open] [--print] [--host=127.0.0.1] [--port=4317]
|
|
22867
23705
|
guardian stop [--json] [--url=http://127.0.0.1:<port>/control-tower]
|
|
22868
23706
|
guardian service install [--json] [--platform=auto|launchd|systemd|windows-task-scheduler] [--force]
|
|
22869
23707
|
guardian service status [--json]
|
|
@@ -22919,6 +23757,7 @@ Defaults are local-first: raw capture, cloud sync, learning graph, and app autop
|
|
|
22919
23757
|
"permissions.json"
|
|
22920
23758
|
];
|
|
22921
23759
|
GUARDIAN_DATA_DIR_NAMES = ["ecl", "receipts", "mcp"];
|
|
23760
|
+
GUARDIAN_MIN_SUPPORTED_NODE_VERSION = [20, 20, 0];
|
|
22922
23761
|
}
|
|
22923
23762
|
});
|
|
22924
23763
|
|
|
@@ -23837,10 +24676,16 @@ function confirmationTokenFor(receipt, actionRequest) {
|
|
|
23837
24676
|
return `guardian-confirm:${stableId(
|
|
23838
24677
|
receipt.receipt_hash,
|
|
23839
24678
|
actionRequest.action_id,
|
|
24679
|
+
actionRequest.app_id,
|
|
23840
24680
|
actionRequest.action_type,
|
|
23841
|
-
actionRequest.
|
|
24681
|
+
actionRequest.target_ref,
|
|
24682
|
+
actionRequest.payload_hash,
|
|
24683
|
+
normalizedPolicyPackBinding(actionRequest.policy_pack_ids)
|
|
23842
24684
|
)}`;
|
|
23843
24685
|
}
|
|
24686
|
+
function normalizedPolicyPackBinding(policyPackIds) {
|
|
24687
|
+
return [...new Set(policyPackIds)].sort().join(",");
|
|
24688
|
+
}
|
|
23844
24689
|
function buildLocalActionExecutionPlan(actionRequest, receipt, now) {
|
|
23845
24690
|
const core = {
|
|
23846
24691
|
action_id: actionRequest.action_id,
|
|
@@ -24937,6 +25782,7 @@ __export(daemon_exports, {
|
|
|
24937
25782
|
processGuardianControlTowerSourcePermissionRequest: () => processGuardianControlTowerSourcePermissionRequest,
|
|
24938
25783
|
processGuardianDaemonHealthRequest: () => processGuardianDaemonHealthRequest,
|
|
24939
25784
|
processGuardianDaemonStopRequest: () => processGuardianDaemonStopRequest,
|
|
25785
|
+
processGuardianLiveCoachEventRequest: () => processGuardianLiveCoachEventRequest,
|
|
24940
25786
|
readGuardianDaemonJsonBody: () => readGuardianDaemonJsonBody,
|
|
24941
25787
|
renderControlTowerStatusPage: () => renderControlTowerStatusPage,
|
|
24942
25788
|
startGuardianDaemonLoopback: () => startGuardianDaemonLoopback
|
|
@@ -25063,7 +25909,8 @@ async function handleRequest(input2) {
|
|
|
25063
25909
|
writeJson(input2.response, 200, {
|
|
25064
25910
|
ok: true,
|
|
25065
25911
|
service: "project-guardian-daemon",
|
|
25066
|
-
rawContentPersistence: false
|
|
25912
|
+
rawContentPersistence: false,
|
|
25913
|
+
version: GUARDIAN_CLI_VERSION
|
|
25067
25914
|
});
|
|
25068
25915
|
return;
|
|
25069
25916
|
}
|
|
@@ -25217,6 +26064,24 @@ async function handleRequest(input2) {
|
|
|
25217
26064
|
writeAdminResponse(input2.response, result2.statusCode, result2.body, parsedBody2.redirect);
|
|
25218
26065
|
return;
|
|
25219
26066
|
}
|
|
26067
|
+
if (input2.request.method === "POST" && input2.request.url === "/v1/guardian/live-coach-event") {
|
|
26068
|
+
const suppliedToken2 = headerValue(input2.request, ADMIN_HEADER);
|
|
26069
|
+
const parsedBody2 = await readGuardianDaemonJsonBody(input2.request);
|
|
26070
|
+
if (!parsedBody2.ok) {
|
|
26071
|
+
writeJson(input2.response, parsedBody2.statusCode, parsedBody2.body);
|
|
26072
|
+
return;
|
|
26073
|
+
}
|
|
26074
|
+
const result2 = await processGuardianLiveCoachEventRequest({
|
|
26075
|
+
profile: input2.profile,
|
|
26076
|
+
token: input2.token,
|
|
26077
|
+
suppliedToken: suppliedToken2,
|
|
26078
|
+
body: parsedBody2.body,
|
|
26079
|
+
now: input2.now,
|
|
26080
|
+
store: input2.store
|
|
26081
|
+
});
|
|
26082
|
+
writeJson(input2.response, result2.statusCode, result2.body);
|
|
26083
|
+
return;
|
|
26084
|
+
}
|
|
25220
26085
|
if (input2.request.method !== "POST" || input2.request.url !== "/v1/guardian/process-prompt") {
|
|
25221
26086
|
writeJson(input2.response, 404, { ok: false, error: "not_found" });
|
|
25222
26087
|
return;
|
|
@@ -25252,7 +26117,8 @@ function processGuardianDaemonHealthRequest(input2) {
|
|
|
25252
26117
|
body: {
|
|
25253
26118
|
ok: true,
|
|
25254
26119
|
service: "project-guardian-daemon",
|
|
25255
|
-
rawContentPersistence: false
|
|
26120
|
+
rawContentPersistence: false,
|
|
26121
|
+
version: GUARDIAN_CLI_VERSION
|
|
25256
26122
|
}
|
|
25257
26123
|
};
|
|
25258
26124
|
}
|
|
@@ -25668,6 +26534,44 @@ async function processGuardianBrowserBridgeRequest(input2) {
|
|
|
25668
26534
|
});
|
|
25669
26535
|
return { statusCode: 200, body: { ok: true, decision } };
|
|
25670
26536
|
}
|
|
26537
|
+
async function processGuardianLiveCoachEventRequest(input2) {
|
|
26538
|
+
if (!isAuthorized(input2.token, input2.suppliedToken)) {
|
|
26539
|
+
return {
|
|
26540
|
+
statusCode: 401,
|
|
26541
|
+
body: {
|
|
26542
|
+
ok: false,
|
|
26543
|
+
error: "unauthorized"
|
|
26544
|
+
}
|
|
26545
|
+
};
|
|
26546
|
+
}
|
|
26547
|
+
const envelope = parseLiveCoachEventEnvelope(input2.body);
|
|
26548
|
+
if (!envelope.ok) {
|
|
26549
|
+
return {
|
|
26550
|
+
statusCode: 400,
|
|
26551
|
+
body: {
|
|
26552
|
+
ok: false,
|
|
26553
|
+
error: envelope.error
|
|
26554
|
+
}
|
|
26555
|
+
};
|
|
26556
|
+
}
|
|
26557
|
+
const timestamp = validDateTime(envelope.request.capturedAt) ?? input2.now().toISOString();
|
|
26558
|
+
const transactionId = `txn:browser-live-coach:${digest4(
|
|
26559
|
+
`${envelope.request.provider}:${envelope.request.destination}:${envelope.request.category}:${timestamp}`
|
|
26560
|
+
).slice(0, 20)}`;
|
|
26561
|
+
const receipt = buildLiveCoachReceipt(envelope.request, transactionId, timestamp);
|
|
26562
|
+
await input2.store.putReceipt(receipt);
|
|
26563
|
+
await input2.store.appendEvent(
|
|
26564
|
+
buildLiveCoachEvent(envelope.request, transactionId, timestamp, receipt)
|
|
26565
|
+
);
|
|
26566
|
+
return {
|
|
26567
|
+
statusCode: 200,
|
|
26568
|
+
body: {
|
|
26569
|
+
ok: true,
|
|
26570
|
+
receipt_id: receipt.receipt_id,
|
|
26571
|
+
raw_content_included: false
|
|
26572
|
+
}
|
|
26573
|
+
};
|
|
26574
|
+
}
|
|
25671
26575
|
async function processBrowserPrompt(input2) {
|
|
25672
26576
|
const timestamp = validDateTime(input2.request.capturedAt) ?? input2.now().toISOString();
|
|
25673
26577
|
const transactionId = `txn:browser:${digest4(`${input2.request.promptText}:${timestamp}`).slice(0, 20)}`;
|
|
@@ -25846,6 +26750,95 @@ function parseBridgeEnvelope(value) {
|
|
|
25846
26750
|
}
|
|
25847
26751
|
};
|
|
25848
26752
|
}
|
|
26753
|
+
function parseLiveCoachEventEnvelope(value) {
|
|
26754
|
+
if (typeof value !== "object" || value === null) {
|
|
26755
|
+
return { ok: false, error: "invalid_json_body" };
|
|
26756
|
+
}
|
|
26757
|
+
const envelope = value;
|
|
26758
|
+
if (envelope.adapter !== "browser_mv3" || typeof envelope.request !== "object" || envelope.request === null) {
|
|
26759
|
+
return { ok: false, error: "invalid_guardian_adapter_envelope" };
|
|
26760
|
+
}
|
|
26761
|
+
const candidate = envelope.request;
|
|
26762
|
+
if ("promptText" in candidate || "rawPrompt" in candidate || "detectedValue" in candidate) {
|
|
26763
|
+
return { ok: false, error: "raw_content_not_allowed_for_live_coach_event" };
|
|
26764
|
+
}
|
|
26765
|
+
const provider = parseProvider(candidate.provider);
|
|
26766
|
+
const destination = stringField(candidate, "destination");
|
|
26767
|
+
const pageOrigin = stringField(candidate, "pageOrigin");
|
|
26768
|
+
const category = parseLiveCoachCategory(candidate.category);
|
|
26769
|
+
const capturedAt = stringField(candidate, "capturedAt");
|
|
26770
|
+
if (!destination || !pageOrigin || !category || !capturedAt) {
|
|
26771
|
+
return { ok: false, error: "missing_required_live_coach_event_fields" };
|
|
26772
|
+
}
|
|
26773
|
+
return {
|
|
26774
|
+
ok: true,
|
|
26775
|
+
request: {
|
|
26776
|
+
provider,
|
|
26777
|
+
destination,
|
|
26778
|
+
pageOrigin,
|
|
26779
|
+
category,
|
|
26780
|
+
capturedAt
|
|
26781
|
+
}
|
|
26782
|
+
};
|
|
26783
|
+
}
|
|
26784
|
+
function parseLiveCoachCategory(value) {
|
|
26785
|
+
return value === "ssn" || value === "password" || value === "secret" || value === "payment" || value === "health" ? value : void 0;
|
|
26786
|
+
}
|
|
26787
|
+
function buildLiveCoachReceipt(request, transactionId, timestamp) {
|
|
26788
|
+
const core = {
|
|
26789
|
+
transaction_id: transactionId,
|
|
26790
|
+
provider: request.provider,
|
|
26791
|
+
destination_hash: digest4(request.destination),
|
|
26792
|
+
page_origin_hash: digest4(request.pageOrigin),
|
|
26793
|
+
category: request.category,
|
|
26794
|
+
created_at: timestamp,
|
|
26795
|
+
raw_content_included: false
|
|
26796
|
+
};
|
|
26797
|
+
return {
|
|
26798
|
+
schema_version: PERSONAL_FABRIC_CONTRACTS_SCHEMA_VERSION,
|
|
26799
|
+
receipt_id: `receipt:${transactionId}:live-coach`,
|
|
26800
|
+
transaction_id: transactionId,
|
|
26801
|
+
receipt_type: "policy",
|
|
26802
|
+
disposition: "warn",
|
|
26803
|
+
policy_basis: [
|
|
26804
|
+
"live-sensitive-prompt-coach",
|
|
26805
|
+
`category:${request.category}`,
|
|
26806
|
+
`provider:${request.provider}`
|
|
26807
|
+
],
|
|
26808
|
+
receipt_hash: `sha256:${digest4(JSON.stringify(core))}`,
|
|
26809
|
+
raw_content_included: false,
|
|
26810
|
+
created_at: timestamp,
|
|
26811
|
+
summary: `Guardian flagged ${liveCoachCategoryLabel(request.category)} while drafting in ${providerDisplayName(request.provider)}.`
|
|
26812
|
+
};
|
|
26813
|
+
}
|
|
26814
|
+
function buildLiveCoachEvent(request, transactionId, timestamp, receipt) {
|
|
26815
|
+
const payload = {
|
|
26816
|
+
provider: request.provider,
|
|
26817
|
+
destination_hash: digest4(request.destination),
|
|
26818
|
+
page_origin_hash: digest4(request.pageOrigin),
|
|
26819
|
+
category: request.category,
|
|
26820
|
+
raw_content_included: false
|
|
26821
|
+
};
|
|
26822
|
+
return {
|
|
26823
|
+
event_id: `event:${transactionId}:live-coach`,
|
|
26824
|
+
transaction_id: transactionId,
|
|
26825
|
+
event_type: "coach_presented",
|
|
26826
|
+
occurred_at: timestamp,
|
|
26827
|
+
actor: "guardian-daemon",
|
|
26828
|
+
summary: `Live Prompt Coach presented ${request.category} warning.`,
|
|
26829
|
+
payload_hash: `sha256:${digest4(JSON.stringify(payload))}`,
|
|
26830
|
+
receipt_id: receipt.receipt_id,
|
|
26831
|
+
graph_refs: [`provider:${request.provider}`, `receipt:${receipt.receipt_id}`],
|
|
26832
|
+
redaction_state: "metadata_only"
|
|
26833
|
+
};
|
|
26834
|
+
}
|
|
26835
|
+
function liveCoachCategoryLabel(category) {
|
|
26836
|
+
if (category === "ssn") return "possible SSN sharing";
|
|
26837
|
+
if (category === "password") return "possible credential sharing";
|
|
26838
|
+
if (category === "secret") return "possible secret sharing";
|
|
26839
|
+
if (category === "payment") return "possible financial data";
|
|
26840
|
+
return "possible health information";
|
|
26841
|
+
}
|
|
25849
26842
|
function parseProvider(value) {
|
|
25850
26843
|
return value === "chatgpt" || value === "claude" || value === "gemini" || value === "perplexity" ? value : "unknown";
|
|
25851
26844
|
}
|