Further Harness Updates
Release rolling / release (push) Successful in 12m11s

This commit is contained in:
2026-08-19 14:55:59 -04:00
parent 0373bc4d25
commit be5c11cec0
9 changed files with 1219 additions and 66 deletions
+367 -22
View File
@@ -1601,6 +1601,78 @@ function bareAgentLooksLikeGuestCliRequest(text) {
)
}
/**
* User asked for a mutating/action job, not a definition.
* @param {string} text
*/
function bareAgentLooksLikeActionRequest(text) {
const s = String(text || '').toLowerCase()
if (!s.trim()) return false
return (
/\b(create|write|make|add|put|place|move|rename|copy|delete|remove|fix|implement|build|install|edit|patch|run)\b/.test(
s
) ||
/\b(director(y|ies)|files?|scripts?|bin utils?)\b/.test(s)
)
}
/**
* Assistant is asking the operator to choose instead of finishing.
* @param {string} text
*/
function bareAgentLooksLikeQuestionDump(text) {
const s = String(text || '')
if (!s.trim()) return false
const low = s.toLowerCase()
if (
/would you like( me)? to/.test(low) ||
/do you want me to/.test(low) ||
/should i (create|move|rename|run|write|add|make)/.test(low) ||
/you('d| would) need to:/.test(low) ||
/the user might need to/.test(low) ||
/let me know if you want/.test(low) ||
/shall i /.test(low)
) {
return true
}
if (
/would you like/.test(low) &&
/\n\s*1[\).:]/.test(s) &&
/\n\s*2[\).:]/.test(s)
) {
return true
}
return false
}
/**
* Claimed a file exists / was named without a verifying tool result.
* @param {string} text
*/
function bareAgentLooksLikeUnverifiedFileClaim(text) {
const s = String(text || '').toLowerCase()
if (!s.trim()) return false
return (
/has been (created|placed|moved|renamed|written|copied) (successfully )?(in|to|at|into)/.test(
s
) ||
/the file will be named/.test(s) ||
/is now in the (correct |right )?location/.test(s) ||
/scripts? (are|is) now in/.test(s)
)
}
/**
* Permission-style ask_user_question payload (create/move/rename).
* @param {unknown} questions
*/
function bareAgentLooksLikePermissionQuestions(questions) {
const blob = JSON.stringify(questions || '').toLowerCase()
return /would you like|do you want me to|should i |create a script|move the|rename the|add additional/.test(
blob
)
}
/** ~/.agent paths, config, history trim, man digest (preamble for /bin/agent). */
/**
@@ -7121,11 +7193,16 @@ function bareAgentToolDefinitions() {
function: {
name: 'run_js_script',
description:
'Run custom guest JavaScript only. Do not use this for curl, wget, ip, ping, or any shell — call run_command. Do not use this to replace read_file, write_file, list_directory, or run_command. Node is not installed. Writes ~/.agent/_tmp_agent_run.mjs and runs it on the Bare kernel. ctx and argv are already injected — never declare them, never export. Body must be: async function run(ctx, argv) { const vfs = ctx.vfs; ... }',
'Run custom guest JavaScript only. Do not use this for curl, wget, ip, ping, or any shell — call run_command. Do not use this to replace read_file, write_file, list_directory, or run_command. Without path=, this ONLY writes a throwaway ~/.agent/_tmp_agent_run.mjs — that is not a user file. Pass path=~/test/name.js (or call write_file) to persist. Node is not installed. ctx and argv are already injected — never declare them, never export. Body must be: async function run(ctx, argv) { const vfs = ctx.vfs; ... }',
parameters: {
type: 'object',
properties: {
code: { type: 'string', description: 'Full ESM/CommonJS script body' }
code: { type: 'string', description: 'Full ESM/CommonJS script body' },
path: {
type: 'string',
description:
'If set, persist the script here (absolute or ~/...) then run it. Use this when the user asked you to create a file.'
}
},
required: ['code']
}
@@ -8663,7 +8740,8 @@ async function bareAgentDispatchTool(o) {
'destination',
'target',
'old_path',
'new_path'
'new_path',
'save_as'
]
let cwdForExpand = resolvedHome
if (paths && paths.lastCwd && typeof bareAgentReadTextFile === 'function') {
@@ -9197,6 +9275,18 @@ async function bareAgentDispatchTool(o) {
}
if (toolName === 'ask_user_question') {
const previewQs = args.questions
if (
typeof bareAgentLooksLikePermissionQuestions === 'function' &&
bareAgentLooksLikePermissionQuestions(previewQs)
) {
return bareAgentJsonResult({
ok: false,
error: 'execute_instead',
hint:
'Do not ask the operator whether to create/move/rename/run. Call write_file, move_path, list_directory now. Keep going until the files exist.'
})
}
const rows = Array.isArray(args.questions) ? args.questions : []
if (!rows.length) {
return bareAgentJsonResult({ ok: false, error: 'questions_required' })
@@ -9282,6 +9372,19 @@ async function bareAgentDispatchTool(o) {
summary
})
}
if (
typeof bareAgentLooksLikeQuestionDump === 'function' &&
bareAgentLooksLikeQuestionDump(summary)
) {
appendProgress('task_complete_rejected_questions')
return bareAgentJsonResult({
ok: false,
error: 'task_not_complete',
hint:
'That is a question for the operator, not a finish. Call write_file / move_path / list_directory and finish the goal. If blocked, return a BLOCKED REPORT (paths, tool errors, what exists, what is missing).',
summary
})
}
appendProgress('task_complete: ' + summary.slice(0, 200))
onTaskComplete(summary || '(done)')
return bareAgentJsonResult({
@@ -9751,16 +9854,44 @@ async function bareAgentDispatchTool(o) {
typeof bareAgentNormalizeGuestScript === 'function'
? bareAgentNormalizeGuestScript(rawCode)
: rawCode
const scriptPath = paths.dir + '/_tmp_agent_run.mjs'
const persistPath =
(typeof args.path === 'string' && args.path.trim()) ||
(typeof args.file_path === 'string' && args.file_path.trim()) ||
(typeof args.save_as === 'string' && args.save_as.trim()) ||
''
const tempPath = paths.dir + '/_tmp_agent_run.mjs'
let scriptPath = tempPath
if (
persistPath &&
persistPath !== tempPath &&
persistPath.startsWith('/') &&
!persistPath.includes('..')
) {
const persist = await bareAgentDispatchTool({
...o,
toolName: 'write_file',
argsJson: JSON.stringify({ path: persistPath, content: code })
})
let persistOk = false
try {
const pj = JSON.parse(persist)
persistOk = Boolean(pj && pj.ok)
} catch {
persistOk = false
}
if (persistOk) scriptPath = persistPath
}
if (!vfs?.writeFile || !execLine) {
return bareAgentJsonResult({ ok: false, error: 'vfs or execLine' })
}
appendProgress('run_js_script (' + code.length + ' chars)')
const body =
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
? ctx.b4a.from(code)
: new TextEncoder().encode(code)
await vfs.writeFile(scriptPath, body)
appendProgress('run_js_script (' + code.length + ' chars) path=' + scriptPath)
if (scriptPath === tempPath) {
const body =
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
? ctx.b4a.from(code)
: new TextEncoder().encode(code)
await vfs.writeFile(scriptPath, body)
}
/** Absolute path → kernel-runner runs .mjs like `./script.mjs` (no host `node` binary). captureExec adds stdout redirect. */
const cmd = bareAgentShellQuote(scriptPath)
const r = await captureExec(cmd, 60000)
@@ -9789,8 +9920,29 @@ async function bareAgentDispatchTool(o) {
stdout_stderr: text
})
}
const persisted = scriptPath !== tempPath
const persistHint = persisted
? 'Script persisted and executed at ' + scriptPath
: 'run_js_script only ran a throwaway temp file at ' +
tempPath +
'. That is NOT a user file. To create a lasting script call write_file({path, content}) then list_directory the destination.'
return bareAgentJsonResult(
r.ok === false ? r : { ok: true, stdout_stderr: r.stdout_stderr }
r.ok === false
? {
ok: false,
error: out.error || 'run_js_script_failed',
stdout_stderr: text,
ran_from: scriptPath,
persisted_to: persisted ? scriptPath : null,
hint: persistHint
}
: {
ok: true,
stdout_stderr: r.stdout_stderr,
ran_from: scriptPath,
persisted_to: persisted ? scriptPath : null,
hint: persistHint
}
)
}
@@ -10014,26 +10166,118 @@ async function bareAgentDispatchTool(o) {
}
if (toolName === 'move_path') {
const from = typeof args.from_path === 'string' ? args.from_path : ''
const to = typeof args.to_path === 'string' ? args.to_path : ''
let from =
(typeof args.from_path === 'string' && args.from_path.trim()) ||
(typeof args.from === 'string' && args.from.trim()) ||
(typeof args.src === 'string' && args.src.trim()) ||
(typeof args.source === 'string' && args.source.trim()) ||
(typeof args.old_path === 'string' && args.old_path.trim()) ||
''
let to =
(typeof args.to_path === 'string' && args.to_path.trim()) ||
(typeof args.to === 'string' && args.to.trim()) ||
(typeof args.dest === 'string' && args.dest.trim()) ||
(typeof args.destination === 'string' && args.destination.trim()) ||
(typeof args.new_path === 'string' && args.new_path.trim()) ||
''
if (!from && paths.dir) {
const tmp = paths.dir + '/_tmp_agent_run.mjs'
try {
if (vfs && typeof vfs.readFile === 'function') {
const buf = await vfs.readFile(tmp)
if (buf) from = tmp
}
} catch {
/* no temp */
}
}
if (!from || !to) {
return bareAgentJsonResult({
ok: false,
error: 'from_and_to_required',
hint: 'move_path needs from_path and to_path (absolute or ~/...). To rename the throwaway script, from_path=~/.agent/_tmp_agent_run.mjs to_path=~/test/bareos-cli.js'
})
}
if (
!bareAgentPathAllowedMutate(from, mutateDenyPrefixes) ||
!bareAgentPathAllowedMutate(to, mutateDenyPrefixes) ||
from.includes('..') ||
to.includes('..')
) {
return bareAgentJsonResult({ ok: false, error: 'path_not_allowed' })
return bareAgentJsonResult({ ok: false, error: 'path_not_allowed', from, to })
}
let finalTo = to
try {
const st =
vfs && typeof vfs.lstat === 'function'
? await vfs.lstat(to)
: vfs && typeof vfs.stat === 'function'
? await vfs.stat(to)
: null
const isDir =
st &&
((typeof st.isDirectory === 'function' && st.isDirectory()) ||
(st && st.kind === 'dir'))
if (isDir) {
let base = from.split('/').filter(Boolean).pop() || 'file'
if (base === '_tmp_agent_run.mjs') {
const named =
(typeof args.filename === 'string' && args.filename.trim()) ||
(typeof args.name === 'string' && args.name.trim()) ||
'cli.js'
base = named.replace(/^.*\//, '')
}
finalTo = to.replace(/\/+$/, '') + '/' + base
}
} catch {
/* dest does not exist yet — treat as file path */
}
if (!execLine) {
return bareAgentJsonResult({ ok: false, error: 'execLine unavailable' })
}
appendProgress('move_path')
appendProgress('move_path ' + from + ' -> ' + finalTo)
const parent = finalTo.replace(/\/[^/]+$/, '')
if (parent && parent !== finalTo && vfs && typeof vfs.mkdir === 'function') {
try {
await vfs.mkdir(parent, { recursive: true })
} catch {
/* optional */
}
}
const cmd =
'mv -- ' + bareAgentShellQuote(from) + ' ' + bareAgentShellQuote(to)
'mv -- ' + bareAgentShellQuote(from) + ' ' + bareAgentShellQuote(finalTo)
const r = await captureExec(cmd, 120000)
return bareAgentJsonResult(
r.ok === false ? r : { ok: true, stdout_stderr: r.stdout_stderr }
)
if (r && r.ok === false) {
return bareAgentJsonResult({ ...r, from, to: finalTo })
}
let verified = false
try {
if (vfs && typeof vfs.lstat === 'function') verified = Boolean(await vfs.lstat(finalTo))
else if (vfs && typeof vfs.stat === 'function') verified = Boolean(await vfs.stat(finalTo))
else if (vfs && typeof vfs.readFile === 'function') {
const got = await vfs.readFile(finalTo)
verified = got != null
}
} catch {
verified = false
}
if (!verified) {
return bareAgentJsonResult({
ok: false,
error: 'move_not_visible',
from,
to: finalTo,
stdout_stderr: r && r.stdout_stderr,
hint: 'mv ran but destination is not visible. Retry with absolute paths and list_directory the target folder.'
})
}
return bareAgentJsonResult({
ok: true,
from,
to: finalTo,
verified: true,
stdout_stderr: r && r.stdout_stderr
})
}
if (toolName === 'delete_path') {
@@ -13777,7 +14021,7 @@ Bare OS by Raven Scott (https://raven-scott.fyi). Repo: https://git.ssh.surf/snx
WORK POLICY.
- Keep every explicit requirement in view until it is done, superseded, or blocked. If blocked, say so plainly.
- Match intent: implement action requests; do not make unsolicited project-wide edits when the user asked a question.
- For clear, reversible local work, do it now. NEVER ASK for permission.
- For clear, reversible local work, do it now. NEVER ASK for permission. Never ask "would you like me to". Pick a reasonable name and do it. Keep calling tools until the original request is verified (list_directory / file_stat / stdout). If you cannot finish, call task_complete with a BLOCKED REPORT: goal, every path tried, verbatim tool errors, what exists now, what is missing. Do not stop to ask questions.
- Claim done, fixed, or tested only when a tool result supports it. Otherwise say what you did not verify.
- Scope to what was asked. Comments are short and factual. No placeholders. Comments must not substitute for a fix.
@@ -13787,13 +14031,13 @@ ACCESS (denylist, not allowlist). You already have full guest admin. You can cre
- Read any absolute path, including /proc (read_proc_file, runtime_diagnostic_bundle). Use read_file offset/limit for large files.
- Run every guest command via run_command (command_deny is empty by default). Prefer list_directory, glob_files, and file_stat over ls/find when you only need names. list_bin lists guest /bin utilities (POSIX-in-JS, not GNU). Never dump curl/ip/ls for the user — call run_command and report stdout.
- Delete and move are enabled. Do not mutate the read-only base system: /bin /etc /boot /lib /usr /share /proc /dev /sys /run.
- Node is not installed in the guest. Never plan or run node, npm, or npx here. Do not use run_js_script to read files, write files, or run shell — call read_file, write_file, run_command instead. curl/wget/ip/ping are run_command({command:"curl -s https://api.ipify.org"}), never run_js_script. Only use run_js_script for custom guest JS. The kernel already injects ctx and argv: never write const/let/var ctx, never export. Body must be only async function run(ctx, argv) { const vfs = ctx.vfs; ... }. Do not import Node builtins. Never paste a "final correct script" into the user reply — call the tool.
- Node is not installed in the guest. Never plan or run node, npm, or npx here. Do not use run_js_script to read files, write files, or run shell — call read_file, write_file, run_command instead. curl/wget/ip/ping are run_command({command:"curl -s https://api.ipify.org"}), never run_js_script. run_js_script always writes a throwaway ~/.agent/_tmp_agent_run.mjs — that is NOT a user file. To create a lasting script in ~/test, call write_file({path:"~/test/name.js", content}) (or pass path= to run_js_script to persist). Then list_directory that folder. Only use run_js_script for custom guest JS. The kernel already injects ctx and argv: never write const/let/var ctx, never export. Body must be only async function run(ctx, argv) { const vfs = ctx.vfs; ... }. Do not import Node builtins. Never paste a "final correct script" into the user reply — call the tool.
- Live kernel: read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json. Man pages and apropos_man are documentation only — never infer what is enabled from them.
- web_fetch uses the same host allow/deny list as wget/curl.
- emit_host_notification and request_host_action are enabled by default. emergency_stop_mutations is the kill switch.
- DISCORD CHANNEL: You have a Direct Message channel with the operator. Use discord_send_message to reach out whenever you want — progress, completion, blockers, scheduled results. Do not wait for them to message first. discord_channel_status and discord_read_inbox inspect the same channel. Only whitelisted users receive DMs.
- Never print ~/.agent/config.json, API keys, seeds, or vault material.
- ask_user_question is only for a real product choice the user must make. Never use it (or chat) to request permission.
- ask_user_question is only for a real product choice the user must make. Never use it (or chat) to request permission. Never offer numbered menus ("Would you like me to: 1. …"). Execute.
CODING LOOP. Multi-step work: todo_write (merge=true). Large unknown surface: enter_plan_mode, write ~/.agent/plan.md, exit_plan_mode, then implement. Plan mode is read-only except that plan file. Do not stop after a plan-only reply — keep calling tools until verified.
1. Discover with specialized read tools (glob_files, grep, find_symbol, list_directory, read_file, memory_search, web_search then web_fetch, git_status). Call read_skill when a skill matches. Read before you edit. Walk-up AGENTS.md and .grok/skills from cwd are already injected when present.
@@ -14152,6 +14396,18 @@ function bareAgentRefusalNudge() {
)
}
/**
* Bounce a question-menu / unverified file claim back into the tool loop.
*/
function bareAgentGoalDriveNudge(kind) {
const k = String(kind || 'continue')
return (
'[harness] Do not ask the operator questions. Do not stop. kind=' +
k +
'. run_js_script is throwaway (~/.agent/_tmp_agent_run.mjs) — that is not a user file. Create lasting files with write_file({path, content}). Move/rename with move_path({from_path, to_path}). Then list_directory the destination and only then claim done. If blocked, task_complete with a BLOCKED REPORT: goal, paths tried, verbatim tool errors, what list_directory shows, what is missing. Call the next tool now.'
)
}
/**
* Recover tool calls the provider streamed as plain text (Hermes / Qwen XML,
* ```bash fences, Grok/Claude `bash` dumps) instead of `delta_tool_calls`.
@@ -15638,6 +15894,13 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
const maxIterBase = Number(configRef.current.max_iterations) || 64
let iter = 0
let instructionDumpNudges = 0
let goalDriveNudges = 0
let sawFileMutation = false
let sawFileVerify = false
const driveGoal =
typeof bareAgentLooksLikeActionRequest === 'function'
? bareAgentLooksLikeActionRequest(task)
: true
for (;;) {
if (masterAbort.signal.aborted) {
@@ -16422,6 +16685,42 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
await bareAgentSaveHistory(ctx, paths.history, messages)
continue
}
const questionDump =
typeof bareAgentLooksLikeQuestionDump === 'function' &&
bareAgentLooksLikeQuestionDump(assistantContent)
const unverifiedClaim =
typeof bareAgentLooksLikeUnverifiedFileClaim === 'function' &&
bareAgentLooksLikeUnverifiedFileClaim(assistantContent)
const needsVerify = sawFileMutation && !sawFileVerify
const neverStarted = driveGoal && !sawFileMutation && !sawFileVerify
const shouldDrive =
questionDump ||
needsVerify ||
(unverifiedClaim && !sawFileVerify) ||
neverStarted
if (goalDriveNudges < 5 && shouldDrive) {
goalDriveNudges += 1
const kind =
goalDriveNudges >= 5
? 'last_chance_report'
: questionDump
? 'questions'
: needsVerify
? 'need_list_directory'
: unverifiedClaim
? 'unverified_claim'
: 'continue'
messages.push({
role: 'user',
content:
typeof bareAgentGoalDriveNudge === 'function'
? bareAgentGoalDriveNudge(kind)
: '[harness] Keep going. Call write_file / move_path / list_directory. Do not ask questions.'
})
appendProgress('goal_drive_nudge n=' + String(goalDriveNudges) + ' kind=' + kind)
await bareAgentSaveHistory(ctx, paths.history, messages)
continue
}
if (
bareAgentAutonomousShouldContinue(configRef.current, {
completed: completed,
@@ -16520,6 +16819,35 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
bareAgentWriteOut(ctx, stdout, spinner + '\r')
statusLineActive = true
if (
name === 'write_file' ||
name === 'create_directory' ||
name === 'move_path' ||
name === 'copy_path' ||
name === 'delete_path' ||
name === 'edit_file' ||
name === 'search_replace' ||
name === 'apply_patch'
) {
sawFileMutation = true
}
if (name === 'run_js_script') {
try {
const a = JSON.parse(argsStr || '{}')
if (a && (a.path || a.file_path || a.save_as)) sawFileMutation = true
} catch {
/* ignore */
}
}
if (
name === 'list_directory' ||
name === 'file_stat' ||
name === 'read_file' ||
name === 'glob_files'
) {
sawFileVerify = true
}
let resultStr = await bareAgentDispatchTool({
ctx,
toolName: name,
@@ -16532,6 +16860,23 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
manCacheRef,
onTaskComplete
})
if (name === 'task_complete') {
let parsedTc = null
try {
parsedTc = JSON.parse(resultStr)
} catch {
parsedTc = null
}
if (parsedTc && parsedTc.ok && sawFileMutation && !sawFileVerify) {
completed = false
resultStr = JSON.stringify({
ok: false,
error: 'not_verified',
hint:
'You created or moved files but never listed them. Call list_directory on the destination, then task_complete with what it shows. If blocked, return a BLOCKED REPORT.'
})
}
}
if (typeof bareAgentRunHooks === 'function' && paths.hooks) {
try {
let parsedArgs = {}