sneakoscope 2.0.5 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +13 -8
- package/dist/cli/install-helpers.js +23 -0
- package/dist/commands/codex-app.js +25 -3
- package/dist/commands/doctor.js +19 -4
- package/dist/commands/mad-sks.js +2 -2
- package/dist/core/agents/agent-orchestrator.js +22 -3
- package/dist/core/agents/agent-proof-evidence.js +24 -2
- package/dist/core/agents/agent-worker-pipeline.js +9 -1
- package/dist/core/agents/native-worker-backend-router.js +19 -1
- package/dist/core/codex-app.js +124 -2
- package/dist/core/commands/naruto-command.js +9 -4
- package/dist/core/fsx.js +1 -1
- package/dist/core/hooks-runtime.js +2 -233
- package/dist/core/init.js +8 -8
- package/dist/core/naruto/naruto-active-pool.js +20 -4
- package/dist/core/pipeline-internals/runtime-core.js +1 -1
- package/dist/core/ppt.js +31 -8
- package/dist/core/product-design-app-server.js +410 -0
- package/dist/core/product-design-plugin.js +139 -0
- package/dist/core/routes.js +8 -8
- package/dist/core/version.js +1 -1
- package/dist/scripts/naruto-active-pool-check.js +13 -1
- package/dist/scripts/naruto-readonly-routing-check.js +116 -0
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +7 -0
- package/dist/scripts/product-design-auto-install-check.js +119 -0
- package/dist/scripts/product-design-plugin-routing-check.js +101 -0
- package/dist/scripts/release-parallel-check.js +15 -1
- package/dist/scripts/release-provenance-check.js +21 -0
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -16,10 +16,13 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
|
|
|
16
16
|
|
|
17
17
|
## Current Release
|
|
18
18
|
|
|
19
|
-
SKS **2.0.
|
|
19
|
+
SKS **2.0.6** wires Codex App Product Design into the design pipeline and hardens Naruto read-only routing on top of the 2.0 execution layer. Design routes can now discover, install, verify, and prefer the remote `product-design@openai-curated-remote` plugin, while read-only native worker runs keep write mode off and avoid treating pre-existing dirty files as generated patches.
|
|
20
20
|
|
|
21
21
|
What changed:
|
|
22
22
|
|
|
23
|
+
- Product Design plugin readiness now checks both local and remote Codex App catalogs, auto-installs the remote plugin when needed, and records the installed/enabled skill surface.
|
|
24
|
+
- UI/design/PPT runtime routes prefer Product Design for research, ideation, audit, design QA, prototype, URL-to-code, image-to-code, share, and user-context steps.
|
|
25
|
+
- Naruto read-only runs force write mode off, propagate no-patch reasons through worker proof, and skip changed-file lease checks when no write-capable patch envelope exists.
|
|
23
26
|
- `codex-sdk` is the default native agent backend for Team, QA, Research, Naruto, MAD-SKS, and direct agent runs, with every runtime task entering through `runCodexTask`.
|
|
24
27
|
- Codex App UI snapshot, preservation, clobber guard, and doctor repair checks protect host-owned Fast UI/profile settings around `sks --mad`.
|
|
25
28
|
- Provider context resolves `openai`, `codex-lb`, and `codex-app` with badge/fallback surfaces while avoiding private Codex App UI mutation.
|
|
@@ -78,7 +81,7 @@ Broader release checks still live behind `npm run release:check`. Detailed relea
|
|
|
78
81
|
sks xai docs
|
|
79
82
|
```
|
|
80
83
|
|
|
81
|
-
- **
|
|
84
|
+
- **CLI-only SKS update notices.** Codex App hooks no longer stop normal work to ask for an SKS update. CLI launch surfaces such as `sks --mad` print a non-blocking latest-version notice, `sks update-check` / `sks update check` show the explicit status, and `sks doctor --fix` runs the guarded global SKS update path before repair.
|
|
82
85
|
|
|
83
86
|
## Retention And Cleanup
|
|
84
87
|
|
|
@@ -359,7 +362,7 @@ sks --mad --allow-package-install --allow-service-control --allow-network --yes
|
|
|
359
362
|
|
|
360
363
|
This syncs existing codex-lb provider auth, creates/uses the `sks-mad-high` xhigh maintenance profile, opens the MAD-SKS permission gate for that Zellij run, starts a same-mission read-only native agent swarm, and launches a Codex CLI layout whose right-side lanes read that MAD ledger. Bare `sks --mad` grants target-project file and shell scope only; add explicit `--allow-*` flags for packages, services, network, Computer Use, browser use, generated assets, file permissions, DB writes, or other high-risk scopes. MAD-SKS is not a DB-only unlock: it is explicit user authorization to widen approved target-project scopes. Catastrophic database wipe/all-row/project-management safeguards remain active, and the pipeline contract still forbids unrequested fallback implementation code.
|
|
361
364
|
|
|
362
|
-
Before launching, SKS checks npm for a newer `sneakoscope
|
|
365
|
+
Before launching, SKS checks npm for a newer `sneakoscope` and prints a non-blocking update notice when one is available; use `sks update now` or `sks doctor --fix` when you want SKS to update itself. Use `--yes` to approve missing dependency installs automatically. Tune MAD swarm startup with `--mad-agents <n>`, `--mad-swarm-work-items <n>`, and `--mad-swarm-backend <backend>`; `--no-mad-swarm` keeps only the cockpit UI if you need a temporary fallback.
|
|
363
366
|
|
|
364
367
|
### Team Missions
|
|
365
368
|
|
|
@@ -659,7 +662,7 @@ npm ls -g sneakoscope --depth=0
|
|
|
659
662
|
sks doctor --fix
|
|
660
663
|
```
|
|
661
664
|
|
|
662
|
-
|
|
665
|
+
CLI update checks compare npm latest against the effective installed version from source metadata, PATH `sks --version`, and global npm package metadata. Codex App hooks do not force update choices during ordinary work. `sks update now` installs through npm global mode instead of mutating the current project's dependencies, and `sks doctor --fix` runs that guarded global update path before setup/config repair. If a global update succeeded but an old shim remains earlier on PATH, `sks doctor --fix` can remove duplicate global installs and refresh the managed setup.
|
|
663
666
|
|
|
664
667
|
### Zellij is missing
|
|
665
668
|
|
|
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
|
|
|
4
4
|
fn main() {
|
|
5
5
|
let mut args = std::env::args().skip(1);
|
|
6
6
|
match args.next().as_deref() {
|
|
7
|
-
Some("--version") => println!("sks-rs 2.0.
|
|
7
|
+
Some("--version") => println!("sks-rs 2.0.6"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build-stamp.v1",
|
|
3
3
|
"package_name": "sneakoscope",
|
|
4
|
-
"package_version": "2.0.
|
|
5
|
-
"source_digest": "
|
|
6
|
-
"source_file_count":
|
|
7
|
-
"built_at_source_time":
|
|
4
|
+
"package_version": "2.0.6",
|
|
5
|
+
"source_digest": "3947e39c47a565506e9ffd37568ae889bc7943f6dc342b5c357976b840770f94",
|
|
6
|
+
"source_file_count": 1953,
|
|
7
|
+
"built_at_source_time": 1780662014263
|
|
8
8
|
}
|
package/dist/bin/sks.js
CHANGED
package/dist/build-manifest.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build.v2",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"package_version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
|
+
"package_version": "2.0.6",
|
|
5
5
|
"typescript": true,
|
|
6
6
|
"mjs_runtime_files": 0,
|
|
7
|
-
"compiled_file_count":
|
|
8
|
-
"compiled_js_count":
|
|
7
|
+
"compiled_file_count": 1019,
|
|
8
|
+
"compiled_js_count": 1019,
|
|
9
9
|
"compiled_dts_count": 0,
|
|
10
|
-
"source_digest": "
|
|
11
|
-
"source_file_count":
|
|
12
|
-
"source_files_hash": "
|
|
13
|
-
"source_list_hash": "
|
|
10
|
+
"source_digest": "3947e39c47a565506e9ffd37568ae889bc7943f6dc342b5c357976b840770f94",
|
|
11
|
+
"source_file_count": 1953,
|
|
12
|
+
"source_files_hash": "5d6f0e4186fc37279e1cf6de0c6b3c7230123c4a588966f8fda2a9324eb75192",
|
|
13
|
+
"source_list_hash": "5d6f0e4186fc37279e1cf6de0c6b3c7230123c4a588966f8fda2a9324eb75192",
|
|
14
14
|
"src_mjs_runtime_files": 0,
|
|
15
15
|
"dist_stamp_schema": "sks.dist-build-stamp.v1",
|
|
16
16
|
"files": [
|
|
@@ -473,6 +473,8 @@
|
|
|
473
473
|
"core/ppt-review/slide-issue-extraction.js",
|
|
474
474
|
"core/ppt.js",
|
|
475
475
|
"core/preflight/parallel-preflight-engine.js",
|
|
476
|
+
"core/product-design-app-server.js",
|
|
477
|
+
"core/product-design-plugin.js",
|
|
476
478
|
"core/prompt-context-builder.js",
|
|
477
479
|
"core/prompt/prompt-placeholder-guard.js",
|
|
478
480
|
"core/proof-field.js",
|
|
@@ -886,6 +888,7 @@
|
|
|
886
888
|
"scripts/naruto-concurrency-governor-check.js",
|
|
887
889
|
"scripts/naruto-gpt-final-pack-check.js",
|
|
888
890
|
"scripts/naruto-parallel-patch-apply-check.js",
|
|
891
|
+
"scripts/naruto-readonly-routing-check.js",
|
|
889
892
|
"scripts/naruto-real-local-gpt-final-smoke.js",
|
|
890
893
|
"scripts/naruto-role-distribution-check.js",
|
|
891
894
|
"scripts/naruto-shadow-clone-swarm-check.js",
|
|
@@ -916,6 +919,8 @@
|
|
|
916
919
|
"scripts/prepublish-fast-check.js",
|
|
917
920
|
"scripts/prepublish-release-check-or-fast.js",
|
|
918
921
|
"scripts/priority-full-closure-check.js",
|
|
922
|
+
"scripts/product-design-auto-install-check.js",
|
|
923
|
+
"scripts/product-design-plugin-routing-check.js",
|
|
919
924
|
"scripts/prompt-placeholder-guard-check.js",
|
|
920
925
|
"scripts/provider-badge-context-check.js",
|
|
921
926
|
"scripts/provider-context-config-toml-check.js",
|
|
@@ -13,6 +13,7 @@ import { context7ConfigToml, DOLLAR_SKILL_NAMES, GETDESIGN_REFERENCE, hasContext
|
|
|
13
13
|
import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
|
|
14
14
|
import { reconcileCodexAppUpgradeProcesses } from '../core/codex-app.js';
|
|
15
15
|
import { recordCodexLbHealthEvent } from '../core/codex-lb-circuit.js';
|
|
16
|
+
import { runSksUpdateCheck, runSksUpdateNow } from '../core/update-check.js';
|
|
16
17
|
import { loadCodexLbEnv, writeCodexLbKeychain, codexLbMetadataPath } from '../core/codex-lb/codex-lb-env.js';
|
|
17
18
|
import { buildCodexLbSetupPlan, codexLbPersistenceSummary, installCodexLbShellProfileSnippet, selectedCodexLbPersistenceModes } from '../core/codex-lb/codex-lb-setup.js';
|
|
18
19
|
const DEFAULT_CODEX_APP_PLUGINS = [
|
|
@@ -2231,6 +2232,28 @@ export async function maybePromptCodexUpdateForLaunch(args = [], opts = {}) {
|
|
|
2231
2232
|
return { status: 'skipped_by_user', latest: latest.version || null, current, command, bin: codex.bin || null };
|
|
2232
2233
|
return installCodexLatest(command, latest.version, current);
|
|
2233
2234
|
}
|
|
2235
|
+
export async function maybePromptSksUpdateForLaunch(args = [], opts = {}) {
|
|
2236
|
+
if (hasFlag(args, '--json') || hasFlag(args, '--skip-sks-update') || process.env.SKS_SKIP_SKS_UPDATE === '1')
|
|
2237
|
+
return { status: 'skipped' };
|
|
2238
|
+
const label = opts.label || 'SKS launch';
|
|
2239
|
+
const check = await runSksUpdateCheck({ timeoutMs: 5000 }).catch((err) => ({
|
|
2240
|
+
ok: false,
|
|
2241
|
+
update_available: false,
|
|
2242
|
+
latest: null,
|
|
2243
|
+
current: PACKAGE_VERSION,
|
|
2244
|
+
command: null,
|
|
2245
|
+
error: err?.message || String(err)
|
|
2246
|
+
}));
|
|
2247
|
+
if (!check.update_available) {
|
|
2248
|
+
return { status: check.error ? 'unavailable' : 'current', latest: check.latest || null, current: check.current || PACKAGE_VERSION, error: check.error || null };
|
|
2249
|
+
}
|
|
2250
|
+
const command = check.command || `sks update now --version ${check.latest}`;
|
|
2251
|
+
if (shouldAutoApproveInstall(args)) {
|
|
2252
|
+
return runSksUpdateNow({ version: check.latest, timeoutMs: 10 * 60 * 1000, maxOutputBytes: 128 * 1024 });
|
|
2253
|
+
}
|
|
2254
|
+
console.log(`SKS update available before ${label}: ${check.current} -> ${check.latest}. Run when ready: ${command}`);
|
|
2255
|
+
return { status: 'available', latest: check.latest || null, current: check.current || PACKAGE_VERSION, command };
|
|
2256
|
+
}
|
|
2234
2257
|
export function shouldAutoApproveInstall(args = [], env = process.env) {
|
|
2235
2258
|
if (hasFlag(args, '--from-postinstall') && env.SKS_POSTINSTALL_AUTO_INSTALL_CLI_TOOLS !== '1')
|
|
2236
2259
|
return false;
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import { flag } from '../cli/args.js';
|
|
2
2
|
import { printJson } from '../cli/output.js';
|
|
3
|
-
import { codexAccessTokenStatus, codexAppIntegrationStatus, codexChromeExtensionStatus, formatCodexAppStatus } from '../core/codex-app.js';
|
|
3
|
+
import { codexAccessTokenStatus, codexAppIntegrationStatus, codexChromeExtensionStatus, codexProductDesignPluginStatus, formatCodexAppStatus, formatCodexProductDesignPluginStatus } from '../core/codex-app.js';
|
|
4
4
|
import { codexAppRemoteControlCommand } from '../cli/codex-app-command.js';
|
|
5
5
|
export async function run(_command, args = []) {
|
|
6
6
|
const action = args[0] || 'check';
|
|
7
7
|
if (action === 'remote-control' || action === 'remote')
|
|
8
8
|
return codexAppRemoteControlCommand(args.slice(1));
|
|
9
|
+
if (action === 'product-design' || action === 'design-product' || action === 'ensure-product-design') {
|
|
10
|
+
const checkOnly = flag(args, '--check-only') || flag(args, '--no-install');
|
|
11
|
+
const status = await codexProductDesignPluginStatus({
|
|
12
|
+
autoInstallProductDesign: !checkOnly && (action === 'product-design'
|
|
13
|
+
|| action === 'design-product'
|
|
14
|
+
|| action === 'ensure-product-design'
|
|
15
|
+
|| flag(args, '--install')
|
|
16
|
+
|| flag(args, '--auto-install'))
|
|
17
|
+
});
|
|
18
|
+
if (flag(args, '--json')) {
|
|
19
|
+
printJson(status);
|
|
20
|
+
if (!status.ok)
|
|
21
|
+
process.exitCode = 1;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
console.log(formatCodexProductDesignPluginStatus(status));
|
|
25
|
+
if (!status.ok)
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
9
29
|
if (action === 'chrome-extension' || action === 'chrome') {
|
|
10
30
|
const status = await codexChromeExtensionStatus();
|
|
11
31
|
if (flag(args, '--json')) {
|
|
@@ -32,7 +52,9 @@ export async function run(_command, args = []) {
|
|
|
32
52
|
return;
|
|
33
53
|
}
|
|
34
54
|
if (action === 'check' || action === 'status') {
|
|
35
|
-
const status = await codexAppIntegrationStatus(
|
|
55
|
+
const status = await codexAppIntegrationStatus({
|
|
56
|
+
autoInstallProductDesign: flag(args, '--install-product-design') || flag(args, '--auto-install-product-design')
|
|
57
|
+
});
|
|
36
58
|
if (flag(args, '--json')) {
|
|
37
59
|
printJson(status);
|
|
38
60
|
if (!status.ok)
|
|
@@ -44,7 +66,7 @@ export async function run(_command, args = []) {
|
|
|
44
66
|
process.exitCode = 1;
|
|
45
67
|
return;
|
|
46
68
|
}
|
|
47
|
-
console.error('Usage: sks codex-app check|status|chrome-extension|pat status|remote-control [--json]');
|
|
69
|
+
console.error('Usage: sks codex-app check|status|product-design [--check-only]|ensure-product-design|chrome-extension|pat status|remote-control [--json]');
|
|
48
70
|
process.exitCode = 1;
|
|
49
71
|
}
|
|
50
72
|
//# sourceMappingURL=codex-app.js.map
|
package/dist/commands/doctor.js
CHANGED
|
@@ -18,10 +18,23 @@ import { appendMigrationEvents, hashConfigText } from '../core/migration/migrati
|
|
|
18
18
|
import { repairCodexAppFastUi } from '../core/codex-app/codex-app-fast-ui-repair.js';
|
|
19
19
|
import { resolveProviderContext } from '../core/provider/provider-context.js';
|
|
20
20
|
import { readLocalModelConfig } from '../core/agents/ollama-worker-config.js';
|
|
21
|
+
import { runSksUpdateNow } from '../core/update-check.js';
|
|
21
22
|
export async function run(_command, args = []) {
|
|
23
|
+
const doctorFix = flag(args, '--fix');
|
|
22
24
|
let setupRepair = null;
|
|
25
|
+
const sksUpdate = doctorFix
|
|
26
|
+
? await runSksUpdateNow({
|
|
27
|
+
timeoutMs: 10 * 60 * 1000,
|
|
28
|
+
maxOutputBytes: 128 * 1024
|
|
29
|
+
}).catch((err) => ({
|
|
30
|
+
schema: 'sks.update-now.v1',
|
|
31
|
+
ok: false,
|
|
32
|
+
status: 'failed',
|
|
33
|
+
error: err?.message || String(err)
|
|
34
|
+
}))
|
|
35
|
+
: null;
|
|
23
36
|
let migrationPreFix = null;
|
|
24
|
-
if (
|
|
37
|
+
if (doctorFix) {
|
|
25
38
|
// Snapshot config content before ANY mutation so the migration journal can
|
|
26
39
|
// record real before/after hashes for the whole --fix transaction.
|
|
27
40
|
migrationPreFix = await captureCodexConfigSnapshot();
|
|
@@ -97,7 +110,6 @@ export async function run(_command, args = []) {
|
|
|
97
110
|
model_provider: null
|
|
98
111
|
}
|
|
99
112
|
}));
|
|
100
|
-
const doctorFix = flag(args, '--fix');
|
|
101
113
|
const explicitCodexAppUiRepair = flag(args, '--repair-codex-app-ui') || flag(args, '--yes');
|
|
102
114
|
const codexAppUiPlan = await repairCodexAppFastUi(root, {
|
|
103
115
|
apply: false,
|
|
@@ -165,7 +177,7 @@ export async function run(_command, args = []) {
|
|
|
165
177
|
const zellijReadiness = buildZellijReadiness(root, zellij, ready);
|
|
166
178
|
const result = {
|
|
167
179
|
schema: 'sks.doctor-status.v1',
|
|
168
|
-
ok: ready.ready,
|
|
180
|
+
ok: ready.ready && (!sksUpdate || sksUpdate.ok !== false),
|
|
169
181
|
root,
|
|
170
182
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
171
183
|
codex,
|
|
@@ -189,7 +201,7 @@ export async function run(_command, args = []) {
|
|
|
189
201
|
ready,
|
|
190
202
|
sneakoscope: { ok: await exists(`${root}/.sneakoscope`) },
|
|
191
203
|
package: { bytes: pkgBytes, human: formatBytes(pkgBytes) },
|
|
192
|
-
repair: { setup: setupRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup }
|
|
204
|
+
repair: { sks_update: sksUpdate, setup: setupRepair, codex_config: configRepair, migration_journal: migrationJournal, global_sks_installs: globalSksInstallCleanup }
|
|
193
205
|
};
|
|
194
206
|
if (flag(args, '--json')) {
|
|
195
207
|
printJson(result);
|
|
@@ -265,6 +277,9 @@ export async function run(_command, args = []) {
|
|
|
265
277
|
if (migrationJournal?.journal_path) {
|
|
266
278
|
console.log(`Migration journal: ${migrationJournal.journal_path} (${migrationJournal.event_count} events, ${migrationJournal.mutations_without_rollback} without rollback)`);
|
|
267
279
|
}
|
|
280
|
+
if (sksUpdate) {
|
|
281
|
+
console.log(`SKS update: ${sksUpdate.status}${sksUpdate.latest ? ` latest ${sksUpdate.latest}` : ''}${sksUpdate.error ? ` (${sksUpdate.error})` : ''}`);
|
|
282
|
+
}
|
|
268
283
|
if (globalSksInstallCleanup) {
|
|
269
284
|
console.log(`Global SKS installs: kept ${globalSksInstallCleanup.kept?.length ?? 0}, removed ${globalSksInstallCleanup.removed?.filter((entry) => entry.ok).length ?? 0}, source repo exempt ${globalSksInstallCleanup.candidates?.filter((entry) => entry.source_repo_exempt).length ?? 0}`);
|
|
270
285
|
}
|
package/dist/commands/mad-sks.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { madHighCommand } from '../core/commands/mad-sks-command.js';
|
|
2
|
-
import { ensureMadLaunchDependencies, formatMadLaunchDependencyAction, maybePromptCodexUpdateForLaunch, maybePromptCodexLbSetupForLaunch } from '../cli/install-helpers.js';
|
|
2
|
+
import { ensureMadLaunchDependencies, formatMadLaunchDependencyAction, maybePromptCodexUpdateForLaunch, maybePromptCodexLbSetupForLaunch, maybePromptSksUpdateForLaunch } from '../cli/install-helpers.js';
|
|
3
3
|
import { PACKAGE_VERSION } from '../core/fsx.js';
|
|
4
4
|
export async function run(_command, args = []) {
|
|
5
5
|
return madHighCommand(['--mad-sks', ...args], {
|
|
6
|
-
maybePromptSksUpdateForLaunch
|
|
6
|
+
maybePromptSksUpdateForLaunch,
|
|
7
7
|
maybePromptCodexUpdateForLaunch,
|
|
8
8
|
ensureMadLaunchDependencies,
|
|
9
9
|
printDepsInstallAction: (action) => console.error(formatMadLaunchDependencyAction(action)),
|
|
@@ -117,6 +117,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
117
117
|
const strategyCompiled = compileStrategy({
|
|
118
118
|
prompt,
|
|
119
119
|
route,
|
|
120
|
+
...(writeCapable ? {} : { writeTargets: [] }),
|
|
120
121
|
agentCount: roster.agent_count,
|
|
121
122
|
visualRequired
|
|
122
123
|
});
|
|
@@ -235,12 +236,13 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
235
236
|
rate_limit_delay_ms: backend === 'codex-sdk' ? 250 : 0,
|
|
236
237
|
resource_pressure_warnings: roster.agent_count > roster.concurrency ? ['agents_exceed_concurrency_batches'] : []
|
|
237
238
|
});
|
|
239
|
+
const effectiveWriteMode = writeCapable ? opts.writeMode || 'off' : 'off';
|
|
238
240
|
const parallelWritePolicy = {
|
|
239
241
|
schema: 'sks.agent-parallel-write-policy.v1',
|
|
240
242
|
generated_at: nowIso(),
|
|
241
243
|
route,
|
|
242
244
|
route_command: routeCommand,
|
|
243
|
-
write_mode:
|
|
245
|
+
write_mode: effectiveWriteMode,
|
|
244
246
|
apply_patches: opts.applyPatches === true,
|
|
245
247
|
dry_run_patches: opts.dryRunPatches === true,
|
|
246
248
|
max_write_agents: Number(opts.maxWriteAgents || 0),
|
|
@@ -779,7 +781,7 @@ async function runAgentPatchSwarmRuntime(root, ledgerRoot, input) {
|
|
|
779
781
|
await queueStore.persistSnapshot();
|
|
780
782
|
const journalSummary = await queueStore.journal.writeSummary();
|
|
781
783
|
const proof = buildAgentPatchProof({ ...proofInput, transactionJournal: journalSummary });
|
|
782
|
-
const zeroPatchBlockers = input.writeCapable && input.parallelWritePolicy?.write_mode === 'parallel' && pendingEntries.length === 0 && input.parallelWritePolicy?.dry_run_patches !== true
|
|
784
|
+
const zeroPatchBlockers = input.writeCapable && input.parallelWritePolicy?.write_mode === 'parallel' && pendingEntries.length === 0 && input.dryRun !== true && input.parallelWritePolicy?.dry_run_patches !== true
|
|
783
785
|
? ['write_mode_parallel_zero_patch_envelopes']
|
|
784
786
|
: [];
|
|
785
787
|
const blockers = [
|
|
@@ -870,6 +872,8 @@ function normalizeVisualLaneCount(value, fallback, maxAgentCount) {
|
|
|
870
872
|
return Math.max(1, Math.min(maxAgentCount, Math.floor(raw)));
|
|
871
873
|
}
|
|
872
874
|
function isWriteCapableRun(opts) {
|
|
875
|
+
if (opts.readonly === true)
|
|
876
|
+
return false;
|
|
873
877
|
return opts.applyPatches === true || opts.dryRunPatches === true || (opts.writeMode !== undefined && opts.writeMode !== 'off');
|
|
874
878
|
}
|
|
875
879
|
function defaultRouteCommand(route) {
|
|
@@ -991,6 +995,7 @@ async function runAgentByBackend(backend, agent, slice, opts) {
|
|
|
991
995
|
...sdkWorkerResult,
|
|
992
996
|
backend: 'codex-sdk',
|
|
993
997
|
patch_envelopes: patchEnvelopes,
|
|
998
|
+
...(patchEnvelopes.length ? {} : { no_patch_reason: buildDirectNoPatchReason(slice, opts) }),
|
|
994
999
|
codex_child_report: sdkReport,
|
|
995
1000
|
codex_sdk_thread: sdkReport,
|
|
996
1001
|
model_authored_patch_envelopes: patchEnvelopes.length > 0,
|
|
@@ -1027,10 +1032,24 @@ function buildDirectSdkWorkerPrompt(slice) {
|
|
|
1027
1032
|
'',
|
|
1028
1033
|
write.length
|
|
1029
1034
|
? `Write-capable slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; include patch_envelopes for write_paths=${JSON.stringify(write)}. Each patch envelope must include schema, source "model_authored", agent_id, session_id, slot_id, generation_index, task_slice_id, lease_id, allowed_paths, operations, and rationale. Each operation must include op, path, search, replace, content, and diff; use empty strings for operation fields that do not apply.`
|
|
1030
|
-
: `Read-only slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}.`,
|
|
1035
|
+
: `Read-only slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; do not report pre-existing repository dirtiness as changed_files.`,
|
|
1031
1036
|
'Required JSON fields: status, summary, findings, changed_files, patch_envelopes, verification, rollback_notes, blockers.'
|
|
1032
1037
|
].join('\n');
|
|
1033
1038
|
}
|
|
1039
|
+
function buildDirectNoPatchReason(slice, opts) {
|
|
1040
|
+
const writePathCount = sdkWritePaths(slice, opts).length;
|
|
1041
|
+
return {
|
|
1042
|
+
schema: 'sks.native-cli-worker-no-patch-reason.v1',
|
|
1043
|
+
generated_at: nowIso(),
|
|
1044
|
+
ok: writePathCount === 0,
|
|
1045
|
+
reason: writePathCount ? 'write_capable_task_without_backend_patch_envelope' : 'read_only_or_no_write_paths',
|
|
1046
|
+
route_justification: writePathCount ? 'backend returned no patch envelopes for a write-capable task' : 'task has no write paths',
|
|
1047
|
+
read_only_or_noop_evidence: writePathCount === 0,
|
|
1048
|
+
task_slice_id: slice?.id || null,
|
|
1049
|
+
backend: 'codex-sdk',
|
|
1050
|
+
blockers: writePathCount ? ['write_capable_no_patch_envelope'] : []
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1034
1053
|
function sdkWritePaths(slice, opts) {
|
|
1035
1054
|
return [
|
|
1036
1055
|
...(Array.isArray(slice?.write_paths) ? slice.write_paths : []),
|
|
@@ -119,6 +119,14 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
119
119
|
return !changed || Boolean(row.rollback_digest);
|
|
120
120
|
}) : true;
|
|
121
121
|
const parallelPatchApplyVerified = patchSwarm ? Array.isArray(patchProof?.wall_clock_parallel_evidence) && patchProof.wall_clock_parallel_evidence.length > 0 || Number(patchSwarm?.parallel_apply_count || 0) > 1 : false;
|
|
122
|
+
const readOnlyNoWriteLeaseMode = isReadOnlyNoWriteLeaseMode({
|
|
123
|
+
results: input.results || [],
|
|
124
|
+
leases: input.partition?.leases || [],
|
|
125
|
+
parallelWritePolicy,
|
|
126
|
+
taskGraph,
|
|
127
|
+
narutoWorkGraph
|
|
128
|
+
});
|
|
129
|
+
const changedFileLeaseBlockers = readOnlyNoWriteLeaseMode ? [] : agentChangedFileLeaseViolations(input.results || [], input.partition?.leases || []);
|
|
122
130
|
const blockers = [
|
|
123
131
|
...(lifecycle.ok ? [] : ['agent_lifecycle_not_all_closed']),
|
|
124
132
|
...(lifecycle.ok ? [] : lifecycle.open_sessions.map((id) => 'session_open:' + id)),
|
|
@@ -195,7 +203,7 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
195
203
|
...(isNarutoRoute && !narutoVerificationDag ? ['naruto_verification_dag_missing'] : []),
|
|
196
204
|
...(isNarutoRoute && !narutoGptFinalPack ? ['naruto_gpt_final_pack_missing'] : []),
|
|
197
205
|
...(isNarutoRoute && !narutoZellijDashboard ? ['naruto_zellij_dashboard_missing'] : []),
|
|
198
|
-
...
|
|
206
|
+
...changedFileLeaseBlockers
|
|
199
207
|
];
|
|
200
208
|
const evidence = {
|
|
201
209
|
schema: AGENT_PROOF_EVIDENCE_SCHEMA,
|
|
@@ -369,7 +377,7 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
369
377
|
triwiki_use_first_count: Number(input.triwikiContext?.use_first?.length || 0),
|
|
370
378
|
triwiki_hydrate_first_count: Number(input.triwikiContext?.hydrate_first?.length || 0),
|
|
371
379
|
triwiki_claim_count: Number(input.triwikiContext?.claim_count || 0),
|
|
372
|
-
changed_files_lease_checked:
|
|
380
|
+
changed_files_lease_checked: !readOnlyNoWriteLeaseMode,
|
|
373
381
|
dependency_collision_risk: input.partition?.no_overlap_proof?.dependency_collision_risk || [],
|
|
374
382
|
blockers
|
|
375
383
|
};
|
|
@@ -448,6 +456,20 @@ function agentChangedFileLeaseViolations(results, leases) {
|
|
|
448
456
|
}
|
|
449
457
|
return violations;
|
|
450
458
|
}
|
|
459
|
+
function isReadOnlyNoWriteLeaseMode(input) {
|
|
460
|
+
const writeLeaseCount = input.leases.filter((lease) => lease.kind === 'write').length;
|
|
461
|
+
if (writeLeaseCount > 0)
|
|
462
|
+
return false;
|
|
463
|
+
const resultWriteSignals = input.results.some((result) => (Array.isArray(result?.writes) && result.writes.length > 0)
|
|
464
|
+
|| (Array.isArray(result?.patch_envelopes) && result.patch_envelopes.length > 0));
|
|
465
|
+
if (resultWriteSignals)
|
|
466
|
+
return false;
|
|
467
|
+
const policyReadonly = input.parallelWritePolicy?.readonly === true;
|
|
468
|
+
const policyWriteOff = String(input.parallelWritePolicy?.write_mode || 'off') === 'off';
|
|
469
|
+
const narutoReadOnly = input.narutoWorkGraph?.readonly === true || Number(input.narutoWorkGraph?.write_allowed_count || 0) === 0;
|
|
470
|
+
const taskGraphNoWrites = Number(input.taskGraph?.write_allowed_count || 0) === 0;
|
|
471
|
+
return policyReadonly || policyWriteOff || narutoReadOnly || taskGraphNoWrites;
|
|
472
|
+
}
|
|
451
473
|
function pathWithin(file, leasePath) {
|
|
452
474
|
const left = String(file || '').replace(/\\/g, '/').replace(/^\.\//, '');
|
|
453
475
|
const right = String(leasePath || '').replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/+$/, '');
|
|
@@ -67,7 +67,8 @@ export function validateAgentWorkerResult(result) {
|
|
|
67
67
|
normalized.blockers.push(...patchEnvelopeValidation.blockers.map((issue) => 'patch_envelope_invalid:' + issue));
|
|
68
68
|
normalized.verification = { status: 'failed', checks: [...normalized.verification.checks, 'agent-patch-envelope-schema'] };
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
const readOnlyOrNoopWithoutPatch = acceptsNoPatchReadOnlyOrNoop(result?.no_patch_reason);
|
|
71
|
+
if (patchEnvelopeValidation.envelopes.length === 0 && (normalized.writes.length > 0 || (!readOnlyOrNoopWithoutPatch && normalized.changed_files.length > 0))) {
|
|
71
72
|
normalized.status = 'blocked';
|
|
72
73
|
normalized.blockers.push('no_patch_generated');
|
|
73
74
|
normalized.verification = { status: 'failed', checks: [...normalized.verification.checks, 'agent-patch-envelope-required-for-write'] };
|
|
@@ -132,4 +133,11 @@ function normalizeVerification(value) {
|
|
|
132
133
|
checks: Array.isArray(value?.checks) ? value.checks : []
|
|
133
134
|
};
|
|
134
135
|
}
|
|
136
|
+
function acceptsNoPatchReadOnlyOrNoop(value) {
|
|
137
|
+
if (!value || typeof value !== 'object')
|
|
138
|
+
return false;
|
|
139
|
+
return value.ok === true
|
|
140
|
+
&& value.read_only_or_noop_evidence === true
|
|
141
|
+
&& String(value.reason || '') === 'read_only_or_no_write_paths';
|
|
142
|
+
}
|
|
135
143
|
//# sourceMappingURL=agent-worker-pipeline.js.map
|
|
@@ -57,6 +57,7 @@ export async function runNativeWorkerBackendRouter(input) {
|
|
|
57
57
|
result = validateAgentWorkerResult({
|
|
58
58
|
...processRun,
|
|
59
59
|
patch_envelopes: patchEnvelopes,
|
|
60
|
+
...(patchEnvelopes.length ? {} : { no_patch_reason: buildNoPatchReason(input, backend) }),
|
|
60
61
|
artifacts: [...new Set([...(processRun.artifacts || []), ...(patchEnvelopes.length ? [input.patchRel] : [])])],
|
|
61
62
|
process_child_report: processReport,
|
|
62
63
|
model_authored_patch_envelopes: false,
|
|
@@ -81,6 +82,7 @@ export async function runNativeWorkerBackendRouter(input) {
|
|
|
81
82
|
...ollamaRun,
|
|
82
83
|
backend: 'ollama',
|
|
83
84
|
patch_envelopes: patchEnvelopes,
|
|
85
|
+
...(patchEnvelopes.length ? {} : { no_patch_reason: buildNoPatchReason(input, backend) }),
|
|
84
86
|
model_authored_patch_envelopes: patchEnvelopes.length > 0,
|
|
85
87
|
fixture_patch_envelopes: false,
|
|
86
88
|
verification: { status: ollamaRun.status === 'done' ? 'passed' : 'failed', checks: [...(ollamaRun.verification?.checks || []), 'native-worker-backend-router', 'ollama-api-generate'] }
|
|
@@ -147,6 +149,7 @@ export async function runNativeWorkerBackendRouter(input) {
|
|
|
147
149
|
...sdkWorkerResult,
|
|
148
150
|
backend: sdkTask.backend === 'local-llm' ? 'local-llm' : 'codex-sdk',
|
|
149
151
|
patch_envelopes: patchEnvelopes,
|
|
152
|
+
...(patchEnvelopes.length ? {} : { no_patch_reason: buildNoPatchReason(input, sdkTask.backend || backend) }),
|
|
150
153
|
codex_child_report: sdkReport,
|
|
151
154
|
codex_sdk_thread: sdkReport,
|
|
152
155
|
model_authored_patch_envelopes: patchEnvelopes.length > 0,
|
|
@@ -189,6 +192,7 @@ export async function runNativeWorkerBackendRouter(input) {
|
|
|
189
192
|
result = validateAgentWorkerResult({
|
|
190
193
|
...zellijRun,
|
|
191
194
|
patch_envelopes: patchEnvelopes,
|
|
195
|
+
...(patchEnvelopes.length ? {} : { no_patch_reason: buildNoPatchReason(input, backend) }),
|
|
192
196
|
zellij_child_report: zellijReport,
|
|
193
197
|
model_authored_patch_envelopes: false,
|
|
194
198
|
fixture_patch_envelopes: false,
|
|
@@ -279,10 +283,24 @@ function buildWorkerPrompt(slice) {
|
|
|
279
283
|
'',
|
|
280
284
|
write.length
|
|
281
285
|
? `Write-capable slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; include patch_envelopes for write_paths=${JSON.stringify(write)}.`
|
|
282
|
-
: `Read-only slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}.`,
|
|
286
|
+
: `Read-only slice. Return JSON matching ${CODEX_AGENT_WORKER_RESULT_SCHEMA_ID}; do not report pre-existing repository dirtiness as changed_files.`,
|
|
283
287
|
'Required JSON fields: status, summary, findings, changed_files, patch_envelopes, verification, rollback_notes, blockers.'
|
|
284
288
|
].join('\n');
|
|
285
289
|
}
|
|
290
|
+
function buildNoPatchReason(input, backend) {
|
|
291
|
+
const writePathCount = writePaths(input.slice, input.intake).length;
|
|
292
|
+
return {
|
|
293
|
+
schema: 'sks.native-cli-worker-no-patch-reason.v1',
|
|
294
|
+
generated_at: nowIso(),
|
|
295
|
+
ok: writePathCount === 0,
|
|
296
|
+
reason: writePathCount ? 'write_capable_task_without_backend_patch_envelope' : 'read_only_or_no_write_paths',
|
|
297
|
+
route_justification: writePathCount ? 'backend returned no patch envelopes for a write-capable task' : 'task has no write paths',
|
|
298
|
+
read_only_or_noop_evidence: writePathCount === 0,
|
|
299
|
+
task_slice_id: input.slice?.id || null,
|
|
300
|
+
backend,
|
|
301
|
+
blockers: writePathCount && backend !== 'fake' ? ['write_capable_no_patch_envelope'] : []
|
|
302
|
+
};
|
|
303
|
+
}
|
|
286
304
|
function hasWriteLease(slice, intake) {
|
|
287
305
|
return writePaths(slice, intake).length > 0;
|
|
288
306
|
}
|