@zq-silk/yui 0.16.1 → 1.0.0-alpha
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/ARCHITECTURE.md +12 -0
- package/ARCHITECTURE.zh-CN.md +8 -0
- package/README.md +9 -4
- package/dist/agent/agent.js +4 -9
- package/dist/agent/executionComponents.js +4 -4
- package/dist/agent/managedRuntimeEnvironment.js +0 -4
- package/dist/agentRun/agentRun.js +13 -23
- package/dist/artifacts/managedGit.js +3 -56
- package/dist/brief/taskBrief.js +3 -3
- package/dist/cli/agentConfigurationPicker.js +24 -21
- package/dist/cli/commandCatalog.js +18 -10
- package/dist/cli/roleWizard.js +41 -30
- package/dist/cli/updateCommand.js +35 -13
- package/dist/cli/updateOrchestrator.js +73 -44
- package/dist/cli/updatePorts.js +76 -86
- package/dist/cli/upgradeCommand.js +4 -8
- package/dist/cli.js +39 -33
- package/dist/commands/controllerCommands.js +2 -2
- package/dist/commands/executionAuditCommands.js +2 -2
- package/dist/commands/projectCommands.js +1 -1
- package/dist/commands/releaseCommands.js +9 -38
- package/dist/commands/taskCommands.js +91 -81
- package/dist/commands/taskCompletionGate.js +0 -117
- package/dist/commands/taskRoleRuntimeStatus.js +2 -2
- package/dist/commands/taskUpstreamCommands.js +93 -54
- package/dist/context/runContextPack.js +30 -54
- package/dist/context/runInputContract.js +9 -0
- package/dist/context/sessionBootstrapManifest.js +11 -19
- package/dist/controller/agentHostObservation.js +4 -2
- package/dist/controller/agentRuntimeObserver.js +4 -4
- package/dist/controller/clientRuntime.js +19 -44
- package/dist/controller/controller.js +24 -10
- package/dist/controller/fileSchedulerStoreAdapter.js +91 -24
- package/dist/controller/globalInputDelivery.js +31 -8
- package/dist/controller/globalRuntimeAttention.js +34 -0
- package/dist/controller/jobSupervisor.js +3 -3
- package/dist/controller/operatorNotification.js +31 -0
- package/dist/controller/providerRetryAdmission.js +3 -1
- package/dist/controller/providerRetryDelivery.js +136 -119
- package/dist/controller/runtime.js +2 -28
- package/dist/controller/sessionOwnerReconciliation.js +42 -24
- package/dist/controller/structuredProviderObservation.js +28 -1
- package/dist/controller/updateReconciliation.js +72 -20
- package/dist/coordination/workMailbox.js +4 -4
- package/dist/core/controllerIdentity.js +25 -0
- package/dist/core/controllerProcessIdentity.js +2 -2
- package/dist/core/controllerServer.js +4 -2
- package/dist/core/protocol.js +1 -1
- package/dist/doctor/doctor.js +2 -1
- package/dist/domain/validation.js +6 -0
- package/dist/event/taskEvent.js +3 -3
- package/dist/execution/workItemExecution.js +2 -2
- package/dist/executor/agentAdapter.js +28 -96
- package/dist/executor/agentConfigurationCatalog.js +13 -68
- package/dist/executor/agentConfigurationFields.js +120 -0
- package/dist/executor/agentConfigurationProbe.js +55 -80
- package/dist/executor/agentExecutor.js +11 -8
- package/dist/executor/effectiveLaunch.js +3 -3
- package/dist/executor/executorRegistry.js +0 -9
- package/dist/executor/fileRoleLaunchPlanner.js +12 -11
- package/dist/grant/capabilityGrant.js +2 -2
- package/dist/input/inputRequest.js +4 -4
- package/dist/integration/changeSet.js +3 -3
- package/dist/integration/integrationAttempt.js +3 -3
- package/dist/integration/integrationSourceApplication.js +1 -1
- package/dist/interaction/operatorPresentation.js +2 -1
- package/dist/job/durableJob.js +1 -1
- package/dist/job/jobRunner.js +2 -2
- package/dist/message/message.js +8 -6
- package/dist/message/messageContinuation.js +8 -9
- package/dist/milestone/milestone.js +3 -3
- package/dist/observability/executionAudit.js +1 -10
- package/dist/observability/runtimeIdentity.js +0 -23
- package/dist/output/agentConfigurationPresentation.js +4 -2
- package/dist/profile/agentProfile.js +3 -3
- package/dist/release/releaseHandover.js +2 -2
- package/dist/release/releaseIdempotencyStore.js +0 -23
- package/dist/release/releaseWorkflowPorts.js +8 -4
- package/dist/release/runtimeRelease.js +9 -7
- package/dist/repository/gitWorkspace.js +66 -19
- package/dist/repository/project.js +3 -3
- package/dist/repository/taskWorkspacePreparer.js +75 -68
- package/dist/resources/liveReferences.js +1 -1
- package/dist/resources/resourceRegistry.js +90 -44
- package/dist/resources/sqliteResourceRegistry.js +5 -7
- package/dist/review/reviewRound.js +5 -5
- package/dist/role/role.js +7 -8
- package/dist/runtime/acpProtocol.js +2 -3
- package/dist/runtime/acpSession.js +21 -5
- package/dist/runtime/agentDriverObservation.js +1 -1
- package/dist/runtime/agentEndpoint.js +4 -1
- package/dist/runtime/agentHost.js +25 -65
- package/dist/runtime/agentHostCleanup.js +85 -0
- package/dist/runtime/agentHostProtocol.js +3 -3
- package/dist/runtime/builtinAgentDrivers.js +46 -119
- package/dist/runtime/builtinTranscriptObserver.js +10 -6
- package/dist/runtime/codexAppServerRuntime.js +55 -89
- package/dist/runtime/codexInteractiveHost.js +1 -1
- package/dist/runtime/jsonLineChannel.js +35 -7
- package/dist/runtime/launchBroker.js +1 -1
- package/dist/runtime/processExitObservation.js +1 -1
- package/dist/runtime/providerContinuationReconciliationService.js +86 -38
- package/dist/runtime/providerRetry.js +15 -0
- package/dist/runtime/providerRuntimeIdentity.js +3 -3
- package/dist/runtime/providerRuntimeReconciler.js +12 -2
- package/dist/runtime/runtimeCoherence.js +7 -3
- package/dist/runtime/runtimeObservation.js +3 -3
- package/dist/runtime/sessionOwnerIdentity.js +1 -1
- package/dist/runtime/structuredProviderHost.js +106 -81
- package/dist/runtime/taskRuntimeIsolation.js +3 -3
- package/dist/runtime/tmuxAdapters.js +3 -3
- package/dist/scheduler/activeRoleRunDelivery.js +5 -1
- package/dist/scheduler/operatorInputNotificationProcessor.js +7 -17
- package/dist/scheduler/taskWake.js +1 -1
- package/dist/storage/baselineSchema.js +606 -0
- package/dist/storage/homeLayout.js +5 -16
- package/dist/storage/recordValidation.js +16 -4
- package/dist/storage/sqliteSchema.js +106 -1741
- package/dist/storage/sqliteStore.js +16 -14
- package/dist/storage/storageSchema.js +8 -7
- package/dist/storage/storageVersions.js +23 -16
- package/dist/storage/taskStore.js +3 -29
- package/dist/storage/upgrade/upgradeOrchestrator.js +14 -112
- package/dist/task/nextAction.js +33 -23
- package/dist/task/task.js +17 -8
- package/dist/task/taskActivation.js +5 -4
- package/dist/telemetry/sqliteTelemetryStore.js +2 -2
- package/dist/verification/gateArtifact.js +5 -3
- package/dist/verification/verificationPlan.js +6 -7
- package/dist/web/assets/assetManifest.js +2 -0
- package/dist/web/assets/client/app.js +72 -3
- package/dist/web/assets/client/components.js +2 -1
- package/dist/web/assets/client/i18n.js +2 -0
- package/dist/web/assets/client/taskSummary.js +345 -0
- package/dist/web/assets/client/taskSurface.js +44 -26
- package/dist/web/assets/client/view.js +33 -0
- package/dist/web/assets/shell.js +1 -0
- package/dist/web/assets/styles/cards.js +21 -0
- package/dist/web/webServer.js +39 -5
- package/dist/web/webSessions.js +165 -0
- package/dist/web/webSnapshot.js +23 -0
- package/dist/web/webTaskSurface.js +23 -0
- package/dist/workItem/workItem.js +6 -6
- package/dist/workspace/cleanupInspection.js +1 -9
- package/dist/worktree/managedWorkspace.js +3 -3
- package/docs/managed-turn-and-session-runtime.md +50 -7
- package/docs/managed-turn-and-session-runtime.zh-CN.md +36 -5
- package/docs/observability/README.md +47 -0
- package/docs/observability/README.zh-CN.md +37 -0
- package/docs/project-refresh.md +9 -0
- package/docs/project-refresh.zh-CN.md +8 -0
- package/docs/provider-retry.md +35 -0
- package/docs/release-workflow.md +70 -214
- package/docs/release-workflow.zh-CN.md +53 -157
- package/docs/roles-and-configuration.md +30 -0
- package/docs/roles-and-configuration.zh-CN.md +20 -0
- package/docs/sqlite-control-plane-design.md +48 -289
- package/docs/sqlite-control-plane-design.zh-CN.md +37 -53
- package/docs/storage-baseline.md +132 -0
- package/docs/storage-baseline.zh-CN.md +106 -0
- package/docs/task-delivery.md +110 -2
- package/docs/task-delivery.zh-CN.md +82 -2
- package/docs/task-discovery.md +9 -0
- package/docs/task-discovery.zh-CN.md +6 -0
- package/docs/testing/verification-levels.md +42 -164
- package/docs/testing/verification-levels.zh-CN.md +29 -115
- package/i18n/README.zh-CN.md +7 -4
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +11 -0
- package/skills/yui-leader/references/execution.md +22 -0
- package/skills/yui-leader/references/planning.md +6 -2
- package/skills/yui-operator/SKILL.md +45 -13
- package/skills/yui-operator/references/task-delivery.md +99 -0
- package/skills/yui-runtime/SKILL.md +5 -3
- package/skills/yui-runtime/references/publication.md +56 -5
- package/skills/yui-runtime/references/recovery.md +12 -2
- package/dist/runtime/agentHostCompatibility.js +0 -127
- package/dist/storage/migrations/agentFailureContext.js +0 -22
- package/dist/storage/migrations/agentRunContract.js +0 -159
- package/dist/storage/migrations/artifactsToGit.js +0 -338
- package/dist/storage/migrations/collapseWorktreeLayout.js +0 -963
- package/dist/storage/migrations/currentInputContract.js +0 -86
- package/dist/storage/migrations/currentRuntimeContract.js +0 -228
- package/dist/storage/migrations/historicalVerificationPlan.js +0 -35
- package/dist/storage/migrations/integrationContinuation.js +0 -105
- package/dist/storage/migrations/narrowAgentFailureContext.js +0 -65
- package/dist/storage/migrations/notificationOnlyWakes.js +0 -74
- package/dist/storage/migrations/removeRuntimeGeneration.js +0 -207
- package/dist/storage/migrations/submitIntent.js +0 -126
- package/dist/storage/migrations/unifyHomeLayout.js +0 -925
- package/dist/storage/migrations/verificationPlanV1.js +0 -162
- package/dist/storage/migrations/verificationPolicy.js +0 -74
- package/dist/storage/migrations/workItemHistory.js +0 -46
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// These are Yui's accepted configuration values, not a native capability probe.
|
|
2
|
+
// Keep existing explicit configuration legal; current native choices come from
|
|
3
|
+
// help and requirements, and may be a smaller set.
|
|
4
|
+
export const CODEX_SANDBOXES = ["read-only", "workspace-write", "danger-full-access"];
|
|
5
|
+
export const CODEX_APPROVALS = ["untrusted", "on-request", "never"];
|
|
6
|
+
export const STATIC_CONFIGURATION_NOTICE = "Static adapter configuration contracts are not native enumeration or proof of Provider acceptance; see field reasons.";
|
|
7
|
+
export function staticAgentConfigurationFields(id) {
|
|
8
|
+
const fields = [
|
|
9
|
+
staticField("model", [], true, "Model values require native metadata; custom IDs remain explicit input."),
|
|
10
|
+
staticField("effort", [], true, "Effort values depend on the selected native model."),
|
|
11
|
+
staticField("permission.strategy", ["default", "bypass", "configured"], false, "These are Yui strategies, not Provider modes.")
|
|
12
|
+
];
|
|
13
|
+
if (id === "codex")
|
|
14
|
+
return [
|
|
15
|
+
...fields,
|
|
16
|
+
staticField("permission.sandbox", CODEX_SANDBOXES, false),
|
|
17
|
+
staticField("permission.approval", CODEX_APPROVALS, false, "Native versions may retire values accepted by the adapter."),
|
|
18
|
+
staticField("search", ["true"], false),
|
|
19
|
+
staticField("profile", [], true),
|
|
20
|
+
staticField("additionalDirectories", [], true)
|
|
21
|
+
];
|
|
22
|
+
if (id === "acp")
|
|
23
|
+
return [
|
|
24
|
+
...fields,
|
|
25
|
+
staticField("permission.mode", [], true, "Mode IDs are enumerated per Session and checked at launch."),
|
|
26
|
+
staticField("additionalDirectories", [], true, "Delivery requires the Agent's initialize capability; it is unverified offline.")
|
|
27
|
+
];
|
|
28
|
+
return [
|
|
29
|
+
...fields,
|
|
30
|
+
staticField("permission.mode", [], true, "No native modes were enumerated."),
|
|
31
|
+
staticField("permission.allowedTools", [], true),
|
|
32
|
+
staticField("permission.disallowedTools", [], true),
|
|
33
|
+
staticField("settingsSources", ["user", "project", "local"], false),
|
|
34
|
+
staticField("settingsFile", [], true),
|
|
35
|
+
staticField("additionalDirectories", [], true)
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
function staticField(key, values, allowCustom, detail = "") {
|
|
39
|
+
return {
|
|
40
|
+
key, choices: values.map(value => ({ value, label: value })), allowCustom,
|
|
41
|
+
reason: `Static adapter configuration contract; native support is unverified.${detail ? ` ${detail}` : ""}`
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** One help interpretation shared by installation inspection and live probes. */
|
|
45
|
+
export function configurationFieldsFromHelp(id, help) {
|
|
46
|
+
const fields = staticAgentConfigurationFields(id);
|
|
47
|
+
if (id === "acp")
|
|
48
|
+
return fields;
|
|
49
|
+
const bypassFlag = id === "codex"
|
|
50
|
+
? "--dangerously-bypass-approvals-and-sandbox" : "--dangerously-skip-permissions";
|
|
51
|
+
const replacements = [
|
|
52
|
+
{
|
|
53
|
+
...staticField("permission.strategy", [
|
|
54
|
+
"default", ...(configurationFlagAvailable(help, bypassFlag) ? ["bypass"] : []), "configured"
|
|
55
|
+
], false),
|
|
56
|
+
reason: `Static Yui strategies; ${bypassFlag} ${configurationFlagAvailable(help, bypassFlag) ? "reported" : "not reported"} by native --help. This does not confirm account policy.`
|
|
57
|
+
},
|
|
58
|
+
...(id === "codex"
|
|
59
|
+
? [
|
|
60
|
+
helpChoiceField("permission.sandbox", help, "--sandbox", false, CODEX_SANDBOXES),
|
|
61
|
+
helpChoiceField("permission.approval", help, "--ask-for-approval", false, CODEX_APPROVALS)
|
|
62
|
+
]
|
|
63
|
+
: [
|
|
64
|
+
helpChoiceField("permission.mode", help, "--permission-mode", true),
|
|
65
|
+
helpChoiceField("effort", help, "--effort", true),
|
|
66
|
+
// The CLI's description often names settings sources without an enum.
|
|
67
|
+
// Retain the explicit static contract, never relabel it as discovery.
|
|
68
|
+
...(configurationHelpChoices(help, "--setting-sources").length === 0 ? []
|
|
69
|
+
: [helpChoiceField("settingsSources", help, "--setting-sources", false)])
|
|
70
|
+
])
|
|
71
|
+
];
|
|
72
|
+
const byKey = new Map(replacements.map(value => [value.key, value]));
|
|
73
|
+
return fields.map(value => byKey.get(value.key) ?? value);
|
|
74
|
+
}
|
|
75
|
+
function helpChoiceField(key, help, flag, allowCustom, supported) {
|
|
76
|
+
const reported = configurationHelpChoices(help, flag);
|
|
77
|
+
const values = supported === undefined ? reported : reported.filter(value => supported.includes(value));
|
|
78
|
+
return {
|
|
79
|
+
key, choices: values.map(value => ({ value, label: value })), allowCustom,
|
|
80
|
+
available: values.length > 0,
|
|
81
|
+
reason: values.length > 0
|
|
82
|
+
? `Native --help ${flag} enumeration${supported === undefined ? "" : ", limited to adapter-supported values"}.`
|
|
83
|
+
: `Native enumeration unavailable: ${flag} values were not reported or are not supported by this adapter.`
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export function configurationFieldWarnings(fields) {
|
|
87
|
+
return [
|
|
88
|
+
STATIC_CONFIGURATION_NOTICE,
|
|
89
|
+
...fields.filter(field => field.available === false)
|
|
90
|
+
.map(field => `${field.key}: ${field.reason ?? "Native capability unavailable."}`)
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
/** Read only an explicit native enum. Prose examples and missing fields are not choices. */
|
|
94
|
+
export function configurationHelpChoices(help, flag) {
|
|
95
|
+
const section = helpSection(help, flag);
|
|
96
|
+
if (section === undefined)
|
|
97
|
+
return [];
|
|
98
|
+
const inline = /(?:\[possible values:\s*([^\]]+)\]|\(choices:\s*([^)]*)\))/i.exec(section);
|
|
99
|
+
const declared = inline?.[1] ?? inline?.[2];
|
|
100
|
+
const bullets = declared === undefined && /Possible values:/i.test(section)
|
|
101
|
+
? [...section.matchAll(/^\s*-\s*([\w.+-]+)\s*:/gm)].map(match => match[1] ?? "")
|
|
102
|
+
: [];
|
|
103
|
+
return [...new Set((declared ?? bullets.join(",")).replace(/["']/g, "").split(",")
|
|
104
|
+
.map(value => value.trim().replace(/\.$/, "")).filter(value => /^[\w.+-]+$/.test(value)))];
|
|
105
|
+
}
|
|
106
|
+
export function configurationFlagAvailable(help, flag) {
|
|
107
|
+
return helpSection(help, flag) !== undefined;
|
|
108
|
+
}
|
|
109
|
+
function helpSection(help, flag) {
|
|
110
|
+
const lines = help.replace(/\r\n/g, "\n").split("\n");
|
|
111
|
+
const escaped = flag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
112
|
+
const declaration = new RegExp(`^\\s*(?:-[A-Za-z],?\\s+)?${escaped}(?=[\\s=,<\\[]|$)`);
|
|
113
|
+
const start = lines.findIndex(line => declaration.test(line));
|
|
114
|
+
if (start < 0)
|
|
115
|
+
return undefined;
|
|
116
|
+
let end = start + 1;
|
|
117
|
+
while (end < lines.length && !/^\s*(?:-[A-Za-z],?\s+|--)[\w-]/.test(lines[end]))
|
|
118
|
+
end++;
|
|
119
|
+
return lines.slice(start, end).join("\n");
|
|
120
|
+
}
|
|
@@ -9,6 +9,7 @@ import { codexClientInitialization } from "../runtime/codexAppServerRuntime.js";
|
|
|
9
9
|
import { acpInitializeRequest, readAcpInitializeResult } from "../runtime/acpProtocol.js";
|
|
10
10
|
import { handshakeObservationFrom } from "../runtime/agentRunConfiguration.js";
|
|
11
11
|
import { YUI_VERSION } from "../version.js";
|
|
12
|
+
import { configurationFieldsFromHelp, configurationFieldWarnings, STATIC_CONFIGURATION_NOTICE } from "./agentConfigurationFields.js";
|
|
12
13
|
/**
|
|
13
14
|
* Codex and Claude Code are configured by flags and their own files; neither
|
|
14
15
|
* plan exchanges capabilities on connect. Saying so explicitly keeps a caller
|
|
@@ -20,8 +21,6 @@ const NO_HANDSHAKE = Object.freeze({
|
|
|
20
21
|
});
|
|
21
22
|
const MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
22
23
|
const PROCESS_TERMINATION_GRACE_MS = 100;
|
|
23
|
-
const CODEX_SANDBOXES = ["read-only", "workspace-write", "danger-full-access"];
|
|
24
|
-
const CODEX_APPROVALS = ["untrusted", "on-request", "never"];
|
|
25
24
|
const ACP_PROBE_REQUEST_ID = 1;
|
|
26
25
|
export async function discoverCodexConfiguration(input) {
|
|
27
26
|
const environment = configuredAgentLaunchEnvironment(input.agent, input.environment);
|
|
@@ -43,17 +42,35 @@ export async function discoverCodexConfiguration(input) {
|
|
|
43
42
|
client.request("configRequirements/read", {}),
|
|
44
43
|
client.request("modelProvider/capabilities/read", {})
|
|
45
44
|
]);
|
|
46
|
-
const requirements =
|
|
47
|
-
const requirementRecord =
|
|
45
|
+
const requirements = requiredObject(requirementsResult, "Codex configuration requirements response").requirements;
|
|
46
|
+
const requirementRecord = requirements === null ? undefined
|
|
47
|
+
: requiredObject(requirements, "Codex configuration requirements");
|
|
48
48
|
const allowedSandboxes = optionalStrings(requirementRecord?.allowedSandboxModes);
|
|
49
|
-
const allowedApprovals =
|
|
49
|
+
const allowedApprovals = optionalApprovalChoices(requirementRecord?.allowedApprovalPolicies);
|
|
50
50
|
const allowedWebSearchModes = optionalStrings(requirementRecord?.allowedWebSearchModes);
|
|
51
|
-
const capabilityRecord =
|
|
52
|
-
|
|
51
|
+
const capabilityRecord = requiredObject(providerCapabilities, "Codex Provider capabilities");
|
|
52
|
+
if (typeof capabilityRecord.webSearch !== "boolean") {
|
|
53
|
+
throw new Error("Codex Provider capabilities did not report webSearch.");
|
|
54
|
+
}
|
|
55
|
+
const webSearch = capabilityRecord.webSearch
|
|
53
56
|
&& (allowedWebSearchModes === undefined || allowedWebSearchModes.includes("live"));
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
const fields = configurationFieldsFromHelp("codex", help).map(candidate => {
|
|
58
|
+
const allowed = candidate.key === "permission.sandbox" ? allowedSandboxes
|
|
59
|
+
: candidate.key === "permission.approval" ? allowedApprovals : undefined;
|
|
60
|
+
if (allowed !== undefined) {
|
|
61
|
+
const choices = candidate.choices.filter(choice => allowed.includes(choice.value));
|
|
62
|
+
return {
|
|
63
|
+
...candidate, choices, available: choices.length > 0,
|
|
64
|
+
reason: `${candidate.reason} Native configuration requirements applied.${choices.length === 0 ? " No usable values were confirmed." : ""}`
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (candidate.key === "search")
|
|
68
|
+
return field("search", webSearch ? [choice("true")] : [], false, webSearch, webSearch ? "Native Provider capability and configuration requirements permit live web search."
|
|
69
|
+
: "Live web search is unavailable or disallowed.");
|
|
70
|
+
if (candidate.key === "profile")
|
|
71
|
+
return codexProfileField(environment);
|
|
72
|
+
return candidate;
|
|
73
|
+
});
|
|
57
74
|
return {
|
|
58
75
|
schemaVersion: 1,
|
|
59
76
|
agentId: input.agent.id,
|
|
@@ -61,21 +78,8 @@ export async function discoverCodexConfiguration(input) {
|
|
|
61
78
|
...(semanticVersion(version) === undefined ? {} : { cliVersion: semanticVersion(version) }),
|
|
62
79
|
handshake: NO_HANDSHAKE,
|
|
63
80
|
models,
|
|
64
|
-
fields
|
|
65
|
-
|
|
66
|
-
field("effort", [], true),
|
|
67
|
-
field("permission.strategy", [
|
|
68
|
-
choice("default"),
|
|
69
|
-
...(bypass ? [choice("bypass")] : []),
|
|
70
|
-
choice("configured")
|
|
71
|
-
], false, true, bypass ? undefined : "Codex bypass strategy is unavailable."),
|
|
72
|
-
field("permission.sandbox", sandboxChoices.map(choice), false),
|
|
73
|
-
field("permission.approval", approvalChoices.map(choice), false),
|
|
74
|
-
field("search", webSearch ? [choice("true")] : [], false, webSearch, webSearch ? undefined : "Live web search is unavailable or disallowed."),
|
|
75
|
-
field("profile", codexProfileChoices(environment).map(choice), true),
|
|
76
|
-
field("additionalDirectories", [], true)
|
|
77
|
-
],
|
|
78
|
-
warnings: client.warnings()
|
|
81
|
+
fields,
|
|
82
|
+
warnings: [...client.warnings(), ...configurationFieldWarnings(fields)]
|
|
79
83
|
};
|
|
80
84
|
}
|
|
81
85
|
finally {
|
|
@@ -105,9 +109,7 @@ export async function discoverClaudeConfiguration(input) {
|
|
|
105
109
|
]);
|
|
106
110
|
const initialized = object(initialization);
|
|
107
111
|
const models = array(initialized?.models, "Claude model catalog").map(claudeModel);
|
|
108
|
-
const
|
|
109
|
-
const bypass = configurationFlagAvailable(help, "--dangerously-skip-permissions");
|
|
110
|
-
const settingsSources = configurationHelpChoices(help, "--setting-sources", ["user", "project", "local"]);
|
|
112
|
+
const fields = configurationFieldsFromHelp("claude", help);
|
|
111
113
|
return {
|
|
112
114
|
schemaVersion: 1,
|
|
113
115
|
agentId: input.agent.id,
|
|
@@ -115,22 +117,8 @@ export async function discoverClaudeConfiguration(input) {
|
|
|
115
117
|
...(semanticVersion(version) === undefined ? {} : { cliVersion: semanticVersion(version) }),
|
|
116
118
|
handshake: NO_HANDSHAKE,
|
|
117
119
|
models,
|
|
118
|
-
fields
|
|
119
|
-
|
|
120
|
-
field("effort", [], true),
|
|
121
|
-
field("permission.strategy", [
|
|
122
|
-
choice("default"),
|
|
123
|
-
...(bypass ? [choice("bypass")] : []),
|
|
124
|
-
choice("configured")
|
|
125
|
-
], false, true, bypass ? undefined : "Claude bypass strategy is unavailable."),
|
|
126
|
-
field("permission.mode", permissionModes.map(choice), true),
|
|
127
|
-
field("permission.allowedTools", [], true),
|
|
128
|
-
field("permission.disallowedTools", [], true),
|
|
129
|
-
field("settingsSources", settingsSources.map(choice), false),
|
|
130
|
-
field("settingsFile", [], true),
|
|
131
|
-
field("additionalDirectories", [], true)
|
|
132
|
-
],
|
|
133
|
-
warnings: []
|
|
120
|
+
fields,
|
|
121
|
+
warnings: configurationFieldWarnings(fields)
|
|
134
122
|
};
|
|
135
123
|
}
|
|
136
124
|
async function listCodexModels(client) {
|
|
@@ -283,7 +271,7 @@ async function requestClaudeInitialization(command, args, cwd, environment, sign
|
|
|
283
271
|
export async function discoverAcpConfiguration(input) {
|
|
284
272
|
const environment = configuredAgentLaunchEnvironment(input.agent, input.environment);
|
|
285
273
|
const negotiated = await requestAcpInitialization(input.agent.command, [...input.agent.baseArgs], input.cwd, environment, input.signal);
|
|
286
|
-
const warnings = [];
|
|
274
|
+
const warnings = [STATIC_CONFIGURATION_NOTICE];
|
|
287
275
|
if (!negotiated.capabilities.loadSession) {
|
|
288
276
|
warnings.push("This ACP Agent does not support `session/load`, so a managed Yui Turn "
|
|
289
277
|
+ "cannot survive a Provider restart.");
|
|
@@ -331,7 +319,7 @@ export async function discoverAcpConfiguration(input) {
|
|
|
331
319
|
field("effort", [], true, true, "ACP selects reasoning effort with session/set_config_option, under the "
|
|
332
320
|
+ "`thought_level` category. As with the model, the accepted values are "
|
|
333
321
|
+ "negotiated per Session and verified at launch rather than listed here."),
|
|
334
|
-
field("permission.strategy", [choice("default"), choice("bypass"), choice("configured")], false, true, "`default` sends no mode, so the Agent's own default stands. `configured` "
|
|
322
|
+
field("permission.strategy", [choice("default"), choice("bypass"), choice("configured")], false, true, "Static Yui strategies: `default` sends no mode, so the Agent's own default stands. `configured` "
|
|
335
323
|
+ "selects one exact mode the Agent offers. `bypass` applies the mode that "
|
|
336
324
|
+ "grants unattended action, and only for an execution component Yui can "
|
|
337
325
|
+ "identify — it is never guessed from a mode's name. None of these change "
|
|
@@ -573,47 +561,34 @@ function terminateProcess(child) {
|
|
|
573
561
|
child.once("exit", () => { clearTimeout(force); });
|
|
574
562
|
child.kill("SIGTERM");
|
|
575
563
|
}
|
|
576
|
-
|
|
564
|
+
function codexProfileField(environment) {
|
|
577
565
|
const root = environment.CODEX_HOME
|
|
578
566
|
?? join(environment.HOME ?? homedir(), ".codex");
|
|
579
567
|
try {
|
|
580
568
|
const profiles = object(parse(readFileSync(join(root, "config.toml"), "utf8")).profiles);
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
catch {
|
|
584
|
-
return [];
|
|
569
|
+
const names = Object.keys(profiles ?? {}).filter((name) => name.trim().length > 0 && !name.includes("\0")).sort();
|
|
570
|
+
return field("profile", names.map(choice), true, undefined, "Local config.toml profile names, not a Provider enumeration; custom names remain explicit input.");
|
|
585
571
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
return [...fallback];
|
|
592
|
-
let end = start + 1;
|
|
593
|
-
while (end < lines.length && !/^\s{2,}(?:-[A-Za-z](?:,\s*)?|--)[\w-]/.test(lines[end] ?? "")) {
|
|
594
|
-
end += 1;
|
|
572
|
+
catch (error) {
|
|
573
|
+
const absent = error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
574
|
+
return field("profile", [], true, absent ? undefined : false, absent
|
|
575
|
+
? "No local config.toml; no profile names observed. Custom names remain explicit input."
|
|
576
|
+
: "Local config.toml could not be read or parsed; profile enumeration unavailable.");
|
|
595
577
|
}
|
|
596
|
-
const section = lines.slice(start, end).join("\n");
|
|
597
|
-
const inline = /(?:\[possible values:\s*([^\]]+)\]|\(choices:\s*([^)]*)\))/i
|
|
598
|
-
.exec(section);
|
|
599
|
-
const declared = inline?.[1] ?? inline?.[2];
|
|
600
|
-
const bulletValues = declared === undefined && /Possible values:/i.test(section)
|
|
601
|
-
? [...section.matchAll(/^\s*-\s*([\w.+-]+)\s*:/gm)].map((match) => match[1] ?? "")
|
|
602
|
-
: [];
|
|
603
|
-
const parsed = [...new Set((declared ?? bulletValues.join(","))
|
|
604
|
-
.replace(/["']/g, "")
|
|
605
|
-
.split(",")
|
|
606
|
-
.map((value) => value.trim().replace(/\.$/, ""))
|
|
607
|
-
.filter((value) => /^[\w.+-]+$/.test(value)))];
|
|
608
|
-
return parsed.length === 0 ? [...fallback] : parsed;
|
|
609
|
-
}
|
|
610
|
-
function configurationFlagAvailable(help, flag) {
|
|
611
|
-
return help.replace(/\r\n/g, "\n").split("\n").some((line) => line.includes(flag));
|
|
612
578
|
}
|
|
613
|
-
function
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
579
|
+
function optionalApprovalChoices(value) {
|
|
580
|
+
if (value === null || value === undefined)
|
|
581
|
+
return undefined;
|
|
582
|
+
// Current Codex also reports structured granular policies. They constrain
|
|
583
|
+
// configuration but cannot be selected by Yui's scalar approval input; do not
|
|
584
|
+
// reject the whole legitimate response or expand them into guessed aliases.
|
|
585
|
+
return array(value, "configuration approval requirements").flatMap(entry => {
|
|
586
|
+
if (typeof entry === "string")
|
|
587
|
+
return [requiredString(entry, "approval requirement")];
|
|
588
|
+
if (object(object(entry)?.granular) !== undefined)
|
|
589
|
+
return [];
|
|
590
|
+
throw new Error("Codex configuration approval requirement is invalid.");
|
|
591
|
+
});
|
|
617
592
|
}
|
|
618
593
|
function optionalStrings(value) {
|
|
619
594
|
if (value === null || value === undefined)
|
|
@@ -7,7 +7,7 @@ import { builtinAgentEndpointImplementation, validateAgentEndpointImplementation
|
|
|
7
7
|
/** Recovery addresses retained execution identity, not a live Session grant.
|
|
8
8
|
* A released Session cache can be absent while its native binding still needs
|
|
9
9
|
* to be stopped. No active Session record is fabricated by this projection. */
|
|
10
|
-
export function
|
|
10
|
+
export function roleSessionControlTarget(set) {
|
|
11
11
|
if (set == null)
|
|
12
12
|
return undefined;
|
|
13
13
|
const current = set.sessions[set.activeAgentId];
|
|
@@ -19,7 +19,10 @@ export function taskRoleControlTarget(set) {
|
|
|
19
19
|
const agentId = fromBinding ? binding.accountScope : current?.agentId;
|
|
20
20
|
if (nativeSessionId === undefined || agentId === undefined)
|
|
21
21
|
return undefined;
|
|
22
|
-
const
|
|
22
|
+
const history = set.owner.scope === "global"
|
|
23
|
+
? Object.values(set.history ?? {})
|
|
24
|
+
: set.history ?? [];
|
|
25
|
+
const session = [...Object.values(set.sessions), ...history]
|
|
23
26
|
.find(entry => entry.nativeSessionId === nativeSessionId && entry.agentId === agentId);
|
|
24
27
|
const adapterId = session?.adapterId ?? (binding === null ? undefined : builtinAgentDriverRegistry().find(binding.providerNamespace)?.adapterId);
|
|
25
28
|
return { nativeSessionId, agentId, adapterId, status: session?.status,
|
|
@@ -33,10 +36,10 @@ export function createRoleSessionSet(owner, activeAgentId, now) {
|
|
|
33
36
|
updatedAt: now.toISOString()
|
|
34
37
|
};
|
|
35
38
|
return owner.scope === "global"
|
|
36
|
-
? { ...base, schemaVersion:
|
|
39
|
+
? { ...base, schemaVersion: 1, providerBinding: null }
|
|
37
40
|
: {
|
|
38
41
|
...base,
|
|
39
|
-
schemaVersion:
|
|
42
|
+
schemaVersion: 1,
|
|
40
43
|
providerBinding: null
|
|
41
44
|
};
|
|
42
45
|
}
|
|
@@ -103,7 +106,7 @@ export function recordRoleAgentSession(set, input, now) {
|
|
|
103
106
|
throw new Error("A native Session cannot change its Endpoint implementation in place.");
|
|
104
107
|
}
|
|
105
108
|
const session = {
|
|
106
|
-
schemaVersion:
|
|
109
|
+
schemaVersion: 1,
|
|
107
110
|
agentId,
|
|
108
111
|
adapterId,
|
|
109
112
|
nativeSessionId,
|
|
@@ -461,7 +464,7 @@ export function validateRoleSessionSet(set) {
|
|
|
461
464
|
validateRoleAgentSession(session, agentId);
|
|
462
465
|
}
|
|
463
466
|
if (set.owner.scope === "global") {
|
|
464
|
-
if (set.schemaVersion !==
|
|
467
|
+
if (set.schemaVersion !== 1) {
|
|
465
468
|
throw new Error("Global Role session set schema version is invalid.");
|
|
466
469
|
}
|
|
467
470
|
const globalSet = set;
|
|
@@ -500,7 +503,7 @@ export function validateRoleSessionSet(set) {
|
|
|
500
503
|
}
|
|
501
504
|
}
|
|
502
505
|
else {
|
|
503
|
-
if (set.schemaVersion !==
|
|
506
|
+
if (set.schemaVersion !== 1) {
|
|
504
507
|
throw new Error("Task Role session set schema version is invalid.");
|
|
505
508
|
}
|
|
506
509
|
if (!Object.hasOwn(set, "providerBinding")) {
|
|
@@ -547,7 +550,7 @@ export function validateRoleSessionSet(set) {
|
|
|
547
550
|
return set;
|
|
548
551
|
}
|
|
549
552
|
export function validateRoleAgentSession(session, expectedAgentId = session.agentId) {
|
|
550
|
-
if (session.schemaVersion !==
|
|
553
|
+
if (session.schemaVersion !== 1) {
|
|
551
554
|
throw new Error(`Role Agent session schema version is invalid: ${expectedAgentId}.`);
|
|
552
555
|
}
|
|
553
556
|
const agentId = requireSafeIdentity(session.agentId, "Agent id");
|
|
@@ -172,8 +172,8 @@ function sessionContinuitySnapshot(snapshot) {
|
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
export function validateEffectiveLaunchSnapshot(snapshot) {
|
|
175
|
-
if (snapshot.schemaVersion !==
|
|
176
|
-
throw new Error("Effective launch snapshot must use schemaVersion
|
|
175
|
+
if (snapshot.schemaVersion !== 1) {
|
|
176
|
+
throw new Error("Effective launch snapshot must use schemaVersion 1.");
|
|
177
177
|
}
|
|
178
178
|
if (snapshot.executionAuthority !== "planning" && snapshot.executionAuthority !== "delivery") {
|
|
179
179
|
throw new Error("Effective launch requires its captured execution authority.");
|
|
@@ -278,7 +278,7 @@ function snapshotFromConfig(input) {
|
|
|
278
278
|
reviewBaseCommit: commit(input.reviewBaseCommit ?? "", "Review base commit")
|
|
279
279
|
};
|
|
280
280
|
const common = {
|
|
281
|
-
schemaVersion:
|
|
281
|
+
schemaVersion: 1,
|
|
282
282
|
executionAuthority: input.executionAuthority,
|
|
283
283
|
sourceDesiredRevision: positiveInteger(input.sourceDesiredRevision, "Source desired revision"),
|
|
284
284
|
agentId: identity(input.agentId, "Effective Agent id"),
|
|
@@ -176,15 +176,6 @@ export class ExecutorRegistry {
|
|
|
176
176
|
});
|
|
177
177
|
return deliveryReport(outcome);
|
|
178
178
|
}
|
|
179
|
-
async notifyOperatorInputOnce(input) {
|
|
180
|
-
if (this.runtimePorts?.notifyOperatorInputOnce !== undefined) {
|
|
181
|
-
return this.runtimePorts.notifyOperatorInputOnce(input);
|
|
182
|
-
}
|
|
183
|
-
const probe = this.readiness(input.adapterId, "operator");
|
|
184
|
-
return this.tmux.sendRoleInputOnceIfReadyAsync === undefined
|
|
185
|
-
? this.tmux.sendRoleInputOnceIfReady("operator", input.roleName, input.receiptId, input.text, probe)
|
|
186
|
-
: this.tmux.sendRoleInputOnceIfReadyAsync("operator", input.roleName, input.receiptId, input.text, probe);
|
|
187
|
-
}
|
|
188
179
|
forgetPrepared(input) {
|
|
189
180
|
for (const [deliveryId, prepared] of this.#prepared) {
|
|
190
181
|
const delivery = prepared.delivery;
|
|
@@ -21,7 +21,7 @@ import { resolveTaskRoleSessionTitle } from "../runtime/sessionTitle.js";
|
|
|
21
21
|
import { parseTaskRuntimeIsolationDescriptor, taskRuntimeIsolationEnvironment } from "../runtime/taskRuntimeIsolation.js";
|
|
22
22
|
import { planningRuntimeCwd } from "../storage/homeLayout.js";
|
|
23
23
|
import { resolveAgentAdapter } from "./agentAdapter.js";
|
|
24
|
-
import { activeLiveRoleAgentSession,
|
|
24
|
+
import { activeLiveRoleAgentSession, roleSessionControlTarget } from "./agentExecutor.js";
|
|
25
25
|
import { assertCodexLaunchOverridesAvailable, inspectCodexLaunchConfig } from "./codexConfigConflict.js";
|
|
26
26
|
import { effectiveRoleForLaunch, resolveEffectiveLaunch, roleSessionMayContinue } from "./effectiveLaunch.js";
|
|
27
27
|
import { classifyWorkspacePreflight, formatWorkspacePreflightError } from "./workspacePreflightClassification.js";
|
|
@@ -69,9 +69,11 @@ export class FileRoleLaunchPlanner {
|
|
|
69
69
|
}
|
|
70
70
|
/** Recovery addresses the recorded Agent/Session, independent of delivery
|
|
71
71
|
* admission, a missing worktree, or the old Endpoint code generation. */
|
|
72
|
-
planNativeControl(
|
|
73
|
-
const set =
|
|
74
|
-
|
|
72
|
+
planNativeControl(owner) {
|
|
73
|
+
const set = owner.scope === "task"
|
|
74
|
+
? this.store.getTaskRoleSessionSet(owner.taskId, owner.roleName)
|
|
75
|
+
: this.store.getGlobalRoleSessionSet(owner.roleName);
|
|
76
|
+
const session = roleSessionControlTarget(set);
|
|
75
77
|
if (session?.adapterId !== "codex")
|
|
76
78
|
throw new Error("Native metadata control requires a recorded Codex Session.");
|
|
77
79
|
const configured = this.store.getConfiguredAgent(session.agentId);
|
|
@@ -79,9 +81,11 @@ export class FileRoleLaunchPlanner {
|
|
|
79
81
|
throw new Error("The recorded native Agent connection is unavailable.");
|
|
80
82
|
}
|
|
81
83
|
const agent = configuredAgentToDefinition(configured);
|
|
82
|
-
const connection =
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
const connection = owner.scope === "task"
|
|
85
|
+
? this.store.listEvents(owner.taskId).find(event => event.type === "runtime.native-connection-bound"
|
|
86
|
+
&& event.payload.roleName === owner.roleName && event.payload.agentId === session.agentId
|
|
87
|
+
&& event.payload.nativeSessionId === session.nativeSessionId)?.payload
|
|
88
|
+
: undefined;
|
|
85
89
|
return {
|
|
86
90
|
command: configured.command, args: [...agent.baseArgs, "app-server", "proxy"], cwd: this.home,
|
|
87
91
|
expectedAccountHome: connection?.nativeAccountHome,
|
|
@@ -758,10 +762,7 @@ function managedClaudeControlPlaneConfig(config, taskId, workItemId, runId) {
|
|
|
758
762
|
}
|
|
759
763
|
function isManagedYuiBashRule(rule) {
|
|
760
764
|
const normalized = rule.trim();
|
|
761
|
-
return /^Bash\(yui(?:\s|:\*|\*|\))/u.test(normalized)
|
|
762
|
-
// Yui no longer writes a control-plane digest into a managed rule; this
|
|
763
|
-
// shape only clears one an earlier release left in a Provider config.
|
|
764
|
-
|| /^Bash\(.*\s--yui-control\s/u.test(normalized);
|
|
765
|
+
return /^Bash\(yui(?:\s|:\*|\*|\))/u.test(normalized);
|
|
765
766
|
}
|
|
766
767
|
function canonicalPath(path) {
|
|
767
768
|
const absolute = resolve(path);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { requireIdentity, requireText, requireTimestamp, requirePositiveInteger } from "../domain/validation.js";
|
|
2
2
|
import { validateTaskRecordReference } from "../task/taskRecordReference.js";
|
|
3
|
-
export const CAPABILITY_GRANT_SCHEMA_VERSION =
|
|
3
|
+
export const CAPABILITY_GRANT_SCHEMA_VERSION = 1;
|
|
4
4
|
const IRREVERSIBILITY_RANK = {
|
|
5
5
|
none: 0,
|
|
6
6
|
reversible: 1,
|
|
@@ -105,7 +105,7 @@ export function revokeGrant(grant, revokedBy, now) {
|
|
|
105
105
|
}
|
|
106
106
|
export function validateCapabilityGrant(grant) {
|
|
107
107
|
if (grant.schemaVersion !== CAPABILITY_GRANT_SCHEMA_VERSION) {
|
|
108
|
-
throw new Error("Capability grant must use schemaVersion
|
|
108
|
+
throw new Error("Capability grant must use schemaVersion 1.");
|
|
109
109
|
}
|
|
110
110
|
validateTaskRecordReference({ taskId: grant.taskId, localId: grant.id }, "capabilityGrant");
|
|
111
111
|
requireIdentity(grant.taskId, "Task id");
|
|
@@ -14,7 +14,7 @@ export function createInputRequest(id, taskId, requester, input, now) {
|
|
|
14
14
|
const timestamp = requireDate(now, "Input request creation time");
|
|
15
15
|
const choices = normalizeChoices(input.choices);
|
|
16
16
|
return validateInputRequest({
|
|
17
|
-
schemaVersion:
|
|
17
|
+
schemaVersion: 1,
|
|
18
18
|
id: requireIdentity(id, "Input request id"),
|
|
19
19
|
taskId: requireIdentity(taskId, "Input request Task id"),
|
|
20
20
|
requester: normalizeRequester(requester),
|
|
@@ -72,12 +72,12 @@ export function validateInputRequest(value) {
|
|
|
72
72
|
"schemaVersion", "id", "taskId", "requester", "question", "choices",
|
|
73
73
|
"blockedRefs", "policy", "status", "createdAt", "updatedAt", ...terminalField
|
|
74
74
|
], "Input request");
|
|
75
|
-
if (request.schemaVersion !==
|
|
76
|
-
throw new Error("Input request must use schemaVersion
|
|
75
|
+
if (request.schemaVersion !== 1)
|
|
76
|
+
throw new Error("Input request must use schemaVersion 1.");
|
|
77
77
|
const choices = validateChoices(request.choices);
|
|
78
78
|
const createdAt = requireTimestamp(request.createdAt, "Input request createdAt");
|
|
79
79
|
const base = {
|
|
80
|
-
schemaVersion:
|
|
80
|
+
schemaVersion: 1,
|
|
81
81
|
id: requireIdentity(request.id, "Input request id"),
|
|
82
82
|
taskId: requireIdentity(request.taskId, "Input request Task id"),
|
|
83
83
|
requester: normalizeRequester(request.requester),
|
|
@@ -3,7 +3,7 @@ import { validateTaskRecordReference } from "../task/taskRecordReference.js";
|
|
|
3
3
|
import { validateChangeSetManifest } from "./changeSetManifest.js";
|
|
4
4
|
export function createWorkItemChangeSet(input, now) {
|
|
5
5
|
return validateChangeSet({
|
|
6
|
-
schemaVersion:
|
|
6
|
+
schemaVersion: 1,
|
|
7
7
|
...input,
|
|
8
8
|
changedPaths: [...input.changedPaths],
|
|
9
9
|
manifest: validateChangeSetManifest(input.manifest),
|
|
@@ -11,8 +11,8 @@ export function createWorkItemChangeSet(input, now) {
|
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
export function validateChangeSet(changeSet) {
|
|
14
|
-
if (changeSet.schemaVersion !==
|
|
15
|
-
throw new Error("ChangeSet must use schemaVersion
|
|
14
|
+
if (changeSet.schemaVersion !== 1)
|
|
15
|
+
throw new Error("ChangeSet must use schemaVersion 1.");
|
|
16
16
|
validateTaskRecordReference({ taskId: changeSet.taskId, localId: changeSet.id }, "changeSet");
|
|
17
17
|
validateTaskRecordReference({
|
|
18
18
|
taskId: changeSet.taskId,
|
|
@@ -4,7 +4,7 @@ import { normalizeCheckResult } from "./checkResult.js";
|
|
|
4
4
|
export function createIntegrationAttempt(input, now) {
|
|
5
5
|
const timestamp = now.toISOString();
|
|
6
6
|
return validateIntegrationAttempt({
|
|
7
|
-
schemaVersion:
|
|
7
|
+
schemaVersion: 1,
|
|
8
8
|
id: input.id,
|
|
9
9
|
taskId: input.taskId,
|
|
10
10
|
projectId: input.projectId,
|
|
@@ -132,8 +132,8 @@ export function supersedeIntegration(attempt, reason, now) {
|
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
134
|
export function validateIntegrationAttempt(attempt) {
|
|
135
|
-
if (attempt.schemaVersion !==
|
|
136
|
-
throw new Error("IntegrationAttempt must use schemaVersion
|
|
135
|
+
if (attempt.schemaVersion !== 1) {
|
|
136
|
+
throw new Error("IntegrationAttempt must use schemaVersion 1.");
|
|
137
137
|
}
|
|
138
138
|
validateTaskRecordReference({
|
|
139
139
|
taskId: attempt.taskId,
|
|
@@ -233,7 +233,7 @@ async function assertOperation(path, kind, commit, before, branch, source) {
|
|
|
233
233
|
throw new Error(`Integration expected ${kind}, found ${active ?? "no active Git operation"}.`);
|
|
234
234
|
if (kind === "rebase") {
|
|
235
235
|
const directory = await gitPath(path, "rebase-merge");
|
|
236
|
-
// Yui invokes the merge backend explicitly.
|
|
236
|
+
// Yui invokes the merge backend explicitly. An apply-backend
|
|
237
237
|
// operation cannot be silently treated as the same execution.
|
|
238
238
|
const [onto, original, headName] = await Promise.all(["onto", "orig-head", "head-name"].map(name => readFile(resolve(directory, name), "utf8")));
|
|
239
239
|
if (source.kind !== "upstream" || onto.trim() !== commit
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* One mailbox batch becomes one short
|
|
2
|
+
* One mailbox batch becomes one short system notification. The durable
|
|
3
3
|
* records remain the context authority; this wake text carries only stable
|
|
4
4
|
* identities and exact CLI reads, never copied Task or Provider narrative.
|
|
5
5
|
*/
|
|
@@ -11,6 +11,7 @@ export function createOperatorBatchPresentation(batchId, items) {
|
|
|
11
11
|
text: [
|
|
12
12
|
"[Yui updates]",
|
|
13
13
|
"Yui recorded the following durable updates. Inspect the referenced records and present only information that changes the user's understanding, authorization, or next action.",
|
|
14
|
+
"This notification is not a new execution assignment or authorization to replay prior operations.",
|
|
14
15
|
...items.flatMap(renderItem)
|
|
15
16
|
].join("\n")
|
|
16
17
|
};
|
package/dist/job/durableJob.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { requireIdentity, requirePositiveInteger, requireText, requireTimestamp } from "../domain/validation.js";
|
|
3
3
|
import { validateTaskRecordReference } from "../task/taskRecordReference.js";
|
|
4
4
|
import { recordOperationEvidence, validateOperationFacts } from "../kernel/operationFacts.js";
|
|
5
|
-
export const CURRENT_DURABLE_JOB_SCHEMA_VERSION =
|
|
5
|
+
export const CURRENT_DURABLE_JOB_SCHEMA_VERSION = 1;
|
|
6
6
|
export const JOB_RUNNER_IMPLEMENTATION = Object.freeze({ id: "yui:job-runner", generation: "1" });
|
|
7
7
|
export const DURABLE_JOB_TERMINAL_STATUSES = [
|
|
8
8
|
"succeeded",
|
package/dist/job/jobRunner.js
CHANGED
|
@@ -128,8 +128,8 @@ export async function runDurableJobRunner(specPath) {
|
|
|
128
128
|
let child;
|
|
129
129
|
try {
|
|
130
130
|
// Issue 08: a structured argv step executes without a shell so its
|
|
131
|
-
// tokens can never be reinterpreted;
|
|
132
|
-
// shell
|
|
131
|
+
// tokens can never be reinterpreted; an explicit command step uses
|
|
132
|
+
// the shell. A per-step cwd/env override applies to either form.
|
|
133
133
|
const stepCwd = jobStepDirectory(spec.workspace, step.cwd);
|
|
134
134
|
const stepEnv = step.env === undefined
|
|
135
135
|
? spec.env
|