zob-harness 0.1.0 → 0.1.1

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.
@@ -1409,7 +1409,7 @@
1409
1409
  "AGENTS.md",
1410
1410
  "docs/ZOB_ADAPTIVE_WORKFLOW_RUNTIME_PLAN.md"
1411
1411
  ],
1412
- "noShipNotes": "Switches active harness mode only. orchestrator routes to adaptive-chief-vision plan_only defaults; child dispatch requires parent-owned contract/preflight gates and writes remain blocked without sandbox/oracle/human approval."
1412
+ "noShipNotes": "Switches active harness mode only. orchestrator routes to adaptive-chief-vision plan_only defaults; vanilla restores Pi base-style unrestricted tool access outside ZOB governance and disables ZOB-specific bash mutation blocks. Child dispatch in governed modes requires parent-owned contract/preflight gates and writes remain blocked without sandbox/oracle/human approval."
1413
1413
  },
1414
1414
  {
1415
1415
  "name": "stop",
@@ -64,6 +64,8 @@ export const MODE_TOOLS: Record<ModeName, string[]> = {
64
64
  oracle: ["read", "grep", "find", "ls", "bash", "delegate_agent", "delegate_task", "zob_coms_list", "zob_coms_get", "zob_coms_await", "zpeer_ask", "zob_goal_room_list", "zob_workspace_claims_list", "zob_worker_pool_status", "zob_merge_queue_list", ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_AUTONOMOUS_READ_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS],
65
65
  orchestrator: ["read", "grep", "find", "ls", "delegate_agent", "delegate_task", "orchestrate_run", "chain_run", ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS],
66
66
  factory: ["read", "bash", "edit", "write", "grep", "find", "ls", "delegate_agent", "delegate_task", "orchestrate_run", "factory_run", "factory_quarantine_review", "factory_quarantine_activate", "factory_quarantine_verify_activation", "chain_run", ...ZOB_RUNTIME_GOAL_TOOLS, ...ZOB_DELEGATION_READ_TOOLS, ...ZOB_ZCOMMIT_TOOLS, ...ZOB_AUTONOMOUS_READ_TOOLS, ...ZOB_AUTONOMOUS_FACTORY_TOOLS, ...ZOB_COMS_TOOLS, ...ZOB_GOAL_ROOM_TOOLS, ...ZOB_GOVERNED_REQUEST_TOOLS, ...ZOB_WORKSPACE_CLAIM_TOOLS, ...ZOB_WORKER_POOL_TOOLS, ...ZOB_MERGE_QUEUE_TOOLS, ...ZOB_MISSION_CONTROL_READ_TOOLS, ...ZOB_MISSION_CONTROL_PROPOSAL_TOOLS, ...ZOB_CONTEXT_READ_TOOLS, ...ZOB_CONTEXT_PROPOSAL_TOOLS, ...ZOB_COMPUTE_READ_TOOLS, ...ZOB_COMPUTE_REPORT_TOOLS, ...ZOB_PROJECT_DNA_READ_TOOLS, ...ZOB_PROJECT_DNA_PROPOSAL_TOOLS],
67
+ // Vanilla is handled specially by applyMode: all currently available Pi tools are enabled.
68
+ vanilla: [],
67
69
  };
68
70
 
69
71
  export const MODE_PROMPTS: Record<ModeName, string> = {
@@ -105,4 +107,10 @@ export const MODE_PROMPTS: Record<ModeName, string> = {
105
107
  - Turn repeated work into reusable prompts, agents, scripts, schemas, or Pi extensions.
106
108
  - Prefer deterministic scaffolding for immutable content; let LLMs enrich structured sections only.
107
109
  - Require sentinel/completion artifacts and validation before scale-up.`,
110
+ vanilla: `ZOB MODE: VANILLA (Pi base-style unrestricted agent)
111
+ - Behave like the base Pi coding agent rather than a governed ZOB workflow agent.
112
+ - ZOB-specific Explore/Plan/Implement/Oracle routing, tool-routing, TODO/goal governance, and bash mutation blocks are disabled for this mode.
113
+ - You may use any available Pi tool and launch arbitrary shell commands, including external coding tools such as codex or project scripts that modify files.
114
+ - Do not claim ZOB safety/oracle/governance guarantees while in vanilla; the user is intentionally choosing direct operator-style execution.
115
+ - Keep normal conversational clarity: state what you are about to run when useful, then execute directly and report results.`,
108
116
  };
@@ -64,7 +64,7 @@ function chooseModelClass(input: ModelRoutingDryRunInput): { modelClass: ModelCl
64
64
  const risk = normalizeRisk(input.risk);
65
65
  const contextTokens = numberOrZero(input.contextTokens);
66
66
  const isOracleLike = includesAny(input.taskType, ["oracle", "review", "validate"]) || includesAny(input.outputContract, ["oracle"]);
67
- const isImplementationLike = includesAny(input.taskType, ["implement", "factory", "synthesis", "worker"]) || input.mode === "implement" || input.mode === "factory";
67
+ const isImplementationLike = includesAny(input.taskType, ["implement", "factory", "synthesis", "worker"]) || input.mode === "implement" || input.mode === "factory" || input.mode === "vanilla";
68
68
 
69
69
  if (contextTokens >= 120_000) {
70
70
  reasonCodes.push("context_tokens_high");
@@ -239,7 +239,7 @@ export function validateModelRoutingConfig(repoRoot: string): Record<string, unk
239
239
  }
240
240
 
241
241
  const expectedClasses: ModelClass[] = ["cheap_scout", "balanced_worker", "strong_reasoning", "strong_oracle", "high_context"];
242
- const modes: ModeName[] = ["explore", "plan", "implement", "oracle", "factory", "orchestrator"];
242
+ const modes: ModeName[] = ["explore", "plan", "implement", "oracle", "factory", "orchestrator", "vanilla"];
243
243
  const modelClasses = isRecord(parsed?.modelClasses) ? parsed.modelClasses : undefined;
244
244
  const defaults = isRecord(parsed?.defaults) ? parsed.defaults : undefined;
245
245
  const byMode = isRecord(defaults?.byMode) ? defaults.byMode : undefined;
@@ -8,7 +8,7 @@ import { isRecord } from "./utils/records.js";
8
8
  const RULE_PACK_SCHEMA = "zob.rule-pack.v1";
9
9
  const RULE_RESOLUTION_SCHEMA = "zob.rule-resolution.v1";
10
10
  const RULE_PACK_ORDER = ["always", "project", "runtime", "factory", "orchestration", "prompts", "docs", "sandbox", "oracle"];
11
- const MODE_NAMES = new Set<ModeName>(["explore", "plan", "implement", "oracle", "factory", "orchestrator"]);
11
+ const MODE_NAMES = new Set<ModeName>(["explore", "plan", "implement", "oracle", "factory", "orchestrator", "vanilla"]);
12
12
  const ENFORCEMENT_LEVELS = new Set<RuleEnforcementLevel>(["advisory", "warn", "preflight_fail", "block", "no_ship", "human_approval"]);
13
13
 
14
14
  const PROFILE_PATHS: Array<{ profile: string; patterns: string[] }> = [
@@ -547,7 +547,7 @@ function delegationArgumentCompletions(state: HarnessRuntimeState, prefix: strin
547
547
 
548
548
  export function registerHarnessCommands(pi: ExtensionAPI, state: HarnessRuntimeState): void {
549
549
  pi.registerCommand("zmode", {
550
- description: "Switch ZOB harness mode: explore | plan | implement | oracle | factory | orchestrator. Orchestrator routes to adaptive-chief-vision plan_only defaults.",
550
+ description: "Switch ZOB harness mode: explore | plan | implement | oracle | factory | orchestrator | vanilla. Orchestrator routes to adaptive-chief-vision plan_only defaults; vanilla restores Pi base-style unrestricted tool access outside ZOB governance.",
551
551
  handler: async (args, ctx) => {
552
552
  const requestedText = args.trim();
553
553
  const adaptiveEntrypoint = resolveAdaptiveZmodeEntrypoint(requestedText);
@@ -106,13 +106,14 @@ function buildZpeerAwarenessPrompt(state: HarnessRuntimeState, repoRoot: string)
106
106
  const SAME_AGENT_MODE_INTENT_PROMPT = [
107
107
  "ZOB SAME-AGENT AUTO-MODE INTENT",
108
108
  "- If the current ZOB mode does not match the next required action, emit at most one standalone intent line:",
109
- " <zob_mode_intent mode=\"explore|plan|implement|oracle|factory|orchestrator\" confidence=\"low|medium|high\" risk=\"low|medium|high\" reason=\"short reason\"/>",
109
+ " <zob_mode_intent mode=\"explore|plan|implement|oracle|factory|orchestrator|vanilla\" confidence=\"low|medium|high\" risk=\"low|medium|high\" reason=\"short reason\"/>",
110
110
  "- This is only a suggestion; the harness validates and applies mode changes.",
111
111
  "- Do not claim the mode switched unless the harness reports it.",
112
112
  "- SINGLE-PLAN RULE: if you produce a complete plan in this response, do not also emit a plan-mode intent.",
113
113
  "- Emit mode=plan only when deferring the actual detailed plan to a follow-up turn; in that case keep this response to a short handoff.",
114
114
  "- Never both: full plan content and mode=plan intent in the same response.",
115
115
  "- Prefer orchestrator for multi-agent decomposition, Chief Vision coordination, Lead/Worker orchestration, TODO/workgraph routing, and parent-owned dispatch.",
116
+ "- Prefer vanilla when the user explicitly asks for Pi base behavior, Vanilla/Vania, Codex, unrestricted/external commands, or arbitrary shell tools outside ZOB governance.",
116
117
  "- Prefer implement for code/file edits, oracle for validation/review/no-ship, factory for reusable repeatable workflows/factories.",
117
118
  "- Do not emit an intent for ordinary discussion or when the current mode already fits.",
118
119
  ].join("\n");
@@ -145,6 +146,7 @@ function handleSameAgentModeIntent(pi: ExtensionAPI, state: HarnessRuntimeState,
145
146
  state.lastModeIntent = { ...intent, at: Date.now(), accepted: validation.accepted, validationReason: validation.reason };
146
147
  if (validation.accepted) {
147
148
  applyMode(pi, state, ctx, intent.mode);
149
+ state.activeRuleResolution = resolveRuleProfile({ repoRoot: ctx.cwd, mode: state.activeMode });
148
150
  ctx.ui.notify(`ZOB same-agent auto-mode: ${previousMode} → ${intent.mode} (${intent.confidence}; ${intent.reason})`, "info");
149
151
  } else {
150
152
  renderHarnessWidget(pi, state, ctx);
@@ -458,16 +460,21 @@ export function registerHarnessEvents(pi: ExtensionAPI, state: HarnessRuntimeSta
458
460
  else if (readiness.decision === "block") ctx.ui.notify(formatMissionReadinessForUi(readiness), "warning");
459
461
  }
460
462
  }
461
- if (event.source === "extension" || state.activeMode !== "explore") return { action: "continue" as const };
463
+ if (event.source === "extension") return { action: "continue" as const };
462
464
  const nextMode = inferModeFromUserIntent(event.text);
463
- if (!nextMode) return { action: "continue" as const };
465
+ if (!nextMode || nextMode === state.activeMode) return { action: "continue" as const };
466
+ if (state.activeMode !== "explore" && nextMode !== "vanilla") return { action: "continue" as const };
467
+ const previousMode = state.activeMode;
464
468
  applyMode(pi, state, ctx, nextMode);
465
- const reason = nextMode === "orchestrator" ? "orchestration intent detected" : nextMode === "factory" ? "factory workflow intent detected" : "write/update intent detected";
466
- ctx.ui.notify(`ZOB auto-mode: explore ${nextMode} (${reason})`, "info");
469
+ state.activeRuleResolution = resolveRuleProfile({ repoRoot: ctx.cwd, mode: state.activeMode });
470
+ const reason = nextMode === "orchestrator" ? "orchestration intent detected" : nextMode === "factory" ? "factory workflow intent detected" : nextMode === "vanilla" ? "vanilla/Pi base or external-command intent detected" : "write/update intent detected";
471
+ ctx.ui.notify(`ZOB auto-mode: ${previousMode} → ${nextMode} (${reason})`, "info");
467
472
  return { action: "continue" as const };
468
473
  });
469
474
 
470
475
  pi.on("tool_call", async (event, ctx) => {
476
+ if (state.activeMode === "vanilla") return { action: "continue" as const };
477
+
471
478
  let violation: string | undefined;
472
479
  let attempted = JSON.stringify(event.input);
473
480
 
@@ -680,6 +687,9 @@ export function registerHarnessEvents(pi: ExtensionAPI, state: HarnessRuntimeSta
680
687
  : "\n\nZOB RULE PROFILE\n- Not resolved yet. Use /rules_status for diagnostics when scope is unclear.";
681
688
  const autonomyHint = `\n\n${formatInteractiveAutonomyPromptHint(state.autonomy)}`;
682
689
  const zpeerHint = buildZpeerAwarenessPrompt(state, state.zobLive.inbound?.repoRoot ?? process.cwd());
690
+ if (state.activeMode === "vanilla") {
691
+ return { systemPrompt: `${event.systemPrompt}\n\n${MODE_PROMPTS.vanilla}` };
692
+ }
683
693
  const contractHint = `\n\nZOB HARNESS OPERATING CONTRACT\n- Prefer Explore -> Plan -> Implement -> Oracle for non-trivial work.\n- Use the six-part contract for delegated work: TASK / EXPECTED OUTCOME / REQUIRED TOOLS / MUST DO / MUST NOT DO / CONTEXT.\n- Do not claim completion without concrete evidence.\n- If output may truncate, prioritize verdict, blockers, and next steps over exhaustive listings.\n\n${SAME_AGENT_MODE_INTENT_PROMPT}\n\n${ZOB_TOOL_ROUTING_CONTRACT}\n\n${ZOB_COMPACTION_CONTINUITY_CONTRACT}\n\n${MODE_PROMPTS[state.activeMode]}${goalHint}${runtimeGoalHint}${rulesHint}${autonomyHint}${zpeerHint}`;
684
694
  return { systemPrompt: `${event.systemPrompt}${contractHint}` };
685
695
  });
@@ -15,7 +15,7 @@ export interface ZobModeIntentValidation {
15
15
  reason: string;
16
16
  }
17
17
 
18
- const VALID_MODES: readonly ModeName[] = ["explore", "plan", "implement", "oracle", "factory", "orchestrator"];
18
+ const VALID_MODES: readonly ModeName[] = ["explore", "plan", "implement", "oracle", "factory", "orchestrator", "vanilla"];
19
19
 
20
20
  function modeName(value: string | undefined): ModeName | undefined {
21
21
  return VALID_MODES.includes(value as ModeName) ? value as ModeName : undefined;
@@ -118,6 +118,7 @@ function hasModeEvidence(mode: ModeName, text: string): boolean {
118
118
  if (mode === "orchestrator") return /\b(orchestrator|orchestrat(?:e|ion|or)|orchestrer|multi[- ]?agent|lead(?:s)?|worker(?:s)?|chief vision|coordonn(?:e|er|ation)|d[eé]l[eè]gu(?:e|er|ation)|delegat(?:e|ion)|sub[- ]?agents?|subtasks?|work graph|todo graph|graphe de travail|graphe todo)\b/i.test(text);
119
119
  if (mode === "factory") return /\b(factory|factory_run|pilot|batch|sentinel|manifest|quarantine|software factory)\b/i.test(text);
120
120
  if (mode === "implement") return /\b(update|modify|modifier|change|changer|fix|patch|implement|impl[eé]mente|edit|write|[eé]cris|ajoute|add|create|cr[eé]e|refactor|refactorise|remplace|am[eé]lior(?:e|er)|appliqu(?:e|er)|mets?|mettre|rends?|rendre|fais\s+en\s+sorte)\b/i.test(text);
121
+ if (mode === "vanilla") return /\b(vanilla|vania|pi\s+base|agent\s+pi\s+de\s+base|base\s+pi|codex|external\s+(?:command|tool|agent)|commande\s+externe|outil\s+externe|unrestricted|arbitrary\s+command|n['’]?importe\s+quelle\s+commande|sans\s+r[eé]glementation|sans\s+garde[- ]?fous|no\s+guardrails?)\b/i.test(text);
121
122
  if (mode === "oracle") return /\b(review|validate|validation|oracle|no[_-]?ship|v[eé]rifie|audit|qa|risks?|blocker)\b/i.test(text);
122
123
  if (mode === "plan") return /\b(plan|design|architecture|propose|roadmap|spec|sp[eé]cifie|comment|how would|strat[eé]gie)\b/i.test(text);
123
124
  return /\b(read|explore|inspect|analy[sz]e|cherche|comprends?|trouve|diagnostic)\b/i.test(text);
@@ -137,6 +138,9 @@ export function validateModeIntent(intent: ZobModeIntent | undefined, currentMod
137
138
  if ((intent.mode === "implement" || intent.mode === "factory" || intent.mode === "orchestrator") && intent.confidence !== "high" && !evidence) {
138
139
  return { accepted: false, reason: `mode ${intent.mode} requires high confidence or explicit evidence` };
139
140
  }
141
+ if (intent.mode === "vanilla" && !evidence) {
142
+ return { accepted: false, reason: "vanilla mode requires explicit user-text evidence for Pi base/unrestricted external-command behavior" };
143
+ }
140
144
  if (intent.mode === "oracle" && intent.confidence === "medium" && !evidence) {
141
145
  return { accepted: false, reason: "oracle mode requires review/validation evidence" };
142
146
  }
@@ -389,6 +389,8 @@ export function restoreHarnessState(state: HarnessRuntimeState, ctx: ExtensionCo
389
389
  export function inferModeFromUserIntent(text: string): ModeName | undefined {
390
390
  const normalized = text.trim().toLowerCase();
391
391
  if (!normalized || normalized.startsWith("/")) return undefined;
392
+ const asksForVanilla = /\b(vanilla|vania|pi\s+base|agent\s+pi\s+de\s+base|base\s+pi|codex|external\s+(?:command|tool|agent)|commande\s+externe|outil\s+externe|unrestricted|arbitrary\s+command|n['’]?importe\s+quelle\s+commande|sans\s+r[eé]glementation|sans\s+garde[- ]?fous|no\s+guardrails?)\b/i.test(normalized);
393
+ if (asksForVanilla) return "vanilla";
392
394
  const asksForOrchestration = /\b(orchestrator|orchestrat(?:e|ion|or)|orchestrer|multi[- ]?agent|lead(?:s)?|worker(?:s)?|chief vision|coordonn(?:e|er|ation)|d[eé]l[eè]gu(?:e|er|ation)|delegat(?:e|ion)|sub[- ]?agents?|subtasks?|work graph|todo graph|graphe de travail|graphe todo)\b/i.test(normalized);
393
395
  if (asksForOrchestration) return "orchestrator";
394
396
  const asksForMutation = /\b(update|udpate|modify|modifier|modifie|change|changer|corrige|correction|fix|patch|implement|impl[eé]mente|edit|write|[eé]cris|ajoute|add|create|cr[eé]e|supprime|delete|remove|refactor|refactorise|remplace|am[eé]lior(?:e|er)|appliqu(?:e|er)|mets?|mettre|rends?|rendre|fais\s+en\s+sorte|mets? .*jour|mise .*jour|faire .*update|continue .*update)\b/i.test(normalized);
@@ -345,7 +345,8 @@ export function renderHarnessWidget(pi: ExtensionAPI, state: HarnessRuntimeState
345
345
  export function applyMode(pi: ExtensionAPI, state: HarnessRuntimeState, ctx: ExtensionContext, mode: ModeName, persist = true): void {
346
346
  state.activeMode = mode;
347
347
  const available = new Set(pi.getAllTools().map((tool) => tool.name));
348
- pi.setActiveTools(MODE_TOOLS[mode].filter((tool) => available.has(tool)));
348
+ const activeTools = mode === "vanilla" ? [...available] : MODE_TOOLS[mode].filter((tool) => available.has(tool));
349
+ pi.setActiveTools(activeTools);
349
350
  if (persist) pi.appendEntry("zob-mode-state", { mode, timestamp: new Date().toISOString() });
350
351
  ctx.ui.setStatus("zob-mode", ctx.ui.theme.fg("accent", `zob:${mode}`));
351
352
  renderHarnessWidget(pi, state, ctx);
@@ -1,4 +1,4 @@
1
- export type ModeName = "explore" | "plan" | "implement" | "oracle" | "factory" | "orchestrator";
1
+ export type ModeName = "explore" | "plan" | "implement" | "oracle" | "factory" | "orchestrator" | "vanilla";
2
2
  export type AgentScope = "project" | "user" | "both";
3
3
  export type ChildThinkingLevel = "low" | "medium" | "high" | "xhigh";
4
4
 
@@ -71,7 +71,8 @@
71
71
  "implement": "balanced_worker",
72
72
  "oracle": "strong_oracle",
73
73
  "factory": "balanced_worker",
74
- "orchestrator": "strong_reasoning"
74
+ "orchestrator": "strong_reasoning",
75
+ "vanilla": "balanced_worker"
75
76
  },
76
77
  "highContextThresholdTokens": 120000,
77
78
  "highContextModelClass": "high_context"
@@ -0,0 +1,14 @@
1
+ ---
2
+ description: Switch to Pi base-style unrestricted Vanilla mode
3
+ argument-hint: "<task>"
4
+ ---
5
+ Switch to `/zmode vanilla` if not already there.
6
+
7
+ Run this task in Vanilla mode: $ARGUMENTS
8
+
9
+ Vanilla behavior:
10
+ - Behave like the base Pi coding agent rather than a governed ZOB workflow agent.
11
+ - ZOB-specific Explore/Plan/Implement/Oracle routing, tool-routing, TODO/goal governance, and bash mutation blocks are disabled for this mode.
12
+ - You may use any available Pi tool and launch arbitrary shell commands, including external coding tools such as codex or project scripts that modify files.
13
+ - Do not claim ZOB safety/oracle/governance guarantees while in Vanilla; the user is intentionally choosing direct operator-style execution.
14
+ - Keep normal conversational clarity: state what you are about to run when useful, then execute directly and report results.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zob-harness",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "A governed, human-controlled Pi harness for contract-driven agentic engineering, safety gates, specialist delegation, and software-factory workflows.",
6
6
  "license": "MIT",