@wrongstack/core 0.302.0 → 0.302.2
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/agent-status-tracker.d.ts +6 -2
- package/dist/chronicle/index.js +1836 -1645
- package/dist/chronicle/metrics-store.d.ts +14 -0
- package/dist/chronicle/project-server-protocol.d.ts +13 -0
- package/dist/chronicle/project-server.js +1759 -1583
- package/dist/chronicle/rollup-adapter.d.ts +2 -0
- package/dist/chronicle/sqlite-journal.d.ts +59 -0
- package/dist/coordination/index.js +790 -248
- package/dist/coordination/mail-tools.d.ts +2 -2
- package/dist/core/continue-intent.d.ts +2 -0
- package/dist/core/conversation-state.d.ts +5 -0
- package/dist/core/index.js +120 -19
- package/dist/defaults/index.js +927 -373
- package/dist/execution/index.js +27 -10
- package/dist/index.d.ts +3 -1
- package/dist/index.js +8762 -6780
- package/dist/infrastructure/index.js +722 -672
- package/dist/kernel/events/memory-events.d.ts +62 -0
- package/dist/plugin/index.js +2154 -1979
- package/dist/session-catalog/client.d.ts +62 -0
- package/dist/session-catalog/endpoint.d.ts +6 -0
- package/dist/session-catalog/index.d.ts +6 -0
- package/dist/session-catalog/index.js +1978 -0
- package/dist/session-catalog/project-server.d.ts +3 -0
- package/dist/session-catalog/project-server.js +1838 -0
- package/dist/session-catalog/protocol.d.ts +275 -0
- package/dist/session-catalog/registry.d.ts +59 -0
- package/dist/session-catalog/store.d.ts +55 -0
- package/dist/storage/index.d.ts +42 -38
- package/dist/storage/index.js +14279 -13393
- package/dist/storage/session-event-bridge.d.ts +2 -2
- package/dist/storage/session-store.d.ts +6 -0
- package/dist/tools/index.js +8 -2
- package/dist/types/context-evidence.d.ts +2 -0
- package/dist/types/messages.d.ts +8 -0
- package/dist/types/session.d.ts +19 -0
- package/dist/utils/context-evidence.d.ts +13 -1
- package/dist/utils/index.js +26 -2
- package/instructions/system-lite.md +11 -2
- package/instructions/system-pro.md +14 -0
- package/instructions/system.md +14 -0
- package/package.json +7 -3
|
@@ -45,12 +45,12 @@ export interface SessionEventBridge {
|
|
|
45
45
|
allows(type: SessionEvent['type']): boolean;
|
|
46
46
|
}
|
|
47
47
|
/** Core events that are always written regardless of auditLevel. */
|
|
48
|
-
declare const CORE_RECONSTRUCT_EVENTS: Set<"agent_error" | "agent_spawned" | "agent_stopped" | "checkpoint" | "compaction" | "context_snapshot" | "error" | "file_event" | "file_observation" | "file_snapshot" | "in_flight_end" | "in_flight_start" | "llm_request" | "llm_response" | "message_appended" | "message_truncated" | "message_updated" | "messages_replaced" | "mode_changed" | "provider_error" | "provider_retry" | "rewound" | "session_end" | "session_forked" | "session_resumed" | "session_start" | "side_effect" | "skill_activated" | "skill_deactivated" | "spec_analyzed" | "spec_parsed" | "task_completed" | "task_created" | "task_failed" | "task_updated" | "tool_call_end" | "tool_call_start" | "tool_progress" | "tool_result" | "tool_use" | "user_input">;
|
|
48
|
+
declare const CORE_RECONSTRUCT_EVENTS: Set<"agent_error" | "agent_spawned" | "agent_stopped" | "checkpoint" | "compaction" | "context_snapshot" | "error" | "file_event" | "file_observation" | "file_snapshot" | "in_flight_end" | "in_flight_start" | "llm_request" | "llm_response" | "message_appended" | "message_truncated" | "message_updated" | "messages_dropped" | "messages_replaced" | "mode_changed" | "provider_error" | "provider_retry" | "rewound" | "session_end" | "session_forked" | "session_resumed" | "session_start" | "side_effect" | "skill_activated" | "skill_deactivated" | "spec_analyzed" | "spec_parsed" | "task_completed" | "task_created" | "task_failed" | "task_updated" | "tool_call_end" | "tool_call_start" | "tool_progress" | "tool_result" | "tool_use" | "user_input">;
|
|
49
49
|
/**
|
|
50
50
|
* Events that are considered "standard" audit detail.
|
|
51
51
|
* These are lightweight and high-value for forensics.
|
|
52
52
|
*/
|
|
53
|
-
declare const STANDARD_AUDIT_EVENTS: Set<"agent_error" | "agent_spawned" | "agent_stopped" | "checkpoint" | "compaction" | "context_snapshot" | "error" | "file_event" | "file_observation" | "file_snapshot" | "in_flight_end" | "in_flight_start" | "llm_request" | "llm_response" | "message_appended" | "message_truncated" | "message_updated" | "messages_replaced" | "mode_changed" | "provider_error" | "provider_retry" | "rewound" | "session_end" | "session_forked" | "session_resumed" | "session_start" | "side_effect" | "skill_activated" | "skill_deactivated" | "spec_analyzed" | "spec_parsed" | "task_completed" | "task_created" | "task_failed" | "task_updated" | "tool_call_end" | "tool_call_start" | "tool_progress" | "tool_result" | "tool_use" | "user_input">;
|
|
53
|
+
declare const STANDARD_AUDIT_EVENTS: Set<"agent_error" | "agent_spawned" | "agent_stopped" | "checkpoint" | "compaction" | "context_snapshot" | "error" | "file_event" | "file_observation" | "file_snapshot" | "in_flight_end" | "in_flight_start" | "llm_request" | "llm_response" | "message_appended" | "message_truncated" | "message_updated" | "messages_dropped" | "messages_replaced" | "mode_changed" | "provider_error" | "provider_retry" | "rewound" | "session_end" | "session_forked" | "session_resumed" | "session_start" | "side_effect" | "skill_activated" | "skill_deactivated" | "spec_analyzed" | "spec_parsed" | "task_completed" | "task_created" | "task_failed" | "task_updated" | "tool_call_end" | "tool_call_start" | "tool_progress" | "tool_result" | "tool_use" | "user_input">;
|
|
54
54
|
/**
|
|
55
55
|
* Create a safe, audit-level-aware bridge around a SessionWriter.
|
|
56
56
|
*
|
|
@@ -11,6 +11,9 @@ export declare class DefaultSessionStore implements SessionStore {
|
|
|
11
11
|
private readonly logger;
|
|
12
12
|
private readonly onAppend?;
|
|
13
13
|
private readonly onAppendBatch?;
|
|
14
|
+
/** Present in built production output; source-only tests retain the local compatibility path. */
|
|
15
|
+
private readonly catalogClient;
|
|
16
|
+
private readonly maintenanceHolderId;
|
|
14
17
|
/**
|
|
15
18
|
* In-memory cache for load() results, keyed by session ID. The cache is
|
|
16
19
|
* invalidated when the file's mtimeMs or size changes (indicating the
|
|
@@ -38,6 +41,7 @@ export declare class DefaultSessionStore implements SessionStore {
|
|
|
38
41
|
* the file has changed externally (e.g., another process wrote to it).
|
|
39
42
|
*/
|
|
40
43
|
clearLoadCache(sessionId?: string): void;
|
|
44
|
+
dispose(): Promise<void>;
|
|
41
45
|
/** Absolute path to the session index file. */
|
|
42
46
|
private get indexFile();
|
|
43
47
|
/** Join session ID to its absolute path within the store directory. */
|
|
@@ -131,6 +135,8 @@ export declare class DefaultSessionStore implements SessionStore {
|
|
|
131
135
|
private appendToIndexStrict;
|
|
132
136
|
/** Best-effort index append used by writer close. */
|
|
133
137
|
private appendToIndex;
|
|
138
|
+
/** Final summary boundary: daemon is authoritative when available. */
|
|
139
|
+
private persistCatalogSummary;
|
|
134
140
|
/** Append a tombstone entry for a deleted session. */
|
|
135
141
|
private writeTombstone;
|
|
136
142
|
/**
|
package/dist/tools/index.js
CHANGED
|
@@ -8352,22 +8352,27 @@ var OneShotOrchestrator = class {
|
|
|
8352
8352
|
*/
|
|
8353
8353
|
resolveFallbackChain(input, config, target) {
|
|
8354
8354
|
const mgr = this.opts.fallbackProfileManager;
|
|
8355
|
+
let fromExplicitSource = false;
|
|
8355
8356
|
let selected = mgr.resolveEffective({
|
|
8356
8357
|
fallbackAuto: false,
|
|
8357
8358
|
exclude: target
|
|
8358
8359
|
});
|
|
8359
8360
|
if (input.fallbackModels && input.fallbackModels.length > 0) {
|
|
8360
|
-
|
|
8361
|
+
const resolved = mgr.resolveEffective({
|
|
8361
8362
|
fallbackModels: input.fallbackModels,
|
|
8362
8363
|
fallbackAuto: false,
|
|
8363
8364
|
exclude: target
|
|
8364
8365
|
});
|
|
8366
|
+
selected = resolved;
|
|
8367
|
+
fromExplicitSource = resolved.length > 0;
|
|
8365
8368
|
} else if (config.fallbackModels && config.fallbackModels.length > 0) {
|
|
8366
|
-
|
|
8369
|
+
const resolved = mgr.resolveEffective({
|
|
8367
8370
|
fallbackModels: config.fallbackModels,
|
|
8368
8371
|
fallbackAuto: false,
|
|
8369
8372
|
exclude: target
|
|
8370
8373
|
});
|
|
8374
|
+
selected = resolved;
|
|
8375
|
+
fromExplicitSource = resolved.length > 0;
|
|
8371
8376
|
} else if (config.fallbackAuto !== false) {
|
|
8372
8377
|
selected = mgr.resolveEffective({
|
|
8373
8378
|
fallbackAuto: true,
|
|
@@ -8375,6 +8380,7 @@ var OneShotOrchestrator = class {
|
|
|
8375
8380
|
});
|
|
8376
8381
|
}
|
|
8377
8382
|
if (config.fallbackAuto === false) return selected;
|
|
8383
|
+
if (fromExplicitSource) return selected;
|
|
8378
8384
|
const combined = [...selected, ...mgr.resolveAllConfigured(target)];
|
|
8379
8385
|
const seen = /* @__PURE__ */ new Set();
|
|
8380
8386
|
return Object.freeze(
|
|
@@ -54,6 +54,8 @@ export interface CompletedWorkEvidence {
|
|
|
54
54
|
}
|
|
55
55
|
export interface ContextEvidenceState {
|
|
56
56
|
currentIntent?: ContextIntentEvidence | undefined;
|
|
57
|
+
/** Recent real human inputs, bounded and rendered as volatile continuity evidence. */
|
|
58
|
+
recentUserTurns?: ContextIntentEvidence[] | undefined;
|
|
57
59
|
sessionGoals: string[];
|
|
58
60
|
implicitFacts: string[];
|
|
59
61
|
activeErrors: string[];
|
package/dist/types/messages.d.ts
CHANGED
|
@@ -3,6 +3,14 @@ export type MessageRole = 'user' | 'assistant' | 'system';
|
|
|
3
3
|
export interface Message {
|
|
4
4
|
role: MessageRole;
|
|
5
5
|
content: string | ContentBlock[];
|
|
6
|
+
/**
|
|
7
|
+
* Local provenance used by context management. `user_input` is reserved for
|
|
8
|
+
* text the human actually submitted; provider adapters intentionally ignore
|
|
9
|
+
* this field. Keeping it on the journaled message lets resumed sessions
|
|
10
|
+
* distinguish real conversation turns from tool-result/runtime `user`
|
|
11
|
+
* messages without relying on brittle text heuristics.
|
|
12
|
+
*/
|
|
13
|
+
origin?: 'user_input' | 'runtime' | undefined;
|
|
6
14
|
/**
|
|
7
15
|
* ISO-8601 timestamp from the originating SessionEvent.
|
|
8
16
|
* Populated by SessionStore.replay() during session load/resume
|
package/dist/types/session.d.ts
CHANGED
|
@@ -137,6 +137,23 @@ export type SessionEvent = {
|
|
|
137
137
|
* payload had on disk. Absent on freshly emitted events.
|
|
138
138
|
*/
|
|
139
139
|
messagesOmitted?: number;
|
|
140
|
+
} | {
|
|
141
|
+
/**
|
|
142
|
+
* The oldest `count` messages were evicted from the front of the history.
|
|
143
|
+
*
|
|
144
|
+
* A delta rather than a `messages_replaced` snapshot, because eviction is
|
|
145
|
+
* the one rewrite that repeats: once a long session reaches
|
|
146
|
+
* `Context.MAX_MESSAGES`, *every* subsequent append overflows by one and
|
|
147
|
+
* drops one. Emitting the surviving history each time made the journal
|
|
148
|
+
* quadratic in session length — measured at 2.1 GB for one session whose
|
|
149
|
+
* actual content was ~10 MB, and 17.9 GB across a 20 GB corpus. Replay
|
|
150
|
+
* splices the same prefix off, so the reconstructed conversation is
|
|
151
|
+
* identical to what the snapshot would have produced.
|
|
152
|
+
*/
|
|
153
|
+
type: 'messages_dropped';
|
|
154
|
+
ts: string;
|
|
155
|
+
version: 1;
|
|
156
|
+
count: number;
|
|
140
157
|
} | {
|
|
141
158
|
/**
|
|
142
159
|
* Exact post-rewrite conversation state. Replay replaces all messages
|
|
@@ -590,6 +607,8 @@ export interface SessionStore {
|
|
|
590
607
|
* number of sessions indexed.
|
|
591
608
|
*/
|
|
592
609
|
rebuildIndex?(): Promise<number>;
|
|
610
|
+
/** Release project-daemon connections owned by this store. */
|
|
611
|
+
dispose?(): Promise<void>;
|
|
593
612
|
/**
|
|
594
613
|
* Streaming event-level search. Walks the JSONL once without buffering
|
|
595
614
|
* the whole file, calling `predicate(event, eventIndex, ts)` for each
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Context } from '../core/context.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type TextBlock } from '../types/blocks.js';
|
|
3
3
|
import type { CompactReport } from '../types/compactor.js';
|
|
4
4
|
import type { CompletedWorkEvidence, CompletedWorkSource, ContextEvidenceState, ToolOutputMetadata } from '../types/context-evidence.js';
|
|
5
5
|
export declare function createContextEvidenceState(): ContextEvidenceState;
|
|
@@ -14,6 +14,18 @@ export interface RecordToolOutputEvidenceInput {
|
|
|
14
14
|
outputLines?: number | undefined;
|
|
15
15
|
}
|
|
16
16
|
export declare function recordUserIntentEvidence(ctx: Context, text: string): void;
|
|
17
|
+
/** Runtime steering/status blocks must not displace real conversation turns. */
|
|
18
|
+
export declare function isRuntimeContextInput(text: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Keep the real conversation thread visible near the stable system prompt.
|
|
21
|
+
*
|
|
22
|
+
* Tool-heavy runs can place hundreds of protocol messages after one human
|
|
23
|
+
* instruction. Re-sending a small, replaceable tail of actual user inputs is
|
|
24
|
+
* cheaper and more reliable than retaining every intervening tool exchange.
|
|
25
|
+
* It is volatile provider evidence, so it never grows the durable chat log or
|
|
26
|
+
* invalidates the cached base prompt.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildConversationContinuityBlock(ctx: Pick<Context, 'contextEvidence' | 'messages'>): TextBlock | undefined;
|
|
17
29
|
export declare function recordToolOutputEvidence(ctx: Context, input: RecordToolOutputEvidenceInput): ToolOutputMetadata;
|
|
18
30
|
export declare function markAssistantReferencedEvidence(ctx: Context, text: string): void;
|
|
19
31
|
export declare function buildContextEvidenceDigest(ctx: Context): string;
|
package/dist/utils/index.js
CHANGED
|
@@ -855,6 +855,9 @@ var MAX_TOOL_CALLS = 80;
|
|
|
855
855
|
var MAX_FACTS = 40;
|
|
856
856
|
var MAX_ERRORS = 20;
|
|
857
857
|
var MAX_DIGEST_CHARS = 4e3;
|
|
858
|
+
var MAX_RECENT_USER_TURNS = 8;
|
|
859
|
+
var MAX_USER_TURN_CHARS = 700;
|
|
860
|
+
var RUNTIME_CONTEXT_INPUT_PATTERN = /^\[(?:kanban todo update|fleet pulse|loop-detector|todo-reconciliation|mailbox|btw|system|context_state)\b/i;
|
|
858
861
|
var RECENT_TOOL_CALL_SCAN_LIMIT = 20;
|
|
859
862
|
var EXTRACT_CONTENT_CAP_CHARS = 1e4;
|
|
860
863
|
var EXTRACT_ERROR_TAIL_LINES = 200;
|
|
@@ -862,6 +865,7 @@ var WRITE_TOOLS = /* @__PURE__ */ new Set(["edit", "write", "replace", "patch"])
|
|
|
862
865
|
var READ_TOOLS = /* @__PURE__ */ new Set(["read", "grep", "glob", "ls", "tree"]);
|
|
863
866
|
function createContextEvidenceState() {
|
|
864
867
|
return {
|
|
868
|
+
recentUserTurns: [],
|
|
865
869
|
sessionGoals: [],
|
|
866
870
|
implicitFacts: [],
|
|
867
871
|
activeErrors: [],
|
|
@@ -873,15 +877,25 @@ function createContextEvidenceState() {
|
|
|
873
877
|
};
|
|
874
878
|
}
|
|
875
879
|
function recordUserIntentEvidence(ctx, text) {
|
|
876
|
-
|
|
880
|
+
if (isRuntimeContextInput(text)) return;
|
|
881
|
+
const intent = normalizeWhitespace(text).slice(0, MAX_USER_TURN_CHARS);
|
|
877
882
|
if (!intent) return;
|
|
878
883
|
const state = ensureEvidence(ctx);
|
|
879
|
-
|
|
884
|
+
const turn = { text: intent, updatedAt: Date.now() };
|
|
885
|
+
state.currentIntent = turn;
|
|
886
|
+
state.recentUserTurns ??= [];
|
|
887
|
+
state.recentUserTurns.push(turn);
|
|
888
|
+
if (state.recentUserTurns.length > MAX_RECENT_USER_TURNS) {
|
|
889
|
+
state.recentUserTurns.splice(0, state.recentUserTurns.length - MAX_RECENT_USER_TURNS);
|
|
890
|
+
}
|
|
880
891
|
if (state.sessionGoals.length === 0 || isGoalish(intent)) {
|
|
881
892
|
pushUniqueBounded(state.sessionGoals, intent, 8);
|
|
882
893
|
}
|
|
883
894
|
state.updatedAt = Date.now();
|
|
884
895
|
}
|
|
896
|
+
function isRuntimeContextInput(text) {
|
|
897
|
+
return RUNTIME_CONTEXT_INPUT_PATTERN.test(text.trim());
|
|
898
|
+
}
|
|
885
899
|
function recordToolOutputEvidence(ctx, input) {
|
|
886
900
|
const state = ensureEvidence(ctx);
|
|
887
901
|
const scanContent = input.content.length > EXTRACT_CONTENT_CAP_CHARS ? input.content.slice(0, EXTRACT_CONTENT_CAP_CHARS) : input.content;
|
|
@@ -949,6 +963,11 @@ function buildContextEvidenceDigest(ctx) {
|
|
|
949
963
|
if (state.currentIntent?.text) {
|
|
950
964
|
lines.push(`intent: ${state.currentIntent.text}`);
|
|
951
965
|
}
|
|
966
|
+
const priorTurns = (state.recentUserTurns ?? []).slice(-6, -1);
|
|
967
|
+
if (priorTurns.length > 0) {
|
|
968
|
+
lines.push("recent_human_instructions:");
|
|
969
|
+
for (const turn of priorTurns) lines.push(`- ${turn.text}`);
|
|
970
|
+
}
|
|
952
971
|
const goals = state.sessionGoals.slice(-3);
|
|
953
972
|
if (goals.length > 0) {
|
|
954
973
|
lines.push("session_goals:");
|
|
@@ -1003,6 +1022,7 @@ function ensureEvidence(ctx) {
|
|
|
1003
1022
|
ctx.contextEvidence = createContextEvidenceState();
|
|
1004
1023
|
}
|
|
1005
1024
|
ctx.contextEvidence.completedWork ??= [];
|
|
1025
|
+
ctx.contextEvidence.recentUserTurns ??= [];
|
|
1006
1026
|
return ctx.contextEvidence;
|
|
1007
1027
|
}
|
|
1008
1028
|
var MAX_COMPLETED_WORK = 50;
|
|
@@ -1709,12 +1729,16 @@ function buildLiveNextStepsGateBlock(ctx) {
|
|
|
1709
1729
|
});
|
|
1710
1730
|
const omitted = openTodos.length - todoSnapshot.length;
|
|
1711
1731
|
if (omitted > 0) todoSnapshot.push(`- \u2026and ${omitted} more open todo(s)`);
|
|
1732
|
+
const todoReconciliation = ctx.tools?.some((tool) => tool.name === "todo") ? [
|
|
1733
|
+
"Before ending the turn, you MUST call the `todo` tool with the complete current list to reconcile actual progress: finished items completed, exactly one actively worked item in_progress, and untouched items pending. A prose claim that work is done does not update the Todo/Kanban state."
|
|
1734
|
+
] : [];
|
|
1712
1735
|
return {
|
|
1713
1736
|
type: "text",
|
|
1714
1737
|
text: [
|
|
1715
1738
|
"[nextsteps_gate]",
|
|
1716
1739
|
`Authoritative live state for this request: open todos = ${openTodos.length}.`,
|
|
1717
1740
|
"You MUST omit <nextsteps> entirely while these todos remain open. Continue or finish the tracked work; do not propose unrelated follow-on work.",
|
|
1741
|
+
...todoReconciliation,
|
|
1718
1742
|
"Open todo snapshot:",
|
|
1719
1743
|
...todoSnapshot,
|
|
1720
1744
|
"[/nextsteps_gate]"
|
|
@@ -28,8 +28,16 @@ The user is an experienced developer; accelerate them and stay focused.
|
|
|
28
28
|
6. Report what changed, what was verified, and what remains unverified.
|
|
29
29
|
|
|
30
30
|
<!--ws:if tool=todo-->
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
## Todo status lifecycle
|
|
32
|
+
|
|
33
|
+
Use a visible `todo` list for tasks with three or more steps. It is authoritative session/UI state; prose does not update it.
|
|
34
|
+
|
|
35
|
+
1. Before work starts, submit the complete list with exactly the selected item `in_progress`; keep finished items `completed` and untouched items `pending`.
|
|
36
|
+
2. After implementation and required verification, immediately submit the complete list again: current item `completed`, and the next pending item `in_progress` when continuing.
|
|
37
|
+
3. Before a final response, reconcile every status. Never leave finished work pending/running, never mark unverified work complete, and never repeat a continuation/next-step prompt instead of updating state.
|
|
38
|
+
4. Submit the final all-`completed` snapshot even though it auto-clears afterward. Session-todo mirror cards map `pending → Todo`, `in_progress → Running`, `completed → Done`.
|
|
39
|
+
|
|
40
|
+
If blocked, keep the item truthful and report the blocker instead of advancing it as successful.
|
|
33
41
|
<!--ws:end-->
|
|
34
42
|
If verification fails twice for unclear reasons, stop and re-read the source instead of guessing.
|
|
35
43
|
|
|
@@ -54,6 +62,7 @@ These conditions are mandatory whenever a task belongs to a Kanban board. They a
|
|
|
54
62
|
2. **Fully specify every card before advancing it.** Fill and verify the description, assignee/agent, due date, tags, subtasks, acceptance criteria, dependencies, and any board-required detail fields. An under-filled card must remain in Backlog.
|
|
55
63
|
3. **Persist every completed action immediately.** After each material action, update the Kanban data itself—not just chat—with the exact column/status transition and the truthful comment, check result, link, attachment, assignment, or other evidence produced. Never fake, batch away, or skip intermediate updates.
|
|
56
64
|
4. **Follow the lifecycle exactly.** Managed cards move only `Backlog → Todo → Running → Review → Done`, one adjacent transition at a time. Use the Kanban transition operation; never jump columns, arbitrarily abandon a card, or push it to Done without review evidence and passed acceptance criteria. Worker completion means the card enters Review; it does not authorize Done.
|
|
65
|
+
5. **Close and advance immediately.** Persist the accepted card in Running before work. Persist Running → Review when work finishes and Review → Done only after acceptance evidence passes. If continuing, move the next eligible card through adjacent transitions to Running before acting. Never leave completed work in Running or repeat a next-step prompt instead of updating the board.
|
|
57
66
|
|
|
58
67
|
If a managed transition is rejected, repair the card details or evidence and retry the same transition. Do not bypass the guard through raw status, column, import, copy, or storage operations.
|
|
59
68
|
<!--ws:end-->
|
|
@@ -107,6 +107,19 @@ Reasoning depth is a dial, not a constant. Match it to the blast radius of what
|
|
|
107
107
|
10. **Leave the knowledge behind, not just the diff.** A task that taught you something durable about this codebase isn't finished until that knowledge is in memory (see Memory management).
|
|
108
108
|
11. **Keep helper scripts temporary and contained.** This rule applies to every agent, regardless of role (leader, coordinator, or subagent). Create all ad hoc helper scripts and their temporary inputs/outputs only under `<project-root>/.temp_files/` — never in the repository root or source directories. Write each helper script so its paths, imports, and generated artifacts work from that location. Delete the helper script and any temporary artifacts it created as soon as they are no longer needed, and always before reporting the task complete. Only remove files created for the current task; never delete pre-existing or user-owned contents of `.temp_files/`. This rule does not apply to permanent project scripts explicitly requested by the user.
|
|
109
109
|
|
|
110
|
+
<!--ws:if tool=todo-->
|
|
111
|
+
## Todo status lifecycle
|
|
112
|
+
|
|
113
|
+
The live `todo` list is authoritative session state shared by the active UI and session-owned Kanban mirror. Prose does not change status.
|
|
114
|
+
|
|
115
|
+
1. Before starting a selected item, call `todo` with the complete list and set exactly that item to `in_progress`; leave finished items `completed` and untouched items `pending`.
|
|
116
|
+
2. After implementation and its required verification finish, immediately call `todo` again: mark the current item `completed` and, when continuing, promote the next pending item to `in_progress` in the same full-list update.
|
|
117
|
+
3. Before any final response, reconcile the complete list. Never leave finished work `pending`/`in_progress`, never mark unverified work `completed`, and never use a repeated continuation or next-step prompt as a substitute for a status update.
|
|
118
|
+
4. When every item is finished, submit the all-`completed` snapshot even though the runtime then auto-clears the tactical list. For session-todo mirror cards, the corresponding states are `pending → Todo`, `in_progress → Running`, and `completed → Done`.
|
|
119
|
+
|
|
120
|
+
If work is blocked, keep its status truthful, state the blocker, and do not silently advance as though it succeeded.
|
|
121
|
+
<!--ws:end-->
|
|
122
|
+
|
|
110
123
|
<!--ws:if tool=kanban-->
|
|
111
124
|
## Work planning with Kanban
|
|
112
125
|
|
|
@@ -145,6 +158,7 @@ These conditions are mandatory whenever a task belongs to a Kanban board. They a
|
|
|
145
158
|
An under-filled card must remain in Backlog. At minimum, every card must have a `description`, `assignee`, `dueDate`, `labels`, `childTaskIds`, and `successCriteria` before it can leave Backlog (these match the `validateRequiredCardDetails` checks in `lifecycle.ts`). Note that `dependsOn` is tracked at the data-model level but is NOT enforced by the lifecycle validator — dependency ordering is managed by the agent/board workflow, not the guard. The `childTaskIds` requirement means new cards on managed boards typically need at least one sub-task — use `kanban` with the `split_atomic` action to create the parent-child structure.
|
|
146
159
|
3. **Persist every completed action immediately.** After each material action, update the Kanban data itself—not just chat—with the exact column/status transition and the truthful comment, check result, link, attachment, assignment, or other evidence produced. Never fake, batch away, or skip intermediate updates.
|
|
147
160
|
4. **Follow the lifecycle exactly.** Managed cards move only `Backlog → Todo → Running → Review → Done`, one adjacent transition at a time. Use the Kanban transition operation; never jump columns, arbitrarily abandon a card, or push it to Done without review evidence and passed acceptance criteria. Worker completion means the card enters Review; it does not authorize Done.
|
|
161
|
+
5. **Close and advance immediately.** Before executing an accepted card, persist its adjacent transition to Running. When its work finishes, persist Running → Review; after acceptance evidence passes, persist Review → Done. If autonomous work continues, select the next eligible card and move it through adjacent transitions to Running before acting on it. Never leave completed work in Running or repeat a next-step prompt to compensate for stale board state.
|
|
148
162
|
|
|
149
163
|
If a managed transition is rejected, repair the card details or evidence and retry the same transition. Do not bypass the guard through raw status, column, import, copy, or storage operations.
|
|
150
164
|
|
package/instructions/system.md
CHANGED
|
@@ -48,6 +48,19 @@ This parse is **internal reasoning**, not something you output. It keeps you anc
|
|
|
48
48
|
8. **Stay focused.** Fix only what was asked — no refactoring or reformatting of neighboring code. Comment only to explain *why*, not *what*. Don't lecture about engineering principles unless asked.
|
|
49
49
|
9. **Keep helper scripts temporary and contained.** This rule applies to every agent, regardless of role (leader, coordinator, or subagent). Create all ad hoc helper scripts and their temporary inputs/outputs only under `<project-root>/.temp_files/` — never in the repository root or source directories. Write each helper script so its paths, imports, and generated artifacts work from that location. Delete the helper script and any temporary artifacts it created as soon as they are no longer needed, and always before reporting the task complete. Only remove files created for the current task; never delete pre-existing or user-owned contents of `.temp_files/`. This rule does not apply to permanent project scripts explicitly requested by the user.
|
|
50
50
|
|
|
51
|
+
<!--ws:if tool=todo-->
|
|
52
|
+
## Todo status lifecycle
|
|
53
|
+
|
|
54
|
+
The live `todo` list is authoritative session state shared by the active UI and session-owned Kanban mirror. Prose does not change status.
|
|
55
|
+
|
|
56
|
+
1. Before starting a selected item, call `todo` with the complete list and set exactly that item to `in_progress`; leave finished items `completed` and untouched items `pending`.
|
|
57
|
+
2. After implementation and its required verification finish, immediately call `todo` again: mark the current item `completed` and, when continuing, promote the next pending item to `in_progress` in the same full-list update.
|
|
58
|
+
3. Before any final response, reconcile the complete list. Never leave finished work `pending`/`in_progress`, never mark unverified work `completed`, and never use a repeated continuation or next-step prompt as a substitute for a status update.
|
|
59
|
+
4. When every item is finished, submit the all-`completed` snapshot even though the runtime then auto-clears the tactical list. For session-todo mirror cards, the corresponding states are `pending → Todo`, `in_progress → Running`, and `completed → Done`.
|
|
60
|
+
|
|
61
|
+
If work is blocked, keep its status truthful, state the blocker, and do not silently advance as though it succeeded.
|
|
62
|
+
<!--ws:end-->
|
|
63
|
+
|
|
51
64
|
<!--ws:if tool=kanban-->
|
|
52
65
|
## Work planning with Kanban
|
|
53
66
|
|
|
@@ -84,6 +97,7 @@ These conditions are mandatory whenever a task belongs to a Kanban board. They a
|
|
|
84
97
|
An under-filled card must remain in Backlog. At minimum, every card must have a `description`, `assignee`, `dueDate`, `labels`, `childTaskIds`, and `successCriteria` before it can leave Backlog (these match the `validateRequiredCardDetails` checks in `lifecycle.ts`). Note that `dependsOn` is tracked at the data-model level but is NOT enforced by the lifecycle validator — dependency ordering is managed by the agent/board workflow, not the guard. The `childTaskIds` requirement means new cards on managed boards typically need at least one sub-task — use `kanban` with the `split_atomic` action to create the parent-child structure.
|
|
85
98
|
3. **Persist every completed action immediately.** After each material action, update the Kanban data itself—not just chat—with the exact column/status transition and the truthful comment, check result, link, attachment, assignment, or other evidence produced. Never fake, batch away, or skip intermediate updates.
|
|
86
99
|
4. **Follow the lifecycle exactly.** Managed cards move only `Backlog → Todo → Running → Review → Done`, one adjacent transition at a time. Use the Kanban transition operation; never jump columns, arbitrarily abandon a card, or push it to Done without review evidence and passed acceptance criteria. Worker completion means the card enters Review; it does not authorize Done.
|
|
100
|
+
5. **Close and advance immediately.** Before executing an accepted card, persist its adjacent transition to Running. When its work finishes, persist Running → Review; after acceptance evidence passes, persist Review → Done. If autonomous work continues, select the next eligible card and move it through adjacent transitions to Running before acting on it. Never leave completed work in Running or repeat a next-step prompt to compensate for stale board state.
|
|
87
101
|
|
|
88
102
|
If a managed transition is rejected, repair the card details or evidence and retry the same transition. Do not bypass the guard through raw status, column, import, copy, or storage operations.
|
|
89
103
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/core",
|
|
3
|
-
"version": "0.302.
|
|
3
|
+
"version": "0.302.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack core: kernel, types, defaults, and shared utilities for the WrongStack CLI agent.",
|
|
6
6
|
"repository": {
|
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
"types": "./dist/storage/index.d.ts",
|
|
97
97
|
"import": "./dist/storage/index.js"
|
|
98
98
|
},
|
|
99
|
+
"./session-catalog": {
|
|
100
|
+
"types": "./dist/session-catalog/index.d.ts",
|
|
101
|
+
"import": "./dist/session-catalog/index.js"
|
|
102
|
+
},
|
|
99
103
|
"./security": {
|
|
100
104
|
"types": "./dist/security/index.d.ts",
|
|
101
105
|
"import": "./dist/security/index.js"
|
|
@@ -173,8 +177,8 @@
|
|
|
173
177
|
"wrongstackApiVersion": "0.1.10",
|
|
174
178
|
"dependencies": {
|
|
175
179
|
"zod": "4.4.3",
|
|
176
|
-
"@wrongstack/
|
|
177
|
-
"@wrongstack/
|
|
180
|
+
"@wrongstack/persistence": "0.302.2",
|
|
181
|
+
"@wrongstack/kanban": "0.302.2"
|
|
178
182
|
},
|
|
179
183
|
"devDependencies": {
|
|
180
184
|
"@types/node": "^26.1.2",
|