sortie-dogs 0.9.8 → 0.9.9
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 +1 -1
- package/dist/asset-version.d.ts +1 -1
- package/dist/asset-version.js +1 -1
- package/dist/core/goal-bound.js +1 -1
- package/dist/plugin/continuation.js +16 -1
- package/dist/plugin/index.js +54 -10
- package/dist/runtime-assets.d.ts +30 -14
- package/dist/runtime-assets.js +44 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ Requirements: Node.js 22.6 or newer, npm, and OpenCode.
|
|
|
22
22
|
|
|
23
23
|
Guides: [日本語](docs/guide-ja.md) · [简体中文](docs/guide-zh-CN.md) · [CLI testing](docs/cli-testing.md)
|
|
24
24
|
|
|
25
|
-
Release: [v0.9.
|
|
25
|
+
Release: [v0.9.9](https://github.com/zufall-upon/Sortie-dogs/releases/tag/v0.9.9)
|
|
26
26
|
|
|
27
27
|
## Why Sortie-dogs?
|
|
28
28
|
|
package/dist/asset-version.d.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Version of the installable runtime assets. Kept in its own module so the plugin can compare an
|
|
3
3
|
* installed project marker without importing every asset body.
|
|
4
4
|
*/
|
|
5
|
-
export declare const RUNTIME_ASSET_VERSION = "0.3.
|
|
5
|
+
export declare const RUNTIME_ASSET_VERSION = "0.3.86-codegen-proof-v1";
|
|
6
6
|
export type RuntimeAssetVersion = typeof RUNTIME_ASSET_VERSION;
|
package/dist/asset-version.js
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Version of the installable runtime assets. Kept in its own module so the plugin can compare an
|
|
3
3
|
* installed project marker without importing every asset body.
|
|
4
4
|
*/
|
|
5
|
-
export const RUNTIME_ASSET_VERSION = "0.3.
|
|
5
|
+
export const RUNTIME_ASSET_VERSION = "0.3.86-codegen-proof-v1";
|
package/dist/core/goal-bound.js
CHANGED
|
@@ -221,7 +221,7 @@ export function reduceGoalFlight(records) {
|
|
|
221
221
|
event.consumed >= 0 && event.consumed <= event.limit && event.operation_id.length > 0 && event.evidence_key.length > 0, "invalid", "Validation admission is malformed.");
|
|
222
222
|
if (event.decision === "ALLOW") {
|
|
223
223
|
requireState(event.scope !== null && event.consumed === state.validation_budget.consumed + 1 &&
|
|
224
|
-
(state.validation_budget.limit === null ||
|
|
224
|
+
(state.validation_budget.limit === null || event.limit >= state.validation_budget.limit) &&
|
|
225
225
|
!state.validation_budget.evidence_keys.includes(event.evidence_key) &&
|
|
226
226
|
!state.validation_budget.reservations.some((entry) => entry.reservation_id === event.reservation_id), "budget", "Validation admission is stale, duplicated, or exhausted.");
|
|
227
227
|
state = { ...state, validation_budget: { consumed: event.consumed, limit: event.limit,
|
|
@@ -483,6 +483,8 @@ export function createContinuationHooks(client, directory, policySource, timings
|
|
|
483
483
|
return false;
|
|
484
484
|
if (terminalCheckpoint(text))
|
|
485
485
|
return false;
|
|
486
|
+
if (topLevelProtocolLines(text).some(({ line }) => /^status\s*:\s*IN_PROGRESS(?:\s|$)/iu.test(line)))
|
|
487
|
+
return true;
|
|
486
488
|
if (/➡️\s*(?:次action|next_action)\s*:\s*\S/iu.test(text))
|
|
487
489
|
return true;
|
|
488
490
|
if (checkpointStatus(text) === "BLOCKED" && !trueBlockerReport(text))
|
|
@@ -1009,6 +1011,7 @@ export function createContinuationHooks(client, directory, policySource, timings
|
|
|
1009
1011
|
state.stepRecoveryActive = false;
|
|
1010
1012
|
clearTimer(state.stepRecoveryTimer);
|
|
1011
1013
|
state.stepRecoveryTimer = undefined;
|
|
1014
|
+
state.stepRecoveryDeferredReport = undefined;
|
|
1012
1015
|
resetRecoveryStall(state);
|
|
1013
1016
|
if (state.notRequiredRevision !== state.turnRevision &&
|
|
1014
1017
|
!output.text.includes(ROLLOVER_MARKER) &&
|
|
@@ -1031,7 +1034,17 @@ export function createContinuationHooks(client, directory, policySource, timings
|
|
|
1031
1034
|
}
|
|
1032
1035
|
else if (nonTerminalProgress(state.latestCoordinatorReport) ||
|
|
1033
1036
|
(state.stepRecoveryActive && !terminalCheckpoint(state.latestCoordinatorReport))) {
|
|
1034
|
-
if (input.allowStepRecoveryFallback
|
|
1037
|
+
if (input.allowStepRecoveryFallback === false) {
|
|
1038
|
+
state.stepRecoveryDeferredReport = state.latestCoordinatorReport;
|
|
1039
|
+
}
|
|
1040
|
+
else if (state.stepRecoveryDeferredReport === state.latestCoordinatorReport) {
|
|
1041
|
+
// A completed text-part event is not message completion. Release its deferred
|
|
1042
|
+
// recovery only when the persisted assistant message later confirms completion.
|
|
1043
|
+
state.stepRecoveryDeferredReport = undefined;
|
|
1044
|
+
state.idleDeferred = true;
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
state.stepRecoveryDeferredReport = undefined;
|
|
1035
1048
|
scheduleStepRecovery(input.sessionID, state, state.latestCoordinatorReport);
|
|
1036
1049
|
}
|
|
1037
1050
|
}
|
|
@@ -1162,6 +1175,7 @@ export function createContinuationHooks(client, directory, policySource, timings
|
|
|
1162
1175
|
state.attempts = 0;
|
|
1163
1176
|
state.directUsed = false;
|
|
1164
1177
|
state.latestCoordinatorReport = undefined;
|
|
1178
|
+
state.stepRecoveryDeferredReport = undefined;
|
|
1165
1179
|
if (!synthetic) {
|
|
1166
1180
|
state.lastStepContinueReport = undefined;
|
|
1167
1181
|
state.lastStepContinueRevision = undefined;
|
|
@@ -1182,6 +1196,7 @@ export function createContinuationHooks(client, directory, policySource, timings
|
|
|
1182
1196
|
state.stepRecoveryTimer = undefined;
|
|
1183
1197
|
if (tool !== CONTINUATION_CAPABILITY) {
|
|
1184
1198
|
state.latestCoordinatorReport = undefined;
|
|
1199
|
+
state.stepRecoveryDeferredReport = undefined;
|
|
1185
1200
|
}
|
|
1186
1201
|
},
|
|
1187
1202
|
blocksTool(sessionID) {
|
package/dist/plugin/index.js
CHANGED
|
@@ -1134,6 +1134,7 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
1134
1134
|
const hostGoalExecutions = new Map();
|
|
1135
1135
|
const goalValidationDefects = new Set();
|
|
1136
1136
|
const goalDeclarationAuthority = new Map();
|
|
1137
|
+
const explicitUserGoalUnitLimits = new Map();
|
|
1137
1138
|
const pendingRealGoalTurns = new Map();
|
|
1138
1139
|
const pendingGoalRecoveries = new Map();
|
|
1139
1140
|
const scheduledGoalRecoveries = new Map();
|
|
@@ -1389,7 +1390,11 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
1389
1390
|
`unit:${unitID}`, "source_snapshot", "candidate", "command", "scope", "exit_code"]))], reason: "acceptance" };
|
|
1390
1391
|
let reservation;
|
|
1391
1392
|
try {
|
|
1392
|
-
|
|
1393
|
+
// A changed candidate produces a new evidence key and must not become a user-facing blocker
|
|
1394
|
+
// merely because earlier necessary validations consumed the initial estimate. Duplicate
|
|
1395
|
+
// evidence remains denied by reserveValidation before this limit is considered.
|
|
1396
|
+
const validationLimit = Math.max(goal.budget?.max_units ?? 1, goal.validation_budget.consumed + 1);
|
|
1397
|
+
reservation = await ledger.reserveValidation(request, validationLimit);
|
|
1393
1398
|
}
|
|
1394
1399
|
catch (error) {
|
|
1395
1400
|
throw denyValidation(`authority-unavailable:${error instanceof Error ? error.name : "unknown"}`);
|
|
@@ -1895,8 +1900,14 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
1895
1900
|
}
|
|
1896
1901
|
const declaration = validated.declaration;
|
|
1897
1902
|
const units = Number(handoffValue(entries, ["goal_budget_units"]));
|
|
1898
|
-
const
|
|
1899
|
-
? units :
|
|
1903
|
+
const declaredUnits = Number.isSafeInteger(units) && units >= state.consumed_units && units > 0
|
|
1904
|
+
? units : undefined;
|
|
1905
|
+
// A model-authored Task declaration must not silently shrink the host's policy allowance.
|
|
1906
|
+
// It may request more capacity, while explicit later budget revisions remain cumulative.
|
|
1907
|
+
const explicitUserLimit = explicitUserGoalUnitLimits.get(sessionID);
|
|
1908
|
+
const maxUnits = declaredUnits === undefined ? state.budget?.max_units ?? 32 :
|
|
1909
|
+
state.budget?.source === "policy-default" && explicitUserLimit !== declaredUnits
|
|
1910
|
+
? Math.max(state.budget.max_units, declaredUnits) : declaredUnits;
|
|
1900
1911
|
const declaredTime = Number(handoffValue(entries, ["goal_budget_time_ms"]));
|
|
1901
1912
|
const declaredCost = Number(handoffValue(entries, ["goal_budget_cost_usd"]));
|
|
1902
1913
|
const timeBudget = Number.isFinite(declaredTime) && declaredTime > 0 ? declaredTime : state.budget?.time_ms ?? null;
|
|
@@ -1923,7 +1934,8 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
1923
1934
|
session_id: sessionID, selected_agent: state.selected_agent ?? COORDINATOR_AGENT,
|
|
1924
1935
|
delivery: declaration.delivery, budget: { max_units: maxUnits,
|
|
1925
1936
|
time_ms: timeBudget, cost_usd: costBudget,
|
|
1926
|
-
source:
|
|
1937
|
+
source: declaredUnits !== undefined && maxUnits !== state.budget?.max_units
|
|
1938
|
+
? "accepted-plan" : state.budget?.source ?? "policy-default" },
|
|
1927
1939
|
acceptance_contract: declaration.contract, reset_no_progress: true });
|
|
1928
1940
|
goalDeclarationAuthority.delete(sessionID);
|
|
1929
1941
|
return state;
|
|
@@ -2354,6 +2366,9 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
2354
2366
|
const bootstrapIdleWarnings = new Set();
|
|
2355
2367
|
const coordinatorTaskCalls = new Map();
|
|
2356
2368
|
const coordinatorTaskWatchdogs = new Map();
|
|
2369
|
+
// A deleted root is terminal for its current host lifetime. Retain only a bounded tombstone so
|
|
2370
|
+
// late generic events and already queued watchdog callbacks cannot recreate recovery state.
|
|
2371
|
+
const terminalCoordinatorTaskWatchdogs = new Set();
|
|
2357
2372
|
const chatTransitions = new Map();
|
|
2358
2373
|
const reflectionOwnedRoots = new Set();
|
|
2359
2374
|
const reflectionClosingRoots = new Set();
|
|
@@ -3886,6 +3901,8 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
3886
3901
|
}
|
|
3887
3902
|
}
|
|
3888
3903
|
function beginCoordinatorTask(sessionID, callID) {
|
|
3904
|
+
if (terminalCoordinatorTaskWatchdogs.has(sessionID))
|
|
3905
|
+
return;
|
|
3889
3906
|
const calls = coordinatorTaskCalls.get(sessionID) ?? new Set();
|
|
3890
3907
|
calls.add(callID);
|
|
3891
3908
|
coordinatorTaskCalls.set(sessionID, calls);
|
|
@@ -3921,7 +3938,7 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
3921
3938
|
coordinatorTaskWatchdogs.delete(sessionID);
|
|
3922
3939
|
}
|
|
3923
3940
|
function armCoordinatorTaskWatchdog(sessionID, activity) {
|
|
3924
|
-
if (!coordinatorTaskCalls.has(sessionID))
|
|
3941
|
+
if (terminalCoordinatorTaskWatchdogs.has(sessionID) || !coordinatorTaskCalls.has(sessionID))
|
|
3925
3942
|
return;
|
|
3926
3943
|
const state = coordinatorTaskWatchdogs.get(sessionID) ?? {
|
|
3927
3944
|
generation: 0,
|
|
@@ -3942,10 +3959,18 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
3942
3959
|
}
|
|
3943
3960
|
function touchCoordinatorTaskWatchdog(sessionID) {
|
|
3944
3961
|
const root = coordinatorRootForSession(sessionID);
|
|
3945
|
-
if (root !== undefined && coordinatorTaskWatchdogs.has(root)) {
|
|
3962
|
+
if (root !== undefined && !terminalCoordinatorTaskWatchdogs.has(root) && coordinatorTaskWatchdogs.has(root)) {
|
|
3946
3963
|
armCoordinatorTaskWatchdog(root, Date.now());
|
|
3947
3964
|
}
|
|
3948
3965
|
}
|
|
3966
|
+
function disarmDeletedCoordinatorTaskWatchdog(sessionID) {
|
|
3967
|
+
terminalCoordinatorTaskWatchdogs.delete(sessionID);
|
|
3968
|
+
terminalCoordinatorTaskWatchdogs.add(sessionID);
|
|
3969
|
+
while (terminalCoordinatorTaskWatchdogs.size > ACTIVE_SESSION_CACHE.maximum) {
|
|
3970
|
+
terminalCoordinatorTaskWatchdogs.delete(terminalCoordinatorTaskWatchdogs.values().next().value);
|
|
3971
|
+
}
|
|
3972
|
+
abortCoordinatorTasks(sessionID);
|
|
3973
|
+
}
|
|
3949
3974
|
function sessionOwnedByRoot(sessionID, rootID) {
|
|
3950
3975
|
return sessionID === rootID || sessionRoots.get(sessionID) === rootID || sessionParents.get(sessionID) === rootID;
|
|
3951
3976
|
}
|
|
@@ -3974,6 +3999,8 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
3974
3999
|
return [...reasons].sort();
|
|
3975
4000
|
}
|
|
3976
4001
|
async function sweepCoordinatorTaskWatchdog(sessionID, generation) {
|
|
4002
|
+
if (terminalCoordinatorTaskWatchdogs.has(sessionID))
|
|
4003
|
+
return;
|
|
3977
4004
|
const state = coordinatorTaskWatchdogs.get(sessionID);
|
|
3978
4005
|
const calls = coordinatorTaskCalls.get(sessionID);
|
|
3979
4006
|
if (state === undefined || calls === undefined || state.generation !== generation || state.recovering)
|
|
@@ -3990,7 +4017,8 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
3990
4017
|
return;
|
|
3991
4018
|
}
|
|
3992
4019
|
const reasons = await watchdogProtectedReasons(sessionID);
|
|
3993
|
-
if (
|
|
4020
|
+
if (terminalCoordinatorTaskWatchdogs.has(sessionID) ||
|
|
4021
|
+
coordinatorTaskWatchdogs.get(sessionID) !== state || state.generation !== generation)
|
|
3994
4022
|
return;
|
|
3995
4023
|
if (reasons.length > 0) {
|
|
3996
4024
|
state.recovering = false;
|
|
@@ -4003,8 +4031,11 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
4003
4031
|
return;
|
|
4004
4032
|
}
|
|
4005
4033
|
const callIDs = [...calls];
|
|
4034
|
+
if (terminalCoordinatorTaskWatchdogs.has(sessionID))
|
|
4035
|
+
return;
|
|
4006
4036
|
const result = await continuation.recoverStalledTask(sessionID, callIDs);
|
|
4007
|
-
if (
|
|
4037
|
+
if (terminalCoordinatorTaskWatchdogs.has(sessionID) ||
|
|
4038
|
+
coordinatorTaskWatchdogs.get(sessionID) !== state || state.generation !== generation)
|
|
4008
4039
|
return;
|
|
4009
4040
|
if (result === "recovered") {
|
|
4010
4041
|
appLogInfo("batch-watchdog.recovered", sessionID, {
|
|
@@ -5630,11 +5661,11 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
5630
5661
|
await serializeChatTransition(chatInput.sessionID, async () => {
|
|
5631
5662
|
const parentID = chatParentID(chatInput);
|
|
5632
5663
|
const synthetic = output.parts.some((part) => isRecord(part) && part.synthetic === true);
|
|
5664
|
+
const selectedAgent = chatInput.agent ?? output.message.agent;
|
|
5633
5665
|
if (parentID !== undefined)
|
|
5634
5666
|
rememberParent(chatInput.sessionID, parentID);
|
|
5635
5667
|
touchCoordinatorTaskWatchdog(chatInput.sessionID);
|
|
5636
5668
|
const coordinatorRoot = isCoordinatorSession(chatInput.sessionID);
|
|
5637
|
-
const selectedAgent = chatInput.agent ?? output.message.agent;
|
|
5638
5669
|
if (chatInput.agent !== undefined && output.message.agent !== chatInput.agent) {
|
|
5639
5670
|
output.message.agent = chatInput.agent;
|
|
5640
5671
|
}
|
|
@@ -5662,6 +5693,10 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
5662
5693
|
}
|
|
5663
5694
|
const coordinatorOrigin = parentID === undefined && requestedCoordinator;
|
|
5664
5695
|
if (coordinatorOrigin) {
|
|
5696
|
+
// A proven explicit real root turn may reuse a host session identifier after deletion. Child
|
|
5697
|
+
// lineage rejection above runs first, so only a new root lifetime clears the tombstone.
|
|
5698
|
+
if (!synthetic)
|
|
5699
|
+
terminalCoordinatorTaskWatchdogs.delete(chatInput.sessionID);
|
|
5665
5700
|
if (!synthetic)
|
|
5666
5701
|
interruptedCoordinatorMessages.delete(chatInput.sessionID);
|
|
5667
5702
|
if (synthetic) {
|
|
@@ -5672,6 +5707,12 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
5672
5707
|
else if (messageID !== undefined) {
|
|
5673
5708
|
await acceptRealGoalTurn(chatInput.sessionID, messageID, selectedAgent, output.parts);
|
|
5674
5709
|
goalDeclarationAuthority.set(chatInput.sessionID, messageID);
|
|
5710
|
+
const explicitUnits = /^\s*goal_budget_units:\s*([1-9][0-9]*)\s*$/imu
|
|
5711
|
+
.exec(output.parts.map(textPart).filter((text) => text !== undefined).join("\n"))?.[1];
|
|
5712
|
+
if (explicitUnits === undefined)
|
|
5713
|
+
explicitUserGoalUnitLimits.delete(chatInput.sessionID);
|
|
5714
|
+
else
|
|
5715
|
+
explicitUserGoalUnitLimits.set(chatInput.sessionID, Number(explicitUnits));
|
|
5675
5716
|
}
|
|
5676
5717
|
else if (selectedAgent !== undefined) {
|
|
5677
5718
|
// Some native hosts persist the user message only after this hook returns. Defer to the
|
|
@@ -6630,6 +6671,10 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
6630
6671
|
}
|
|
6631
6672
|
if (eventSessionID === undefined)
|
|
6632
6673
|
return;
|
|
6674
|
+
// Deletion is terminal for watchdog recovery. Disarm synchronously before any generic event
|
|
6675
|
+
// processing can await, touch activity, or let a queued sweep recover the cancelled root.
|
|
6676
|
+
if (event.type === "session.deleted")
|
|
6677
|
+
disarmDeletedCoordinatorTaskWatchdog(eventSessionID);
|
|
6633
6678
|
if (event.type === "message.updated" && info !== undefined) {
|
|
6634
6679
|
rememberCoordinatorInterruption(eventSessionID, info);
|
|
6635
6680
|
await acceptPersistedRealGoalEvent(eventSessionID, info);
|
|
@@ -6723,7 +6768,6 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
6723
6768
|
touchCoordinatorTaskWatchdog(eventSessionID);
|
|
6724
6769
|
if (event.type === "session.deleted") {
|
|
6725
6770
|
fastLane.forget(eventSessionID);
|
|
6726
|
-
abortCoordinatorTasks(eventSessionID);
|
|
6727
6771
|
if (reflectionStore !== undefined && reflectionConfiguration?.layers.run && reflectionOwnedRoots.has(eventSessionID)) {
|
|
6728
6772
|
reflectionClosingRoots.add(eventSessionID);
|
|
6729
6773
|
await waitForReflections(eventSessionID);
|
package/dist/runtime-assets.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface RuntimeAsset {
|
|
|
7
7
|
}
|
|
8
8
|
export declare const runtimeAssets: readonly [{
|
|
9
9
|
readonly name: "dog-coordinator";
|
|
10
|
-
readonly version: "0.3.
|
|
10
|
+
readonly version: "0.3.86-codegen-proof-v1";
|
|
11
11
|
readonly installPath: "agent/dog-coordinator.md";
|
|
12
12
|
readonly content: `---
|
|
13
13
|
description: Canonical MkII coordinator packaged by Sortie-dogs
|
|
@@ -1386,6 +1386,14 @@ explicitly record dog-reviewer skipped and permit staging. For a high-risk candi
|
|
|
1386
1386
|
dog-reviewer only after canonical validation passes and require its PASS before the coordinator
|
|
1387
1387
|
stages or commits. Return reviewer findings through dog-coordinator and fail closed while
|
|
1388
1388
|
unreviewed. If dog-reviewer is unavailable or does not return PASS, fail closed before staging.
|
|
1389
|
+
Before risk classification or terminal DONE, require one criterion-level trace per accepted criterion:
|
|
1390
|
+
criterion -> changed or inspected implementation path -> concrete exercising test/input/branch -> PASS.
|
|
1391
|
+
An aggregate validation command without that mapping is insufficient. Multi-form criteria must cover their
|
|
1392
|
+
materially distinct syntax, value-shape, scope, and error paths; any missing path remains UNPROVEN and requires
|
|
1393
|
+
continued implementation or validation. Include the complete trace in every high-risk SourceReview artifact.
|
|
1394
|
+
Any generated input/output pair in the changed manifest is high risk and requires SourceReview. DONE requires
|
|
1395
|
+
generator command evidence, post-generation candidate identity, generated-output stability, and canonical
|
|
1396
|
+
validation after generation. Reject evidence produced only before regeneration.
|
|
1389
1397
|
|
|
1390
1398
|
GATE_POLICY_FIXTURE
|
|
1391
1399
|
risk_rule: high when source_manifest has an entry outside test/, validation level is targeted, or operation_manifest mutates non-artifact state; a qualifying artifact-only candidate is low-risk despite operation_manifest
|
|
@@ -1420,11 +1428,19 @@ At each checkpoint and terminal return, preserve concise proof internally. The u
|
|
|
1420
1428
|
return MUST begin with its conclusion: no plan, progress, assessment, Evidence heading, or preamble.
|
|
1421
1429
|
Use exactly one of DONE, INTERRUPTED, BLOCKED, or NEED_DECISION with one status emoji and a short
|
|
1422
1430
|
Japanese conclusion. Then render Japanese \u5909\u66F4\u70B9, \u78BA\u8A8D\u7D50\u679C, and \u6B21 paragraphs without bullets or decorative
|
|
1423
|
-
emoji.
|
|
1424
|
-
|
|
1431
|
+
emoji. After those paragraphs, always render one durable fallback card in the same assistant message:
|
|
1432
|
+
<details>
|
|
1433
|
+
<summary><strong>\uD83D\uDC3E SORTIE DOGS \u2014 \u5E30\u9084\u5831\u544A</strong></summary>
|
|
1434
|
+
|
|
1435
|
+
**\u4EFB\u52D9:** <same short conclusion>
|
|
1436
|
+
**\u78BA\u8A8D:** <concise validation/review summary without internal identifiers>
|
|
1437
|
+
|
|
1438
|
+
</details>
|
|
1439
|
+
The plugin replaces that exact persisted card in place with measured Speed, Cost, and \u9054\u6210 paragraphs,
|
|
1440
|
+
one fixed icon per section, observed pack/model usage, validation/review, and evidence-backed traits.
|
|
1425
1441
|
Its Markdown token bars and PACK RECORD summarize retained project goals, with coverage and team titles;
|
|
1426
1442
|
they never imply lifetime history, XP, levels, unmeasured savings, or a leaderboard rank.
|
|
1427
|
-
Never write
|
|
1443
|
+
Never write measured metrics, token bars, PACK RECORD, traits, or badges yourself. Do not estimate or fabricate them.
|
|
1428
1444
|
Use \u4EFB\u52D9\u5B8C\u4E86 for DONE, \u4E2D\u65AD\u5E30\u9084\uFF08\u672A\u5B8C\u4E86\uFF09 for INTERRUPTED, \u5916\u90E8\u8981\u56E0\u3067\u5F85\u6A5F\uFF08\u672A\u5B8C\u4E86\uFF09 for BLOCKED,
|
|
1429
1445
|
and \u6307\u793A\u5F85\u3061\uFF08\u672A\u5B8C\u4E86\uFF09 for NEED_DECISION; preserve the machine status token and first-line checkpoint.
|
|
1430
1446
|
Never render a user-facing Evidence heading or Evidence details block, evidence reference, internal reason code,
|
|
@@ -1452,10 +1468,10 @@ TERMINAL_STATUS_SEMANTICS_FIXTURE
|
|
|
1452
1468
|
END_TERMINAL_STATUS_SEMANTICS_FIXTURE
|
|
1453
1469
|
|
|
1454
1470
|
RUNTIME_ASSET_VERSION_SYNC_FIXTURE
|
|
1455
|
-
runtime_version: 0.3.
|
|
1471
|
+
runtime_version: 0.3.86-codegen-proof-v1
|
|
1456
1472
|
shared_marker: src/asset-version.ts
|
|
1457
|
-
packaged_expectation: test/plugin-loader.test.ts uses 0.3.
|
|
1458
|
-
initialize_expectation: test/initialize.test.ts uses 0.3.
|
|
1473
|
+
packaged_expectation: test/plugin-loader.test.ts uses 0.3.86-codegen-proof-v1
|
|
1474
|
+
initialize_expectation: test/initialize.test.ts uses 0.3.86-codegen-proof-v1
|
|
1459
1475
|
rule: runtime asset versions, shared marker, packaged expectation, and initialize expectation change together
|
|
1460
1476
|
END_RUNTIME_ASSET_VERSION_SYNC_FIXTURE
|
|
1461
1477
|
|
|
@@ -1478,32 +1494,32 @@ END_INTERNAL_TERMINAL_PROOF_FIXTURE
|
|
|
1478
1494
|
`;
|
|
1479
1495
|
}, {
|
|
1480
1496
|
readonly name: "dog-worker";
|
|
1481
|
-
readonly version: "0.3.
|
|
1497
|
+
readonly version: "0.3.86-codegen-proof-v1";
|
|
1482
1498
|
readonly installPath: "agent/dog-worker.md";
|
|
1483
1499
|
readonly content: string;
|
|
1484
1500
|
}, {
|
|
1485
1501
|
readonly name: "dog-luna-worker";
|
|
1486
|
-
readonly version: "0.3.
|
|
1502
|
+
readonly version: "0.3.86-codegen-proof-v1";
|
|
1487
1503
|
readonly installPath: "agent/dog-luna-worker.md";
|
|
1488
1504
|
readonly content: string;
|
|
1489
1505
|
}, {
|
|
1490
1506
|
readonly name: "dog-scout";
|
|
1491
|
-
readonly version: "0.3.
|
|
1507
|
+
readonly version: "0.3.86-codegen-proof-v1";
|
|
1492
1508
|
readonly installPath: "agent/dog-scout.md";
|
|
1493
1509
|
readonly content: "---\ndescription: Bounded evidence scout for dog-coordinator\nmode: subagent\nsteps: 8\npermission:\n bash: deny\n webfetch: deny\n task: deny\n question: deny\n glob: deny\n grep: deny\n edit: deny\n list: deny\n write: deny\n patch: deny\ntools:\n bash: false\n webfetch: false\n task: false\n question: false\n glob: false\n grep: false\n edit: false\n list: false\n write: false\n patch: false\n---\n# dog-scout\n\nAccept one concrete missing_evidence_code: manifest, validation, or owner-risk. Accept only an\nexplicit absolute project_root and a known_paths list of at most four paths from dog-coordinator.\nResolve only that evidence key from those paths under project_root; never resolve a path against the\nsession directory. Use Read only, with at most 120 lines and no more than one read per supplied path.\nDo not resolve a second key, explore, invoke another tool, retry, edit, stage, commit, or become user-facing.\n\nWhen project_root is missing, or a supplied path does not resolve under it, or a resolved path is\nunreadable, report that dispatch defect as the facts for the requested key and name the exact paths.\nDo not retry, guess another root, or answer from an unread path.\n\nReturn exactly one concise JSON object of at most 800 characters with exactly these keys:\nmissing_evidence_code, facts, evidence_paths, risks. Use no Markdown, code fence, commentary, or raw log. Return it only\nto dog-coordinator. Write the facts and risks prose in the language the dispatch uses for its own\nprose; keep the keys, paths, commands, and identifiers verbatim.\n";
|
|
1494
1510
|
}, {
|
|
1495
1511
|
readonly name: "dog-reviewer";
|
|
1496
|
-
readonly version: "0.3.
|
|
1512
|
+
readonly version: "0.3.86-codegen-proof-v1";
|
|
1497
1513
|
readonly installPath: "agent/dog-reviewer.md";
|
|
1498
|
-
readonly content: "---\ndescription: Independent source reviewer for dog-coordinator\nmode: subagent\npermission:\n bash: deny\n webfetch: deny\n task: deny\n question: deny\n glob: deny\n grep: deny\n edit: deny\n list: deny\n write: deny\n patch: deny\n read: deny\ntools:\n bash: false\n webfetch: false\n task: false\n question: false\n glob: false\n grep: false\n edit: false\n list: false\n write: false\n patch: false\n read: false\n---\n# dog-reviewer\n\nAccept only one bounded SourceReview request from dog-coordinator after canonical\nvalidation for one high-risk candidate. Review only the supplied acceptance criteria, exact\nmanifest, changedLogicSummary, supplied changed-code excerpts, and validation evidence. Confirm every acceptance item explicitly\nmaps to at least one changedLogicSummary entry and assess that changed logic against the mapped\nacceptance item. Missing or incomplete coverage is a concrete finding, never PASS.\nRequire one indexed acceptance[i] -> changedLogicSummary[j] mapping line per acceptance item and\nreject a missing index or unequal mapping count before assessing the changed logic.\nDo not request raw logs or full source files, review low-risk candidates, expand scope, or dispatch\nanother agent.\nTreat those supplied fields as the complete bounded SourceReview artifact; use only that artifact and invoke no tools.\nDo not infer that a branch or exemption is absent from source because a prose summary omits it.\nIf the supplied excerpts do not establish a claim, report an evidence gap and request the exact\nbranch/helper excerpt in the next artifact; do not prescribe a source fix for an unproven defect.\n\nReturn one concise PASS or concrete-finding response only to dog-coordinator before the\ncoordinator commit. Write every finding, evidence, and required-fix sentence in the language the\nsupplied artifact uses for its own prose, one statement per line, and keep verdict values,\nidentifiers, paths, and commands verbatim. Do not implement, remediate, resolve blockers, edit,\nstage, commit, or become user-facing. Remain host-routed: do not require or identify a provider, vendor, model, variant,\nor transport.\n";
|
|
1514
|
+
readonly content: "---\ndescription: Independent source reviewer for dog-coordinator\nmode: subagent\npermission:\n bash: deny\n webfetch: deny\n task: deny\n question: deny\n glob: deny\n grep: deny\n edit: deny\n list: deny\n write: deny\n patch: deny\n read: deny\ntools:\n bash: false\n webfetch: false\n task: false\n question: false\n glob: false\n grep: false\n edit: false\n list: false\n write: false\n patch: false\n read: false\n---\n# dog-reviewer\n\nAccept only one bounded SourceReview request from dog-coordinator after canonical\nvalidation for one high-risk candidate. Review only the supplied acceptance criteria, exact\nmanifest, changedLogicSummary, supplied changed-code excerpts, and validation evidence. Confirm every acceptance item explicitly\nmaps to at least one changedLogicSummary entry and assess that changed logic against the mapped\nacceptance item. Missing or incomplete coverage is a concrete finding, never PASS.\nRequire one indexed acceptance[i] -> changedLogicSummary[j] mapping line per acceptance item and\nreject a missing index or unequal mapping count before assessing the changed logic.\nAlso require each acceptance item to map to a concrete exercising test/input/branch and result. A broad\nsuite PASS without criterion-level exercise evidence is insufficient. When one item contains materially\ndifferent syntax forms, value shapes, scopes, or error paths, reject PASS unless representative traces cover\neach path or the artifact proves they share one implementation path.\nWhen changed files include generator inputs or checked-in generated outputs, require the canonical generator\ncommand, a stable post-generation diff, and validation executed after generation. Reject PASS if helper logic\nexists only in a generated output, regeneration removes behavior, or validation predates the generated candidate.\nDo not request raw logs or full source files, review low-risk candidates, expand scope, or dispatch\nanother agent.\nTreat those supplied fields as the complete bounded SourceReview artifact; use only that artifact and invoke no tools.\nDo not infer that a branch or exemption is absent from source because a prose summary omits it.\nIf the supplied excerpts do not establish a claim, report an evidence gap and request the exact\nbranch/helper excerpt in the next artifact; do not prescribe a source fix for an unproven defect.\n\nReturn one concise PASS or concrete-finding response only to dog-coordinator before the\ncoordinator commit. Write every finding, evidence, and required-fix sentence in the language the\nsupplied artifact uses for its own prose, one statement per line, and keep verdict values,\nidentifiers, paths, and commands verbatim. Do not implement, remediate, resolve blockers, edit,\nstage, commit, or become user-facing. Remain host-routed: do not require or identify a provider, vendor, model, variant,\nor transport.\n";
|
|
1499
1515
|
}, {
|
|
1500
1516
|
readonly name: "dog-advisor";
|
|
1501
|
-
readonly version: "0.3.
|
|
1517
|
+
readonly version: "0.3.86-codegen-proof-v1";
|
|
1502
1518
|
readonly installPath: "agent/dog-advisor.md";
|
|
1503
1519
|
readonly content: "---\ndescription: Focused technical advisor for dog-coordinator\nmode: subagent\npermission:\n bash: deny\n webfetch: deny\n task: deny\n question: deny\n glob: deny\n grep: deny\n edit: deny\n list: deny\n write: deny\n patch: deny\n read: deny\ntools:\n bash: false\n webfetch: false\n task: false\n question: false\n glob: false\n grep: false\n edit: false\n list: false\n write: false\n patch: false\n read: false\n---\n# dog-advisor\n\nAccept only one bounded Strategy request from dog-coordinator for one candidate and one focused\nquestion. Use only the supplied acceptance criteria, exact manifest, constraints, and concise\nevidence. Do not request raw logs or full source files, expand scope, or dispatch another agent.\nTreat those supplied fields as the complete bounded Strategy artifact; use only that artifact and invoke no tools.\nReject every SourceReview request and return the rejection only to dog-coordinator; SourceReview is\ndog-reviewer-only work.\n\nReturn concise options and one recommendation only to dog-coordinator. Write every option,\nrecommendation, and consideration in the language the supplied request uses for its own prose, one\nstatement per line, and keep identifiers, paths, and commands verbatim. Do not perform\nSourceReview, implement, remediate, resolve blockers, edit, stage, commit, or become user-facing.\nImplementation remains dog-worker work. Remain host-routed: do not require or identify a\nprovider, vendor, model, variant, or transport.\n";
|
|
1504
1520
|
}, {
|
|
1505
1521
|
readonly name: "sortie";
|
|
1506
|
-
readonly version: "0.3.
|
|
1522
|
+
readonly version: "0.3.86-codegen-proof-v1";
|
|
1507
1523
|
readonly installPath: "command/sortie.md";
|
|
1508
1524
|
readonly content: "---\ndescription: Start the canonical Sortie-dogs MkII workflow\nagent: dog-coordinator\n---\nRequest: $ARGUMENTS\n\n1. If $ARGUMENTS is empty, request task context and stop; give project init guidance first.\n2. Do not preflight installed runtime assets. The plugin reports version skew without adding model\n turns; proceed from task evidence and project instructions.\n3. On restart or re-entry, reconstruct context from project-local durable artifacts and the\n latest bounded handoff or checkpoint. Preserve both manifests and ordered validation history;\n resume the same task through dog-coordinator with only the required delta.\n4. Otherwise transfer request and project context to dog-coordinator. Frontmatter is the single coordinator\n transfer; never route a worker to the user.\n";
|
|
1509
1525
|
}];
|
package/dist/runtime-assets.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GOAL_DECLARATION_FORMAT } from "./core/goal-declaration-format.js";
|
|
2
|
-
const ASSET_VERSION = "0.3.
|
|
2
|
+
const ASSET_VERSION = "0.3.86-codegen-proof-v1";
|
|
3
3
|
// Kept local so source-mode CLI execution does not load the plugin graph.
|
|
4
4
|
const BACKLOG_DRAIN_CAPABILITY = "sortie_enable_backlog_drain";
|
|
5
5
|
const PARALLEL_PREPARE_CAPABILITY = "sortie_prepare_parallel_dispatch";
|
|
@@ -97,6 +97,21 @@ is terminal for those causes. Only an external dependency or user-controlled dec
|
|
|
97
97
|
and every terminal BLOCKED report must include its own line in the exact form TRUE_BLOCKER: external: <condition>
|
|
98
98
|
or TRUE_BLOCKER: user-decision: <condition>. Never stage outside exact manifest paths, use
|
|
99
99
|
git add -A, amend, push, or perform coordinator-owned commit work.
|
|
100
|
+
Validation budget exhaustion, host counters, local routing, and unavailable host capabilities are process
|
|
101
|
+
defects, never TRUE_BLOCKER: external and never a reason to ask the user for an internal route. Return the
|
|
102
|
+
typed defect to dog-coordinator for autonomous repair. A changed candidate may run the next declared
|
|
103
|
+
validation; an unchanged duplicate remains forbidden.
|
|
104
|
+
|
|
105
|
+
Before returning canonical PASS, build a criterion-level trace for every accepted criterion. Each trace
|
|
106
|
+
must name the criterion, the changed implementation path or inspected existing path, the concrete test
|
|
107
|
+
case/input form or static branch that exercises it, and PASS or UNPROVEN. A broad suite result alone does
|
|
108
|
+
not prove every criterion. Split criteria that cover multiple syntax forms, value shapes, scopes, or error
|
|
109
|
+
paths into representative paths. If any accepted edge remains UNPROVEN, add a manifest-authorized check or
|
|
110
|
+
return the evidence gap; never report completion from aggregate validation alone.
|
|
111
|
+
Treat generated-source boundaries as high risk. If a manifest changes a generator input, grammar, schema,
|
|
112
|
+
template, or a checked-in generated output, identify the repository's canonical generator and run it before
|
|
113
|
+
the final validation. Prove the regenerated output is stable and that canonical validation ran against that
|
|
114
|
+
post-generation candidate; tests against a hand-edited generated file are insufficient.
|
|
100
115
|
|
|
101
116
|
## Parallel immutable commit artifact
|
|
102
117
|
|
|
@@ -1584,7 +1599,7 @@ CONTRACT_PREFLIGHT_FIXTURE
|
|
|
1584
1599
|
repair: fix the named pointer; an unchanged resend earns retry-exhausted
|
|
1585
1600
|
END_CONTRACT_PREFLIGHT_FIXTURE
|
|
1586
1601
|
|
|
1587
|
-
## Validation, review, and commit gates
|
|
1602
|
+
## Validation, review, and commit gates
|
|
1588
1603
|
|
|
1589
1604
|
The coordinator owns every staging and commit action. Reject and report any worker attempt to
|
|
1590
1605
|
stage or commit. Run the canonical validation before staging; a nonzero exit blocks both staging
|
|
@@ -1592,7 +1607,15 @@ and commit. Classify candidate risk only after canonical validation. For a low-r
|
|
|
1592
1607
|
explicitly record dog-reviewer skipped and permit staging. For a high-risk candidate, run
|
|
1593
1608
|
dog-reviewer only after canonical validation passes and require its PASS before the coordinator
|
|
1594
1609
|
stages or commits. Return reviewer findings through dog-coordinator and fail closed while
|
|
1595
|
-
unreviewed. If dog-reviewer is unavailable or does not return PASS, fail closed before staging.
|
|
1610
|
+
unreviewed. If dog-reviewer is unavailable or does not return PASS, fail closed before staging.
|
|
1611
|
+
Before risk classification or terminal DONE, require one criterion-level trace per accepted criterion:
|
|
1612
|
+
criterion -> changed or inspected implementation path -> concrete exercising test/input/branch -> PASS.
|
|
1613
|
+
An aggregate validation command without that mapping is insufficient. Multi-form criteria must cover their
|
|
1614
|
+
materially distinct syntax, value-shape, scope, and error paths; any missing path remains UNPROVEN and requires
|
|
1615
|
+
continued implementation or validation. Include the complete trace in every high-risk SourceReview artifact.
|
|
1616
|
+
Any generated input/output pair in the changed manifest is high risk and requires SourceReview. DONE requires
|
|
1617
|
+
generator command evidence, post-generation candidate identity, generated-output stability, and canonical
|
|
1618
|
+
validation after generation. Reject evidence produced only before regeneration.
|
|
1596
1619
|
|
|
1597
1620
|
GATE_POLICY_FIXTURE
|
|
1598
1621
|
risk_rule: high when source_manifest has an entry outside test/, validation level is targeted, or operation_manifest mutates non-artifact state; a qualifying artifact-only candidate is low-risk despite operation_manifest
|
|
@@ -1627,11 +1650,19 @@ At each checkpoint and terminal return, preserve concise proof internally. The u
|
|
|
1627
1650
|
return MUST begin with its conclusion: no plan, progress, assessment, Evidence heading, or preamble.
|
|
1628
1651
|
Use exactly one of DONE, INTERRUPTED, BLOCKED, or NEED_DECISION with one status emoji and a short
|
|
1629
1652
|
Japanese conclusion. Then render Japanese 変更点, 確認結果, and 次 paragraphs without bullets or decorative
|
|
1630
|
-
emoji.
|
|
1631
|
-
|
|
1653
|
+
emoji. After those paragraphs, always render one durable fallback card in the same assistant message:
|
|
1654
|
+
<details>
|
|
1655
|
+
<summary><strong>🐾 SORTIE DOGS — 帰還報告</strong></summary>
|
|
1656
|
+
|
|
1657
|
+
**任務:** <same short conclusion>
|
|
1658
|
+
**確認:** <concise validation/review summary without internal identifiers>
|
|
1659
|
+
|
|
1660
|
+
</details>
|
|
1661
|
+
The plugin replaces that exact persisted card in place with measured Speed, Cost, and 達成 paragraphs,
|
|
1662
|
+
one fixed icon per section, observed pack/model usage, validation/review, and evidence-backed traits.
|
|
1632
1663
|
Its Markdown token bars and PACK RECORD summarize retained project goals, with coverage and team titles;
|
|
1633
1664
|
they never imply lifetime history, XP, levels, unmeasured savings, or a leaderboard rank.
|
|
1634
|
-
Never write
|
|
1665
|
+
Never write measured metrics, token bars, PACK RECORD, traits, or badges yourself. Do not estimate or fabricate them.
|
|
1635
1666
|
Use 任務完了 for DONE, 中断帰還(未完了) for INTERRUPTED, 外部要因で待機(未完了) for BLOCKED,
|
|
1636
1667
|
and 指示待ち(未完了) for NEED_DECISION; preserve the machine status token and first-line checkpoint.
|
|
1637
1668
|
Never render a user-facing Evidence heading or Evidence details block, evidence reference, internal reason code,
|
|
@@ -1786,6 +1817,13 @@ maps to at least one changedLogicSummary entry and assess that changed logic aga
|
|
|
1786
1817
|
acceptance item. Missing or incomplete coverage is a concrete finding, never PASS.
|
|
1787
1818
|
Require one indexed acceptance[i] -> changedLogicSummary[j] mapping line per acceptance item and
|
|
1788
1819
|
reject a missing index or unequal mapping count before assessing the changed logic.
|
|
1820
|
+
Also require each acceptance item to map to a concrete exercising test/input/branch and result. A broad
|
|
1821
|
+
suite PASS without criterion-level exercise evidence is insufficient. When one item contains materially
|
|
1822
|
+
different syntax forms, value shapes, scopes, or error paths, reject PASS unless representative traces cover
|
|
1823
|
+
each path or the artifact proves they share one implementation path.
|
|
1824
|
+
When changed files include generator inputs or checked-in generated outputs, require the canonical generator
|
|
1825
|
+
command, a stable post-generation diff, and validation executed after generation. Reject PASS if helper logic
|
|
1826
|
+
exists only in a generated output, regeneration removes behavior, or validation predates the generated candidate.
|
|
1789
1827
|
Do not request raw logs or full source files, review low-risk candidates, expand scope, or dispatch
|
|
1790
1828
|
another agent.
|
|
1791
1829
|
Treat those supplied fields as the complete bounded SourceReview artifact; use only that artifact and invoke no tools.
|