@possumtech/rummy 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/.env.example +40 -15
  2. package/.xai.key +1 -0
  3. package/PLUGINS.md +169 -53
  4. package/README.md +38 -32
  5. package/SPEC.md +366 -179
  6. package/bin/digest.js +1097 -0
  7. package/biome/no-fallbacks.grit +2 -2
  8. package/gemini.key +1 -0
  9. package/lang/en.json +10 -1
  10. package/migrations/001_initial_schema.sql +9 -2
  11. package/package.json +19 -8
  12. package/service.js +1 -0
  13. package/src/agent/AgentLoop.js +76 -26
  14. package/src/agent/ContextAssembler.js +2 -0
  15. package/src/agent/Entries.js +238 -60
  16. package/src/agent/ProjectAgent.js +44 -0
  17. package/src/agent/TurnExecutor.js +99 -30
  18. package/src/agent/XmlParser.js +206 -111
  19. package/src/agent/errors.js +35 -0
  20. package/src/agent/known_queries.sql +1 -1
  21. package/src/agent/known_store.sql +3 -42
  22. package/src/agent/materializeContext.js +30 -1
  23. package/src/agent/runs.sql +8 -18
  24. package/src/agent/tokens.js +0 -1
  25. package/src/agent/turns.sql +1 -0
  26. package/src/hooks/Hooks.js +26 -0
  27. package/src/hooks/RummyContext.js +12 -1
  28. package/src/lib/hedberg/README.md +60 -0
  29. package/src/lib/hedberg/hedberg.js +60 -0
  30. package/src/lib/hedberg/marker.js +158 -0
  31. package/src/{plugins → lib}/hedberg/matcher.js +1 -2
  32. package/src/llm/LlmProvider.js +41 -3
  33. package/src/llm/openaiStream.js +17 -0
  34. package/src/plugins/ask_user/ask_user.js +12 -2
  35. package/src/plugins/ask_user/ask_userDoc.md +1 -5
  36. package/src/plugins/budget/README.md +29 -24
  37. package/src/plugins/budget/budget.js +166 -110
  38. package/src/plugins/cli/README.md +3 -4
  39. package/src/plugins/cli/cli.js +31 -5
  40. package/src/plugins/cloudflare/cloudflare.js +136 -0
  41. package/src/plugins/cp/cp.js +41 -4
  42. package/src/plugins/cp/cpDoc.md +5 -6
  43. package/src/plugins/engine/engine.sql +1 -1
  44. package/src/plugins/env/README.md +5 -4
  45. package/src/plugins/env/env.js +7 -4
  46. package/src/plugins/env/envDoc.md +7 -8
  47. package/src/plugins/error/error.js +56 -15
  48. package/src/plugins/file/README.md +12 -3
  49. package/src/plugins/file/file.js +2 -2
  50. package/src/plugins/get/get.js +59 -36
  51. package/src/plugins/get/getDoc.md +10 -34
  52. package/src/plugins/google/google.js +115 -0
  53. package/src/plugins/hedberg/hedberg.js +13 -56
  54. package/src/plugins/helpers.js +66 -12
  55. package/src/plugins/index.js +1 -2
  56. package/src/plugins/instructions/README.md +44 -47
  57. package/src/plugins/instructions/instructions-system.md +44 -0
  58. package/src/plugins/instructions/instructions-user.md +53 -0
  59. package/src/plugins/instructions/instructions.js +58 -189
  60. package/src/plugins/known/README.md +6 -7
  61. package/src/plugins/known/known.js +24 -30
  62. package/src/plugins/log/log.js +41 -32
  63. package/src/plugins/mv/mv.js +40 -1
  64. package/src/plugins/mv/mvDoc.md +1 -8
  65. package/src/plugins/ollama/ollama.js +4 -3
  66. package/src/plugins/openai/openai.js +4 -3
  67. package/src/plugins/openrouter/openrouter.js +14 -4
  68. package/src/plugins/persona/README.md +11 -13
  69. package/src/plugins/persona/default.md +29 -0
  70. package/src/plugins/persona/persona.js +10 -66
  71. package/src/plugins/policy/policy.js +23 -22
  72. package/src/plugins/prompt/README.md +37 -27
  73. package/src/plugins/prompt/prompt.js +13 -19
  74. package/src/plugins/rm/rm.js +18 -0
  75. package/src/plugins/rm/rmDoc.md +5 -6
  76. package/src/plugins/rpc/rpc.js +3 -3
  77. package/src/plugins/set/set.js +205 -323
  78. package/src/plugins/set/setDoc.md +47 -17
  79. package/src/plugins/sh/README.md +6 -5
  80. package/src/plugins/sh/sh.js +8 -5
  81. package/src/plugins/sh/shDoc.md +7 -8
  82. package/src/plugins/skill/README.md +37 -14
  83. package/src/plugins/skill/skill.js +200 -101
  84. package/src/plugins/skill/skillDoc.js +3 -0
  85. package/src/plugins/skill/skillDoc.md +9 -0
  86. package/src/plugins/stream/README.md +7 -6
  87. package/src/plugins/stream/finalize.js +100 -0
  88. package/src/plugins/stream/stream.js +13 -45
  89. package/src/plugins/telemetry/telemetry.js +27 -4
  90. package/src/plugins/think/think.js +2 -3
  91. package/src/plugins/think/thinkDoc.md +2 -4
  92. package/src/plugins/unknown/README.md +1 -1
  93. package/src/plugins/unknown/unknown.js +17 -19
  94. package/src/plugins/update/update.js +4 -51
  95. package/src/plugins/update/updateDoc.md +21 -6
  96. package/src/plugins/xai/xai.js +68 -102
  97. package/src/plugins/yolo/yolo.js +102 -75
  98. package/src/sql/functions/hedmatch.js +1 -1
  99. package/src/sql/functions/hedreplace.js +1 -1
  100. package/src/sql/functions/hedsearch.js +1 -1
  101. package/src/sql/functions/slugify.js +16 -2
  102. package/BENCH_ENVIRONMENT.md +0 -230
  103. package/CLIENT_INTERFACE.md +0 -396
  104. package/last_run.txt +0 -5617
  105. package/scriptify/ask_run.js +0 -77
  106. package/scriptify/cache_probe.js +0 -66
  107. package/scriptify/cache_probe_grok.js +0 -74
  108. package/src/agent/budget.js +0 -33
  109. package/src/agent/config.js +0 -38
  110. package/src/plugins/hedberg/README.md +0 -71
  111. package/src/plugins/hedberg/docs.md +0 -0
  112. package/src/plugins/hedberg/edits.js +0 -55
  113. package/src/plugins/hedberg/normalize.js +0 -17
  114. package/src/plugins/hedberg/sed.js +0 -49
  115. package/src/plugins/instructions/instructions.md +0 -34
  116. package/src/plugins/instructions/instructions_104.md +0 -8
  117. package/src/plugins/instructions/instructions_105.md +0 -39
  118. package/src/plugins/instructions/instructions_106.md +0 -22
  119. package/src/plugins/instructions/instructions_107.md +0 -17
  120. package/src/plugins/instructions/instructions_108.md +0 -0
  121. package/src/plugins/known/knownDoc.js +0 -3
  122. package/src/plugins/known/knownDoc.md +0 -8
  123. package/src/plugins/unknown/unknownDoc.js +0 -3
  124. package/src/plugins/unknown/unknownDoc.md +0 -11
  125. package/turns/cli_1777462658211/turn_001.txt +0 -772
  126. package/turns/cli_1777462658211/turn_002.txt +0 -606
  127. package/turns/cli_1777462658211/turn_003.txt +0 -667
  128. package/turns/cli_1777462658211/turn_004.txt +0 -297
  129. package/turns/cli_1777462658211/turn_005.txt +0 -301
  130. package/turns/cli_1777462658211/turn_006.txt +0 -262
  131. package/turns/cli_1777465095132/turn_001.txt +0 -715
  132. package/turns/cli_1777465095132/turn_002.txt +0 -236
  133. package/turns/cli_1777465095132/turn_003.txt +0 -287
  134. package/turns/cli_1777465095132/turn_004.txt +0 -694
  135. package/turns/cli_1777465095132/turn_005.txt +0 -422
  136. package/turns/cli_1777465095132/turn_006.txt +0 -365
  137. package/turns/cli_1777465095132/turn_007.txt +0 -885
  138. package/turns/cli_1777465095132/turn_008.txt +0 -1277
  139. package/turns/cli_1777465095132/turn_009.txt +0 -736
  140. /package/src/{plugins → lib}/hedberg/patterns.js +0 -0
