gaia-framework 1.60.0 → 1.61.0
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/CLAUDE.md +1 -1
- package/README.md +1 -1
- package/_gaia/_config/global.yaml +1 -1
- package/_gaia/_config/manifest.yaml +1 -1
- package/_gaia/core/config.yaml +1 -1
- package/_gaia/core/engine/workflow.xml +1 -10
- package/_gaia/lifecycle/skills/memory-management.md +133 -9
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/checklist.md +15 -0
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/instructions.xml +153 -57
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/workflow.yaml +5 -0
- package/gaia-install.sh +1 -1
- package/package.json +1 -1
- package/_gaia/lifecycle/skills/memory-management-cross-agent.md +0 -218
package/CLAUDE.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
# GAIA Framework v1.
|
|
2
|
+
# GAIA Framework v1.61.0
|
|
3
3
|
|
|
4
4
|
This project uses the **GAIA** (Generative Agile Intelligence Architecture) framework — an AI agent framework for Claude Code that orchestrates software product development through 26 specialized agents, 65 workflows, and 8 shared skills.
|
|
5
5
|
|
package/README.md
CHANGED
package/_gaia/core/config.yaml
CHANGED
|
@@ -68,17 +68,8 @@ execution modes (normal/yolo/planning), checkpoints, and quality gates.
|
|
|
68
68
|
<action if="agent is 'dev-*' (wildcard)">Check if workflow.yaml declares agent_auto_detect: true. If true, execute the agent_auto_detect_strategy from workflow.yaml to determine the stack. If auto-detection succeeds, resolve to {project-root}/_gaia/dev/agents/{detected_stack}-dev.md and inform user: "Auto-detected developer: {agent_name} based on {detection_source}." If auto-detection fails or agent_auto_detect is false/absent: ask user which stack developer to use (typescript, angular, flutter, java, python, mobile, go), then resolve to {project-root}/_gaia/dev/agents/{stack}-dev.md</action>
|
|
69
69
|
<action if="agent file resolved">Read the agent persona file — adopt its persona, name, communication style, rules, and domain knowledge for the duration of this workflow</action>
|
|
70
70
|
<action if="agent file resolved">Do NOT execute the agent's activation protocol, greeting, or menu — the workflow engine controls step execution</action>
|
|
71
|
+
<action if="agent file resolved">Do NOT load the agent's memory sidecar — the workflow engine manages its own checkpoints</action>
|
|
71
72
|
<action if="agent file resolved">Check for {project-root}/_gaia/_config/agents/{agent-id}.customize.yaml. If found, load and merge overrides (persona_overrides, menu_additions, menu_removals, skill_additions, rule_additions, skill_overrides, skill_section_overrides). For dev agents, also check all-dev.customize.yaml and merge (agent-specific takes precedence over all-dev).</action>
|
|
72
|
-
|
|
73
|
-
<!-- Memory Load Protocol (E9-S7) — Load agent memory sidecar files after persona, before instructions -->
|
|
74
|
-
<action if="agent file resolved">Read {project-root}/_memory/config.yaml to resolve agent tier and sidecar path. If the file does not exist, log "Memory config not found — skipping memory loading." and skip all remaining memory load actions in this step.</action>
|
|
75
|
-
<action if="agent file resolved">Resolve the agent's tier classification: look up the resolved agent ID in _memory/config.yaml tier lists — check tiers.tier_1.agents, tiers.tier_2.agents, and tiers.tier_3.agents in that order. If the agent ID is not found in any tier list (untiered), treat as Tier 3 by default — load decision-log.md only if it exists, with no budget enforcement.</action>
|
|
76
|
-
<action if="agent file resolved">Resolve sidecar path: read agents.{agent-id}.sidecar from _memory/config.yaml, construct absolute path as {project-root}/_memory/{sidecar_value}/. If the agent entry is not found in the agents section, construct path as {project-root}/_memory/{agent-id}-sidecar/.</action>
|
|
77
|
-
<action if="agent file resolved">Check if the sidecar directory exists. If the directory does not exist or is empty, skip all file loading silently — no error, no warning. Proceed to Step 4.</action>
|
|
78
|
-
<action if="agent file resolved and tier == 1">Load canonical sidecar files (silently skip any that do not exist): ground-truth.md, decision-log.md, conversation-context.md (3 files). These provide the agent's persistent ground truth, decision history, and recent conversation context.</action>
|
|
79
|
-
<action if="agent file resolved and tier == 2">Load canonical sidecar files (silently skip any that do not exist): decision-log.md, conversation-context.md (2 files). Tier 2 agents do not have ground-truth.md.</action>
|
|
80
|
-
<action if="agent file resolved and tier == 3 or untiered">Load canonical sidecar file (silently skip if it does not exist): decision-log.md (1 file). Tier 3 and untiered agents receive minimal memory context.</action>
|
|
81
|
-
<action if="agent file resolved and tier in [1, 2]">Estimate token budget usage: sum the byte lengths of all loaded sidecar files, divide by the token_approximation value (default: 4 chars per token, from _memory/config.yaml archival.token_approximation). Compare against the agent's session_budget from the tier definition in _memory/config.yaml. If usage reaches or exceeds the budget_warn_at threshold (0.8 / 80% from _memory/config.yaml archival.budget_warn_at): display warning "Memory budget at {N}% for {agent_name} — {used}K of {budget}K tokens." For Tier 3 and untiered agents (session_budget: null), skip the token budget check entirely.</action>
|
|
82
73
|
</step>
|
|
83
74
|
|
|
84
75
|
<step n="4" title="Load Instructions">
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: memory-management
|
|
3
|
-
version: '1.
|
|
3
|
+
version: '1.0'
|
|
4
4
|
applicable_agents: [all]
|
|
5
|
-
description: '
|
|
5
|
+
description: 'Session load/save, decision formatting, stale detection, deduplication, context summarization'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
<!-- SECTION: decision-formatting -->
|
|
@@ -96,13 +96,13 @@ Persist agent session data to sidecar files. Agent-agnostic — takes sidecar pa
|
|
|
96
96
|
- Read entire file, replace in memory, write entire file back
|
|
97
97
|
|
|
98
98
|
**Token budget enforcement (before write):**
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
99
|
+
- Calculate projected file size after append (current size + new entries size)
|
|
100
|
+
- Approximate tokens: character count / 4
|
|
101
|
+
- If projected size exceeds `tier_budget`: warn with current/max budget and offer options:
|
|
102
|
+
- **Archive oldest entries** — move oldest N entries to `archive/` subdirectory to make room
|
|
103
|
+
- **Force save** — save anyway, exceeding the budget
|
|
104
104
|
- Never silently truncate or block a save operation
|
|
105
|
-
-
|
|
105
|
+
- Warn at 80% of budget ("approaching limit"), warn at 90% ("near limit"), trigger archival prompt at 100%
|
|
106
106
|
<!-- END SECTION -->
|
|
107
107
|
|
|
108
108
|
<!-- SECTION: context-summarization -->
|
|
@@ -195,4 +195,128 @@ Detect and merge duplicate decision entries within a decision log.
|
|
|
195
195
|
**Output:** List of duplicate pairs with recommended action (auto-archive or review).
|
|
196
196
|
<!-- END SECTION -->
|
|
197
197
|
|
|
198
|
-
<!--
|
|
198
|
+
<!-- SECTION: cross-ref-loading -->
|
|
199
|
+
## Cross-Reference Loading (ADR-015)
|
|
200
|
+
|
|
201
|
+
Load another agent's sidecar files as read-only cross-references. All cross-ref loading is JIT (just-in-time) — never preloaded at session start.
|
|
202
|
+
|
|
203
|
+
### Schema: `<memory-reads>` Tag
|
|
204
|
+
|
|
205
|
+
Agent persona files declare cross-references using this XML schema inside the `<agent>` block:
|
|
206
|
+
|
|
207
|
+
```xml
|
|
208
|
+
<memory-reads>
|
|
209
|
+
<cross-ref agent="{agent-id}" file="{file-name}" mode="{recent|full|summary}" required="{true|false}" />
|
|
210
|
+
<!-- Additional cross-ref entries -->
|
|
211
|
+
</memory-reads>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Attributes:**
|
|
215
|
+
- `agent` (required) — the agent ID whose sidecar to read (e.g., "architect", "validator")
|
|
216
|
+
- `file` (required) — the sidecar file to read (e.g., "decision-log", "ground-truth", "conversation-context")
|
|
217
|
+
- `mode` (required) — loading mode: `recent`, `full`, or `summary`
|
|
218
|
+
- `required` (optional, default: "true") — if "false", skip gracefully when the sidecar is absent
|
|
219
|
+
|
|
220
|
+
### Read-Only Access: `load_cross_ref()`
|
|
221
|
+
|
|
222
|
+
Cross-references are loaded through `load_cross_ref()`, which is a **read-only** path — separate from `load_own()` (the agent's own sidecar, which supports read/write).
|
|
223
|
+
|
|
224
|
+
**Parameters:**
|
|
225
|
+
- `sidecar_path` — absolute path to the **target** agent's sidecar directory (e.g., `_memory/architect-sidecar/`)
|
|
226
|
+
- `file_name` — which file to read (e.g., "decision-log.md", "ground-truth.md")
|
|
227
|
+
- `mode` — loading mode: `recent`, `full`, or `summary`
|
|
228
|
+
- `budget_remaining` — remaining token budget for cross-references
|
|
229
|
+
|
|
230
|
+
**Write-Guard:**
|
|
231
|
+
Any attempt to write to a sidecar that is not the current agent's own sidecar MUST raise a **hard error** (not a warning). The write-guard blocks all write operations through `load_cross_ref()`. Only `load_own()` permits writes, and only to the agent's own sidecar directory.
|
|
232
|
+
|
|
233
|
+
**Procedure:**
|
|
234
|
+
1. Validate the target sidecar path is NOT the current agent's own sidecar (self-reference guard — see Validation section below)
|
|
235
|
+
2. Check budget_remaining BEFORE loading — if insufficient, apply progressive downgrade
|
|
236
|
+
3. Read the target file from disk (read-only — no file creation, no modification)
|
|
237
|
+
4. Apply mode filtering (see Loading Modes below)
|
|
238
|
+
5. Return filtered content as read-only data
|
|
239
|
+
|
|
240
|
+
### Loading Modes
|
|
241
|
+
|
|
242
|
+
**`recent` mode** — Load entries from the last 2 sprints only:
|
|
243
|
+
- Parse decision-log entries using ADR-016 format
|
|
244
|
+
- Filter by Sprint field: keep entries where sprint matches current sprint or previous sprint
|
|
245
|
+
- If sprint metadata is absent from entries, fall back to date-based filtering (last 30 days)
|
|
246
|
+
- Approximate token cost: character count / 4
|
|
247
|
+
|
|
248
|
+
**`full` mode** — Load the entire file content:
|
|
249
|
+
- Read full file, respect budget cap
|
|
250
|
+
- If file exceeds budget_remaining: truncate oldest entries first (keep most recent)
|
|
251
|
+
- Approximate token cost: character count / 4
|
|
252
|
+
|
|
253
|
+
**`summary` mode** — Load section headers only:
|
|
254
|
+
- Parse the file for markdown headers (lines starting with `#`, `##`, `###`)
|
|
255
|
+
- Stop at section boundaries — do not load body content
|
|
256
|
+
- Minimal token cost
|
|
257
|
+
|
|
258
|
+
### JIT Loading
|
|
259
|
+
|
|
260
|
+
Cross-references are loaded **just-in-time** during workflow step execution — NOT at agent activation or session start. Loading is triggered only when a workflow step explicitly requires cross-agent context.
|
|
261
|
+
|
|
262
|
+
**Trigger:** The workflow engine checks `<memory-reads>` declarations and loads cross-references only when the current step's execution context requires cross-agent data. No cross-references are preloaded eagerly.
|
|
263
|
+
|
|
264
|
+
### Budget Enforcement
|
|
265
|
+
|
|
266
|
+
**Pre-load budget check:** Before each cross-reference load, calculate:
|
|
267
|
+
- Tokens already consumed by own sidecar
|
|
268
|
+
- Tokens already consumed by previously loaded cross-references
|
|
269
|
+
- Estimated tokens for the next cross-reference (based on mode and file size)
|
|
270
|
+
|
|
271
|
+
**Progressive downgrade chain:** When budget is insufficient for the requested mode:
|
|
272
|
+
1. `full` → downgrade to `recent`
|
|
273
|
+
2. `recent` → downgrade to `summary`
|
|
274
|
+
3. `summary` → downgrade to `skip` (do not load, log warning)
|
|
275
|
+
|
|
276
|
+
Log every downgrade as a warning in the session checkpoint:
|
|
277
|
+
`"Cross-ref downgraded: {agent}/{file} from {original_mode} to {new_mode} — budget {used}/{total}"`
|
|
278
|
+
|
|
279
|
+
**Val's 50% cross-ref budget cap:**
|
|
280
|
+
Val (validator) has a `cross_ref_budget_cap` of 0.5 in `_memory/config.yaml`, meaning cross-references may consume at most 50% of Val's 300K session budget (= 150K tokens max for cross-refs). Val's load priority order: architect → pm → sm. If the 150K cap is hit mid-load, remaining cross-references are downgraded progressively.
|
|
281
|
+
|
|
282
|
+
**Tier budget ceilings:**
|
|
283
|
+
- Tier 1 agents: 300K session budget (own sidecar + cross-refs combined)
|
|
284
|
+
- Tier 2 agents: 100K session budget (own sidecar + cross-refs combined)
|
|
285
|
+
- Tier 3 agents: no explicit budget enforcement
|
|
286
|
+
|
|
287
|
+
### Graceful Error Handling
|
|
288
|
+
|
|
289
|
+
**Missing sidecar directory or file:**
|
|
290
|
+
- If the target sidecar directory does not exist: log a warning ("Cross-ref skipped: {agent} sidecar directory not found"), skip this cross-reference, and continue workflow execution
|
|
291
|
+
- If the target file within the sidecar does not exist: log a warning ("Cross-ref skipped: {agent}/{file} not found"), skip, continue
|
|
292
|
+
|
|
293
|
+
**Malformed or corrupt sidecar files:**
|
|
294
|
+
- If the target file exists but cannot be parsed (malformed markdown, corrupt content, unparseable entries): log a warning ("Cross-ref skipped: {agent}/{file} is malformed"), skip this cross-reference, and continue
|
|
295
|
+
- Never halt the workflow due to a cross-reference loading failure
|
|
296
|
+
|
|
297
|
+
**Absent optional cross-references:**
|
|
298
|
+
- If `<cross-ref required="false">` and the target is absent: skip silently (no warning)
|
|
299
|
+
- If `<cross-ref required="true">` (default) and the target is absent: log warning but still continue
|
|
300
|
+
|
|
301
|
+
### Consistency Validation
|
|
302
|
+
|
|
303
|
+
At session start, validate that agent persona `<memory-reads>` declarations are consistent with `_memory/config.yaml` cross_references matrix:
|
|
304
|
+
|
|
305
|
+
1. Parse the agent's `<memory-reads>` block from the persona file
|
|
306
|
+
2. Load the agent's entry from `_memory/config.yaml` → `cross_references.{agent_id}.reads_from`
|
|
307
|
+
3. Compare: every entry in config.yaml should have a matching `<cross-ref>` in the persona file
|
|
308
|
+
4. If mismatch found: produce a **warning** (not an error) — `_memory/config.yaml` is the authoritative source. The persona file declaration should mirror it.
|
|
309
|
+
|
|
310
|
+
**Self-reference guard:**
|
|
311
|
+
If an agent's `<memory-reads>` declares a `<cross-ref>` where the `agent` attribute matches the current agent's own ID, reject it with a validation error at session start. An agent must not reference its own sidecar as a cross-reference — own-sidecar access is through `load_own()`.
|
|
312
|
+
|
|
313
|
+
### Checkpoint Provenance
|
|
314
|
+
|
|
315
|
+
After loading cross-references, record in the session checkpoint:
|
|
316
|
+
- Which cross-references were loaded (agent, file, mode)
|
|
317
|
+
- File checksums (`shasum -a 256`) of each loaded cross-reference file
|
|
318
|
+
- Any downgrades or skips that occurred
|
|
319
|
+
- Total tokens consumed by cross-references
|
|
320
|
+
|
|
321
|
+
This enables `/gaia-resume` to detect stale cross-references when resuming a session.
|
|
322
|
+
<!-- END SECTION -->
|
|
@@ -42,6 +42,21 @@ validation-target: 'Ground truth refresh workflow'
|
|
|
42
42
|
- [ ] ground-truth-management sections loaded JIT
|
|
43
43
|
- [ ] Sections: full-refresh, incremental-refresh, entry-structure, conflict-resolution, token-budget
|
|
44
44
|
|
|
45
|
+
## --agent Parameter (E9-S11)
|
|
46
|
+
- [ ] workflow.yaml declares agent parameter with flag --agent and allowed values [val, theo, derek, nate, all]
|
|
47
|
+
- [ ] Default agent is val (backward compatible — no --agent behaves identically to pre-E9-S11)
|
|
48
|
+
- [ ] Invalid agent names produce clear error with valid values list
|
|
49
|
+
- [ ] Per-agent sidecar initialization creates missing ground-truth.md for any Tier 1 agent
|
|
50
|
+
- [ ] Theo inventory scans filesystem structure + architecture.md
|
|
51
|
+
- [ ] Derek inventory scans prd.md + epics-and-stories.md + sprint-status.yaml
|
|
52
|
+
- [ ] Nate inventory scans sprint-status.yaml + story files in implementation-artifacts/
|
|
53
|
+
- [ ] Val inventory uses existing 6-target scan (unchanged)
|
|
54
|
+
- [ ] Decision log entries route to target agent's own decision-log.md
|
|
55
|
+
- [ ] Per-agent ground_truth_budget enforced (Val 200K, Theo 150K, Derek 100K, Nate 100K)
|
|
56
|
+
- [ ] --agent all runs val → theo → derek → nate sequentially
|
|
57
|
+
- [ ] --agent all continues on per-agent failure and reports which succeeded/failed
|
|
58
|
+
- [ ] --agent all presents combined summary with per-agent status
|
|
59
|
+
|
|
45
60
|
## Integration
|
|
46
61
|
- [ ] Manifest entry exists in workflow-manifest.csv
|
|
47
62
|
- [ ] Works identically standalone or as sub-step
|
package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/instructions.xml
CHANGED
|
@@ -7,95 +7,166 @@
|
|
|
7
7
|
<mandate>Behavior must be identical whether called standalone or as sub-step from another workflow</mandate>
|
|
8
8
|
</critical>
|
|
9
9
|
|
|
10
|
-
<step n="1" title="
|
|
11
|
-
<action>
|
|
12
|
-
<action
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<action
|
|
10
|
+
<step n="1" title="Resolve Agent Target">
|
|
11
|
+
<action>Parse $ARGUMENTS for --agent value. If --agent is absent, default to "val" for backward compatibility.</action>
|
|
12
|
+
<action>Validate agent name against allowed values: val, theo, derek, nate, all.
|
|
13
|
+
If the agent name is not in the allowed values list: HALT with error:
|
|
14
|
+
"Unknown agent '{agent_name}'. Valid values: val, theo, derek, nate, all."</action>
|
|
15
|
+
<action>Resolve target sidecar path and inventory source files based on agent:
|
|
16
|
+
- val: sidecar = {memory_path}/validator-sidecar/, inventory = 6-target scan (existing)
|
|
17
|
+
- theo: sidecar = {memory_path}/architect-sidecar/, inventory = filesystem structure + {planning_artifacts}/architecture.md
|
|
18
|
+
- derek: sidecar = {memory_path}/pm-sidecar/, inventory = {planning_artifacts}/prd.md + {planning_artifacts}/epics-and-stories.md + {implementation_artifacts}/sprint-status.yaml
|
|
19
|
+
- nate: sidecar = {memory_path}/sm-sidecar/, inventory = {implementation_artifacts}/sprint-status.yaml + story files in {implementation_artifacts}/
|
|
20
|
+
- all: run sequentially for val, theo, derek, nate (see Step 13)</action>
|
|
21
|
+
<action if="agent == all">Set agent_queue = [val, theo, derek, nate]. Proceed to Step 13 for orchestration.</action>
|
|
16
22
|
</step>
|
|
17
23
|
|
|
18
|
-
<step n="2" title="
|
|
24
|
+
<step n="2" title="Initialize Agent Sidecar">
|
|
25
|
+
<action>Check if the resolved target sidecar directory exists (e.g., {memory_path}/validator-sidecar/ for val, {memory_path}/architect-sidecar/ for theo, {memory_path}/pm-sidecar/ for derek, {memory_path}/sm-sidecar/ for nate)</action>
|
|
26
|
+
<action if="directory missing">Create the resolved sidecar directory</action>
|
|
27
|
+
<action if="ground-truth.md missing">Create ground-truth.md in the resolved sidecar directory with empty header containing last-refresh timestamp set to "never"</action>
|
|
28
|
+
<action if="decision-log.md missing">Create decision-log.md in the resolved sidecar directory with header: "# {agent_display_name} Decision Log" and empty entries</action>
|
|
29
|
+
<action if="conversation-context.md missing">Create conversation-context.md in the resolved sidecar directory with header: "# {agent_display_name} Conversation Context" and empty rolling state</action>
|
|
30
|
+
</step>
|
|
31
|
+
|
|
32
|
+
<step n="3" title="Determine Refresh Mode">
|
|
19
33
|
<action>Check if --incremental flag was passed</action>
|
|
20
34
|
<action if="incremental">Set mode to incremental — only scan files modified since last-refresh timestamp from ground-truth.md header</action>
|
|
21
35
|
<action if="not incremental">Set mode to full — scan all targets completely. Full refresh catches deletions and renames that incremental would miss.</action>
|
|
22
36
|
</step>
|
|
23
37
|
|
|
24
|
-
<step n="
|
|
38
|
+
<step n="4" title="Load Entry Structure">
|
|
25
39
|
<action>Load ground-truth-management skill section: entry-structure (JIT)</action>
|
|
26
40
|
<action>Use entry-structure format for all ground truth entries written in subsequent steps</action>
|
|
27
41
|
</step>
|
|
28
42
|
|
|
29
|
-
<step n="
|
|
30
|
-
<action>Read existing
|
|
43
|
+
<step n="5" title="Parse Previous State">
|
|
44
|
+
<action>Read existing ground-truth.md from the resolved target sidecar directory</action>
|
|
31
45
|
<action>Extract last-refresh timestamp from header</action>
|
|
32
46
|
<action>Parse all existing entries into a lookup map keyed by file path for diff comparison</action>
|
|
33
47
|
<action if="incremental mode">Filter scan targets to only files modified after last-refresh timestamp</action>
|
|
34
48
|
</step>
|
|
35
49
|
|
|
36
|
-
<step n="
|
|
50
|
+
<step n="6" title="Scan Inventory Targets">
|
|
37
51
|
<action>Load ground-truth-management skill section based on mode: full-refresh or incremental-refresh (JIT)</action>
|
|
38
|
-
<action>Scan the following 6 inventory targets, showing section-by-section progress to the user after each target completes.</action>
|
|
39
52
|
|
|
40
|
-
<action
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
<action if="agent == val">
|
|
54
|
+
Scan the following 6 inventory targets (existing Val scan — unchanged for backward compatibility), showing section-by-section progress to the user after each target completes.
|
|
55
|
+
|
|
56
|
+
<action title="Exclusion list">
|
|
57
|
+
ALWAYS exclude these directories and files from scanning — they are framework internals, not project code:
|
|
58
|
+
_gaia/, .claude/, bin/, _memory/, node_modules/, .git/, build/, dist/, .DS_Store, *.lock
|
|
59
|
+
</action>
|
|
60
|
+
|
|
61
|
+
<action title="Target 1: Project Source Files">
|
|
62
|
+
Scan {project-path}/**/* (excluding the exclusion list above)
|
|
63
|
+
Extract: file inventory, directory structure, languages used, entry points
|
|
64
|
+
Report progress: "Scanning project source files... found N files across N directories."
|
|
65
|
+
</action>
|
|
66
|
+
|
|
67
|
+
<action title="Target 2: Project Config Files">
|
|
68
|
+
Scan {project-path}/*.{json,yaml,yml,toml,xml,env.example} (root-level config files)
|
|
69
|
+
Extract: config keys, settings, dependency declarations
|
|
70
|
+
Report progress: "Scanning project config files... found N config files."
|
|
71
|
+
</action>
|
|
72
|
+
|
|
73
|
+
<action title="Target 3: Project Package Manifests">
|
|
74
|
+
Scan {project-path}/**/package.json, pubspec.yaml, pom.xml, build.gradle, requirements.txt, Cargo.toml, go.mod, Gemfile, *.csproj (whichever exist)
|
|
75
|
+
Extract: dependencies, versions, scripts, build targets
|
|
76
|
+
Report progress: "Scanning package manifests... found N manifests."
|
|
77
|
+
</action>
|
|
78
|
+
|
|
79
|
+
<action title="Target 4: Planning Artifacts">
|
|
80
|
+
Scan {project-root}/docs/planning-artifacts/*.md
|
|
81
|
+
Extract: artifact name, type, date
|
|
82
|
+
Report progress: "Scanning planning artifacts... found N artifacts."
|
|
83
|
+
</action>
|
|
84
|
+
|
|
85
|
+
<action title="Target 5: Implementation Artifacts">
|
|
86
|
+
Scan {project-root}/docs/implementation-artifacts/*.md
|
|
87
|
+
Extract: artifact name, type, story key if applicable
|
|
88
|
+
Report progress: "Scanning implementation artifacts... found N artifacts."
|
|
89
|
+
</action>
|
|
90
|
+
|
|
91
|
+
<action title="Target 6: Test Artifacts">
|
|
92
|
+
Scan {project-root}/docs/test-artifacts/*.md
|
|
93
|
+
Extract: artifact name, type, coverage area
|
|
94
|
+
Report progress: "Scanning test artifacts... found N artifacts."
|
|
95
|
+
</action>
|
|
43
96
|
</action>
|
|
44
97
|
|
|
45
|
-
<action
|
|
46
|
-
Scan
|
|
47
|
-
Extract: file inventory, directory structure, languages used, entry points
|
|
48
|
-
Report progress: "Scanning project source files... found N files across N directories."
|
|
49
|
-
</action>
|
|
98
|
+
<action if="agent == theo">
|
|
99
|
+
Scan theo-specific inventory targets (architecture ground truth):
|
|
50
100
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
101
|
+
<action title="Target 1: Filesystem Structure">
|
|
102
|
+
Scan {project-path}/ for directory structure, file types, and project layout.
|
|
103
|
+
Extract: tech stack, components, module boundaries, entry points, build configuration.
|
|
104
|
+
Report progress: "Scanning filesystem structure for Theo... found N directories, N files."
|
|
105
|
+
</action>
|
|
56
106
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
107
|
+
<action title="Target 2: Architecture Document">
|
|
108
|
+
Scan {planning_artifacts}/architecture.md
|
|
109
|
+
Extract: ADRs, architectural decisions, component diagrams, dependency info, integration points, tech stack decisions.
|
|
110
|
+
Report progress: "Scanning architecture.md for Theo... extracted N ADRs, N components."
|
|
111
|
+
</action>
|
|
61
112
|
</action>
|
|
62
113
|
|
|
63
|
-
<action
|
|
64
|
-
Scan
|
|
65
|
-
|
|
66
|
-
|
|
114
|
+
<action if="agent == derek">
|
|
115
|
+
Scan derek-specific inventory targets (product ground truth):
|
|
116
|
+
|
|
117
|
+
<action title="Target 1: Product Requirements">
|
|
118
|
+
Scan {planning_artifacts}/prd.md
|
|
119
|
+
Extract: functional requirements, non-functional requirements, user stories overview, feature list, product goals.
|
|
120
|
+
Report progress: "Scanning prd.md for Derek... extracted N requirements."
|
|
121
|
+
</action>
|
|
122
|
+
|
|
123
|
+
<action title="Target 2: Epics and Stories">
|
|
124
|
+
Scan {planning_artifacts}/epics-and-stories.md
|
|
125
|
+
Extract: epic list, story breakdown, acceptance criteria summaries, dependency graph, sizing data.
|
|
126
|
+
Report progress: "Scanning epics-and-stories.md for Derek... extracted N epics, N stories."
|
|
127
|
+
</action>
|
|
128
|
+
|
|
129
|
+
<action title="Target 3: Sprint Status">
|
|
130
|
+
Scan {implementation_artifacts}/sprint-status.yaml
|
|
131
|
+
Extract: current sprint state, story statuses, velocity data, blocked items, completion rates.
|
|
132
|
+
Report progress: "Scanning sprint-status.yaml for Derek... extracted sprint state."
|
|
133
|
+
</action>
|
|
67
134
|
</action>
|
|
68
135
|
|
|
69
|
-
<action
|
|
70
|
-
Scan
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
136
|
+
<action if="agent == nate">
|
|
137
|
+
Scan nate-specific inventory targets (sprint ground truth):
|
|
138
|
+
|
|
139
|
+
<action title="Target 1: Sprint Status">
|
|
140
|
+
Scan {implementation_artifacts}/sprint-status.yaml
|
|
141
|
+
Extract: sprint metadata, story statuses, velocity metrics, blocked items, wave assignments.
|
|
142
|
+
Report progress: "Scanning sprint-status.yaml for Nate... extracted sprint state."
|
|
143
|
+
</action>
|
|
74
144
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
145
|
+
<action title="Target 2: Story Files">
|
|
146
|
+
Scan all story files in {implementation_artifacts}/ matching pattern *-*.md (story files)
|
|
147
|
+
Extract: story statuses, completion rates, subtask progress, blockers, review gate states.
|
|
148
|
+
Report progress: "Scanning story files in implementation-artifacts for Nate... found N stories."
|
|
149
|
+
</action>
|
|
79
150
|
</action>
|
|
80
151
|
</step>
|
|
81
152
|
|
|
82
|
-
<step n="
|
|
83
|
-
<action>Compare scan results against previous state from Step
|
|
153
|
+
<step n="7" title="Compare and Detect Changes">
|
|
154
|
+
<action>Compare scan results against previous state from Step 5</action>
|
|
84
155
|
<action>Classify each entry as: ADDED (new file not in previous state), UPDATED (file exists but metadata changed), UNCHANGED (no changes detected)</action>
|
|
85
156
|
<action if="full mode">For entries in previous state not found in scan results: mark as REMOVED with detection date (e.g., "REMOVED (file deleted, detected 2026-03-19)"). Do NOT silently delete entries.</action>
|
|
86
157
|
<action if="incremental mode">Skip deletion detection — incremental mode cannot detect deletions. This is a documented limitation.</action>
|
|
87
158
|
<action>Load ground-truth-management skill section: conflict-resolution (JIT) if any conflicts are detected between scan results and existing entries</action>
|
|
88
159
|
</step>
|
|
89
160
|
|
|
90
|
-
<step n="
|
|
91
|
-
<action>Update
|
|
161
|
+
<step n="8" title="Write Ground Truth">
|
|
162
|
+
<action>Update ground-truth.md in the resolved target agent's sidecar directory with all scan results</action>
|
|
92
163
|
<action>Write header with last-refresh timestamp set to current date/time</action>
|
|
93
|
-
<action>Organize entries by category
|
|
164
|
+
<action>Organize entries by category appropriate to the target agent</action>
|
|
94
165
|
<action>Include verified counts, locations, and structural patterns for each category</action>
|
|
95
166
|
<action>Preserve REMOVED entries with their detection dates — do not purge</action>
|
|
96
167
|
</step>
|
|
97
168
|
|
|
98
|
-
<step n="
|
|
169
|
+
<step n="9" title="Generate Diff Report">
|
|
99
170
|
<action>Generate diff/delta report summarizing changes since last refresh</action>
|
|
100
171
|
<action>Include counts by category: added, removed, updated entries</action>
|
|
101
172
|
<action>Include total entry count across all categories</action>
|
|
@@ -103,23 +174,48 @@
|
|
|
103
174
|
<action>Present the full diff report to the user</action>
|
|
104
175
|
</step>
|
|
105
176
|
|
|
106
|
-
<step n="
|
|
107
|
-
<action>Append the diff/delta report to
|
|
108
|
-
|
|
109
|
-
|
|
177
|
+
<step n="10" title="Log to Decision Log">
|
|
178
|
+
<action>Append the diff/delta report to the target agent's own decision-log.md in the resolved sidecar directory.
|
|
179
|
+
Route to the correct file based on resolved agent target:
|
|
180
|
+
- val: {memory_path}/validator-sidecar/decision-log.md
|
|
181
|
+
- theo: {memory_path}/architect-sidecar/decision-log.md
|
|
182
|
+
- derek: {memory_path}/pm-sidecar/decision-log.md
|
|
183
|
+
- nate: {memory_path}/sm-sidecar/decision-log.md
|
|
184
|
+
Never write to another agent's decision-log.md — this would violate cross-agent write isolation.</action>
|
|
185
|
+
<action>Include date, refresh mode (full or incremental), target agent name, and summary</action>
|
|
186
|
+
<action>Format: "## Refresh — {date} ({mode}) — Agent: {agent_name}\n{summary}"</action>
|
|
110
187
|
</step>
|
|
111
188
|
|
|
112
|
-
<step n="
|
|
189
|
+
<step n="11" title="Check Token Budget">
|
|
113
190
|
<action>Load ground-truth-management skill section: token-budget (JIT)</action>
|
|
114
|
-
<action>
|
|
115
|
-
|
|
191
|
+
<action>Load the correct per-agent ground_truth_budget from {memory_path}/config.yaml based on target agent:
|
|
192
|
+
- Val: 200K (200,000 tokens)
|
|
193
|
+
- Theo: 150K (150,000 tokens)
|
|
194
|
+
- Derek: 100K (100,000 tokens)
|
|
195
|
+
- Nate: 100K (100,000 tokens)
|
|
196
|
+
These are distinct from the 300K session_budget — ground_truth_budget controls only ground-truth.md size.</action>
|
|
197
|
+
<action>Estimate token count of the target agent's ground-truth.md</action>
|
|
198
|
+
<action>If token count exceeds the per-agent budget threshold: trigger archival of oldest REMOVED entries per token-budget skill guidance</action>
|
|
199
|
+
<action if="agent == all">Report per-agent usage separately (e.g., "Theo: 42K/150K, Derek: 18K/100K")</action>
|
|
116
200
|
<action>Report token usage to user</action>
|
|
117
201
|
</step>
|
|
118
202
|
|
|
119
|
-
<step n="
|
|
203
|
+
<step n="12" title="Present Results">
|
|
120
204
|
<template-output file="{memory_path}/validator-sidecar/ground-truth.md">
|
|
121
|
-
Ground truth refreshed
|
|
205
|
+
Ground truth refreshed for the target agent with verified inventory.
|
|
206
|
+
Output path is resolved at runtime based on --agent parameter (defaults to validator-sidecar).
|
|
122
207
|
Includes last-refresh timestamp, categorized entries, and REMOVED markers for deleted files.
|
|
123
208
|
</template-output>
|
|
124
209
|
</step>
|
|
210
|
+
|
|
211
|
+
<step n="13" title="Orchestrate --agent all" if="agent == all">
|
|
212
|
+
<action>Run refresh sequentially for each agent in order: val, theo, derek, nate.
|
|
213
|
+
Each agent's refresh completes fully (Steps 2-12) before the next begins.
|
|
214
|
+
No cross-contamination of sidecar writes — each agent writes only to its own sidecar.</action>
|
|
215
|
+
<action>On per-agent failure (e.g., missing source file like prd.md): log the error with reason, continue with remaining agents. Do not halt the entire sequence.</action>
|
|
216
|
+
<action>After all agents complete: present a combined summary with per-agent status:
|
|
217
|
+
- Which agents succeeded and their entry counts
|
|
218
|
+
- Which agents failed and the failure reasons
|
|
219
|
+
Format: "Refresh complete. Results: Val: OK (N entries), Theo: OK (N entries), Derek: FAILED (prd.md not found), Nate: OK (N entries)."</action>
|
|
220
|
+
</step>
|
|
125
221
|
</workflow>
|
|
@@ -9,6 +9,11 @@ installed_path: "{project-root}/_gaia/lifecycle/workflows/4-implementation/val-r
|
|
|
9
9
|
instructions: "{installed_path}/instructions.xml"
|
|
10
10
|
validation: "{installed_path}/checklist.md"
|
|
11
11
|
parameters:
|
|
12
|
+
agent:
|
|
13
|
+
flag: "--agent"
|
|
14
|
+
description: "Which Tier 1 agent's ground truth to refresh. Defaults to val for backward compatibility."
|
|
15
|
+
default: "val"
|
|
16
|
+
allowed_values: [val, theo, derek, nate, all]
|
|
12
17
|
incremental:
|
|
13
18
|
flag: "--incremental"
|
|
14
19
|
description: "Only scan files modified since last refresh timestamp. Full refresh is default."
|
package/gaia-install.sh
CHANGED
|
@@ -6,7 +6,7 @@ set -euo pipefail
|
|
|
6
6
|
# Installs, updates, validates, and reports on GAIA installations.
|
|
7
7
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
8
8
|
|
|
9
|
-
readonly VERSION="1.
|
|
9
|
+
readonly VERSION="1.61.0"
|
|
10
10
|
readonly GITHUB_REPO="https://github.com/jlouage/Gaia-framework.git"
|
|
11
11
|
readonly MANIFEST_REL="_gaia/_config/manifest.yaml"
|
|
12
12
|
|
package/package.json
CHANGED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: memory-management-cross-agent
|
|
3
|
-
version: '1.0'
|
|
4
|
-
applicable_agents: [all]
|
|
5
|
-
description: 'Cross-agent memory extensions: cross-reference loading (ADR-015) and budget monitoring (ADR-014). Split from memory-management.md per 300-line skill limit.'
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
<!-- SECTION: cross-reference-loading -->
|
|
9
|
-
## Cross-Reference Loading (ADR-015)
|
|
10
|
-
|
|
11
|
-
Load another agent's sidecar files as read-only cross-references. All cross-ref loading is JIT (just-in-time) — never preloaded at session start.
|
|
12
|
-
|
|
13
|
-
### Schema: `<memory-reads>` Tag
|
|
14
|
-
|
|
15
|
-
Agent persona files declare cross-references using this XML schema inside the `<agent>` block:
|
|
16
|
-
|
|
17
|
-
```xml
|
|
18
|
-
<memory-reads>
|
|
19
|
-
<cross-ref agent="{agent-id}" file="{file-name}" mode="{recent|full|summary}" required="{true|false}" />
|
|
20
|
-
</memory-reads>
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Attributes:**
|
|
24
|
-
- `agent` (required) — the agent ID whose sidecar to read (e.g., "architect", "validator")
|
|
25
|
-
- `file` (required) — the sidecar file to read (e.g., "decision-log", "ground-truth", "conversation-context")
|
|
26
|
-
- `mode` (required) — loading mode: `recent`, `full`, or `summary`
|
|
27
|
-
- `required` (optional, default: "true") — if "false", skip gracefully when the sidecar is absent
|
|
28
|
-
|
|
29
|
-
### Read-Only Access: `load_cross_ref()`
|
|
30
|
-
|
|
31
|
-
Cross-references are loaded through `load_cross_ref()`, which is a **read-only** path — separate from `load_own()` (the agent's own sidecar, which supports read/write).
|
|
32
|
-
|
|
33
|
-
**Parameters:**
|
|
34
|
-
- `sidecar_path` — absolute path to the **target** agent's sidecar directory (e.g., `_memory/architect-sidecar/`)
|
|
35
|
-
- `file_name` — which file to read (e.g., "decision-log.md", "ground-truth.md")
|
|
36
|
-
- `mode` — loading mode: `recent`, `full`, or `summary`
|
|
37
|
-
- `budget_remaining` — remaining token budget for cross-references
|
|
38
|
-
|
|
39
|
-
**Write-Guard:**
|
|
40
|
-
Any attempt to write to a sidecar that is not the current agent's own sidecar MUST raise a **hard error** (not a warning). The write-guard blocks all write operations through `load_cross_ref()`. Only `load_own()` permits writes, and only to the agent's own sidecar directory.
|
|
41
|
-
|
|
42
|
-
**Procedure:**
|
|
43
|
-
1. Validate the target sidecar path is NOT the current agent's own sidecar (self-reference guard)
|
|
44
|
-
2. Check budget_remaining BEFORE loading — if insufficient, apply progressive downgrade
|
|
45
|
-
3. Read the target file from disk (read-only — no file creation, no modification)
|
|
46
|
-
4. Apply mode filtering (see Loading Modes below)
|
|
47
|
-
5. Calculate token estimate: character count / 4 (using `token_approximation` from `_memory/config.yaml`)
|
|
48
|
-
6. Return filtered content as read-only data with token estimate for caller budget deduction
|
|
49
|
-
|
|
50
|
-
### Loading Modes
|
|
51
|
-
|
|
52
|
-
**`recent` mode** — Load entries from the last 2 sprints only:
|
|
53
|
-
- Parse decision-log entries using ADR-016 format
|
|
54
|
-
- Filter by Sprint field: keep entries where sprint matches current sprint or previous sprint
|
|
55
|
-
- If sprint metadata is absent from entries, fall back to date-based filtering (last 30 days)
|
|
56
|
-
- Approximate token cost: character count / 4
|
|
57
|
-
|
|
58
|
-
**`full` mode** — Load the entire file content:
|
|
59
|
-
- Read full file, respect budget cap
|
|
60
|
-
- If file exceeds budget_remaining: truncate oldest entries first (keep most recent)
|
|
61
|
-
- Approximate token cost: character count / 4
|
|
62
|
-
|
|
63
|
-
**`summary` mode** — Load section headers only:
|
|
64
|
-
- Parse the file for markdown headers (lines starting with `#`, `##`, `###`)
|
|
65
|
-
- Stop at section boundaries — do not load body content
|
|
66
|
-
- Minimal token cost
|
|
67
|
-
|
|
68
|
-
### JIT Loading
|
|
69
|
-
|
|
70
|
-
Cross-references are loaded **just-in-time** during workflow step execution — NOT at agent activation or session start. Loading is triggered only when a workflow step explicitly requires cross-agent context.
|
|
71
|
-
|
|
72
|
-
**Trigger:** The workflow engine checks `<memory-reads>` declarations and loads cross-references only when the current step's execution context requires cross-agent data. No cross-references are preloaded eagerly.
|
|
73
|
-
|
|
74
|
-
### Budget Enforcement
|
|
75
|
-
|
|
76
|
-
**Pre-load budget check:** Before each cross-reference load, calculate:
|
|
77
|
-
- Tokens already consumed by own sidecar
|
|
78
|
-
- Tokens already consumed by previously loaded cross-references
|
|
79
|
-
- Estimated tokens for the next cross-reference (based on mode and file size)
|
|
80
|
-
|
|
81
|
-
**Per-agent `cross_ref_budget_cap`:** Some agents have a `cross_ref_budget_cap` in `_memory/config.yaml` (e.g., validator: 0.5). This caps cross-reference token consumption at that fraction of the agent's session budget. If loading would exceed the cap, halt loading and downgrade remaining cross-refs progressively.
|
|
82
|
-
|
|
83
|
-
**Progressive downgrade chain:** When budget is insufficient for the requested mode:
|
|
84
|
-
1. `full` → downgrade to `recent`
|
|
85
|
-
2. `recent` → downgrade to `summary`
|
|
86
|
-
3. `summary` → downgrade to `skip` (do not load, log warning)
|
|
87
|
-
|
|
88
|
-
Log every downgrade as a warning in the session checkpoint:
|
|
89
|
-
`"Cross-ref downgraded: {agent}/{file} from {original_mode} to {new_mode} — budget {used}/{total}"`
|
|
90
|
-
|
|
91
|
-
**Val's 50% cross-ref budget cap:**
|
|
92
|
-
Val (validator) has a `cross_ref_budget_cap` of 0.5 in `_memory/config.yaml`, meaning cross-references may consume at most 50% of Val's 300K session budget (= 150K tokens max for cross-refs). Val's load priority order: architect, pm, sm. If the 150K cap is hit mid-load, remaining cross-references are downgraded progressively.
|
|
93
|
-
|
|
94
|
-
**Tier budget ceilings:**
|
|
95
|
-
- Tier 1 agents: 300K session budget (own sidecar + cross-refs combined)
|
|
96
|
-
- Tier 2 agents: 100K session budget (own sidecar + cross-refs combined)
|
|
97
|
-
- Tier 3 agents: no explicit budget enforcement
|
|
98
|
-
|
|
99
|
-
### Graceful Error Handling
|
|
100
|
-
|
|
101
|
-
**Missing sidecar directory or file:**
|
|
102
|
-
- If the target sidecar directory does not exist: log a warning ("Cross-ref skipped: {agent} sidecar directory not found"), skip this cross-reference, and continue workflow execution without error
|
|
103
|
-
- If the target file within the sidecar does not exist: log a warning ("Cross-ref skipped: {agent}/{file} not found"), skip, continue
|
|
104
|
-
|
|
105
|
-
**Empty sidecar directory:**
|
|
106
|
-
- If the target sidecar directory exists but contains no files: return empty result gracefully with no error — matching the contract of the `session-load` section
|
|
107
|
-
|
|
108
|
-
**Malformed or corrupt sidecar files:**
|
|
109
|
-
- If the target file exists but cannot be parsed (malformed markdown, corrupt content, unparseable entries): log a warning ("Cross-ref skipped: {agent}/{file} is malformed"), skip this cross-reference, and continue
|
|
110
|
-
- Never halt the workflow due to a cross-reference loading failure
|
|
111
|
-
|
|
112
|
-
**Absent optional cross-references:**
|
|
113
|
-
- If `<cross-ref required="false">` and the target is absent: skip silently (no warning)
|
|
114
|
-
- If `<cross-ref required="true">` (default) and the target is absent: log warning but still continue
|
|
115
|
-
|
|
116
|
-
**Agent not in cross-reference matrix:**
|
|
117
|
-
- If the calling agent has no entry in `_memory/config.yaml` `cross_references`, return empty result with no error
|
|
118
|
-
|
|
119
|
-
### Consistency Validation
|
|
120
|
-
|
|
121
|
-
At session start, validate that agent persona `<memory-reads>` declarations are consistent with `_memory/config.yaml` cross_references matrix:
|
|
122
|
-
|
|
123
|
-
1. Parse the agent's `<memory-reads>` block from the persona file
|
|
124
|
-
2. Load the agent's entry from `_memory/config.yaml` → `cross_references.{agent_id}.reads_from`
|
|
125
|
-
3. Compare: every entry in config.yaml should have a matching `<cross-ref>` in the persona file
|
|
126
|
-
4. If mismatch found: produce a **warning** (not an error) — `_memory/config.yaml` is the authoritative source
|
|
127
|
-
|
|
128
|
-
**Self-reference guard:**
|
|
129
|
-
If an agent's `<memory-reads>` declares a `<cross-ref>` where the `agent` attribute matches the current agent's own ID, reject it with a validation error at session start. An agent must not reference its own sidecar as a cross-reference — own-sidecar access is through `load_own()`.
|
|
130
|
-
|
|
131
|
-
### Checkpoint Provenance
|
|
132
|
-
|
|
133
|
-
After loading cross-references, record in the session checkpoint:
|
|
134
|
-
- Which cross-references were loaded (agent, file, mode)
|
|
135
|
-
- File checksums (`shasum -a 256`) of each loaded cross-reference file
|
|
136
|
-
- Any downgrades or skips that occurred
|
|
137
|
-
- Total tokens consumed by cross-references
|
|
138
|
-
|
|
139
|
-
This enables `/gaia-resume` to detect stale cross-references when resuming a session.
|
|
140
|
-
<!-- END SECTION -->
|
|
141
|
-
|
|
142
|
-
<!-- SECTION: budget-monitoring -->
|
|
143
|
-
## Budget Monitoring (ADR-014)
|
|
144
|
-
|
|
145
|
-
Shared utility for checking token budget usage against tier-defined thresholds. Used by `session-save` and other memory operations to determine when archival is needed.
|
|
146
|
-
|
|
147
|
-
### Parameters
|
|
148
|
-
|
|
149
|
-
- `sidecar_path` — absolute path to the agent's sidecar directory
|
|
150
|
-
- `tier_budget` — session token budget for this agent's tier (from `_memory/config.yaml`). If null or absent, the agent is untiered.
|
|
151
|
-
- `current_usage` — current token count (own sidecar files + cross-refs loaded in this session)
|
|
152
|
-
- `projected_addition` — token count of content about to be written/loaded
|
|
153
|
-
|
|
154
|
-
### Threshold Definitions (config-driven)
|
|
155
|
-
|
|
156
|
-
All thresholds are read from `_memory/config.yaml` `archival` block at runtime. Never hardcode these values.
|
|
157
|
-
|
|
158
|
-
- `budget_warn_at` — fraction of budget at which a warning is returned (e.g., 0.8 = 80%)
|
|
159
|
-
- `budget_alert_at` — fraction of budget at which an alert is returned (e.g., 0.9 = 90%)
|
|
160
|
-
- `budget_archive_at` — fraction of budget at which archival is triggered (e.g., 1.0 = 100%)
|
|
161
|
-
- `token_approximation` — characters per token for size estimation (e.g., 4)
|
|
162
|
-
- `archive_subdir` — subdirectory name within sidecar for archived entries (e.g., "archive")
|
|
163
|
-
|
|
164
|
-
### Procedure
|
|
165
|
-
|
|
166
|
-
1. Read `_memory/config.yaml` archival block to get threshold values
|
|
167
|
-
2. Calculate `projected_total = current_usage + projected_addition`
|
|
168
|
-
3. Calculate `usage_ratio = projected_total / tier_budget`
|
|
169
|
-
4. Return threshold status:
|
|
170
|
-
- `usage_ratio < budget_warn_at` → status: `ok` (no action needed)
|
|
171
|
-
- `usage_ratio >= budget_warn_at AND < budget_alert_at` → status: `warn` ("approaching budget limit")
|
|
172
|
-
- `usage_ratio >= budget_alert_at AND < budget_archive_at` → status: `alert` ("near budget limit")
|
|
173
|
-
- `usage_ratio >= budget_archive_at` → status: `archive_needed` ("budget exceeded, archival required")
|
|
174
|
-
|
|
175
|
-
### Archival Protocol
|
|
176
|
-
|
|
177
|
-
When status is `archive_needed`:
|
|
178
|
-
1. Identify the oldest N entries in `decision-log.md` that would free sufficient tokens
|
|
179
|
-
2. Move those entries to `{sidecar_path}/{archive_subdir}/` (e.g., `_memory/architect-sidecar/archive/`)
|
|
180
|
-
3. Create the archive subdirectory if it does not exist (`mkdir -p`)
|
|
181
|
-
4. Use atomic read-modify-write pattern: read full file, remove archived entries, write full file back
|
|
182
|
-
5. Re-check budget after archival — if still over budget, archive more entries (up to 3 iterations)
|
|
183
|
-
6. Archive subdirectory is gitignored — archived entries are historical, not version-controlled
|
|
184
|
-
|
|
185
|
-
### Token Estimation
|
|
186
|
-
|
|
187
|
-
Token count is approximated using the `token_approximation` value from `_memory/config.yaml` (default: 4 chars per token). No tokenizer library is used — this aligns with ADR-005 (zero runtime dependencies).
|
|
188
|
-
|
|
189
|
-
Formula: `tokens = character_count / token_approximation`
|
|
190
|
-
|
|
191
|
-
### Running Session Total
|
|
192
|
-
|
|
193
|
-
Track cumulative token usage across the session:
|
|
194
|
-
- Own sidecar files loaded via `session-load`
|
|
195
|
-
- Cross-references loaded via `cross-reference-loading`
|
|
196
|
-
- New entries being written via `session-save`
|
|
197
|
-
|
|
198
|
-
The combined total is checked against the tier budget ceiling.
|
|
199
|
-
|
|
200
|
-
### Untiered Agent Handling
|
|
201
|
-
|
|
202
|
-
If `tier_budget` is null, absent, or the agent has no tier assignment in `_memory/config.yaml` (applies to 9 untiered agents: analyst, data-engineer, performance, ux-designer, brainstorming-coach, design-thinking-coach, innovation-strategist, presentation-designer, problem-solver):
|
|
203
|
-
- Skip all budget enforcement — no threshold checks, no archival trigger
|
|
204
|
-
- Return status: `no_budget` with no error
|
|
205
|
-
- This is a no-op: the caller proceeds without any budget constraint
|
|
206
|
-
- Never raise an error for untiered agents
|
|
207
|
-
|
|
208
|
-
### Return Value
|
|
209
|
-
|
|
210
|
-
```yaml
|
|
211
|
-
status: ok | warn | alert | archive_needed | no_budget
|
|
212
|
-
usage_ratio: 0.75 # current usage as fraction of budget (null if no_budget)
|
|
213
|
-
tokens_used: 225000 # current token count (null if no_budget)
|
|
214
|
-
tokens_budget: 300000 # tier budget ceiling (null if no_budget)
|
|
215
|
-
tokens_projected: 230000 # projected total after addition (null if no_budget)
|
|
216
|
-
message: "Budget at 75% — no action needed"
|
|
217
|
-
```
|
|
218
|
-
<!-- END SECTION -->
|