fix: 将只读状态预算收敛到 YAML
This commit is contained in:
@@ -59,6 +59,9 @@ controlPlane:
|
||||
unideskWorkspace: /root/unidesk
|
||||
lanes:
|
||||
nc01-v02:
|
||||
status:
|
||||
readOnlyCapture:
|
||||
timeoutMs: 20000
|
||||
deployment:
|
||||
format: unidesk-yaml-only
|
||||
gitopsRoot: deploy/gitops/node/nc01
|
||||
|
||||
@@ -23,6 +23,8 @@ deliveryTiming:
|
||||
endToEndBudgetSeconds: 120
|
||||
observability:
|
||||
configRef: config/platform-infra/observability.yaml
|
||||
readOnlyCapture:
|
||||
timeoutMs: 25000
|
||||
tracesEndpoint: http://otel-collector.platform-infra.svc.cluster.local:4318/v1/traces
|
||||
serviceName: unidesk-cicd
|
||||
propagation:
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# R8 任务报告
|
||||
|
||||
## 任务定位
|
||||
|
||||
- MDTODO:`R8`。
|
||||
- Issue:`pikasTech/unidesk#2165`。
|
||||
- PR:`pikasTech/unidesk#2168`。
|
||||
- 本轮范围:仅处理主代理 blocker comment `#issuecomment-4978743309`。
|
||||
- Target:`NC01`。
|
||||
- targetWorkspace:`/root/unidesk/.worktree/2165-pac-status-visible`。
|
||||
- ref:`fix/2165-pac-status-visible`。
|
||||
|
||||
## 根因
|
||||
|
||||
- 首轮修复已建立稳定的 typed observation,使 PaC `status/history/debug-step` 与 AgentRun `control-plane status` 在 timeout、remote failure、empty response 和 parse failure 时不再以空 stdout 结束。
|
||||
- 首轮仍把 PaC 只读 capture 预算 `25000ms` 与 AgentRun status capture 预算 `20000ms` 写成 TypeScript 常量。
|
||||
- 这些预算属于可调运维事实;源码常量绕过 owning YAML,无法披露来源路径,也无法在选中对象缺失预算时 fail-closed。
|
||||
|
||||
## 官方最佳实践
|
||||
|
||||
- 遵循仓库 `AGENTS.md` 与 `docs/reference/yaml-first-ops.md`:owning YAML 是可调运维事实的唯一真相,parser 只做结构与类型校验,代码只消费已验证值。
|
||||
- 遵循 `docs/reference/cli.md`:远端 timeout、空响应和解析失败必须形成有界 typed 输出,并保留稳定退出语义与只读 drill-down。
|
||||
- 遵循 Issue #2165 的 P0 SPEC:Kubernetes、Tekton、Argo 和既有 runtime 聚合器继续作为状态 authority;预算配置不新增状态源、缓存 authority 或交付 mutation。
|
||||
|
||||
## Current Control Flow
|
||||
|
||||
1. CLI 读取 PaC 或 AgentRun YAML。
|
||||
2. parser 解析目标、consumer 或 lane。
|
||||
3. capture 调用使用 TypeScript 文件内固定的 timeout 常量。
|
||||
4. typed observation 披露实际 timeout 数值,但无法证明该数值的 owning config path。
|
||||
5. YAML 缺失预算时仍可继续执行,不能按当前选中对象 fail-closed。
|
||||
|
||||
## Desired Control Flow
|
||||
|
||||
1. PaC parser 必填读取 `config/platform-infra/pipelines-as-code.yaml#observability.readOnlyCapture.timeoutMs`。
|
||||
2. AgentRun lane parser 必填读取 `config/agentrun.yaml#controlPlane.lanes.<lane>.status.readOnlyCapture.timeoutMs`。
|
||||
3. parser 将预算值与精确 config path 放入 typed spec,不提供源码默认值。
|
||||
4. capture 只使用已验证的 YAML 预算。
|
||||
5. PaC text/JSON observation 与 AgentRun status text/JSON 摘要同时披露 config path 和实际 timeout。
|
||||
6. 缺失字段时 parser 在发起远端读取前失败,并指出缺失 YAML 路径。
|
||||
|
||||
## 修改
|
||||
|
||||
- `config/platform-infra/pipelines-as-code.yaml`
|
||||
- 新增 `observability.readOnlyCapture.timeoutMs: 25000`。
|
||||
- `scripts/src/platform-infra-pipelines-as-code.ts`
|
||||
- 删除 `pacReadOnlyCaptureTimeoutMs` 源码常量。
|
||||
- parser 必填校验预算并记录精确 config path。
|
||||
- `status/history/debug-step` capture 使用 YAML 预算。
|
||||
- typed observation 与默认 text 输出披露预算路径和实际数值。
|
||||
- `config/agentrun.yaml`
|
||||
- 在 `controlPlane.lanes.nc01-v02.status.readOnlyCapture.timeoutMs` 声明 `20000`。
|
||||
- `scripts/src/agentrun-lanes.ts`
|
||||
- lane parser 必填解析 status capture 预算与精确 config path。
|
||||
- `scripts/src/agentrun/control-plane.ts`
|
||||
- 删除 `agentRunStatusCaptureTimeoutMs` 源码常量。
|
||||
- source、runtime 和 git-mirror 只读 capture 使用选中 lane 的 YAML 预算。
|
||||
- status 结果披露 `readCaptureBudget`。
|
||||
|
||||
## 验证证据
|
||||
|
||||
- 定向 Bun 测试验证 PaC typed observation 保留 timeout、config path、首断点与只读 Next。
|
||||
- TypeScript 语法检查覆盖修改的 parser、PaC 与 AgentRun control-plane 文件。
|
||||
- YAML 读取和原 CLI 入口验证证明预算由选中配置解析,并在 text/JSON 中可见。
|
||||
- `git diff --check` 验证补丁格式。
|
||||
- 所有目标源码、Git、验证和原入口观察均通过 `trans NC01:/root/unidesk/.worktree/2165-pac-status-visible ...` 执行。
|
||||
|
||||
## 权限与变更边界
|
||||
|
||||
- 保留现有 typed observation、即时 progress、只读 Next 和非 mutation 行为。
|
||||
- 未增加 env、ConfigMap、数据库、缓存或第二状态源 authority。
|
||||
- 未增加合同、租约、安全围栏或锁。
|
||||
- 未执行 Vitest、PK01 操作、人工 PipelineRun、Argo、mirror 或其他交付 mutation。
|
||||
- 不自行合并 PR;管理性结论由主代理审核。
|
||||
|
||||
## 剩余边界
|
||||
|
||||
- Issue #2167 不属于 R8 当前 blocker 修复范围,本轮不扩展其 authority、实现或验收。
|
||||
- PR 合并与后续交付由主代理审核后决定。
|
||||
@@ -173,6 +173,12 @@ export interface AgentRunLaneSpec {
|
||||
readonly nodeKubeRoute: string;
|
||||
readonly nodeUnideskWorkspace: string;
|
||||
readonly version: string;
|
||||
readonly status: {
|
||||
readonly readOnlyCapture: {
|
||||
readonly timeoutMs: number;
|
||||
readonly configPath: string;
|
||||
};
|
||||
};
|
||||
readonly source: {
|
||||
readonly statusMode: "host-worktree" | "k3s-git-mirror";
|
||||
readonly repository: string;
|
||||
@@ -677,6 +683,8 @@ function parseLanes(input: Record<string, unknown>, nodes: Record<string, AgentR
|
||||
|
||||
function parseLane(lane: string, node: AgentRunNodeSpec, input: Record<string, unknown>, configPath: string): AgentRunLaneSpec {
|
||||
const path = `${configPath}.controlPlane.lanes.${lane}`;
|
||||
const status = recordField(input, "status", path);
|
||||
const readOnlyCapture = recordField(status, "readOnlyCapture", `${path}.status`);
|
||||
const source = recordField(input, "source", path);
|
||||
const runtime = recordField(input, "runtime", path);
|
||||
const ci = recordField(input, "ci", path);
|
||||
@@ -694,6 +702,12 @@ function parseLane(lane: string, node: AgentRunNodeSpec, input: Record<string, u
|
||||
nodeKubeRoute: node.kubeRoute,
|
||||
nodeUnideskWorkspace: node.unideskWorkspace,
|
||||
version,
|
||||
status: {
|
||||
readOnlyCapture: {
|
||||
timeoutMs: integerField(readOnlyCapture, "timeoutMs", `${path}.status.readOnlyCapture`),
|
||||
configPath: `${path}.status.readOnlyCapture.timeoutMs`,
|
||||
},
|
||||
},
|
||||
source: {
|
||||
statusMode,
|
||||
repository: stringField(source, "repository", `${path}.source`),
|
||||
|
||||
@@ -47,8 +47,6 @@ import { compactAgentRunLaneStatusTarget, compactLaneSecretsStatus } from "./tri
|
||||
import { capture, captureJsonPayload, compactCapture, record, stringOrNull, timedStatusStage } from "./utils";
|
||||
import { yamlLaneK3sSourceStatusScript, yamlLaneRuntimeStatusScript, yamlLaneSourceStatusScript } from "./yaml-lane";
|
||||
|
||||
const agentRunStatusCaptureTimeoutMs = 20_000;
|
||||
|
||||
export function parseSecretSyncOptions(args: string[]): SecretSyncOptions {
|
||||
const base = parseConfirmOptions(args);
|
||||
let node: string | null = null;
|
||||
@@ -419,7 +417,7 @@ export async function statusPipelinesAsCodeLane(config: UniDeskConfig, options:
|
||||
const artifact = record(pacSummary.artifact);
|
||||
const pacArgo = record(pacSummary.argo);
|
||||
const pipelineRunName = options.pipelineRun ?? stringOrNull(latestPipelineRun.name);
|
||||
const runtimeProbe = await timedStatusStage("runtime", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneRuntimeStatusScript(spec, pipelineRunName)], { runtimeTimeoutMs: agentRunStatusCaptureTimeoutMs }));
|
||||
const runtimeProbe = await timedStatusStage("runtime", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneRuntimeStatusScript(spec, pipelineRunName)], { runtimeTimeoutMs: spec.status.readOnlyCapture.timeoutMs }));
|
||||
const runtimePayload = captureJsonPayload(runtimeProbe.value);
|
||||
const manager = record(runtimePayload.manager);
|
||||
const database = record(runtimePayload.database);
|
||||
@@ -530,6 +528,7 @@ export async function statusPipelinesAsCodeLane(config: UniDeskConfig, options:
|
||||
command: "agentrun control-plane status",
|
||||
mode: "pipelines-as-code-migrated-lane",
|
||||
configPath: target.configPath,
|
||||
readCaptureBudget: spec.status.readOnlyCapture,
|
||||
target: options.full || options.raw ? agentRunLaneSummary(spec) : compactAgentRunLaneStatusTarget(spec),
|
||||
summary,
|
||||
alignment: {
|
||||
@@ -642,8 +641,8 @@ export async function statusYamlLane(config: UniDeskConfig, options: StatusOptio
|
||||
if (deliveryAuthority.kind === "pac-pr-merge") return await statusPipelinesAsCodeLane(config, options, target, deliveryAuthority);
|
||||
if (deliveryAuthority.kind === "unknown") return unknownDeliveryAuthorityStatus(options, target, deliveryAuthority);
|
||||
const sourceProbe = await timedStatusStage("source", () => spec.source.statusMode === "k3s-git-mirror"
|
||||
? capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneK3sSourceStatusScript(spec)], { runtimeTimeoutMs: agentRunStatusCaptureTimeoutMs })
|
||||
: capture(config, `${spec.nodeRoute}:${spec.source.workspace}`, ["sh", "--", yamlLaneSourceStatusScript(spec)], { runtimeTimeoutMs: agentRunStatusCaptureTimeoutMs }));
|
||||
? capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneK3sSourceStatusScript(spec)], { runtimeTimeoutMs: spec.status.readOnlyCapture.timeoutMs })
|
||||
: capture(config, `${spec.nodeRoute}:${spec.source.workspace}`, ["sh", "--", yamlLaneSourceStatusScript(spec)], { runtimeTimeoutMs: spec.status.readOnlyCapture.timeoutMs }));
|
||||
const sourcePayload = captureJsonPayload(sourceProbe.value);
|
||||
const branchTipCommit = stringOrNull(sourcePayload.remoteBranchCommit) ?? stringOrNull(sourcePayload.localHead);
|
||||
const initialSourceCommit = options.sourceCommit
|
||||
@@ -651,8 +650,8 @@ export async function statusYamlLane(config: UniDeskConfig, options: StatusOptio
|
||||
?? stringOrNull(sourcePayload.localHead);
|
||||
const pipelineRunName = options.pipelineRun ?? (initialSourceCommit ? agentRunPipelineRunName(spec, initialSourceCommit) : null);
|
||||
const [runtimeProbe, mirrorProbe] = await Promise.all([
|
||||
timedStatusStage("runtime", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneRuntimeStatusScript(spec, pipelineRunName)], { runtimeTimeoutMs: agentRunStatusCaptureTimeoutMs })),
|
||||
timedStatusStage("git-mirror", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneGitMirrorStatusScript(spec)], { runtimeTimeoutMs: agentRunStatusCaptureTimeoutMs })),
|
||||
timedStatusStage("runtime", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneRuntimeStatusScript(spec, pipelineRunName)], { runtimeTimeoutMs: spec.status.readOnlyCapture.timeoutMs })),
|
||||
timedStatusStage("git-mirror", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneGitMirrorStatusScript(spec)], { runtimeTimeoutMs: spec.status.readOnlyCapture.timeoutMs })),
|
||||
]);
|
||||
const runtimePayload = captureJsonPayload(runtimeProbe.value);
|
||||
const mirrorPayload = captureJsonPayload(mirrorProbe.value);
|
||||
@@ -904,6 +903,7 @@ export async function statusYamlLane(config: UniDeskConfig, options: StatusOptio
|
||||
command: "agentrun control-plane status",
|
||||
mode: "yaml-declared-node-lane",
|
||||
configPath: target.configPath,
|
||||
readCaptureBudget: spec.status.readOnlyCapture,
|
||||
target: options.full || options.raw ? agentRunLaneSummary(spec) : compactAgentRunLaneStatusTarget(spec),
|
||||
summary: options.full || options.raw ? detailedSummary : commanderSummary,
|
||||
alignment: {
|
||||
|
||||
@@ -64,6 +64,7 @@ describe("PaC 失败证据合同", () => {
|
||||
parsed: null,
|
||||
elapsedMs: 25001,
|
||||
timeoutMs: 25000,
|
||||
configPath: "config/platform-infra/pipelines-as-code.yaml#observability.readOnlyCapture.timeoutMs",
|
||||
next: "bun scripts/cli.ts platform-infra pipelines-as-code history --target NC01 --consumer agentrun-nc01-v02 --limit 5",
|
||||
});
|
||||
expect(observation).toMatchObject({
|
||||
@@ -74,6 +75,7 @@ describe("PaC 失败证据合同", () => {
|
||||
stage: "history-remote-observe",
|
||||
elapsedMs: 25001,
|
||||
timeoutMs: 25000,
|
||||
configPath: "config/platform-infra/pipelines-as-code.yaml#observability.readOnlyCapture.timeoutMs",
|
||||
exitCode: 124,
|
||||
firstBreak: { code: "pac-read-timeout", phase: "remote-read" },
|
||||
});
|
||||
@@ -81,6 +83,7 @@ describe("PaC 失败证据合同", () => {
|
||||
expect(output).toContain("READ OBSERVATION");
|
||||
expect(output).toContain("history-remote-observe");
|
||||
expect(output).toContain("pac-read-timeout");
|
||||
expect(output).toContain("config/platform-infra/pipelines-as-code.yaml#observability.readOnlyCapture.timeoutMs");
|
||||
expect(output).toContain("next-read-only:");
|
||||
});
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ const remoteScriptFile = rootPath("scripts", "src", "platform-infra-pipelines-as
|
||||
const evaluatorFile = rootPath("scripts", "native", "cicd", "pac-status-evaluator.cjs");
|
||||
const sourceArtifactRuntimeObserverFile = rootPath("scripts", "native", "cicd", "pac-source-artifact-runtime.mjs");
|
||||
const fieldManager = "unidesk-platform-infra-pipelines-as-code";
|
||||
const pacReadOnlyCaptureTimeoutMs = 25_000;
|
||||
const y = createYamlFieldReader(configLabel);
|
||||
|
||||
function kubernetesLabelValue(value: string): string {
|
||||
@@ -111,6 +110,10 @@ export interface PacConfig {
|
||||
deliveryTiming: PacDeliveryTimingPolicy;
|
||||
observability: {
|
||||
configRef: string;
|
||||
readOnlyCapture: {
|
||||
timeoutMs: number;
|
||||
configPath: string;
|
||||
};
|
||||
tracesEndpoint: string;
|
||||
serviceName: string;
|
||||
propagation: string[];
|
||||
@@ -530,6 +533,7 @@ export function parsePacConfigDocument(
|
||||
const display = y.objectField(root, "display", "");
|
||||
const deliveryTiming = y.objectField(root, "deliveryTiming", "");
|
||||
const observability = y.objectField(root, "observability", "");
|
||||
const readOnlyCapture = y.objectField(observability, "readOnlyCapture", "observability");
|
||||
const observabilitySampling = y.objectField(observability, "sampling", "observability");
|
||||
const exporterFailure = y.objectField(observability, "exporterFailure", "observability");
|
||||
const admin = y.objectField(gitea, "admin", "gitea");
|
||||
@@ -569,6 +573,10 @@ export function parsePacConfigDocument(
|
||||
},
|
||||
observability: {
|
||||
configRef: y.stringField(observability, "configRef", "observability"),
|
||||
readOnlyCapture: {
|
||||
timeoutMs: integerInRange(readOnlyCapture.timeoutMs, 1_000, 120_000, "observability.readOnlyCapture.timeoutMs"),
|
||||
configPath: `${configLabel}#observability.readOnlyCapture.timeoutMs`,
|
||||
},
|
||||
tracesEndpoint: urlField(observability, "tracesEndpoint", "observability"),
|
||||
serviceName: y.stringField(observability, "serviceName", "observability"),
|
||||
propagation: y.stringArrayField(observability, "propagation", "observability"),
|
||||
@@ -1371,7 +1379,7 @@ async function status(config: UniDeskConfig, options: CommonOptions): Promise<Re
|
||||
const repository = resolveRepository(pac, consumer.repositoryRef);
|
||||
const secrets = ensureSecrets(pac, false);
|
||||
const next = nextCommands(target.id, consumer.id, pac.defaults.consumerId);
|
||||
const observed = await capturePacReadOnly(config, "status", target, consumer, remoteScript("status", pac, target, repository, consumer, { ...options, confirm: false, dryRun: true, wait: false }, secrets, ""), `${stringValue(next.status)} --full`);
|
||||
const observed = await capturePacReadOnly(config, pac, "status", target, consumer, remoteScript("status", pac, target, repository, consumer, { ...options, confirm: false, dryRun: true, wait: false }, secrets, ""), `${stringValue(next.status)} --full`);
|
||||
const { result, parsed, observation } = observed;
|
||||
const summary = parsed === null ? null : statusSummary(parsed);
|
||||
const deliveryAuthority = resolveCicdDeliveryAuthority({ consumerId: consumer.id, node: consumer.node, lane: consumer.lane });
|
||||
@@ -1627,7 +1635,7 @@ async function history(config: UniDeskConfig, options: HistoryOptions): Promise<
|
||||
const next = selection.nextConsumerId === null
|
||||
? pacNodeReadOnlyNext(target.id)
|
||||
: pacReadOnlyNext(target.id, selection.nextConsumerId);
|
||||
const observed = await capturePacReadOnly(config, "history", target, firstConsumer, remoteScript("history", pac, target, firstRepository, firstConsumer, { ...options, confirm: false, dryRun: true, wait: false }, secrets, "", selectedConsumers), stringValue(record(next).history));
|
||||
const observed = await capturePacReadOnly(config, pac, "history", target, firstConsumer, remoteScript("history", pac, target, firstRepository, firstConsumer, { ...options, confirm: false, dryRun: true, wait: false }, secrets, "", selectedConsumers), stringValue(record(next).history));
|
||||
const { result, parsed, observation } = observed;
|
||||
const remote = parsed ?? compactCapture(result, { full: true });
|
||||
const historyErrors = arrayRecords(record(remote).historyErrors);
|
||||
@@ -1723,7 +1731,7 @@ async function debugStep(config: UniDeskConfig, options: HistoryOptions): Promis
|
||||
const consumer = resolveConsumer(pac, selection.selectedConsumerIds[0] ?? null);
|
||||
const repository = resolveRepository(pac, consumer.repositoryRef);
|
||||
const next = nextCommands(target.id, consumer.id, pac.defaults.consumerId);
|
||||
const observed = await capturePacReadOnly(config, "debug-step", target, consumer, remoteScript("debug-step", pac, target, repository, consumer, { ...options, confirm: false, dryRun: true, wait: false }, emptySecretMaterial(), ""), stringValue(next.status));
|
||||
const observed = await capturePacReadOnly(config, pac, "debug-step", target, consumer, remoteScript("debug-step", pac, target, repository, consumer, { ...options, confirm: false, dryRun: true, wait: false }, emptySecretMaterial(), ""), stringValue(next.status));
|
||||
const { result, parsed, observation } = observed;
|
||||
const fixtureChecks = parsed === null ? [] : arrayRecords(parsed.checks);
|
||||
const fixtureDisclosure = pacDebugFixtureDisclosure(fixtureChecks, options.detailId);
|
||||
@@ -1747,6 +1755,7 @@ async function debugStep(config: UniDeskConfig, options: HistoryOptions): Promis
|
||||
|
||||
async function capturePacReadOnly(
|
||||
config: UniDeskConfig,
|
||||
pac: PacConfig,
|
||||
action: PacReadOnlyAction,
|
||||
target: PacTarget,
|
||||
consumer: PacConsumer,
|
||||
@@ -1755,8 +1764,9 @@ async function capturePacReadOnly(
|
||||
): Promise<{ readonly result: Awaited<ReturnType<typeof capture>>; readonly parsed: Record<string, unknown> | null; readonly observation: PacReadOnlyCaptureObservation }> {
|
||||
const stage = `${action}-remote-observe`;
|
||||
const startedAt = Date.now();
|
||||
printPacReadOnlyProgress(target, consumer, stage, "started", startedAt, { timeoutMs: pacReadOnlyCaptureTimeoutMs });
|
||||
const result = await capture(config, target.route, ["sh"], script, { runtimeTimeoutMs: pacReadOnlyCaptureTimeoutMs });
|
||||
const captureBudget = pac.observability.readOnlyCapture;
|
||||
printPacReadOnlyProgress(target, consumer, stage, "started", startedAt, captureBudget);
|
||||
const result = await capture(config, target.route, ["sh"], script, { runtimeTimeoutMs: captureBudget.timeoutMs });
|
||||
const parsed = parseJsonOutput(result.stdout);
|
||||
const observation = pacReadOnlyCaptureObservation({
|
||||
action,
|
||||
@@ -1765,7 +1775,8 @@ async function capturePacReadOnly(
|
||||
result,
|
||||
parsed,
|
||||
elapsedMs: Date.now() - startedAt,
|
||||
timeoutMs: pacReadOnlyCaptureTimeoutMs,
|
||||
timeoutMs: captureBudget.timeoutMs,
|
||||
configPath: captureBudget.configPath,
|
||||
next,
|
||||
});
|
||||
printPacReadOnlyProgress(target, consumer, stage, observation.status, startedAt, {
|
||||
@@ -1783,6 +1794,7 @@ export function pacReadOnlyCaptureObservation(options: {
|
||||
readonly parsed: Record<string, unknown> | null;
|
||||
readonly elapsedMs: number;
|
||||
readonly timeoutMs: number;
|
||||
readonly configPath: string;
|
||||
readonly next: string;
|
||||
}): PacReadOnlyCaptureObservation {
|
||||
const stdoutBytes = Buffer.byteLength(options.result.stdout, "utf8");
|
||||
@@ -1806,6 +1818,7 @@ export function pacReadOnlyCaptureObservation(options: {
|
||||
stage: `${options.action}-remote-observe`,
|
||||
elapsedMs: options.elapsedMs,
|
||||
timeoutMs: options.timeoutMs,
|
||||
configPath: options.configPath,
|
||||
exitCode: options.result.exitCode,
|
||||
stdoutBytes,
|
||||
stderrBytes,
|
||||
@@ -2452,6 +2465,7 @@ function compactStatusJson(result: Record<string, unknown>): Record<string, unkn
|
||||
capabilities: record(result.config).capabilities,
|
||||
warnings: result.warnings,
|
||||
deliveryBudget: result.deliveryBudget,
|
||||
observation: result.observation,
|
||||
summary: compactStatusSummary(record(result.summary)),
|
||||
next: result.next,
|
||||
valuesPrinted: false,
|
||||
@@ -2575,6 +2589,7 @@ export function compactHistoryJson(result: Record<string, unknown>, includeTaskD
|
||||
consumers: result.consumers,
|
||||
detailId: result.detailId,
|
||||
deliveryBudget: result.deliveryBudget,
|
||||
observation: result.observation,
|
||||
rows: arrayRecords(result.rows).map((row) => {
|
||||
const taskRuns = record(row.taskRuns);
|
||||
const artifact = record(row.artifact);
|
||||
@@ -3125,6 +3140,7 @@ function renderPacReadObservation(result: Record<string, unknown>): string[] {
|
||||
boolText(observation.partial),
|
||||
stringValue(firstBreak.code),
|
||||
]]),
|
||||
` budget-config: ${stringValue(observation.configPath)}`,
|
||||
` next-read-only: ${stringValue(observation.next)}`,
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user