sortie-dogs 0.10.10 → 0.10.12
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/dist/asset-version.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* installed project marker without importing every asset body.
|
|
4
4
|
*/
|
|
5
5
|
export declare const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
|
|
6
|
-
export declare const V010_RUNTIME_ASSET_VERSION = "0.10.0-v0912-language4-cost-rpt10-compaction-ref2-proposal1-review-remediation1-surface4-proposal-recovery2-quality1-terminal2-route1-path1-permission2-prerequisite1-v2-bridge1-intent1-reflection1-cancel1";
|
|
6
|
+
export declare const V010_RUNTIME_ASSET_VERSION = "0.10.0-v0912-language4-cost-rpt10-compaction-ref2-proposal1-review-remediation1-surface4-proposal-recovery2-quality1-terminal2-route1-path1-permission2-prerequisite1-v2-bridge1-intent1-reflection1-cancel1-proposal-budget1-goal-recovery1-delegate-execute1";
|
|
7
7
|
export type RuntimeAssetVersion = typeof RUNTIME_ASSET_VERSION | typeof V010_RUNTIME_ASSET_VERSION;
|
package/dist/asset-version.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* installed project marker without importing every asset body.
|
|
4
4
|
*/
|
|
5
5
|
export const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
|
|
6
|
-
export const V010_RUNTIME_ASSET_VERSION = "0.10.0-v0912-language4-cost-rpt10-compaction-ref2-proposal1-review-remediation1-surface4-proposal-recovery2-quality1-terminal2-route1-path1-permission2-prerequisite1-v2-bridge1-intent1-reflection1-cancel1";
|
|
6
|
+
export const V010_RUNTIME_ASSET_VERSION = "0.10.0-v0912-language4-cost-rpt10-compaction-ref2-proposal1-review-remediation1-surface4-proposal-recovery2-quality1-terminal2-route1-path1-permission2-prerequisite1-v2-bridge1-intent1-reflection1-cancel1-proposal-budget1-goal-recovery1-delegate-execute1";
|
|
@@ -86,6 +86,24 @@ export interface OperatorProposalState {
|
|
|
86
86
|
proposal: OperatorProposalPacket | null;
|
|
87
87
|
approval_rationale: string | null;
|
|
88
88
|
}
|
|
89
|
+
export interface OperatorProposalBudgetDiagnostic {
|
|
90
|
+
readonly status: "proposal-budget-exhausted";
|
|
91
|
+
readonly code: "operator-proposal-read-budget-exhausted" | "operator-proposal-submission-budget-exhausted";
|
|
92
|
+
readonly reads: number;
|
|
93
|
+
readonly max_reads: number;
|
|
94
|
+
readonly remaining_reads: number;
|
|
95
|
+
readonly submissions: number;
|
|
96
|
+
readonly max_submissions: number;
|
|
97
|
+
readonly remaining_submissions: number;
|
|
98
|
+
readonly required_minimum_budget: {
|
|
99
|
+
readonly max_reads: number;
|
|
100
|
+
readonly max_submissions: number;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export declare class OperatorProposalBudgetError extends Error {
|
|
104
|
+
readonly diagnostic: OperatorProposalBudgetDiagnostic;
|
|
105
|
+
constructor(diagnostic: OperatorProposalBudgetDiagnostic);
|
|
106
|
+
}
|
|
89
107
|
/** Durable pre-execution lane. It grants investigation and submission, never source mutation or execution. */
|
|
90
108
|
export declare class OperatorProposalRuntime {
|
|
91
109
|
readonly profile: RuntimeProfile;
|
|
@@ -101,6 +119,7 @@ export declare class OperatorProposalRuntime {
|
|
|
101
119
|
read(root: string): Promise<OperatorProposalState | undefined>;
|
|
102
120
|
private readUnlocked;
|
|
103
121
|
private save;
|
|
122
|
+
private assertBudgetAvailable;
|
|
104
123
|
task(state: OperatorProposalState): OperatorTask;
|
|
105
124
|
/** Root-visible bounded handle; the canonical prompt remains only in durable host state. */
|
|
106
125
|
referenceTask(state: OperatorProposalState): OperatorTask;
|
|
@@ -93,6 +93,13 @@ const normalizedRelativePath = (value) => {
|
|
|
93
93
|
return false;
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
|
+
export class OperatorProposalBudgetError extends Error {
|
|
97
|
+
diagnostic;
|
|
98
|
+
constructor(diagnostic) {
|
|
99
|
+
super(diagnostic.code);
|
|
100
|
+
this.diagnostic = diagnostic;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
96
103
|
function parseIntent(value) {
|
|
97
104
|
const proposalBudget = record(value) && Object.hasOwn(value, "proposal_budget")
|
|
98
105
|
? value.proposal_budget
|
|
@@ -366,6 +373,18 @@ export class OperatorProposalRuntime {
|
|
|
366
373
|
}
|
|
367
374
|
this.states.set(state.root_session_id, structuredClone(state));
|
|
368
375
|
}
|
|
376
|
+
assertBudgetAvailable(state) {
|
|
377
|
+
const remainingReads = state.intent.proposal_budget.max_reads - state.read_count;
|
|
378
|
+
const remainingSubmissions = state.intent.proposal_budget.max_submissions - state.submission_count;
|
|
379
|
+
if (remainingReads > 0 && remainingSubmissions > 0)
|
|
380
|
+
return;
|
|
381
|
+
throw new OperatorProposalBudgetError({ status: "proposal-budget-exhausted",
|
|
382
|
+
code: remainingReads <= 0 ? "operator-proposal-read-budget-exhausted" : "operator-proposal-submission-budget-exhausted",
|
|
383
|
+
reads: state.read_count, max_reads: state.intent.proposal_budget.max_reads, remaining_reads: Math.max(0, remainingReads),
|
|
384
|
+
submissions: state.submission_count, max_submissions: state.intent.proposal_budget.max_submissions,
|
|
385
|
+
remaining_submissions: Math.max(0, remainingSubmissions),
|
|
386
|
+
required_minimum_budget: { max_reads: state.read_count + 1, max_submissions: state.submission_count + 1 } });
|
|
387
|
+
}
|
|
369
388
|
task(state) {
|
|
370
389
|
return { subagent_type: this.profile.agentNames["dog-operator"], description: "承認前の調査と実行契約案作成",
|
|
371
390
|
prompt: [`SORTIE_OPERATOR_PROPOSAL ${JSON.stringify({ root: state.root_session_id, intent_id: state.intent_id, intent_hash: state.intent_hash })}`,
|
|
@@ -435,8 +454,10 @@ export class OperatorProposalRuntime {
|
|
|
435
454
|
async beginUnlocked(root, raw) {
|
|
436
455
|
const intent = parseIntent(raw), intentHash = hash(JSON.stringify(intent)), previous = await this.readUnlocked(root);
|
|
437
456
|
if (previous) {
|
|
438
|
-
if (previous.intent_hash === intentHash)
|
|
457
|
+
if (previous.intent_hash === intentHash) {
|
|
458
|
+
this.assertBudgetAvailable(previous);
|
|
439
459
|
return previous;
|
|
460
|
+
}
|
|
440
461
|
if (previous.phase !== "approved")
|
|
441
462
|
throw new Error("operator-proposal-active-intent-immutable");
|
|
442
463
|
throw new Error("operator-proposal-new-intent-requires-explicit-root-revision");
|
|
@@ -446,6 +467,7 @@ export class OperatorProposalRuntime {
|
|
|
446
467
|
intent_id: `intent-${intentHash.slice(0, 24)}`, intent_hash: intentHash, intent, created_at: new Date().toISOString(), phase: "investigating",
|
|
447
468
|
goal_binding: null, proposal_call_id: null, proposal_session_id: null, read_count: spend.reads, read_paths: [], submission_count: spend.submissions, proposal_id: null,
|
|
448
469
|
proposal_revision: null, proposal_hash: null, proposal: null, approval_rationale: null };
|
|
470
|
+
this.assertBudgetAvailable(state);
|
|
449
471
|
await this.save(state);
|
|
450
472
|
return state;
|
|
451
473
|
}
|
|
@@ -474,6 +496,7 @@ export class OperatorProposalRuntime {
|
|
|
474
496
|
const state = await this.requiredUnlocked(root);
|
|
475
497
|
if (state.phase !== "investigating" || state.proposal_call_id !== null)
|
|
476
498
|
throw new Error("operator-proposal-dispatch-not-authorized");
|
|
499
|
+
this.assertBudgetAvailable(state);
|
|
477
500
|
const canonical = this.resolveTask(state, args);
|
|
478
501
|
// Reserve only after the grant check, while competing admissions remain queued.
|
|
479
502
|
await reserveBudget?.();
|
package/dist/plugin/index.js
CHANGED
|
@@ -7573,6 +7573,10 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
7573
7573
|
registerGoalDeclaration: async (root, prompt) => {
|
|
7574
7574
|
if (!isCoordinatorSession(root) && !await recoverCoordinatorRoot(root))
|
|
7575
7575
|
throw new Error("operator-coordinator-required");
|
|
7576
|
+
// In one-shot CLI turns OpenCode may persist the user message only after chat.message returns.
|
|
7577
|
+
// Proposal preparation can reach registration first, so recover that exact pending real turn here
|
|
7578
|
+
// instead of freezing a prepared contract that can never consume its user revision authority.
|
|
7579
|
+
await recoverPendingRealGoalTurn(root);
|
|
7576
7580
|
const registered = await bindGoalDeclaration(root, prompt);
|
|
7577
7581
|
if (registered?.goal_id === null || registered === undefined)
|
|
7578
7582
|
throw new Error("operator-goal-registration-unavailable");
|
|
@@ -7588,6 +7592,7 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
7588
7592
|
relinkRegisteredGoal: async (root, request) => {
|
|
7589
7593
|
if (!isCoordinatorSession(root) && !await recoverCoordinatorRoot(root))
|
|
7590
7594
|
throw new Error("operator-coordinator-required");
|
|
7595
|
+
await recoverPendingRealGoalTurn(root);
|
|
7591
7596
|
await recoverCompletedGoalReservations(root);
|
|
7592
7597
|
const ledger = await goalLedger(root), snapshot = await ledger.readGoal(), state = snapshot.state;
|
|
7593
7598
|
if (state.phase !== "active" || state.receipt !== null)
|
package/dist/plugin/profiled.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { V010_RUNTIME_ASSET_VERSION } from "../asset-version.js";
|
|
2
2
|
import { OperatorContractError, OperatorRuntime } from "../core/operator-runtime.js";
|
|
3
|
-
import { DEFAULT_OPERATOR_PROPOSAL_BUDGET, OPERATOR_APPROVAL_CONTRACT, OPERATOR_PROPOSAL_BUDGET_CAPS, OperatorProposalRuntime } from "../core/operator-proposal.js";
|
|
3
|
+
import { DEFAULT_OPERATOR_PROPOSAL_BUDGET, OPERATOR_APPROVAL_CONTRACT, OPERATOR_PROPOSAL_BUDGET_CAPS, OperatorProposalBudgetError, OperatorProposalRuntime } from "../core/operator-proposal.js";
|
|
4
4
|
import { CANONICAL_AGENT_ROLES, canonicalAgent, profileAgent, profileTool, V010_RUNTIME_PROFILE } from "../core/runtime-profile.js";
|
|
5
5
|
import { SortieDogsPlugin as canonicalPlugin } from "./index.js";
|
|
6
6
|
import { taskChildSessionID } from "./task-result-repair.js";
|
|
@@ -760,7 +760,15 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
760
760
|
tools[beginProposal] = { description: `Root-only: freeze original ordered requirements and grant one bounded read-only proposal investigation to dogs-coordinator. The result contains one exact short Task reference; pass task.subagent_type, task.description, and task.prompt byte-for-byte without appending or paraphrasing. The native parent retains that reference; the host expands it only inside the directly claimed proposal child. ${OPERATOR_INTENT_CONTRACT}`,
|
|
761
761
|
args: { intent_json: intentSchema }, execute: async (args, context) => {
|
|
762
762
|
await requireRoot(context.sessionID);
|
|
763
|
-
let state
|
|
763
|
+
let state;
|
|
764
|
+
try {
|
|
765
|
+
state = await proposals.begin(context.sessionID, JSON.parse(args.intent_json));
|
|
766
|
+
}
|
|
767
|
+
catch (error) {
|
|
768
|
+
if (error instanceof OperatorProposalBudgetError)
|
|
769
|
+
return JSON.stringify(error.diagnostic);
|
|
770
|
+
throw error;
|
|
771
|
+
}
|
|
764
772
|
state = await proposals.bindGoal(context.sessionID, await control.proposalGoalBinding(context.sessionID));
|
|
765
773
|
return JSON.stringify({ ...proposals.packet(state), task: proposals.referenceTask(state),
|
|
766
774
|
dispatch_instruction: "Pass this short Task reference verbatim; do not append or paraphrase it." });
|
|
@@ -1108,6 +1116,16 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
1108
1116
|
await proposals.accountRead(root, request.sessionID, normalizeRelativePath(relative(input.directory, resolve(input.directory, args.filePath))));
|
|
1109
1117
|
return;
|
|
1110
1118
|
}
|
|
1119
|
+
if (who.role === "dog-operator" && request.tool === "execute") {
|
|
1120
|
+
const state = await operators.required(root);
|
|
1121
|
+
// OpenCode V2 exposes the delegate's operator_next capability through Code Mode's
|
|
1122
|
+
// execute conduit. Nested Sortie tools still enforce their own root/delegate identity;
|
|
1123
|
+
// denying the conduit prevents a valid multi-unit delegate from creating any worker.
|
|
1124
|
+
if (state.phase !== "running" || state.operatorSessionID !== request.sessionID) {
|
|
1125
|
+
throw new Error("operator-execute-owner-mismatch");
|
|
1126
|
+
}
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1111
1129
|
if (who.role === "dog-operator" && request.tool === "read") {
|
|
1112
1130
|
if (typeof args.filePath !== "string")
|
|
1113
1131
|
throw new Error("operator-read-path-required");
|