@fractalsynapse/dsh-chapters 0.0.0-stage → 0.2.20
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/LICENSE +14 -0
- package/README.md +76 -2
- package/cordis.patch.yml +363 -0
- package/docs/architecture.md +692 -0
- package/docs/autorun-guide.md +248 -0
- package/docs/backlog.md +2022 -0
- package/docs/contract.md +938 -0
- package/docs/development.md +990 -0
- package/docs/host-compaction-seam.md +225 -0
- package/docs/host-protected-head-ask.md +80 -0
- package/docs/knowledge-repo.md +1332 -0
- package/docs/plans-carriage.md +571 -0
- package/docs/project-state.md +642 -0
- package/docs/provider.md +98 -0
- package/docs/superpowers/plans/2026-10-17-chapters-save.md +198 -0
- package/docs/superpowers/plans/2026-11-02-chapter-removal.md +151 -0
- package/docs/superpowers/specs/2026-11-02-chapter-removal-design.md +115 -0
- package/docs/verify.md +561 -0
- package/lib/archive.d.ts +161 -0
- package/lib/archive.js +229 -0
- package/lib/archive.js.map +1 -0
- package/lib/arrival.d.ts +23 -0
- package/lib/arrival.js +125 -0
- package/lib/arrival.js.map +1 -0
- package/lib/artifact-query.d.ts +62 -0
- package/lib/artifact-query.js +187 -0
- package/lib/artifact-query.js.map +1 -0
- package/lib/attach.d.ts +46 -0
- package/lib/attach.js +120 -0
- package/lib/attach.js.map +1 -0
- package/lib/auto-save.d.ts +145 -0
- package/lib/auto-save.js +334 -0
- package/lib/auto-save.js.map +1 -0
- package/lib/aux-message.d.ts +17 -0
- package/lib/aux-message.js +20 -0
- package/lib/aux-message.js.map +1 -0
- package/lib/client.js +1419 -0
- package/lib/client.js.map +1 -0
- package/lib/codegraph.d.ts +76 -0
- package/lib/codegraph.js +190 -0
- package/lib/codegraph.js.map +1 -0
- package/lib/commands.d.ts +52 -0
- package/lib/commands.js +946 -0
- package/lib/commands.js.map +1 -0
- package/lib/compose.d.ts +30 -0
- package/lib/compose.js +185 -0
- package/lib/compose.js.map +1 -0
- package/lib/continue-core.d.ts +245 -0
- package/lib/continue-core.js +405 -0
- package/lib/continue-core.js.map +1 -0
- package/lib/diag.d.ts +55 -0
- package/lib/diag.js +186 -0
- package/lib/diag.js.map +1 -0
- package/lib/engine-core.d.ts +301 -0
- package/lib/engine-core.js +531 -0
- package/lib/engine-core.js.map +1 -0
- package/lib/engine-note.d.ts +35 -0
- package/lib/engine-note.js +32 -0
- package/lib/engine-note.js.map +1 -0
- package/lib/engine.d.ts +329 -0
- package/lib/engine.js +1179 -0
- package/lib/engine.js.map +1 -0
- package/lib/enrich-queue.d.ts +66 -0
- package/lib/enrich-queue.js +126 -0
- package/lib/enrich-queue.js.map +1 -0
- package/lib/enrich-store.d.ts +31 -0
- package/lib/enrich-store.js +103 -0
- package/lib/enrich-store.js.map +1 -0
- package/lib/enrich-wire.d.ts +163 -0
- package/lib/enrich-wire.js +353 -0
- package/lib/enrich-wire.js.map +1 -0
- package/lib/enrich.d.ts +102 -0
- package/lib/enrich.js +267 -0
- package/lib/enrich.js.map +1 -0
- package/lib/gitops.d.ts +107 -0
- package/lib/gitops.js +539 -0
- package/lib/gitops.js.map +1 -0
- package/lib/index.d.ts +241 -0
- package/lib/index.js +1162 -0
- package/lib/index.js.map +1 -0
- package/lib/indexing.d.ts +98 -0
- package/lib/indexing.js +223 -0
- package/lib/indexing.js.map +1 -0
- package/lib/injections.d.ts +90 -0
- package/lib/injections.js +165 -0
- package/lib/injections.js.map +1 -0
- package/lib/last-resort.d.ts +24 -0
- package/lib/last-resort.js +27 -0
- package/lib/last-resort.js.map +1 -0
- package/lib/log-shape.d.ts +38 -0
- package/lib/log-shape.js +93 -0
- package/lib/log-shape.js.map +1 -0
- package/lib/models-command.d.ts +74 -0
- package/lib/models-command.js +100 -0
- package/lib/models-command.js.map +1 -0
- package/lib/notice.d.ts +74 -0
- package/lib/notice.js +92 -0
- package/lib/notice.js.map +1 -0
- package/lib/plans.d.ts +154 -0
- package/lib/plans.js +315 -0
- package/lib/plans.js.map +1 -0
- package/lib/preset.d.ts +186 -0
- package/lib/preset.js +212 -0
- package/lib/preset.js.map +1 -0
- package/lib/prompt-keys.d.ts +7 -0
- package/lib/prompt-keys.js +8 -0
- package/lib/prompt-keys.js.map +1 -0
- package/lib/prompt-loop.d.ts +73 -0
- package/lib/prompt-loop.js +147 -0
- package/lib/prompt-loop.js.map +1 -0
- package/lib/prompt-push.d.ts +47 -0
- package/lib/prompt-push.js +115 -0
- package/lib/prompt-push.js.map +1 -0
- package/lib/prompt-runner.d.ts +48 -0
- package/lib/prompt-runner.js +90 -0
- package/lib/prompt-runner.js.map +1 -0
- package/lib/prompt-state.d.ts +142 -0
- package/lib/prompt-state.js +101 -0
- package/lib/prompt-state.js.map +1 -0
- package/lib/prompt.d.ts +270 -0
- package/lib/prompt.js +408 -0
- package/lib/prompt.js.map +1 -0
- package/lib/provider.d.ts +44 -0
- package/lib/provider.js +66 -0
- package/lib/provider.js.map +1 -0
- package/lib/redact.d.ts +24 -0
- package/lib/redact.js +85 -0
- package/lib/redact.js.map +1 -0
- package/lib/registry.d.ts +187 -0
- package/lib/registry.js +235 -0
- package/lib/registry.js.map +1 -0
- package/lib/removal.d.ts +159 -0
- package/lib/removal.js +556 -0
- package/lib/removal.js.map +1 -0
- package/lib/render.d.ts +97 -0
- package/lib/render.js +530 -0
- package/lib/render.js.map +1 -0
- package/lib/repair-run.d.ts +76 -0
- package/lib/repair-run.js +506 -0
- package/lib/repair-run.js.map +1 -0
- package/lib/repair.d.ts +208 -0
- package/lib/repair.js +357 -0
- package/lib/repair.js.map +1 -0
- package/lib/repo.d.ts +78 -0
- package/lib/repo.js +184 -0
- package/lib/repo.js.map +1 -0
- package/lib/rules-commands.d.ts +46 -0
- package/lib/rules-commands.js +379 -0
- package/lib/rules-commands.js.map +1 -0
- package/lib/rules.d.ts +267 -0
- package/lib/rules.js +478 -0
- package/lib/rules.js.map +1 -0
- package/lib/save-core.d.ts +72 -0
- package/lib/save-core.js +220 -0
- package/lib/save-core.js.map +1 -0
- package/lib/search.d.ts +112 -0
- package/lib/search.js +282 -0
- package/lib/search.js.map +1 -0
- package/lib/session-rules.d.ts +222 -0
- package/lib/session-rules.js +454 -0
- package/lib/session-rules.js.map +1 -0
- package/lib/signature.d.ts +45 -0
- package/lib/signature.js +199 -0
- package/lib/signature.js.map +1 -0
- package/lib/store.d.ts +156 -0
- package/lib/store.js +368 -0
- package/lib/store.js.map +1 -0
- package/lib/sync.d.ts +220 -0
- package/lib/sync.js +810 -0
- package/lib/sync.js.map +1 -0
- package/lib/tools.d.ts +113 -0
- package/lib/tools.js +1090 -0
- package/lib/tools.js.map +1 -0
- package/lib/treedx/client.d.ts +57 -0
- package/lib/treedx/client.js +82 -0
- package/lib/treedx/client.js.map +1 -0
- package/lib/treedx/provider.d.ts +39 -0
- package/lib/treedx/provider.js +479 -0
- package/lib/treedx/provider.js.map +1 -0
- package/lib/treedx/state.d.ts +27 -0
- package/lib/treedx/state.js +65 -0
- package/lib/treedx/state.js.map +1 -0
- package/lib/types.d.ts +210 -0
- package/lib/types.js +31 -0
- package/lib/types.js.map +1 -0
- package/lib/version.d.ts +9 -0
- package/lib/version.js +10 -0
- package/lib/version.js.map +1 -0
- package/lib/vocabulary.d.ts +41 -0
- package/lib/vocabulary.js +118 -0
- package/lib/vocabulary.js.map +1 -0
- package/lib/warnings.d.ts +10 -0
- package/lib/warnings.js +18 -0
- package/lib/warnings.js.map +1 -0
- package/package.json +151 -4
package/lib/notice.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/** Our producer id. Changing this orphans every already-seeded continuation. */
|
|
2
|
+
export const NOTICE_PLUGIN = 'dsh-chapters';
|
|
3
|
+
/** The v4 producer-owned source kind (issue #43). `plugin:<producer>` is the
|
|
4
|
+
* form the 0.2.x kernel itself admits for third-party producers; the bare
|
|
5
|
+
* `plugin` wrapper it retired. */
|
|
6
|
+
export const NOTICE_SOURCE_KIND = `plugin:${NOTICE_PLUGIN}`;
|
|
7
|
+
/** The section name our TOC rides under inside the snapshot. */
|
|
8
|
+
export const NOTICE_SECTION = 'chapters:toc';
|
|
9
|
+
/**
|
|
10
|
+
* The kinds this plugin may emit, pinned to what the installed v4 kernel
|
|
11
|
+
* admits (seed/load boundary + persistence row admission). The retired v3
|
|
12
|
+
* `plugin` wrapper is deliberately NOT in this list — it is refused below
|
|
13
|
+
* with the kernel's own refusal text.
|
|
14
|
+
*/
|
|
15
|
+
export const ACCEPTED_SOURCE_KINDS = ['user', NOTICE_SOURCE_KIND];
|
|
16
|
+
/** `ContextForm` values, exactly as published (semantic, never visual). */
|
|
17
|
+
export const ACCEPTED_CONTEXT_FORMS = [
|
|
18
|
+
'instructions', 'catalog', 'snapshot', 'notice', 'relay', 'recall',
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Build the one seed event for a continuation. Throws rather than emit an
|
|
22
|
+
* event the kernel would reject at seed time — a refusal here is cheap, a
|
|
23
|
+
* bricked log is not.
|
|
24
|
+
*/
|
|
25
|
+
export function buildTocNotice(tocText, opts) {
|
|
26
|
+
if (tocText.trim().length === 0)
|
|
27
|
+
throw new Error('chapters: TOC notice text must not be empty');
|
|
28
|
+
const id = opts.newId();
|
|
29
|
+
if (id.length === 0)
|
|
30
|
+
throw new Error('chapters: notice message needs a non-empty id ("lacks an identified message")');
|
|
31
|
+
const event = {
|
|
32
|
+
type: 'user/message',
|
|
33
|
+
seq: 0, // seeds must be contiguous from 0 (FINDINGS: a seq-3 seed is rejected)
|
|
34
|
+
time: opts.time ?? Date.now(),
|
|
35
|
+
surfaceOp: 'append',
|
|
36
|
+
data: {
|
|
37
|
+
id,
|
|
38
|
+
role: 'user',
|
|
39
|
+
source: {
|
|
40
|
+
kind: NOTICE_SOURCE_KIND,
|
|
41
|
+
form: 'snapshot',
|
|
42
|
+
sections: [{ name: NOTICE_SECTION, text: tocText }],
|
|
43
|
+
},
|
|
44
|
+
// content mirrors sections[0].text byte-identically: the model reads
|
|
45
|
+
// `content`; the UI and attribution read `source`. One text, two faces.
|
|
46
|
+
content: [{ type: 'text', text: tocText }],
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
assertKernelAcceptedUserMessage(event);
|
|
50
|
+
return event;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Transcription of the kernel's seed-time checks (message-shape + v4 source
|
|
54
|
+
* admission + the recorded rejections). Kept as an exported predicate so tests
|
|
55
|
+
* pin our output against the same rules the host applies, and any future
|
|
56
|
+
* notice variant fails HERE, at the boundary of authorship. The v4 rows are
|
|
57
|
+
* drift-gated against the kernel's own admission function
|
|
58
|
+
* (`dsh-session-format-v3-to-v4` `assertV4RowAdmission`) in
|
|
59
|
+
* tests/unit/host-seed-contract.test.ts — this transcription is the fast lane,
|
|
60
|
+
* the kernel is the authority.
|
|
61
|
+
*/
|
|
62
|
+
export function assertKernelAcceptedUserMessage(event) {
|
|
63
|
+
if (event.type !== 'user/message')
|
|
64
|
+
throw new Error(`chapters: unexpected notice event type ${event.type}`);
|
|
65
|
+
const data = event.data;
|
|
66
|
+
if (data === undefined || typeof data !== 'object')
|
|
67
|
+
throw new Error('chapters: notice event needs data');
|
|
68
|
+
if (typeof data.id !== 'string' || data.id.length === 0) {
|
|
69
|
+
throw new Error('chapters: seed user/message lacks an identified message');
|
|
70
|
+
}
|
|
71
|
+
if (data.role !== 'user')
|
|
72
|
+
throw new Error('chapters: seed message must have role "user"');
|
|
73
|
+
const source = data.source;
|
|
74
|
+
if (source === undefined || typeof source !== 'object' || typeof source.kind !== 'string' || source.kind.length === 0) {
|
|
75
|
+
throw new Error('chapters: seed message has invalid source (object with non-empty string kind required)');
|
|
76
|
+
}
|
|
77
|
+
// The retired v3 wrapper, refused with the kernel's own v4 words — reproducing
|
|
78
|
+
// the production refusal at our authorship boundary (issue #43).
|
|
79
|
+
if (source.kind === 'plugin') {
|
|
80
|
+
throw new Error('chapters: format v4 message requires a producer-owned source kind (use plugin:dsh-chapters; the bare plugin wrapper was retired)');
|
|
81
|
+
}
|
|
82
|
+
if (!ACCEPTED_SOURCE_KINDS.includes(source.kind)) {
|
|
83
|
+
throw new Error(`chapters: source kind "${source.kind}" is outside the pinned vocabulary`);
|
|
84
|
+
}
|
|
85
|
+
if (source.form !== undefined && !ACCEPTED_CONTEXT_FORMS.includes(source.form)) {
|
|
86
|
+
throw new Error(`chapters: context form "${String(source.form)}" is outside the published ContextForm union`);
|
|
87
|
+
}
|
|
88
|
+
if (!Array.isArray(data.content) || data.content.length === 0) {
|
|
89
|
+
throw new Error('chapters: seed message has invalid content');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=notice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notice.js","sourceRoot":"","sources":["../src/notice.ts"],"names":[],"mappings":"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"}
|
package/lib/plans.d.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plan detector (docs/plans-carriage.md § 1): a session plan is ONE thing in the
|
|
3
|
+
* durable log — a `tool/call` for `exit_plan_mode` whose `arguments.plan` carries the
|
|
4
|
+
* complete markdown, answered by a `tool/result` that carries the human verdict.
|
|
5
|
+
* There is no plan document event and no plan store: reading those two events is the
|
|
6
|
+
* whole job, and it must be read identically by the renderer, the segmentation tool
|
|
7
|
+
* and the notice builder.
|
|
8
|
+
*
|
|
9
|
+
* Host facts this mirrors, cited so an upgrade can re-verify them:
|
|
10
|
+
* - parameters `{ plan: string, required }` — `@deepseek-ai/dsh-plan-mode`
|
|
11
|
+
* `lib/index.js:232-236`; the plan must start with a `#` heading (`:256`).
|
|
12
|
+
* - an approved review returns the canonical `{ approved: true }` plus the fixed
|
|
13
|
+
* render text (`:237-251`).
|
|
14
|
+
* - "Keep planning" throws carrying the feedback; a dismissed review throws naming
|
|
15
|
+
* the takeover (`:277-289`).
|
|
16
|
+
* - state is a log-only `plan/mode { active }` event appended at the NEXT accepted
|
|
17
|
+
* in-turn pre-step (`:374, 389`), so the RESULT — not the mode event — is the
|
|
18
|
+
* primary verdict. An approved exit narrates silently (`pendingIntents narrate:false`),
|
|
19
|
+
* so the mode event may not exist at all by archive time.
|
|
20
|
+
* - a freshly created agent begins with plan mode INACTIVE and cannot inherit the
|
|
21
|
+
* parent's `plan/mode` events (package README § Known Limitations), which is why the
|
|
22
|
+
* notice has to carry this text at all.
|
|
23
|
+
*
|
|
24
|
+
* Verdict classes, and why `failed` exists: the host also throws when the review never
|
|
25
|
+
* opened (no user-questions channel, the service reloaded mid-review, the call ran
|
|
26
|
+
* outside plan mode, the markdown had no heading). Those carry NO human verdict, so
|
|
27
|
+
* labelling them `rejected` would invent one. (`docs/plans-carriage.md` § 1 amendment,
|
|
28
|
+
* 2026-10-09: `failed` is the fifth status; the record's four were the ones a human
|
|
29
|
+
* answered.)
|
|
30
|
+
*
|
|
31
|
+
* Pure module: no cordis, no fs, no DSH imports, no hash/token helpers (the renderer
|
|
32
|
+
* owns those, so this file cannot form an import cycle with it).
|
|
33
|
+
*/
|
|
34
|
+
import type { NoticePlan, PlanFact, PlanStatus, SessionEventLike } from './types.ts';
|
|
35
|
+
export declare const PLAN_TOOL = "exit_plan_mode";
|
|
36
|
+
/**
|
|
37
|
+
* Why a child exists. `continue` extends the SAME stream of work (the tool
|
|
38
|
+
* `chapters_continue`), so the operative plan stays a live directive — and plan mode
|
|
39
|
+
* can be seeded so the gate survives the boundary, which is what keeps the agent
|
|
40
|
+
* anchored to the task across compactions (decision 2026-10-10). `branch` splits a
|
|
41
|
+
* NEW direction off the history (`chapters_fork`, `/chapters-fork`), so plans are
|
|
42
|
+
* history: cited, never re-asserted, never seeded.
|
|
43
|
+
*/
|
|
44
|
+
export type PlanIntent = 'continue' | 'branch';
|
|
45
|
+
export declare const PLAN_MODE_EVENT = "plan/mode";
|
|
46
|
+
export type { NoticePlan, PlanFact, PlanStatus };
|
|
47
|
+
/** A plan as the log states it. Never model-authored (invariant 4). */
|
|
48
|
+
export interface PlanDoc {
|
|
49
|
+
/** The `tool/call` event seq — the plan's identity in the log. */
|
|
50
|
+
seq: number;
|
|
51
|
+
/** The verdict result seq, or null when the review was never answered. */
|
|
52
|
+
resultSeq: number | null;
|
|
53
|
+
callId: string;
|
|
54
|
+
/** First heading of the plan (the host requires an H1; any level is accepted). */
|
|
55
|
+
title: string;
|
|
56
|
+
status: PlanStatus;
|
|
57
|
+
/** The plan markdown, injected spans screened out. Full bytes — never clipped here. */
|
|
58
|
+
text: string;
|
|
59
|
+
bytes: number;
|
|
60
|
+
/** H2/H3 outline, in document order, fenced code excluded. */
|
|
61
|
+
outline: string[];
|
|
62
|
+
/** The verdict text as logged (feedback, dismissal reason, service fault), or null. */
|
|
63
|
+
verdict: string | null;
|
|
64
|
+
/** False when `seq` is above the archive ceiling: an unfinished turn, parent log only. */
|
|
65
|
+
archived: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface ModeFlip {
|
|
68
|
+
seq: number;
|
|
69
|
+
active: boolean;
|
|
70
|
+
}
|
|
71
|
+
export interface PlanScan {
|
|
72
|
+
plans: PlanDoc[];
|
|
73
|
+
/** Every `plan/mode` event in the scanned range, oldest first. */
|
|
74
|
+
flips: ModeFlip[];
|
|
75
|
+
/** Last logged value wins (the host projection rule). Null when no event exists. */
|
|
76
|
+
modeActive: boolean | null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The first markdown heading at any level, or '' when the payload has none. The
|
|
80
|
+
* DISPLAY title is bounded: a plan whose H1 is a 4KB paragraph would otherwise be
|
|
81
|
+
* printed in full in every chapter that carries it and again in every child notice
|
|
82
|
+
* built from that path. Bounded here, not at the call sites — and the artifact keeps
|
|
83
|
+
* the untouched heading, because the artifact keeps every byte.
|
|
84
|
+
*/
|
|
85
|
+
export declare const PLAN_TITLE_MAX = 120;
|
|
86
|
+
export declare function planTitleOf(text: string): string;
|
|
87
|
+
/** Outline budget: entries × chars. An outline is an INDEX, not the document — the
|
|
88
|
+
* full heading map with line numbers is one `chapters_artifact toc` call away, so
|
|
89
|
+
* printing 24 unbounded headings per plan (a 4 KB H2 is a real thing people write)
|
|
90
|
+
* would repeat the 0.1.8 mistake at a smaller scale. */
|
|
91
|
+
export declare const PLAN_OUTLINE_MAX_ENTRIES = 12;
|
|
92
|
+
export declare const PLAN_OUTLINE_TITLE_MAX = 60;
|
|
93
|
+
/**
|
|
94
|
+
* The plan's own table of contents: H2/H3 headings in document order, with fenced
|
|
95
|
+
* blocks excluded so a `# comment` inside a code sample never poses as a heading
|
|
96
|
+
* (the same discipline `artifact-query.buildToc` applies to stored blobs). Each
|
|
97
|
+
* entry is bounded; when entries are dropped a trailing `+N more` says so — a
|
|
98
|
+
* silently shortened index is the lie this codebase exists to avoid.
|
|
99
|
+
*/
|
|
100
|
+
export declare function planOutlineOf(text: string, maxEntries?: number): {
|
|
101
|
+
outline: string[];
|
|
102
|
+
levels: number[];
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* One verdict, from the result the host logged. Order matters: a dismissed or
|
|
106
|
+
* keep-planning failure text can contain the word "approved" only as a quote, so
|
|
107
|
+
* the non-approval shapes are tested before the approval shape, and `isError`
|
|
108
|
+
* decides when the prose is ambiguous.
|
|
109
|
+
*/
|
|
110
|
+
export declare function classifyVerdict(resultText: string, isError: boolean): PlanStatus;
|
|
111
|
+
/** Plan submissions paired with their verdicts, in log order, over ANY event list. */
|
|
112
|
+
export declare function detectPlans(events: readonly SessionEventLike[], opts?: {
|
|
113
|
+
ceiling?: number;
|
|
114
|
+
}): PlanScan;
|
|
115
|
+
/** True when the range carries at least one plan submission (composer split test). */
|
|
116
|
+
export declare function planCallSeqs(events: readonly SessionEventLike[]): number[];
|
|
117
|
+
/**
|
|
118
|
+
* The `## Plans` block of the continuation notice (docs/plans-carriage.md § 4).
|
|
119
|
+
* EMPTY when the path holds no plans, so a session that never planned contributes
|
|
120
|
+
* zero injected bytes — the property that keeps the model tapes matching.
|
|
121
|
+
*
|
|
122
|
+
* Flat, in the CAUSAL order the caller supplies (never re-sorted by `seq` — different
|
|
123
|
+
* sessions own different seq spaces): the model never traverses.
|
|
124
|
+
* `estTokens` arrives only from the caller's own measurement — this file owns no
|
|
125
|
+
* token maths, so the notice can never disagree with the budget gate.
|
|
126
|
+
*/
|
|
127
|
+
export declare function buildPlansSection(plans: readonly NoticePlan[], opts?: {
|
|
128
|
+
modeActive?: boolean | null;
|
|
129
|
+
intent?: PlanIntent;
|
|
130
|
+
seeded?: boolean;
|
|
131
|
+
}): string;
|
|
132
|
+
/**
|
|
133
|
+
* The in-place checkpoint's plan carriage (the PLOT mechanism, applied to plans —
|
|
134
|
+
* docs/plans-carriage.md § 9). Shadowing a region can hide the chapter that carries a
|
|
135
|
+
* plan, and a directive that only survives in a file the child may never open is a
|
|
136
|
+
* directive the agent drifts from. So the OPERATIVE plan travels in the checkpoint
|
|
137
|
+
* text itself, bounded, with its citation and the sha that still resolves the whole.
|
|
138
|
+
*
|
|
139
|
+
* "Operative" is session-level, not region-level — the newest submission on the log,
|
|
140
|
+
* whatever region it happened to fall in — because that is what "the current task"
|
|
141
|
+
* means to the agent reading the checkpoint.
|
|
142
|
+
*/
|
|
143
|
+
export declare function carryActivePlan(plans: readonly PlanDoc[], opts: {
|
|
144
|
+
maxChars: number;
|
|
145
|
+
}): string | null;
|
|
146
|
+
/**
|
|
147
|
+
* Topics for a plan DOCUMENT: the file paths the plan names, plus its most
|
|
148
|
+
* characteristic terms. Same vocabulary as the transcript's index floor
|
|
149
|
+
* (`signature.chapterTopics`), deliberately re-derived here rather than imported —
|
|
150
|
+
* a plan is prose the agent wrote on purpose, so its own path mentions are the
|
|
151
|
+
* strongest signal about what it changes, and they must land in the same topic
|
|
152
|
+
* namespace the chapter index already uses.
|
|
153
|
+
*/
|
|
154
|
+
export declare function planTopicsOf(planText: string, maxTerms?: number): string[];
|
package/lib/plans.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { callArg, callArgsText, lastResultFor, toolResultIsError, toolResultText } from "./log-shape.js";
|
|
2
|
+
import { stripReminderSpans } from "./injections.js";
|
|
3
|
+
export const PLAN_TOOL = 'exit_plan_mode';
|
|
4
|
+
export const PLAN_MODE_EVENT = 'plan/mode';
|
|
5
|
+
const RE_APPROVED = /(?:\{\s*"?approved"?\s*:\s*true)|(?:plan approved\b)/i;
|
|
6
|
+
const RE_DISMISSED = /dismissed the plan review|to speak instead/i;
|
|
7
|
+
const RE_KEEP_PLANNING = /keep planning/i;
|
|
8
|
+
/**
|
|
9
|
+
* The first markdown heading at any level, or '' when the payload has none. The
|
|
10
|
+
* DISPLAY title is bounded: a plan whose H1 is a 4KB paragraph would otherwise be
|
|
11
|
+
* printed in full in every chapter that carries it and again in every child notice
|
|
12
|
+
* built from that path. Bounded here, not at the call sites — and the artifact keeps
|
|
13
|
+
* the untouched heading, because the artifact keeps every byte.
|
|
14
|
+
*/
|
|
15
|
+
export const PLAN_TITLE_MAX = 120;
|
|
16
|
+
export function planTitleOf(text) {
|
|
17
|
+
for (const line of text.split('\n')) {
|
|
18
|
+
const m = /^#{1,6}\s+(.+?)\s*$/.exec(line);
|
|
19
|
+
if (m === null)
|
|
20
|
+
continue;
|
|
21
|
+
const title = m[1].replace(/\s+#+\s*$/, ''); // closed ATX heading: "# Title #"
|
|
22
|
+
return title.length > PLAN_TITLE_MAX ? `${title.slice(0, PLAN_TITLE_MAX - 1).trimEnd()}…` : title;
|
|
23
|
+
}
|
|
24
|
+
return '';
|
|
25
|
+
}
|
|
26
|
+
/** Outline budget: entries × chars. An outline is an INDEX, not the document — the
|
|
27
|
+
* full heading map with line numbers is one `chapters_artifact toc` call away, so
|
|
28
|
+
* printing 24 unbounded headings per plan (a 4 KB H2 is a real thing people write)
|
|
29
|
+
* would repeat the 0.1.8 mistake at a smaller scale. */
|
|
30
|
+
export const PLAN_OUTLINE_MAX_ENTRIES = 12;
|
|
31
|
+
export const PLAN_OUTLINE_TITLE_MAX = 60;
|
|
32
|
+
/**
|
|
33
|
+
* The plan's own table of contents: H2/H3 headings in document order, with fenced
|
|
34
|
+
* blocks excluded so a `# comment` inside a code sample never poses as a heading
|
|
35
|
+
* (the same discipline `artifact-query.buildToc` applies to stored blobs). Each
|
|
36
|
+
* entry is bounded; when entries are dropped a trailing `+N more` says so — a
|
|
37
|
+
* silently shortened index is the lie this codebase exists to avoid.
|
|
38
|
+
*/
|
|
39
|
+
export function planOutlineOf(text, maxEntries = PLAN_OUTLINE_MAX_ENTRIES) {
|
|
40
|
+
const outline = [];
|
|
41
|
+
const levels = [];
|
|
42
|
+
let truncated = false;
|
|
43
|
+
let inFence = false;
|
|
44
|
+
let fenceChar = '';
|
|
45
|
+
for (const line of text.split('\n')) {
|
|
46
|
+
const fence = /^\s{0,3}(`{3,}|~{3,})/.test(line);
|
|
47
|
+
if (fence) {
|
|
48
|
+
const marker = line.trim().slice(0, 3);
|
|
49
|
+
if (!inFence) {
|
|
50
|
+
inFence = true;
|
|
51
|
+
fenceChar = marker[0];
|
|
52
|
+
}
|
|
53
|
+
else if (marker[0] === fenceChar)
|
|
54
|
+
inFence = false;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (inFence)
|
|
58
|
+
continue;
|
|
59
|
+
const m = /^(#{2,3})\s+(.+?)\s*$/.exec(line);
|
|
60
|
+
if (m === null)
|
|
61
|
+
continue;
|
|
62
|
+
if (outline.length >= maxEntries) {
|
|
63
|
+
truncated = true;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
const heading = m[2].replace(/\s+#+\s*$/, '');
|
|
67
|
+
outline.push(heading.length > PLAN_OUTLINE_TITLE_MAX ? `${heading.slice(0, PLAN_OUTLINE_TITLE_MAX - 1).trimEnd()}…` : heading);
|
|
68
|
+
levels.push(m[1].length);
|
|
69
|
+
}
|
|
70
|
+
if (truncated)
|
|
71
|
+
outline.push(`+more (chapters_artifact 'toc' lists every heading)`);
|
|
72
|
+
return { outline, levels };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* One verdict, from the result the host logged. Order matters: a dismissed or
|
|
76
|
+
* keep-planning failure text can contain the word "approved" only as a quote, so
|
|
77
|
+
* the non-approval shapes are tested before the approval shape, and `isError`
|
|
78
|
+
* decides when the prose is ambiguous.
|
|
79
|
+
*/
|
|
80
|
+
export function classifyVerdict(resultText, isError) {
|
|
81
|
+
if (RE_DISMISSED.test(resultText))
|
|
82
|
+
return 'dismissed';
|
|
83
|
+
if (RE_KEEP_PLANNING.test(resultText))
|
|
84
|
+
return 'rejected';
|
|
85
|
+
if (!isError && RE_APPROVED.test(resultText))
|
|
86
|
+
return 'approved';
|
|
87
|
+
if (isError)
|
|
88
|
+
return 'failed';
|
|
89
|
+
// A success that says nothing recognizable is NOT an approval: refuse to invent one.
|
|
90
|
+
return 'failed';
|
|
91
|
+
}
|
|
92
|
+
/** Plan submissions paired with their verdicts, in log order, over ANY event list. */
|
|
93
|
+
export function detectPlans(events, opts = {}) {
|
|
94
|
+
const ceiling = opts.ceiling ?? Number.POSITIVE_INFINITY;
|
|
95
|
+
const sorted = [...events].sort((a, b) => a.seq - b.seq);
|
|
96
|
+
const results = sorted.filter((e) => e.type === 'tool/result');
|
|
97
|
+
const plans = [];
|
|
98
|
+
for (const call of sorted) {
|
|
99
|
+
if (call.type !== 'tool/call')
|
|
100
|
+
continue;
|
|
101
|
+
const data = (call.data ?? {});
|
|
102
|
+
if (String(data.name ?? '') !== PLAN_TOOL)
|
|
103
|
+
continue;
|
|
104
|
+
const callId = typeof data.callId === 'string' ? data.callId : '';
|
|
105
|
+
const raw = callArg(data, 'plan') ?? callArgsText(data);
|
|
106
|
+
// Screened at the source (a plan is model-authored bytes, but an injected span
|
|
107
|
+
// riding inside it is host state — same reasoning as injections.ts:62-70).
|
|
108
|
+
const text = stripReminderSpans(raw).text.trim();
|
|
109
|
+
const answer = callId === '' ? undefined : lastResultFor(results, callId);
|
|
110
|
+
let status = 'pending';
|
|
111
|
+
let verdict = null;
|
|
112
|
+
let resultSeq = null;
|
|
113
|
+
if (answer !== undefined) {
|
|
114
|
+
resultSeq = answer.seq;
|
|
115
|
+
const ad = (answer.data ?? {});
|
|
116
|
+
verdict = stripReminderSpans(toolResultText(ad)).text.trim() || null;
|
|
117
|
+
status = classifyVerdict(verdict ?? '', toolResultIsError(ad));
|
|
118
|
+
}
|
|
119
|
+
const { outline } = planOutlineOf(text);
|
|
120
|
+
plans.push({
|
|
121
|
+
seq: call.seq,
|
|
122
|
+
resultSeq,
|
|
123
|
+
callId,
|
|
124
|
+
title: planTitleOf(text),
|
|
125
|
+
status,
|
|
126
|
+
text,
|
|
127
|
+
bytes: Buffer.byteLength(text, 'utf8'),
|
|
128
|
+
outline,
|
|
129
|
+
verdict,
|
|
130
|
+
archived: call.seq <= ceiling,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// Same-title re-submission: the newest is operative; everything earlier in the
|
|
134
|
+
// group is superseded, whatever its own verdict was. Deterministic, no judgement.
|
|
135
|
+
const byTitle = new Map();
|
|
136
|
+
for (const p of plans) {
|
|
137
|
+
const key = p.title.trim().toLowerCase();
|
|
138
|
+
if (key === '')
|
|
139
|
+
continue;
|
|
140
|
+
const group = byTitle.get(key) ?? [];
|
|
141
|
+
group.push(p);
|
|
142
|
+
byTitle.set(key, group);
|
|
143
|
+
}
|
|
144
|
+
for (const group of byTitle.values()) {
|
|
145
|
+
if (group.length < 2)
|
|
146
|
+
continue;
|
|
147
|
+
for (const earlier of group.slice(0, -1))
|
|
148
|
+
earlier.status = 'superseded';
|
|
149
|
+
}
|
|
150
|
+
const flips = [];
|
|
151
|
+
for (const ev of sorted) {
|
|
152
|
+
if (ev.type !== PLAN_MODE_EVENT)
|
|
153
|
+
continue;
|
|
154
|
+
const active = ev.data?.active;
|
|
155
|
+
if (typeof active === 'boolean')
|
|
156
|
+
flips.push({ seq: ev.seq, active });
|
|
157
|
+
}
|
|
158
|
+
return { plans, flips, modeActive: flips.length > 0 ? flips[flips.length - 1].active : null };
|
|
159
|
+
}
|
|
160
|
+
/** True when the range carries at least one plan submission (composer split test). */
|
|
161
|
+
export function planCallSeqs(events) {
|
|
162
|
+
return detectPlans(events).plans.map((p) => p.seq);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* `PlanFact` (the chapter/registry machine facts) and `NoticePlan` (the flat notice
|
|
166
|
+
* row) are declared in types.ts and re-exported above, so the renderer, the zod
|
|
167
|
+
* schema and the notice builder cannot drift into three shapes.
|
|
168
|
+
*/
|
|
169
|
+
const STATUS_WORD = {
|
|
170
|
+
approved: 'APPROVED',
|
|
171
|
+
rejected: 'REJECTED — the user sent it back with feedback',
|
|
172
|
+
dismissed: 'DISMISSED — the user took over the conversation',
|
|
173
|
+
pending: 'PENDING — the review was never answered',
|
|
174
|
+
superseded: 'SUPERSEDED by a later submission',
|
|
175
|
+
failed: 'NOT ACCEPTED — the review could not be opened',
|
|
176
|
+
};
|
|
177
|
+
const shorterSha = (sha) => sha.slice(0, 7);
|
|
178
|
+
/**
|
|
179
|
+
* The `## Plans` block of the continuation notice (docs/plans-carriage.md § 4).
|
|
180
|
+
* EMPTY when the path holds no plans, so a session that never planned contributes
|
|
181
|
+
* zero injected bytes — the property that keeps the model tapes matching.
|
|
182
|
+
*
|
|
183
|
+
* Flat, in the CAUSAL order the caller supplies (never re-sorted by `seq` — different
|
|
184
|
+
* sessions own different seq spaces): the model never traverses.
|
|
185
|
+
* `estTokens` arrives only from the caller's own measurement — this file owns no
|
|
186
|
+
* token maths, so the notice can never disagree with the budget gate.
|
|
187
|
+
*/
|
|
188
|
+
export function buildPlansSection(plans, opts = {}) {
|
|
189
|
+
if (plans.length === 0)
|
|
190
|
+
return '';
|
|
191
|
+
// A BRANCH splits off a new direction, so its plans are history: they already sit
|
|
192
|
+
// in the chapters the TOC cites, and a call-out would tell the child to keep
|
|
193
|
+
// working a directive it just chose to leave behind (decision, 2026-10-10).
|
|
194
|
+
if (opts.intent === 'branch')
|
|
195
|
+
return '';
|
|
196
|
+
// CAUSAL order is the caller's, not something this function can reconstruct: an
|
|
197
|
+
// ancestor path's rows come from DIFFERENT sessions, each with its own seq space
|
|
198
|
+
// (a child's seq 3 is not "before" a root's seq 40). The notice builder therefore
|
|
199
|
+
// hands rows in reading order — chapters root-first, plans within a chapter by
|
|
200
|
+
// seq, then the caller's unarchived tail — which is exactly the flattening rule
|
|
201
|
+
// the chapter list follows. Sorting by seq here would order two sessions' plans
|
|
202
|
+
// by unrelated counters and crown the wrong plan operative.
|
|
203
|
+
const sorted = [...plans];
|
|
204
|
+
const operative = sorted[sorted.length - 1];
|
|
205
|
+
const counts = new Map();
|
|
206
|
+
for (const p of sorted)
|
|
207
|
+
counts.set(p.status, (counts.get(p.status) ?? 0) + 1);
|
|
208
|
+
const tally = [...counts.entries()].map(([s, n]) => `${n} ${s}`).join(', ');
|
|
209
|
+
const previous = sorted.slice(0, -1);
|
|
210
|
+
const lines = [
|
|
211
|
+
`## Active plan`,
|
|
212
|
+
`(this continuation keeps the same stream of work: ${sorted.length} plan(s) submitted on the path — ${tally})`,
|
|
213
|
+
'',
|
|
214
|
+
];
|
|
215
|
+
const ref = (p) => {
|
|
216
|
+
const bits = [];
|
|
217
|
+
if (p.chapterPath !== undefined) {
|
|
218
|
+
bits.push(`ch. ${p.chapterNumber ?? '?'} ${p.chapterPath}`);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
bits.push(`NOT ARCHIVED — parent log seq ${p.seq} only`);
|
|
222
|
+
}
|
|
223
|
+
if (p.artifactPath !== undefined)
|
|
224
|
+
bits.push(`full text: ${p.artifactPath}`);
|
|
225
|
+
if (p.docPath !== undefined)
|
|
226
|
+
bits.push(`plan document: ${p.docPath}`);
|
|
227
|
+
if (p.sha256 !== undefined)
|
|
228
|
+
bits.push(`sha ${shorterSha(p.sha256)}…`);
|
|
229
|
+
if (p.estTokens !== undefined)
|
|
230
|
+
bits.push(`~${p.estTokens} tok`);
|
|
231
|
+
return bits.join(' · ');
|
|
232
|
+
};
|
|
233
|
+
lines.push(`- ACTIVE PLAN: "${operative.title}" — ${STATUS_WORD[operative.status]} (${ref(operative)})`);
|
|
234
|
+
if (operative.status !== 'approved') {
|
|
235
|
+
lines.push(' This plan was never approved: do NOT implement it. Ask the user, or keep planning.');
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
lines.push(' Read the full text with chapters_artifact (toc | search | read) before implementing.');
|
|
239
|
+
lines.push(' Do NOT re-plan from recall: the bytes are in the store.');
|
|
240
|
+
}
|
|
241
|
+
if (previous.length > 0) {
|
|
242
|
+
lines.push('', '## Previous plans on this path', '(history — cited for evolution and status, not directives)');
|
|
243
|
+
for (const p of previous) {
|
|
244
|
+
if (p.status === 'superseded' && p.title === operative.title)
|
|
245
|
+
continue;
|
|
246
|
+
lines.push(`- "${p.title}" — ${STATUS_WORD[p.status]} (${ref(p)})`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (opts.seeded === true) {
|
|
250
|
+
lines.push('', 'Plan mode is ACTIVE in this session — the directive above is live, not history. Keep');
|
|
251
|
+
lines.push('planning until a plan is approved; implementation begins only after that approval.');
|
|
252
|
+
}
|
|
253
|
+
else if (opts.modeActive === true) {
|
|
254
|
+
lines.push('', 'Plan mode was ACTIVE at the end of the archived span, and a created session does not');
|
|
255
|
+
lines.push('inherit it: this child starts OUTSIDE plan mode. Ask the user whether to keep planning or act.');
|
|
256
|
+
}
|
|
257
|
+
return lines.join('\n');
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* The in-place checkpoint's plan carriage (the PLOT mechanism, applied to plans —
|
|
261
|
+
* docs/plans-carriage.md § 9). Shadowing a region can hide the chapter that carries a
|
|
262
|
+
* plan, and a directive that only survives in a file the child may never open is a
|
|
263
|
+
* directive the agent drifts from. So the OPERATIVE plan travels in the checkpoint
|
|
264
|
+
* text itself, bounded, with its citation and the sha that still resolves the whole.
|
|
265
|
+
*
|
|
266
|
+
* "Operative" is session-level, not region-level — the newest submission on the log,
|
|
267
|
+
* whatever region it happened to fall in — because that is what "the current task"
|
|
268
|
+
* means to the agent reading the checkpoint.
|
|
269
|
+
*/
|
|
270
|
+
export function carryActivePlan(plans, opts) {
|
|
271
|
+
const operative = plans[plans.length - 1];
|
|
272
|
+
if (operative === undefined)
|
|
273
|
+
return null;
|
|
274
|
+
const title = operative.title === '' ? '(untitled plan)' : operative.title;
|
|
275
|
+
const body = operative.text.replace(/^#{1,6}\s+.+\n/, '').trim();
|
|
276
|
+
const clipped = body.length > opts.maxChars ? `${body.slice(0, opts.maxChars).trimEnd()}…` : body;
|
|
277
|
+
return [
|
|
278
|
+
`ACTIVE PLAN: "${title}" — ${STATUS_WORD[operative.status]} (submitted seq ${operative.seq}`
|
|
279
|
+
+ (operative.resultSeq !== null ? `, answered seq ${operative.resultSeq}` : ', no verdict yet') + ')',
|
|
280
|
+
'',
|
|
281
|
+
clipped,
|
|
282
|
+
...(body.length > opts.maxChars
|
|
283
|
+
// No hash claimed: at summarize time the chapter does not exist yet, and a
|
|
284
|
+
// sha we cannot verify would be a citation to nothing.
|
|
285
|
+
? ['', '(carried truncated — the archive chapter holding this plan cites its complete text)']
|
|
286
|
+
: []),
|
|
287
|
+
].join('\n');
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Topics for a plan DOCUMENT: the file paths the plan names, plus its most
|
|
291
|
+
* characteristic terms. Same vocabulary as the transcript's index floor
|
|
292
|
+
* (`signature.chapterTopics`), deliberately re-derived here rather than imported —
|
|
293
|
+
* a plan is prose the agent wrote on purpose, so its own path mentions are the
|
|
294
|
+
* strongest signal about what it changes, and they must land in the same topic
|
|
295
|
+
* namespace the chapter index already uses.
|
|
296
|
+
*/
|
|
297
|
+
export function planTopicsOf(planText, maxTerms = 8) {
|
|
298
|
+
const paths = new Set();
|
|
299
|
+
for (const m of planText.matchAll(/([\w@.\-/]+\.[A-Za-z]{1,6})\b/g)) {
|
|
300
|
+
const p = m[1];
|
|
301
|
+
if (p.length > 3 && !p.startsWith('http'))
|
|
302
|
+
paths.add(p);
|
|
303
|
+
}
|
|
304
|
+
const stop = new Set(['plan', 'goal', 'tests', 'criteria', 'changes', 'subsystem', 'steps', 'summary', 'overview', 'context', 'assumptions', 'risks', 'rollback', 'acceptance', 'success', 'approach', 'implementation']);
|
|
305
|
+
const terms = new Map();
|
|
306
|
+
for (const raw of planText.toLowerCase().split(/[^a-z0-9_+.\-/]+/)) {
|
|
307
|
+
const t = raw.replace(/^[.+\-/]+|[.+\-/]+$/g, '');
|
|
308
|
+
if (t.length < 4 || t.length > 28 || stop.has(t) || /^\d+$/.test(t))
|
|
309
|
+
continue;
|
|
310
|
+
terms.set(t, (terms.get(t) ?? 0) + 1);
|
|
311
|
+
}
|
|
312
|
+
const top = [...terms.entries()].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1)).slice(0, maxTerms).map(([t]) => t);
|
|
313
|
+
return [...paths, ...top];
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=plans.js.map
|
package/lib/plans.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plans.js","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"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"}
|