@f5-sales-demo/xcsh 23.2.2 → 23.3.3
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/package.json +8 -8
- package/src/commands/blindfold-args.ts +16 -3
- package/src/commands/blindfold-help.ts +2 -2
- package/src/commands/blindfold.ts +2 -2
- package/src/internal-urls/build-info.generated.ts +8 -8
- package/src/internal-urls/docs-index.generated.ts +2 -1
- package/src/internal-urls/public-citation-destinations.generated.ts +2 -2
- package/src/internal-urls/terraform-documentation-assets.generated.ts +28 -28
- package/src/internal-urls/terraform-documentation.ts +1 -1
- package/src/internal-urls/terraform-property-index.ts +14 -1
- package/src/internal-urls/terraform-property-ranking.ts +10 -3
- package/src/internal-urls/terraform-provider-pin.generated.ts +1 -1
- package/src/prompts/tools/xcsh-blindfold.md +1 -1
- package/src/services/blindfold-contract/blindfold-contract-v1.txt +1 -0
- package/src/services/blindfold-contract/lock.json +6 -0
- package/src/services/blindfold-documents.ts +1 -12
- package/src/services/blindfold-ensure.ts +428 -0
- package/src/services/blindfold.ts +16 -6
- package/src/terraform-documentation-smoke.ts +2 -2
- package/src/terraform-port-smoke.ts +15 -0
- package/src/tools/xcsh-blindfold.ts +6 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/xcsh",
|
|
4
|
-
"version": "23.
|
|
4
|
+
"version": "23.3.3",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/f5-sales-demo/xcsh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -68,13 +68,13 @@
|
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"@agentclientprotocol/sdk": "1.4.0",
|
|
71
|
-
"@f5-sales-demo/pi-agent-core": "23.
|
|
72
|
-
"@f5-sales-demo/pi-ai": "23.
|
|
73
|
-
"@f5-sales-demo/pi-natives": "23.
|
|
74
|
-
"@f5-sales-demo/pi-resource-management": "23.
|
|
75
|
-
"@f5-sales-demo/pi-tui": "23.
|
|
76
|
-
"@f5-sales-demo/pi-utils": "23.
|
|
77
|
-
"@f5-sales-demo/xcsh-stats": "23.
|
|
71
|
+
"@f5-sales-demo/pi-agent-core": "23.3.3",
|
|
72
|
+
"@f5-sales-demo/pi-ai": "23.3.3",
|
|
73
|
+
"@f5-sales-demo/pi-natives": "23.3.3",
|
|
74
|
+
"@f5-sales-demo/pi-resource-management": "23.3.3",
|
|
75
|
+
"@f5-sales-demo/pi-tui": "23.3.3",
|
|
76
|
+
"@f5-sales-demo/pi-utils": "23.3.3",
|
|
77
|
+
"@f5-sales-demo/xcsh-stats": "23.3.3",
|
|
78
78
|
"@mozilla/readability": "^0.6",
|
|
79
79
|
"@resvg/resvg-wasm": "2.6.2",
|
|
80
80
|
"@sinclair/typebox": "0.34.52",
|
|
@@ -3,6 +3,7 @@ import { Args, CliUsageError, Flags, parseCommandArgv } from "@f5-sales-demo/pi-
|
|
|
3
3
|
import type { BlindfoldArgs, BlindfoldOperation } from "../services/blindfold";
|
|
4
4
|
|
|
5
5
|
export const blindfoldFlags = {
|
|
6
|
+
file: Flags.string({ char: "f", description: "Resource manifest with x-xcsh-blindfold version 1" }),
|
|
6
7
|
input: Flags.string({ description: "Secret filename or - for stdin" }),
|
|
7
8
|
"public-key": Flags.string({ description: "Public key JSON/YAML file; requires --policy-document (offline)" }),
|
|
8
9
|
"policy-document": Flags.string({ description: "Policy JSON/YAML file; requires --public-key (offline)" }),
|
|
@@ -25,7 +26,7 @@ export const blindfoldFlags = {
|
|
|
25
26
|
json: Flags.boolean({ description: "Print public JSON report" }),
|
|
26
27
|
};
|
|
27
28
|
const aliases = { "get-public-key": "public-key", "get-policy-document": "policy", encrypt: "encrypt" } as const;
|
|
28
|
-
const supported = ["public-key", "policy", "encrypt", "certificate", "create", "replace"];
|
|
29
|
+
const supported = ["public-key", "policy", "encrypt", "certificate", "create", "replace", "ensure"];
|
|
29
30
|
const common = ["context-name", "output-file", "result-file", "json"];
|
|
30
31
|
export function flagsForBlindfold(operation: string, compatibility = false) {
|
|
31
32
|
const names =
|
|
@@ -43,7 +44,18 @@ export function flagsForBlindfold(operation: string, compatibility = false) {
|
|
|
43
44
|
"encoding",
|
|
44
45
|
...(compatibility ? ["outfile", "outfmt"] : []),
|
|
45
46
|
]
|
|
46
|
-
: [
|
|
47
|
+
: [
|
|
48
|
+
...common,
|
|
49
|
+
...(operation === "ensure" ? ["file"] : []),
|
|
50
|
+
"cert",
|
|
51
|
+
"key",
|
|
52
|
+
"bundle",
|
|
53
|
+
"name",
|
|
54
|
+
"namespace",
|
|
55
|
+
"policy",
|
|
56
|
+
"passphrase-env",
|
|
57
|
+
"dry-run",
|
|
58
|
+
];
|
|
47
59
|
return Object.fromEntries(names.map(name => [name, blindfoldFlags[name as keyof typeof blindfoldFlags]]));
|
|
48
60
|
}
|
|
49
61
|
export function parseBlindfoldCli(
|
|
@@ -70,6 +82,7 @@ export function parseBlindfoldCli(
|
|
|
70
82
|
throw new CliUsageError("Select one secret input source");
|
|
71
83
|
const args: BlindfoldArgs & { json?: boolean } = {
|
|
72
84
|
operation: operation as BlindfoldOperation,
|
|
85
|
+
file: f.file as string | undefined,
|
|
73
86
|
compatibility,
|
|
74
87
|
encoding: f.encoding as "base64" | "location" | undefined,
|
|
75
88
|
outfile: f.outfile as string | undefined,
|
|
@@ -125,7 +138,7 @@ export function parseBlindfoldCli(
|
|
|
125
138
|
)
|
|
126
139
|
)
|
|
127
140
|
throw new CliUsageError("File paths must be nonempty");
|
|
128
|
-
if (["certificate", "create", "replace"].includes(operation)) {
|
|
141
|
+
if (["certificate", "create", "replace", "ensure"].includes(operation) && !args.file) {
|
|
129
142
|
if (!args.name || (args.bundle ? args.cert || args.key : !args.cert || !args.key))
|
|
130
143
|
throw new CliUsageError("Use --name and either --bundle or --cert with --key");
|
|
131
144
|
}
|
|
@@ -19,13 +19,13 @@ export function showBlindfoldHelp(argv: string[], bin: string): void {
|
|
|
19
19
|
if (!operation || ["--help", "-h"].includes(operation)) {
|
|
20
20
|
writeCliOutput(
|
|
21
21
|
process.stdout,
|
|
22
|
-
`${bin} ${compatibility ? "request secrets" : "blindfold"} ${compatibility ? "get-public-key | get-policy-document | encrypt" : "public-key | policy | encrypt | certificate | create | replace"}\nUse an operation followed by --help. Authentication uses xcsh context.\n`,
|
|
22
|
+
`${bin} ${compatibility ? "request secrets" : "blindfold"} ${compatibility ? "get-public-key | get-policy-document | encrypt" : "public-key | policy | encrypt | certificate | create | replace | ensure"}\nUse an operation followed by --help. Authentication uses xcsh context.\n`,
|
|
23
23
|
);
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
26
|
try {
|
|
27
27
|
if (
|
|
28
|
-
!["public-key", "policy", "encrypt", "certificate", "create", "replace"].includes(operation) ||
|
|
28
|
+
!["public-key", "policy", "encrypt", "certificate", "create", "replace", "ensure"].includes(operation) ||
|
|
29
29
|
(compatibility && !["get-public-key", "get-policy-document", "encrypt"].includes(leaf!))
|
|
30
30
|
)
|
|
31
31
|
throw new CliUsageError("Unknown Blindfold operation");
|
|
@@ -26,7 +26,7 @@ export async function runBlindfold(argv: string[], compatibility = false): Promi
|
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
28
|
const report = await service.run(args, { signal: controller.signal });
|
|
29
|
-
if (args.json || args.outputFile || ["create", "replace"].includes(report.operation))
|
|
29
|
+
if (args.json || args.outputFile || ["create", "replace", "ensure"].includes(report.operation))
|
|
30
30
|
writeCliOutput(process.stdout, `${JSON.stringify(report, null, 2)}\n`);
|
|
31
31
|
} catch (error) {
|
|
32
32
|
writeCliOutput(
|
|
@@ -44,7 +44,7 @@ export default class Blindfold extends Command {
|
|
|
44
44
|
static args = {
|
|
45
45
|
operation: Args.string({
|
|
46
46
|
required: true,
|
|
47
|
-
description: "public-key, policy, encrypt, certificate, create, replace",
|
|
47
|
+
description: "public-key, policy, encrypt, certificate, create, replace, ensure",
|
|
48
48
|
}),
|
|
49
49
|
file: Args.string({ description: "Encryption input file or - for redirected stdin" }),
|
|
50
50
|
};
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "23.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "23.3.3",
|
|
21
|
+
"commit": "a4b8565902152715688c02c2751ddfb89ecb1c44",
|
|
22
|
+
"shortCommit": "a4b8565",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v23.
|
|
25
|
-
"commitDate": "2026-10-
|
|
26
|
-
"buildDate": "2026-10-
|
|
24
|
+
"tag": "v23.3.3",
|
|
25
|
+
"commitDate": "2026-10-10T03:30:23Z",
|
|
26
|
+
"buildDate": "2026-10-10T04:12:29.541Z",
|
|
27
27
|
"dirty": true,
|
|
28
28
|
"prNumber": "",
|
|
29
29
|
"repoUrl": "https://github.com/f5-sales-demo/xcsh",
|
|
30
30
|
"repoSlug": "f5-sales-demo/xcsh",
|
|
31
|
-
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/
|
|
32
|
-
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v23.
|
|
31
|
+
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/a4b8565902152715688c02c2751ddfb89ecb1c44",
|
|
32
|
+
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v23.3.3"
|
|
33
33
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// Auto-generated by scripts/generate-docs-index.ts - DO NOT EDIT
|
|
2
2
|
|
|
3
|
-
export const EMBEDDED_DOC_FILENAMES: readonly string[] = ["development/blindfold-awareness-4831.md","development/blindfold-compatibility-4791.md","development/blindfold-delivery-ledger.md","development/blindfold-interchangeability-4803.md","development/blindfold-protocol.md","en/architecture-contribution/agent-session-runtime.mdx","en/architecture-contribution/build-release.mdx","en/architecture-contribution/extension-discovery.mdx","en/architecture-contribution/index.mdx","en/architecture-contribution/native-development.mdx","en/architecture-contribution/native-runtime.mdx","en/architecture-contribution/parallelism-qualification.mdx","en/architecture-contribution/prompt-authoring.mdx","en/architecture-contribution/provider-streaming.mdx","en/architecture-contribution/storage-artifacts.mdx","en/architecture-contribution/tool-runtime.mdx","en/architecture-contribution/tui-runtime.mdx","en/architecture-contribution/tui-style-guide.mdx","en/architecture-contribution/upstream-pi.mdx","en/automate-extend/extensions-custom-tools.mdx","en/automate-extend/headless-protocols.mdx","en/automate-extend/hooks-rules.mdx","en/automate-extend/index.mdx","en/automate-extend/plugins-marketplaces.mdx","en/automate-extend/sdk.mdx","en/automate-extend/skills.mdx","en/configure-secure/environment-reference.mdx","en/configure-secure/index.mdx","en/configure-secure/providers-routing.mdx","en/configure-secure/sandbox-boundaries.mdx","en/configure-secure/secrets-obfuscation.mdx","en/configure-secure/settings-files.mdx","en/f5-distributed-cloud/api-catalog.mdx","en/f5-distributed-cloud/blindfold-certificates.mdx","en/f5-distributed-cloud/contexts-namespaces.mdx","en/f5-distributed-cloud/create-apply-update.mdx","en/f5-distributed-cloud/get-export-delete.mdx","en/f5-distributed-cloud/index.mdx","en/f5-distributed-cloud/manifest-fundamentals.mdx","en/f5-distributed-cloud/validate-diff.mdx","en/getting-started/first-manifest.mdx","en/getting-started/index.mdx","en/getting-started/model-authentication.mdx","en/index.mdx","en/integrations-deployment/chrome.mdx","en/integrations-deployment/containers.mdx","en/integrations-deployment/herdr.mdx","en/integrations-deployment/index.mdx","en/integrations-deployment/office.mdx","en/integrations-deployment/vscode.mdx","en/reference-troubleshooting/cli-reference.mdx","en/reference-troubleshooting/configuration-schema.mdx","en/reference-troubleshooting/diagnostics.mdx","en/reference-troubleshooting/index.mdx","en/reference-troubleshooting/slash-keybindings.mdx","en/use-xcsh/agent-loop.mdx","en/use-xcsh/built-in-tools.mdx","en/use-xcsh/execution-modes.mdx","en/use-xcsh/index.mdx","en/use-xcsh/interactive-tui.mdx","en/use-xcsh/planning-agents.mdx","en/use-xcsh/sessions-memory.mdx","en/use-xcsh/tui-navigation.mdx","issue-intake.md"];
|
|
3
|
+
export const EMBEDDED_DOC_FILENAMES: readonly string[] = ["development/blindfold-awareness-4831.md","development/blindfold-compatibility-4791.md","development/blindfold-delivery-ledger.md","development/blindfold-ensure.md","development/blindfold-interchangeability-4803.md","development/blindfold-protocol.md","en/architecture-contribution/agent-session-runtime.mdx","en/architecture-contribution/build-release.mdx","en/architecture-contribution/extension-discovery.mdx","en/architecture-contribution/index.mdx","en/architecture-contribution/native-development.mdx","en/architecture-contribution/native-runtime.mdx","en/architecture-contribution/parallelism-qualification.mdx","en/architecture-contribution/prompt-authoring.mdx","en/architecture-contribution/provider-streaming.mdx","en/architecture-contribution/storage-artifacts.mdx","en/architecture-contribution/tool-runtime.mdx","en/architecture-contribution/tui-runtime.mdx","en/architecture-contribution/tui-style-guide.mdx","en/architecture-contribution/upstream-pi.mdx","en/automate-extend/extensions-custom-tools.mdx","en/automate-extend/headless-protocols.mdx","en/automate-extend/hooks-rules.mdx","en/automate-extend/index.mdx","en/automate-extend/plugins-marketplaces.mdx","en/automate-extend/sdk.mdx","en/automate-extend/skills.mdx","en/configure-secure/environment-reference.mdx","en/configure-secure/index.mdx","en/configure-secure/providers-routing.mdx","en/configure-secure/sandbox-boundaries.mdx","en/configure-secure/secrets-obfuscation.mdx","en/configure-secure/settings-files.mdx","en/f5-distributed-cloud/api-catalog.mdx","en/f5-distributed-cloud/blindfold-certificates.mdx","en/f5-distributed-cloud/contexts-namespaces.mdx","en/f5-distributed-cloud/create-apply-update.mdx","en/f5-distributed-cloud/get-export-delete.mdx","en/f5-distributed-cloud/index.mdx","en/f5-distributed-cloud/manifest-fundamentals.mdx","en/f5-distributed-cloud/validate-diff.mdx","en/getting-started/first-manifest.mdx","en/getting-started/index.mdx","en/getting-started/model-authentication.mdx","en/index.mdx","en/integrations-deployment/chrome.mdx","en/integrations-deployment/containers.mdx","en/integrations-deployment/herdr.mdx","en/integrations-deployment/index.mdx","en/integrations-deployment/office.mdx","en/integrations-deployment/vscode.mdx","en/reference-troubleshooting/cli-reference.mdx","en/reference-troubleshooting/configuration-schema.mdx","en/reference-troubleshooting/diagnostics.mdx","en/reference-troubleshooting/index.mdx","en/reference-troubleshooting/slash-keybindings.mdx","en/use-xcsh/agent-loop.mdx","en/use-xcsh/built-in-tools.mdx","en/use-xcsh/execution-modes.mdx","en/use-xcsh/index.mdx","en/use-xcsh/interactive-tui.mdx","en/use-xcsh/planning-agents.mdx","en/use-xcsh/sessions-memory.mdx","en/use-xcsh/tui-navigation.mdx","issue-intake.md"];
|
|
4
4
|
|
|
5
5
|
export const EMBEDDED_DOCS: Readonly<Record<string, string>> = {
|
|
6
6
|
"development/blindfold-awareness-4831.md": "# Progressive discovery and native Blindfold awareness\n\nIssue: [#4831](https://github.com/f5-sales-demo/xcsh/issues/4831)\n\n## Contract\n\nOptional native, custom, plugin and RPC host tools remain registered but deferred by default. Explicit eager\nmode, tool scopes and exclusions remain authoritative. Activated schemas stay available for the session and\nresume. Registration refresh updates discovery and drops vanished selections without activating dormant tools.\n\nNative certificate and private-input intent is determined from user-authored text. Embedded clients supply the\noriginal task separately from document context. A transient, bounded Markdown hint points to discovery and\nnative task routes; it never executes encryption or loads a schema. Repeated turns contain one hint and stored\nhistory contains none. Agent-authored messages, managed certificates, inspection, unrelated TLS/encryption and\nother platforms do not create intent. Session changes clear follow-up intent.\n\nThe maintained native guide supplies complete sections for `xcsh://blindfold/`, `/encrypt`, `/certificate` and `/verify`. The index is under 2 KiB; hints are under 1 KiB. The native tool name, schema and containment controls are unchanged.\n\n## Verification\n\n- Bootstrap: `bash scripts/ci-bun-install.sh` and `bun scripts/ensure-dev-native.ts` succeeded on the fresh Ubuntu worktree.\n- Red: initial valid runtime run had 11 passes and 13 expected failures; additional embedded-context and synthetic-turn tests failed before their repairs.\n- Focused: 51 discovery/Blindfold regression tests and 54 runtime, route, Plan Mode and configuration tests passed. Native Blindfold: 17 passed. Agent core: 57 passed. Office package: 436 passed, 4 skipped.\n- `bun run check:ts` and `bun run check:docs-quality` passed (29 documentation tests).\n- The original 26,000-character neutral prompt budget is retained. Repairs render real environment fields,\ndefer plugin descriptions to the catalog, and remove duplicated Terraform instructions while retaining the\ndocumented constraints. Missing progressive schema, API, portability, knowledge and redaction policies were\nrestored.\n- Full-suite isolation repair: the isolated plugin-home probe now runs in its own process, avoiding registrations left by earlier discovery tests. Browser host-tool acceptance waits through actual prompt setup and asserts the complete request/result loop.\n- Changed-file PII enforcement and authored prose terminology checks passed.\n\n## Model comparison\n\nThe sanitized receipt is `packages/coding-agent/test/evidence/blindfold-awareness-v1/comparison.json`. A\nfrozen six-task corpus ran with `openai-codex/gpt-6.1-sol`, medium effort, identical settings and synthetic\nprivate offline inputs under v23.0.3 eager, v23.0.3 progressive and the candidate. All 18 tasks passed without\nlive mutations or observed secret/payload leakage. First-request tokens include cached input exactly once.\nDiscovery calls and total task input tokens remain in the receipt.\n\n| Profile | Neutral first input tokens | Neutral system prompt bytes |\n| --- | ---: | ---: |\n| Eager | 43,290 | 78,332 |\n| Existing progressive | 16,431 | 26,745 |\n| Candidate | 16,327 | 25,501 |\n\nOne run per task is evidence for this corpus, not a statistical model guarantee. Plugin and RPC tools are\nsynthetic integrations. Offline encryption writes a fresh mode-0600 location artifact; no certificate or\nshowcase mutation is performed. Private task inputs and runtime directories were removed by the harness.\n\n## Delivery gates\n\n- [ ] Full final coding-agent package run and required CI.\n- [ ] Linked PR merged and normal release published.\n- [ ] Immutable artifact digest verification and installed Mac/Ubuntu identity.\n- [ ] Installed task routes and discovery/containment acceptance.\n\nSource SDK and representative browser/Office integration checks do not establish physical Chrome or Office application acceptance. No physical GUI session has been exercised for this change.\n",
|
|
7
7
|
"development/blindfold-compatibility-4791.md": "# Blindfold secrets compatibility\n\nHistorical v22.15.0 contract. Its selected interfaces did not prove executable-only\nreplacement in the BYOC article: location output, snake_case documents and policy\ndefaults differ from vesctl. [v23.0.0 interchangeability acceptance](blindfold-interchangeability-4803.md)\ncorrects that scope and records the new container interchangeability qualification.\n\n\nFrozen reference, before implementation: Docker Hub `kreynoldsf5/vesctl@sha256:6ef8dc145b53130273bca4d3400ff9349e057ae36ed8e36d943eb1465e7edd82`.\nVersion `0-2-24`, source `394fae804d196ebd18fa24b14e39c178f64485d7`, build timestamp `2021-08-24T17:39:03+00:00`.\nPublished image pulled on Ubuntu. All six help levels and version returned exit 0, help on stdout, empty stderr.\nReference gets only read-only synthetic fixtures and no tenant credentials. Retrieval cannot run without credentials; it fails before contacting a credential-free loopback fixture server.\n\n| Interface | Pinned vesctl observation | xcsh selected contract |\n| --- | --- | --- |\n| Command paths | request secrets get-public-key, get-policy-document, encrypt | Same three paths, native service |\n| Policy selection | --namespace, --name; namespace default default | --namespace/-n, --name; default shared/ves-io-allow-volterra |\n| Namespace short flag | -n rejected, exit 1 | Supported for secret policy |\n| Public material | Native data wrapper accepted in synthetic encryption | Single JSON/YAML data wrapper |\n| Flat fields | Panics, exit 2 | Reject unsupported/ambiguous document |\n| Encryption input | Exactly one positional filename | Positional, --input, -, redirected stdin |\n| stdin | - treated as filename; missing positional rejected | Bounded native asynchronous read, cancellation |\n| Encryption stdout | Banner then bare Base64; empty stderr, exit 0 | One string:/// value and newline |\n| Usage errors | Exit 1; diagnostics duplicated on stdout and stderr | Exit 2, diagnostic only on stderr |\n| Output selection | --outfmt global format, --output directory, --outfile artifact | `--output json` or `--output yaml` on retrieval only; native `--output-file`/`--result-file`/`--json` |\n| Authentication | Requires legacy config or credential flags | Native xcsh context only |\n\nExplicitly unsupported: request aliases req/r, general request/rpc/configuration commands, build-blindfold-bundle, --key-version, --policy-doc (stale help example), --outfile, --outfmt, -o, --config, --server-urls/-u, --p12-bundle, --cert/-c, --key/-k, --cacert/-a, --hw-key, --show-curl, --timeout, .vesconfig and VES credential variables.\nThe selected --output has xcsh format semantics. JSON remains the default. Random ciphertext is qualified by independent decryption/field checks.\n\n## Delivery tasks\n\n- Reference help and synthetic observations: recorded above; private observations outside checkout.\n- Fresh Ubuntu worktree and prescribed dependency bootstrap: passed at base 02b803e90e409fdf421f86b2be41f145ae9a8983.\n- Planning: named rigor skills unavailable in installed skill inventory; this contract and issue 4791 provide the explicit plan and completion ledger.\n- CLI TDD red: missing blindfold-args module, exit 1; three tests awaiting implementation.\n- Native TDD red: missing asynchronous export; service TDD red: supplied files rejected for absent credentials. Both corrected.\n- Focused verification: 48 tests across eight files, 226 assertions, zero failures (including assistant offline containment). Independent recovery of pinned vesctl and native envelopes validates tenant/version/policy/exponent/modulus and all binary plaintext bytes.\n- Process acceptance: file and explicit/implicit stdin, legacy configuration isolation, invalid usage before input, SIGINT 130, oversized stdin, stdout separation and broken pipe passed. Offline startup bypasses context and resource modules.\n- TypeScript: full check:ts passed. Rust: check:rs passed; test:rs passed (328 tests across the component runs).\n- Bootstrap environment: first full TypeScript run lacked the pinned generated Terraform asset. Sequential generator produced reviewed v15.2.0 SQLite and gzip hashes; package suite rerun completed: 10,080 passed, 562 skipped, one stale audit failure corrected by regeneration. An overlapping build/generator attempt failed and was stopped; no implementation claim relies on it.\n- Standalone source build: passed with verified documentation/native assets; compatibility help and file/stdin offline encryption passed. This is candidate validation, not released installation acceptance.\n- Source-boundary audit: regenerated after CLI changes; two tests and 1445 assertions passed. Refreshed 87 dependent authority digests; docs-quality contract passed.\n- Candidate native-context acceptance: isolated saved context and project link, real public JSON/policy YAML retrieval and exact-document offline encryption passed with empty stderr.\n- PR #4794: synced to current main, auto-merge enabled; hosted check and shell tests, Linux modern/macOS ARM64 native builds and container tests passed. Prose lint corrected by fencing literal format flags.\n- Remaining: green PR CI and merge, immutable release, Ubuntu then Mac installed/live/assistant acceptance, public guide and cleanup.\n\n## Released acceptance\n\nImmutable [v22.15.0](https://github.com/f5-sales-demo/xcsh/releases/tag/v22.15.0), source `785fcc49cfabf4d097525639643fd3438a644412`, release workflow `37653536435`. Feature PR\nPR #4794 and release PR #4798 merged; full feature and release code/native matrices passed. Intel native notarization verification passed on rerun after Apple had accepted the\nsubmission.\n\nUbuntu standalone acceptance ran first, then an independent Mac Homebrew installation. Both created fresh private test CA/protected keys, retrieved JSON/YAML through a saved native\ncontext, encrypted offline via file and stdin, supplied the exact location to existing `xcsh create`, attached a fresh fixed-response HTTP-LB, and verified strict CA trust,\nintended SNI, matching fingerprint and HTTPS 200. Existing `xcsh update` rotated the certificate; changed fingerprint and HTTPS 200 passed. Generic resource CLI received the\nmatching native credential snapshot through its existing environment interface.\n\nEach installed host ran two assistant prompts with file paths and required artifacts. Private provider requests, tool results, stdout/stderr were scanned for\nkey/password/token/ciphertext markers; zero leaks. Mac CLI and native hashes match published provenance, strict codesign passes, and both are accepted as Notarized Developer ID.\nUbuntu binary/provenance checksums and embedded native digests match immutable GitHub assets.\n\nLinux x64 binary SHA-256: `0e64b0ac0975168e03d867d7d6629fa88f2e5506d789dbc161caa3be50fe06a6`. Mac ARM64 binary: `f97008269551ad7ebb84dfa23dc3048da2bc464cc9683e39dc6c6a5d43acc9ca`; native: `312b82bde28eac6dc9fac4fd3a20f9d37d611a641bda6d12f83e319a4dfa8596`.\n\nPrivate per-host ownership/expiry/teardown records retain the released demos. Candidate auxiliary resources are removed during cleanup. Guide publication and task worktree retirement are tracked in #4799.\n",
|
|
8
8
|
"development/blindfold-delivery-ledger.md": "# Issue 4750 delivery ledger\n\nCandidate base: `9bebb2ecc9763c343cf21162b5f1198ade67d003` (`origin/main`, v22.13.0).\nBranch: `feature/issue-4750-native-blindfold`; fresh Ubuntu worktree under `.worktrees/feature/issue-4750-native-blindfold`.\n\n## Planning and audit\n\nImplement one Rust native input/encryption boundary, shared TypeScript service, CLI and assistant adapters. Follow the binary contract in `blindfold-protocol.md`; preserve complete\npublic exponent and avoid the retired provider's OAEP format. Deploy only owned lab resources. Credentials and test CA/key/runtime evidence stay outside the checkout. Repository\nnamed rigor skills were unavailable; planning, TDD evidence and this completion ledger record the required process directly.\n\n## Acceptance ledger\n\n| Check | Command or operation | Expected | Actual | Evidence |\n| --- | --- | --- | --- | --- |\n| Bootstrap | `bash scripts/ci-bun-install.sh`; `bun scripts/ensure-dev-native.ts` | Source-matched addon | Passed | Private bootstrap logs; native receipts |\n| TDD red | `bun test packages/natives/test/blindfold.test.ts` | Missing new native export | Failed on missing blindfoldPrepare | Session test transcript |\n| Service TDD red | `bun test packages/coding-agent/test/blindfold-service.test.ts` | Missing shared service | Failed on absent module | Session test transcript |\n| Native inputs/protocol | Focused three-file tests | Independent secret recovery; supported formats; failure boundaries | 28 passed, 119 assertions; later ABI regressions: 29 native tests passed | Public native-live receipt |\n| TypeScript | `bun run check:ts` | All checks pass | Passed before temporary packaging loader reset | Private check logs |\n| Rust | all-target Clippy, `bun run test:rs` | Pass | Passed | Private Rust logs |\n| Package | `bun --cwd=packages/coding-agent run build` | Standalone CLI | Passed | Private build log |\n| Package runtime | Compiled CLI help, dry-run, explicit replace | Native runtime and tenant readback | Passed | Public native-live receipt |\n| Containment | Scan 29 captured requests/results/logs/reports | No plaintext keys/tokens | Zero leaks | Public native-live receipt |\n| Live RSA | `bun run dev blindfold create`; fixed-response LB create; TLS | Trusted SNI/VIP TLS, matching fingerprint, HTTP 200 | TLS 1.3, matching RSA fingerprint, HTTP 200 | Public sanitized receipt; private runtime |\n| Rotation | `bun run dev blindfold replace` second RSA pair; TLS | New fingerprint and HTTP 200 | Passed | Public sanitized receipt |\n| Rejected rotation | RSA to EC on referenced resource | Existing certificate remains working | F5 HTTP 400; original RSA TLS intact | Public sanitized receipt |\n| Live EC | Separate EC certificate, LB reference update; TLS | EC fingerprint and HTTPS | Passed | Public sanitized receipt |\n| Retained demo | Restore rotated RSA LB reference; remove auxiliary EC | Final working demo; auxiliary absent | RSA TLS verified; EC GET 404 | Private ownership/expiry/teardown record |\n| Docs | docs-quality, unittest, PII enforcement | Source-backed guide and safe evidence | Passed; 28 checker tests | docs/en guide and evidence manifest |\n| Full TS suite | `bun run test:ts` after prescribed optional-loader reset | Full pass | Final feature CI passed: 9,996 passed, zero failures; bounded process checks repaired | Private stable-suite log |\n| Hosted native matrix | Existing CI full_native_matrix | All supported platforms | Passed all eight variants | Release CI 37591704077 |\n| Delivery | Commit/push/linked PR/CI/merge/release | Released installation and public docs | Merged #4752, #4770, #4774, #4780; v22.14.4 immutable; installed TLS passed | Issue #4750 |\n\nThe delivery rows are accepted against immutable v22.14.4. The retained demo expires 30 days after its private creation timestamp; ownership, CA and teardown commands are recorded privately. No provider function integration is included.\n\n## Released installation acceptance\n\nRelease: [v22.14.4](https://github.com/f5-sales-demo/xcsh/releases/tag/v22.14.4)\nSource commit: `cd5b50251630100e05a402552a68814003abd8bd`; workflow run `37591704077`.\nLinux x64 binary SHA-256: `385172b1652b899797ab927f7f651321bd0ebf8fb16a83ae7d8342c37f6e736e`.\nThe binary, checksum, provenance and baseline/modern addons match GitHub immutable asset digests. Both native variants load independently on Debian 12; the standalone binary reports `xcsh/22.14.4` and its Blindfold help works there.\n\nInstalled protected PEM replacement and PKCS#12 replacement passed. A fresh protected RSA key pair was then rotated into the retained demo; trusted SNI/VIP TLS served the matching\npublic fingerprint and returned HTTP 200 over TLS 1.3. Name collision and mismatched-key replacement failed without damaging the endpoint. Private ownership/expiry/teardown records\nwere updated to the final retained certificate.\n\nThe [public guide](https://f5-sales-demo.github.io/xcsh/en/f5-distributed-cloud/blindfold-certificates/) returns HTTP 200. Auxiliary EC resource absence was confirmed by named HTTP\n404. Actual tenant identities, private keys, passphrases, tokens and encrypted payloads stay outside this public ledger.\n\nThe installed Linux ABI failure in immutable v22.14.2 was reproduced on Debian 12 and repaired in #4780. Target-specific Clang wrappers bind vendored OpenSSL to napi's release sysroot; unsupported unversioned C23 libc symbols are rejected before publication. Prior immutable assets were preserved.\n",
|
|
9
|
+
"development/blindfold-ensure.md": "# Idempotent Blindfold ensure\n\n`xcsh blindfold ensure --name NAME -n NAMESPACE --cert chain.pem --key key.pem` creates or rotates a\nnamed certificate, or returns `unchanged` without a write when public material, context, and remote\nprovenance match. `--bundle FILE` and `--passphrase-env NAME` use native protected inputs.\n`--dry-run client` validates inputs and reads context without encrypting or mutating tenant resources.\nRaw `encrypt`, `certificate`, `create`, `replace`, compatibility output and saved manifests remain.\n\n`xcsh blindfold ensure -f resource.yaml` removes a version 1 `x-xcsh-blindfold` extension before sending\nthe manifest. The extension has a `certificates` array with unique `id`, a recognized certificate-node\nJSON `pointer`, `certificate_file`/`private_key_file` or `pkcs12_file`, optional `passphrase_env` and\n`policy`. File paths resolve relative to the manifest. The shared assistant service accepts paths\nand environment names only, and returns no plaintext or encrypted payloads.\n\nThe reserved provenance annotation contains public chain/SPKI identity, context digest, ciphertext\nhash and algorithm. It is reconciliation metadata, not attestation. Missing or inconsistent metadata\nrequires regeneration. RSA/EC cutover requires a new certificate/reference. A write is attempted\nonce and reconciled by named complete-form readback. Concurrent tool ownership is unsupported.\n\nThe embedded immutable contract is pinned under `src/services/blindfold-contract` in the coding-agent\npackage. Qualification receipts distinguish source tests from installed and live acceptance.\n",
|
|
9
10
|
"development/blindfold-interchangeability-4803.md": "# Blindfold interchangeability acceptance\n\nIssue [#4803](https://github.com/f5-sales-demo/xcsh/issues/4803) corrects the\nv22.15.0 compatibility contract. The earlier #4791 acceptance proves native\ncertificate/TLS behavior with xcsh's selected interfaces; it does not prove\nexecutable-only replacement in the BYOC article. Its location output, snake_case\ndocuments and policy defaults differ from container vesctl.\n\nThe reference is frozen at article revision\n`e7acf7fd53b2f19d9aca7ca43f23e47c2187ab9e`. Relevant commands and the consumer\nexpression are in `packages/coding-agent/test/fixtures/blindfold/article.json`.\nThe README says the file contains a location; the actual consumer prepends\n`string:///` to bare base64. No upstream files or deployment stack were changed.\nThe article uses deprecated `volterra`; the unreleased next-generation\n`f5-sales-demo/terraform-provider-xcsh` remains under feature iteration. Future\nBlindfold provider development is separate from this CLI acceptance.\n\n## Frozen container reference\n\nAll vesctl probes ran inside Ubuntu Docker containers using\n`kreynoldsf5/vesctl@sha256:6ef8dc145b53130273bca4d3400ff9349e057ae36ed8e36d943eb1465e7edd82`.\nHistorical version: `0-2-24`, source\n`394fae804d196ebd18fa24b14e39c178f64485d7`. Downloaded `0.2.47` was run exclusively\ninside that container after verifying binary SHA-256\n`35d29e517498feff9f12a41ff702e90f10a1cc8a20c589c3e524474dbfe53801`.\n\nSynthetic HTTPS serves read-only public documents under `/api`, with synthetic\ncertificate credentials. Offline encryption containers use `--network none`.\nFrozen pre-implementation help, requests, formats, stdout/stderr, exits and raw\nartifact observations are in `container-reference-before.json` beside the\nsanitized public fixtures. Ciphertext is represented by lengths and hashes in\nthat public observation file.\n\n| Observation | Both container versions |\n| --- | --- |\n| Public key path | `/api/secret_management/get_public_key?key_version=0` by default; explicit positive version sent unchanged |\n| Policy path | `/api/secret_management/namespaces/{namespace}/secret_policys/{name}/get_policy_document` with name/namespace query parameters |\n| Retrieval | camelCase YAML; observed `--outfmt json` and `yaml` both return YAML |\n| Policy selectors | required name; namespace defaults to `default` |\n| Encryption stdout | banner plus bare base64; empty stderr, exit 0 |\n| Binary outfile | raw envelope, 2622 bytes for synthetic 2048-byte input; empty stdout/stderr, exit 0 |\n| Encryption outfmt | does not alter ciphertext encoding |\n\nxcsh supports explicit JSON/YAML selection for public documents. It checks a\npositive requested version against the returned version instead of accepting\nthe fixture's deliberately mismatched response. Zero selects server default.\n\n## Repeatable automated acceptance\n\n```bash\nbun test packages/coding-agent/test/blindfold-producer-matrix.test.ts \\\n packages/coding-agent/test/blindfold-interchangeability.test.ts --max-concurrency 2\npython3 scripts/uat-blindfold-reference.py --run-dir /private/new-reference-run\n```\n\nThe reference command requires Docker-capable Ubuntu, Python cryptography, Bun\nand a successfully bootstrapped source/native build. It downloads only the\nverified reference binary. It never executes vesctl on the host and never gives\na container tenant credentials. Ordinary CI runs deterministic checked-in\nfixtures without Docker or network access.\n\nThe deterministic matrix covers reference/native producers, camelCase,\nsnake_case, agreeing mixed aliases, JSON/YAML, independent binary plaintext\nrecovery and raw output. Conflict, duplicate-key, multi-document, malformed\nfield, version, format/output conflict, symlink, existing file, cancellation,\nsize and assistant boundary tests complete the focused regression checks.\nRandom ciphertext is never compared byte-for-byte.\n\n## Live acceptance command\n\n```bash\npython3 scripts/uat-blindfold-live.py --executable /absolute/installed/xcsh \\\n --run-dir /private/new-live-run --context approved-context \\\n --namespace approved-lab-namespace --timeout 300\n```\n\nThe selected native context must already exist. Its private export supplies the\nsame credential snapshot to existing resource commands. The run uses a fresh\nmode-0700 directory, fresh resource names and checked subprocess exits. It\nqualifies public document retrieval, the bare-base64 consumer, canonical\nlocation/stdin/YAML, mode-0600 binary artifacts, public reports, named certificate\nreadback, private CA trust, intended SNI, fingerprint/HTTPS 200, ready/valid state\nand rotation. Cleanup deletes only run-owned objects and verifies absence.\nOptional `--retain-hours` records private ownership, expiry and teardown.\n\n## Delivery ledger\n\n- Fresh Ubuntu worktree: based on `159909645`, prescribed frozen bootstrap and\n source-matched native readiness passed. Named rigor skills were unavailable;\n the accepted user plan, issue and this ledger provide planning/audit records.\n- TDD red: four adapter tests failed on missing defaults, aliases, exact-version\n request and raw output; green after implementation.\n- Focused baseline: 51 tests, 297 assertions, zero failures. Expanded matrix:\n 64 document combinations and raw/integrity checks, 656 assertions, passed.\n- Reusable container UAT passed three times: 16 producer/consumer matrix cases across\n both reference versions; independent recovery, integrity, raw artifacts and\n exact substituted article pipeline passed. Final run also passed twelve reference JSON/YAML and camel/snake/agreeing-alias cases; conflicting reference aliases were observed accepted while xcsh rejects conflicts.\n- Full TypeScript check passed. Rust gate reports no Rust-affecting changes;\n native protocol/certificate tests passed. Full suite initially lacked the\n pinned generated Terraform asset; that run was stopped, the reviewed asset\n generated and verified, then the suite restarted.\n- Source-boundary audit regenerated; two tests and 1445 assertions passed.\n- Candidate live harness passed: trusted CA/SNI/fingerprint and HTTPS 200, ready/valid state, fresh rotation, exact consumer, canonical stdin/YAML, secure raw files, public-report containment and verified run-owned cleanup. Initial harness readback used a replace form that omitted runtime state; fixed and rerun fresh. Failed run resources were also removed and verified absent.\n- Candidate assistant: two successful file-only preparations, secure location artifacts and private provider/tool/stdout/stderr scans passed.\n- Full TypeScript suite passed: coding-agent 10,088 passed, 562 skipped, zero failures; other workspace suites passed. Full check:ts, docs-quality and 28 checker tests passed; Python harness lint, prose lint and final diff checks passed.\n- Feature PR #4804 merged at `580901c517c95dd3c581066410501705d8dc2ad4`.\n Final head CI `37678176558`, lint `37678177309` and container `37678176588`\n all passed. Release freshness was repaired through #4807 after authoritative\n Claude Code version drift; the gate remains enforced.\n- Release PR #4808 merged at `e2f2413e7bd7a48dcbe12727b3a81af80824b790`.\n [v23.0.0](https://github.com/f5-sales-demo/xcsh/releases/tag/v23.0.0) is immutable.\n Full release native/code/test/install matrix passed in `37683390178`.\n Intel modern-addon notarization assessment passed on attempt 3 after Apple\n had already accepted the prior signed bundle; signing policy was preserved.\n- Released Ubuntu standalone verified immutable binary/provenance/native hashes.\n Sales Demo native-context article pipeline, trusted CA/SNI/fingerprints/HTTPS 200,\n ready/valid state, rotation, canonical stdin/YAML, raw artifacts, public reports,\n two assistant preparations and provider/tool containment passed. Run-owned LB\n and certificate were deleted and absence verified. A first tenant run hit the\n route quota and was cleaned up; the user authorized Sales Demo for the retry.\n- Mac Homebrew `23.0.0` CLI/native immutable hashes and strict Developer ID /\n notarization checks passed. Python strict CA acceptance exposed missing CA\n key-usage metadata in the harness; add explicit keyCertSign/cRLSign and rerun\n fresh after cleanup. No trust checks were relaxed.\n- Mac strict CA live rerun passed: intended SNI/private CA/fingerprint/HTTPS 200, ready/valid state, fresh rotation, native-context article pipeline and canonical/raw regressions. Both run-owned resources and the first failed run resources were deleted and absence verified.\n- Released Mac assistant: two successful file-only preparations and secure location artifacts; private provider/tool/stdout/stderr scans found no key, token or ciphertext leakage. Complete release workflow `37683390178` is green, including npm, Homebrew and MDM installed channel checks.\n- Sanitized released acceptance receipt: `blindfold-interchangeability-receipt-4803.json`. Public guide/evidence publication tracked in #4805.\n- Remaining delivery: public guide and final\n sanitized receipts/cleanup. Implementation and repair worktrees were retired\n after ignored-file inspection; private evidence remains outside Git.\n",
|
|
10
11
|
"development/blindfold-protocol.md": "# Blindfold protocol contract\n\nThis contract was recovered from vesctl 0.2.47 offline synthetic encryption and independently decrypted before implementation. The runtime uses bundled OpenSSL and native code;\nvesctl is not a dependency. Synthetic tests exercise recovery independently with Node crypto and big integers. Live certificate TLS acceptance verifies F5 decryption for RSA and EC\ninputs.\n\nAll envelope lengths are unsigned 32-bit big-endian. All integers use big-endian encoding. RSA exponent and modulus are unsigned, minimally encoded, length-prefixed byte strings. The complete public exponent is preserved.\n\n| Field | Encoding |\n| --- | --- |\n| Tenant | Length-prefixed UTF-8 canonical tenant ID |\n| Key version | Unsigned 32-bit big-endian |\n| Policy ID | Unsigned 64-bit big-endian |\n| Algorithm | One byte, value 2 |\n| Public exponent | Length-prefixed unsigned big-endian bytes |\n| Public modulus | Length-prefixed unsigned big-endian bytes |\n| Wrapped key block | Length-prefixed RSA modulus-width bytes |\n| Encrypted secret | AES-256-GCM ciphertext followed by 16-byte tag; no length prefix |\n\nFor policy ID `p` and original exponent `e`, the effective RSA exponent is `e * (2*p + 2^31 + 1)`. Arithmetic must not truncate the policy or exponent.\n\nConstruct a random block of modulus byte width minus two. Set bytes 0–3 to `de ad be ef`. Bytes 4–15 are the 12-byte GCM nonce; bytes 16–47 are the 32-byte AES key. The remaining\nbytes remain random. Interpret the block as an unsigned integer and compute its modular exponentiation with the effective exponent and modulus. Serialize the wrapped result at the\nfull modulus byte width. GCM uses empty additional authenticated data. Base64-encode the entire envelope and prefix `string:///`.\n\nThe synthetic reference used a generated 2048-bit RSA key, policy 101, and a 2048-byte secret. Independently deriving the private exponent modulo the RSA group order recovered\n`deadbeef`, the nonce, AES key and the entire plaintext. Wrong-policy recovery and altered GCM ciphertext must fail. Production code contains no decryption endpoint.\n\nPrivate input buffers, normalized key PEM and AES key block use zeroizing native allocations. OpenSSL owns parsed private-key allocations; the intermediate RSA plaintext big\ninteger is cleared after use. The native API returns only encrypted material and public certificate metadata. Service/tool results exclude encrypted payloads; requested artifacts\nstay on disk.\n",
|
|
11
12
|
"en/architecture-contribution/agent-session-runtime.mdx": "---\ntitle: \"Agent loop and sessions\"\ndescription: \"Trace a user message through model selection, tool calls, append-only session state, compaction, and rendering.\"\nsidebar:\n order: 1\n label: \"Agent loop and sessions\"\nhead:\n - tag: style\n content: |\n .sl-markdown-content .expressive-code { max-width: 100%; overflow-x: auto; }\n .sl-markdown-content table { display: block; max-width: 100%; overflow-x: auto; }\n---\n\nThe command-line interface (CLI) parses arguments, resolves configuration and providers, creates a session, streams model events, dispatches tools, and renders the resulting entries.\n\n```text\nuser message\n -> cli.ts parse argv, resolve config and providers\n -> session factory create or resume the session\n -> provider stream AssistantMessageEvent deltas\n -> tool dispatch execute, append result, loop\n -> session JSONL append-only record\n -> renderer view of the appended state\n```\n\n## How do I trace a behavior?\n\nStart at `packages/coding-agent/src/cli.ts`, follow the session factory and event handlers, then inspect the persisted JSON Lines (JSONL) rather than relying only on terminal rendering. Provider and tool tests should assert the event sequence that caused the visible result.\n\n## Where does compaction act?\n\nCompaction transforms older conversation context before the next model turn; it does not rewrite the original session evidence. Test both the summary and subsequent message construction.\n\nTrace a normal response, a tool-producing response, and an aborted response separately. Each path\nmust append events in causal order, settle an active provider or tool only once, and leave a\nresumable leaf. To test compaction, force the configured threshold, capture the summary entry,\nresume from that leaf, and verify that the next model input includes the summary while the original\nJSONL entries remain readable. Rendering assertions belong after these state assertions because the\nTUI can repaint without changing the durable graph.\n",
|