@@ -1,68 +1,25 @@
1
- import { parseEditContent } from "./edits.js";
2
- import HeuristicMatcher, { generatePatch } from "./matcher.js";
3
- import { parseJsonEdit } from "./normalize.js";
4
- import { hedmatch, hedsearch } from "./patterns.js";
5
- import { parseSed } from "./sed.js";
6
-
7
- // Stochastic→deterministic boundary; exposes pattern/edit utilities on core.hedberg. SPEC #hedberg.
8
- export default class Hedberg {
1
+ // Hedberg plugin shim. The library lives at `src/lib/hedberg/`; this
2
+ // shim's only job is to expose the same surface as `core.hooks.hedberg`
3
+ // for external plugins (e.g. rummy.repo's FileScanner) that can't
4
+ // reach into rummy/main's internals via direct import.
5
+ //
6
+ // Internal plugins should import from `src/lib/hedberg/` directly —
7
+ // the hook namespace is for plugins shipped in separate packages.
8
+
9
+ import Hedberg from "../../lib/hedberg/hedberg.js";
10
+ import { generatePatch } from "../../lib/hedberg/matcher.js";
11
+ import { hedmatch, hedsearch } from "../../lib/hedberg/patterns.js";
12
+
13
+ export default class HedbergPlugin {
9
14
  #core;
10
15
 
11
16
  constructor(core) {
12
17
  this.#core = core;
13
-
14
18
  core.hooks.hedberg = {
15
19
  match: hedmatch,
16
20
  search: hedsearch,
17
21
  replace: Hedberg.replace,
18
- parseSed,
19
- parseEdits: parseEditContent,
20
- parseJsonEdit,
21
22
  generatePatch,
22
23
  };
23
24
  }
24
-
25
- // Order: sed regex → literal → heuristic fuzzy.
26
- static replace(body, search, replacement, { sed = false, flags = "" } = {}) {
27
- let patch = null;
28
- let warning = null;
29
- let error = null;
30
- const searchText = search;
31
- const replaceText = replacement;
32
-
33
- if (sed) {
34
- try {
35
- const re = new RegExp(
36
- searchText,
37
- flags.includes("g") ? flags : `${flags}g`,
38
- );
39
- // Strip regex-meta escapes in replacement; String.replace only interprets `$`, not `\`.
40
- const unescaped = replaceText.replace(/\\([[\](){}.*+?^$|\\])/g, "$1");
41
- patch = body.replace(re, unescaped);
42
- if (patch === body) patch = null;
43
- } catch {
44
- // Invalid regex — fall through to literal/heuristic interpretation
45
- }
46
- }
47
-
48
- if (!patch && body.includes(searchText)) {
49
- patch = body.replaceAll(searchText, replaceText);
50
- }
51
-
52
- if (!patch) {
53
- const matched = HeuristicMatcher.matchAndPatch(
54
- "",
55
- body,
56
- searchText,
57
- replaceText,
58
- );
59
- patch = matched.newContent;
60
- warning = matched.warning;
61
- error = matched.error;
62
- }
63
-
64
- return { patch, searchText, replaceText, warning, error };
65
- }
66
25
  }
67
-
68
- export { generatePatch };
@@ -2,6 +2,47 @@ import { readFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
 
5
+ // Hard system ceiling on the size of any summarized projection. Single
6
+ // source of truth — every plugin's `summarized` view must produce output
7
+ // ≤ this many characters; materializeContext's defensive cap fires when
8
+ // a plugin breaks the contract. Change this number, everything downstream
9
+ // stays consistent (no "450 here, 480 there, 500 over yonder" drift).
10
+ export const SUMMARY_MAX_CHARS = 500;
11
+
12
+ // Render a single entry as a heredoc-fenced block. Replaces the prior
13
+ // per-plugin XML tag rendering (`<known path="..." ...>body</known>`).
14
+ //
15
+ // Why heredoc, not XML: the model emits XML for actions (`<set>`,
16
+ // `<get>`, `<sh>`). When entries were ALSO XML, the inner tag could
17
+ // look indistinguishable from a tool call — a file containing a
18
+ // `<set>` example, an env streamed-stdout containing tool-shaped text,
19
+ // or the model's own `<known>` body containing accidental tag-shaped
20
+ // content could leak into the model's emit pattern. Heredoc fences
21
+ // have zero training prior in tool-emission position, so they're
22
+ // structurally separate from the action grammar.
23
+ //
24
+ // Format: `{json-meta} <<:::{path}\n{body}\n:::{path}`. The path is the
25
+ // terminator — collision requires the body to literally contain its own
26
+ // URI on a line by itself, which is vanishingly rare without active
27
+ // malice. JSON metadata is sorted-key stringified for prefix-cache
28
+ // stability (different field order = different bytes = cache miss).
29
+ export function renderEntry(path, metadata, body) {
30
+ const meta = canonicalJson(metadata);
31
+ if (!body) {
32
+ return `${meta} <<:::${path}\n:::${path}`;
33
+ }
34
+ const trailingNewline = body.endsWith("\n") ? "" : "\n";
35
+ return `${meta} <<:::${path}\n${body}${trailingNewline}:::${path}`;
36
+ }
37
+
38
+ // JSON.stringify with sorted top-level keys for byte-stable output.
39
+ function canonicalJson(obj) {
40
+ const keys = Object.keys(obj).sort();
41
+ const sorted = {};
42
+ for (const k of keys) sorted[k] = obj[k];
43
+ return JSON.stringify(sorted);
44
+ }
45
+
5
46
  // Read sibling tooldoc .md; strips HTML comments (rationale stays out of the model packet).
6
47
  export function loadDoc(metaUrl, name) {
7
48
  const dir = dirname(fileURLToPath(metaUrl));
@@ -18,11 +59,19 @@ export function logPathToDataBase(logPath) {
18
59
  return `${m[2]}://turn_${m[1]}/${m[3]}`;
19
60
  }
20
61
 
21
- // env/sh stdout/stderr summary projection: header with line range + last
22
- // TAIL_LINES of body. The header tells the model exactly which slice is
23
- // shown so it can issue <get line="N" limit="M"/> for the rest without
24
- // re-running the command.
25
- export function streamSummary(label, entry, TAIL_LINES = 12) {
62
+ // env/sh stdout/stderr summary projection: line-tail with a final hard
63
+ // truncation to SUMMARY_MAX_CHARS. The line cap is the natural unit
64
+ // when the program emits text; the final size cap is the contract floor
65
+ // (see materializeContext) and protects against few-newline output like
66
+ // terminal-control programs (cmatrix, htop) emitting one giant ANSI line.
67
+ //
68
+ // Output stays as a flat string (not a renderEntry block) because the
69
+ // caller (log.assembleLog) wraps each log entry in renderEntry with its
70
+ // own metadata; this is the BODY of that block. Effectively double
71
+ // fencing — `<<:::log://turn_3/sh/foo` outer, then this header inside —
72
+ // but that's correct: the outer fence labels "this is sh activity at
73
+ // turn 3", and the body inside is the slice of stdout the model sees.
74
+ export function streamSummary(label, entry, MAX_LINES = 20) {
26
75
  if (!entry.body) return "";
27
76
  const { body, attributes } = entry;
28
77
  const command = attributes.command;
@@ -32,13 +81,18 @@ export function streamSummary(label, entry, TAIL_LINES = 12) {
32
81
  ? body.slice(0, -1).split("\n")
33
82
  : body.split("\n");
34
83
  const total = lines.length;
35
- if (total <= TAIL_LINES) {
36
- return `# ${label} ${command} (${channel}, ${total}L)\n${body}`;
37
- }
38
- const startLine = total - TAIL_LINES + 1;
39
- const tail =
40
- lines.slice(-TAIL_LINES).join("\n") + (trailingNewline ? "\n" : "");
41
- return `# ${label} ${command} (${channel}, tail L${startLine}-${total}/${total}; <get line="1" limit="N"/> for head)\n${tail}`;
84
+ const lineTail =
85
+ total <= MAX_LINES
86
+ ? body
87
+ : lines.slice(-MAX_LINES).join("\n") + (trailingNewline ? "\n" : "");
88
+
89
+ const header =
90
+ total <= MAX_LINES
91
+ ? `# ${label} ${command} (${channel}, ${total}L)`
92
+ : `# ${label} ${command} (${channel}, lines ${total - MAX_LINES + 1} through ${total} of ${total}; <get line="1" limit="N"/> for head)`;
93
+
94
+ const out = `${header}\n${lineTail}`;
95
+ return out.length > SUMMARY_MAX_CHARS ? out.slice(0, SUMMARY_MAX_CHARS) : out;
42
96
  }
43
97
 
44
98
  // Pattern-result log entry shared by get/set/store/rm.
@@ -3,10 +3,9 @@ import { existsSync } from "node:fs";
3
3
  import { readdir, stat } from "node:fs/promises";
4
4
  import { basename, isAbsolute, join } from "node:path";
5
5
  import { pathToFileURL } from "node:url";
6
- import config from "../agent/config.js";
7
6
  import PluginContext from "../hooks/PluginContext.js";
8
7
 
9
- const { PLUGINS_LOAD_TIMEOUT } = config;
8
+ const PLUGINS_LOAD_TIMEOUT = Number(process.env.RUMMY_PLUGINS_LOAD_TIMEOUT);
10
9
 
11
10
  let globalPrefix;
12
11
  function getGlobalPrefix() {
@@ -1,59 +1,56 @@
1
1
  # instructions {#instructions_plugin}
2
2
 
3
3
  Projects the model-facing instructions into the assembled packet.
4
- Cleanly split into a stable system-side base and a dynamic user-side
5
- phase directive so prompt caching holds across turns within a run.
4
+ Split into a stable system-side base and a per-turn user-side
5
+ imperative reminder so prompt caching holds across turns within a
6
+ run.
6
7
 
7
8
  ## Registration
8
9
 
9
- - **View**: `full` — renders the `instructions.md` base (identity +
10
- `[%TOOLS%]` + `[%TOOLDOCS%]` + optional persona) for the
11
- `instructions://system` entry. Stable across turns.
12
- - **Event**: `turn.started` — writes `instructions://system` entry
13
- with `{ persona, toolSet }` attributes.
14
- - **Filter**: `instructions.toolDocs` gathers docs from all tool
15
- plugins into a docsMap.
16
- - **Filter**: `assembly.user` (priority 250) renders the current
17
- phase's `instructions_10N.md` as `<instructions>` immediately
18
- before `<prompt>`. Phase selected from the latest `<update status>`
19
- emission in this turn's row set.
10
+ - **Filter**: `assembly.system` (priority 50) — renders the system-
11
+ prompt header + Core XML Command Grammar from
12
+ `instructions-system.md` with `[%TOOLS%]` substituted to the
13
+ active-toolset tag list.
14
+ - **Filter**: `assembly.system` (priority 100) renders the joined
15
+ per-tool docs. Each tool plugin contributes its block via the
16
+ `instructions.toolDocs` sub-filter (registry-style: filter
17
+ participants mutate a docsMap keyed by tool name). Render order
18
+ follows tool-registration order.
19
+ - **Filter**: `assembly.user` (priority 165) renders
20
+ `instructions-user.md` as `<instructions>` late in the user
21
+ message, between `<unknowns>` (150) and `<budget>` (175). The
22
+ user message is a sandwich: `<prompt>` (30) leads for cache
23
+ stability, dynamic state fills the middle, then rules and
24
+ budget close out so the action site sees them with recency.
25
+ - **Filter**: `instructions.toolDocs` — sub-filter the toolDocs
26
+ participant calls. Tool plugins (and skill) extend this filter
27
+ to publish their per-tool docs.
28
+ - **Hook**: `hooks.instructions.findLatestSummary` — locates the
29
+ most recent `<update status="200">` for cli.js to print as the
30
+ run's final answer.
31
+
32
+ The persona block is rendered by the persona plugin's own
33
+ `assembly.system` participant at priority 150.
20
34
 
21
35
  ## Files
22
36
 
23
- - `instructions.js` — plugin registration and assembly logic.
24
- - `instructions.md` — the system-side base template. Static across
25
- turns; only identity + `[%TOOLS%]` + `[%TOOLDOCS%]` placeholders.
26
- - `instructions_104.md` `instructions_108.md` — phase-specific
27
- directives keyed by the 1XY status encoding (Define / Discover /
28
- Distill / Demote / Deploy).
29
- - `protocol.js` — placeholder module reserved for deterministic
30
- protocol rule enforcement. Currently pass-through.
31
-
32
- ## Navigation validation
33
-
34
- `validateNavigation(status, rummy)` rejects illegal stage transitions
35
- emitted via `<update status="N">`:
36
-
37
- - **Forward skip** — `nextPhase > currentPhase + 1`. Models advancing
38
- more than one stage at once are jumping past required work. Returns
39
- and continuations (`nextPhase ≤ currentPhase`) always pass.
40
- - **Status 200 outside Deployment** — 200 is Deployment Completion.
41
- Emitting it from earlier phases skips the actual Deployment work.
42
- - **Deployment with prior prompts** — entering or remaining in
43
- Deployment (phase 7) requires zero visible PRIOR prompts. Covers
44
- 167 (entry), 177 / 200 (continuation, completion).
45
-
46
- On rejection the update entry is marked `rejected` (the phase router
47
- skips it) and an error log is emitted; rejections count as normal
48
- strikes.
37
+ - `instructions.js` — plugin registration and per-section assembly.
38
+ - `instructions-system.md` — header + Core XML Command Grammar.
39
+ Static within a run; only `[%TOOLS%]` substitutes at render. No
40
+ per-turn content here, ever.
41
+ - `instructions-user.md` the per-turn imperative reminder
42
+ rendered as `<instructions>` in the user message. Same bytes
43
+ every turn.
44
+ - `protocol.js` / `protocol.test.js` pass-through stub on
45
+ `entry.recording` (priority 1) reserved for future
46
+ deterministic protocol rule enforcement.
49
47
 
50
48
  ## Cache shape
51
49
 
52
- - System message includes the base template + tool docs + persona.
53
- Identical bytes every turn within a run cache-stable.
54
- - User message includes `<instructions>` at priority 250 changes
55
- as the phase advances, which is expected cache-turnover territory.
56
-
57
- If you add a per-turn-dynamic piece to `instructions.md` by mistake,
58
- the system prompt changes every turn and the cache prefix collapses.
59
- Put anything turn-specific in a phase file instead.
50
+ The full system prompt (header + Core grammar + tool docs +
51
+ persona) is built by the `assembly.system` chain. Each participant
52
+ returns identical bytes across all turns of a run, so the
53
+ concatenated result is byte-stable cache-stable. If you add a
54
+ per-turn-dynamic piece to any system-side participant by mistake,
55
+ the system prompt changes every turn and the cache prefix
56
+ collapses. Per-turn content belongs in the user message.
@@ -0,0 +1,44 @@
1
+ # Folksonomic XML Command Definitions: [%TOOLS%]
2
+
3
+ YOU MUST ONLY use the available Folksonomic XML Commands.
4
+
5
+ YOU MUST NOT use shell commands for entry file operations. Entry files require XML Commands.
6
+ Example: <get path="src/*.txt" manifest/>
7
+ Example:
8
+ <set path="file_on_disk.txt" tags="searchable,tags,internal,useful"><<NEW
9
+ Entries without a scheme prefix are files.
10
+ NEW</set>
11
+
12
+ * Files, entries, prompts, and log events are all accessible with the XML Commands.
13
+ * Entries without a scheme (`{scheme}://`) are files; with a scheme are not.
14
+
15
+ ## Core XML Command Grammar
16
+
17
+ <{set|get|mv|cp|rm} path="{path}" visibility="{visible|summarized|archived}" tags="{tags}" {manifest}>{body}</{set|get|mv|cp|rm}>
18
+
19
+ ### path: Unified address scheme for memory entries, log entries, prompts, and project files
20
+
21
+ * Paths without a `scheme://` are file system relative paths
22
+ * Accessing and modifying entries is unified for memory entries, logs entries, prompts, and project files
23
+ * Accepts patterns (glob, regex, jsonpath, xpath) for search and bulk operations
24
+
25
+ ### visibility: Promote and Demote Visibility State to Control Context Relevance
26
+
27
+ * visible: Full entry body in context, uses `"tokens":N` context budget
28
+ * summarized: Short tag-line in context, very small context budget penalty
29
+ * archived: Hidden from context, recallable later by path reference or pattern search
30
+
31
+ * The visibility state is analogous to having onboard cache (visible), RAM (summarized), and drive (archived) memory.
32
+ * When an entry is "visible", it will appear in both the summary and visible sections.
33
+
34
+ ### tags: Enhance your memory with folksonomic tagging of entries
35
+
36
+ * The `set` command's "tags" attribute sets tags. The other Core XML Commands filter by tags
37
+
38
+ ### manifest
39
+
40
+ * Adding the manifest attribute only returns a list of paths (and their token count) that would match the command.
41
+
42
+ ### body
43
+
44
+ * Whether the command's tag body is optional and what it is for depends on the specific Core XML Command.
@@ -0,0 +1,53 @@
1
+ # Folksonomic XML Command Instructions
2
+
3
+ YOU MUST ensure that all unknowns have been RESOLVED (with known entry references) or REJECTED before delivering.
4
+ YOU MUST distill unknowns into key, relevant knowns that are topical, taxonomized, tagged, and referenced.
5
+ YOU MUST ONLY populate known entries with linked, `visible` source entry information, NOT from summarized snippets or model training.
6
+ YOU SHOULD routinely demote irrelevant source entries and log entries to optimize for relevance and budget constraints
7
+
8
+ * The `"tokens":N` field shows how much context is consumed if "visible". Entries consume very few tokens when summarized.
9
+ * Use `<get path="..." manifest/>` to list paths and their token amounts for bulk operations.
10
+ * Use `<get tags="..." manifest/>` to recall entries by tags when paths are forgotten.
11
+ * Use `<get path="..." line="X" limit="Y"/>` to read subsets of entries that would exceed your `tokensFree` budget.
12
+
13
+ Example:
14
+ <get path="**" manifest>capital</get>
15
+ <get path="prompt://3" line="1" limit="100"/>
16
+
17
+ <set path="trivia/capitals.csv" visibility="visible"/>
18
+
19
+ <set path="known://trivia/geography/capitals" tags="countries,france,capital,geography,trivia"><<NEW
20
+ # Related
21
+ [trivia question](prompt://3)
22
+ [unknown resolving](unknown://countries/france/capital)
23
+ [source entry](trivia/capitals.csv)
24
+
25
+ { relevant information derived from the linked, visible source entry }
26
+ NEW</set>
27
+
28
+ <set path="known://plan"><<SEARCH
29
+ - [ ] Discover key, relevant information
30
+ SEARCH<<REPLACE
31
+ - [ ] Discover key, relevant information about French capital
32
+ - [ ] Locate authoritative capital source
33
+ - [ ] Cross-check with secondary source
34
+ REPLACE</set>
35
+
36
+ <set path="prompt://3" visibility="summarized"/>
37
+ <set path="unknown://countries/france/capital" tags="RESOLVED" visibility="summarized"/>
38
+ <set path="trivia/capitals.csv" visibility="summarized"/>
39
+ { summarizing entries that may be relevant again, archiving what probably won't be, deleting what definitely won't be }
40
+
41
+ <set path="known://plan"><<SEARCH - [ ] Find the capital of France SEARCH<<REPLACE - [x] Find the capital of France REPLACE</set>
42
+ <update status="102">distilled the capital of France into known entry; demoted the source</update>
43
+
44
+ Example:
45
+ <set path="known://plan"><<SEARCH
46
+ - [ ] Deliver answer to trivia question
47
+ SEARCH<<REPLACE
48
+ - [x] Deliver answer to trivia question
49
+ REPLACE</set>
50
+ <update status="200">Paris</update>
51
+
52
+ YOU MUST NOT allow the `"tokens":N` sum of source entries, prompts, or log events to exceed `tokensFree="N"` budget.
53
+ YOU MUST terminate your turn with <update status="{102|200}">{ direct answer or one-line summary }</update> (<= 80 chars)