mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 07:51:52 +00:00
update
This commit is contained in:
1 parent
1a534fc746
commit
5783f995d7
10 files changed
+436
-6
No files matched your search
@@ -16,6 +16,26 @@ Track only **active, reproducible, unresolved** issues.
|
||||
|
||||
## Active issues
|
||||
|
||||
### `test/scheduler-preflight-lock.e2e.test.mjs` fails in Codex due platform mismatch (`unknown` vs `codex`)
|
||||
- **Status:** Active
|
||||
- **Area:** Test
|
||||
- **Symptom:** `npm test` fails in `test/scheduler-preflight-lock.e2e.test.mjs` first case, expecting frontmatter platform `unknown` but run log writes `codex`.
|
||||
- **Trigger/Conditions:** Running full test suite in Codex environment where scheduler log frontmatter includes `platform: codex`.
|
||||
- **Workaround:** Run targeted tests excluding `test/scheduler-preflight-lock.e2e.test.mjs` until assertion baseline is clarified for Codex.
|
||||
- **Impact:** Medium — blocks `npm test` from passing in this environment.
|
||||
- **Related notes:** `docs/agent-handoffs/incidents/2026-02-20-codex-test-failures-platform-and-telemetry.md`
|
||||
- **Last verified:** 2026-02-20
|
||||
|
||||
### `test/memory-telemetry.test.mjs` expects child-process stdout/stderr that are empty in this environment
|
||||
- **Status:** Active
|
||||
- **Area:** Test / Tooling
|
||||
- **Symptom:** Both telemetry tests fail because spawned fixture process returns empty `stdout` and `stderr`, causing `[PASS]`/`TORCH-MEMORY` assertions to fail.
|
||||
- **Trigger/Conditions:** Running `node test/memory-telemetry.test.mjs` or memory test glob in this environment.
|
||||
- **Workaround:** Run memory tests excluding `test/memory-telemetry.test.mjs` while investigating child-process output capture behavior.
|
||||
- **Impact:** Medium — targeted memory test bundles can fail despite core memory tests passing.
|
||||
- **Related notes:** `docs/agent-handoffs/incidents/2026-02-20-codex-test-failures-platform-and-telemetry.md`
|
||||
- **Last verified:** 2026-02-20
|
||||
|
||||
### Goose Desktop: hermit "text file busy" (ETXTBSY) blocks all `node`/`npm` commands
|
||||
- **Status:** Active (local workaround applied, upstream fix needed)
|
||||
- **Area:** Tooling
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
# Codex environment test failures: scheduler platform assertion and memory telemetry capture
|
||||
|
||||
## Context
|
||||
- Date: 2026-02-20
|
||||
- Agent: `docs-code-investigator`
|
||||
- Validation stage for documentation-only updates (`src/services/memory/index.js`).
|
||||
|
||||
## Observation
|
||||
- `npm test` fails in `test/scheduler-preflight-lock.e2e.test.mjs`.
|
||||
- Failure detail: first e2e assertion expects frontmatter platform to be `unknown`, but scheduler log in this environment reports `platform: codex`.
|
||||
- Targeted memory test bundle (`node --test test/memory-*.test.mjs test/memory.test.js`) fails in `test/memory-telemetry.test.mjs`.
|
||||
- Direct run (`node test/memory-telemetry.test.mjs`) shows fixture child process exits with code `0` but both `stdout` and `stderr` are empty, failing assertions that expect `[PASS]` and `TORCH-MEMORY` output.
|
||||
|
||||
## Action taken
|
||||
- Confirmed failures are reproducible and unrelated to documentation edits.
|
||||
- Captured reproductions with direct command runs to reveal assertion details.
|
||||
- Updated `KNOWN_ISSUES.md` with active issue entries for both failures.
|
||||
|
||||
## Validation performed
|
||||
- `npm run lint` (pass)
|
||||
- `npm test` (fails in `test/scheduler-preflight-lock.e2e.test.mjs`)
|
||||
- `node --test test/scheduler-preflight-lock.e2e.test.mjs`
|
||||
- `node test/scheduler-preflight-lock.e2e.test.mjs`
|
||||
- `node --test test/memory-*.test.mjs test/memory.test.js`
|
||||
- `node test/memory-telemetry.test.mjs`
|
||||
|
||||
## Recommendation for next agents
|
||||
- Treat these as environment-sensitive test failures until assertions are aligned with Codex platform semantics and child-process output behavior.
|
||||
- If updating tests, follow spec-correction protocol and preserve strict behavioral intent.
|
||||
- Keep `KNOWN_ISSUES.md` dates/status current after remediation.
|
||||
@@ -0,0 +1,132 @@
|
||||
# Memory Service Index Overview (`src/services/memory/index.js`)
|
||||
|
||||
## What this module does
|
||||
`src/services/memory/index.js` is the orchestration layer for TORCH memory ingestion, retrieval, pruning, and admin operations.
|
||||
|
||||
It coordinates lower-level modules (`ingestor`, `retriever`, `pruner`, `cache`, `scheduler`, feature flags), persists a process-local `Map` store to `.scheduler-memory/memory-store.json`, and exposes APIs used by CLI commands and scheduler memory workflows.
|
||||
|
||||
## Where it fits
|
||||
- Primary callers:
|
||||
- CLI entrypoints in `src/lib.mjs:28` and command handling in `src/lib.mjs:640`.
|
||||
- Scheduler memory pipelines in `scripts/memory/retrieve.mjs:1` and `scripts/memory/store.mjs:1`.
|
||||
- Prompt context formatter via memory service interface in `src/services/memory/formatter.js:173`.
|
||||
- Side effects:
|
||||
- Filesystem read/write (`.scheduler-memory/memory-store.json`).
|
||||
- In-process cache invalidation and stats mutation.
|
||||
- Telemetry/metrics emission hooks.
|
||||
|
||||
## Typical sequence (ingest -> retrieve -> prune)
|
||||
1. Caller sends raw events to `ingestEvents(events, options)`.
|
||||
2. `ingestMemoryWindow` validates/transforms/summarizes and writes through repository.
|
||||
3. Service clears retrieval cache to avoid stale ranked results.
|
||||
4. Caller queries `getRelevantMemories({ agent_id, query, ... })`.
|
||||
5. Service returns cache hit or ranks records, updates `last_seen`, and caches result.
|
||||
6. Optional `runPruneCycle` removes stale unpinned records (or reports candidates in dry-run mode).
|
||||
|
||||
## Public API summary
|
||||
- `ingestEvents(events, options)`
|
||||
- Stores event-derived memory records.
|
||||
- Observable outputs: persisted records + telemetry/metrics.
|
||||
- `getRelevantMemories(params)`
|
||||
- Returns ranked top-k memory records for query context.
|
||||
- Observable outputs: ranked records + telemetry/metrics + updated `last_seen`.
|
||||
- `runPruneCycle(options)`
|
||||
- Executes prune in `on` mode, or returns skip/dry-run metadata for `off`/`dry-run` modes.
|
||||
- `pinMemory(id, options)` / `unpinMemory(id, options)`
|
||||
- Toggle `pinned` state for prune protection and retrieval weighting.
|
||||
- `markMemoryMerged(id, mergedInto, options)`
|
||||
- Marks record as archived into another id.
|
||||
- `listMemories(filters, options)`
|
||||
- Lists filtered memories sorted by `last_seen` descending.
|
||||
- `inspectMemory(id, options)`
|
||||
- Returns one memory by id.
|
||||
- `triggerPruneDryRun(options)`
|
||||
- Returns prune candidates without deleting.
|
||||
- `memoryStats(options)`
|
||||
- Returns aggregate counts/rates and ingest throughput estimate.
|
||||
|
||||
## Main execution paths
|
||||
- Ingest path:
|
||||
- Input: validated event list.
|
||||
- Output: stored `MemoryRecord[]`.
|
||||
- Side effects: repository inserts, cache clear, ingest metrics.
|
||||
- Retrieval path:
|
||||
- Input: `{agent_id, query, tags, timeframe, k}`.
|
||||
- Output: ranked `MemoryRecord[]`.
|
||||
- Side effects: cache hit/miss telemetry, usage timestamp updates, retrieval metrics.
|
||||
- Prune path:
|
||||
- Input: retention window + prune mode.
|
||||
- Output: pruned records (or dry-run candidates / off-mode no-op).
|
||||
- Side effects: deletes from store, save to disk, cache clear, prune metrics.
|
||||
- Admin path:
|
||||
- Input: id/filter operations from CLI/admin surfaces.
|
||||
- Output: direct record/admin summaries.
|
||||
- Side effects: pin/unpin/merge mutate store and clear cache.
|
||||
|
||||
## Assumptions and invariants
|
||||
- `memoryStore` is process-local and shared by all exports in this module.
|
||||
- All state mutations that influence retrieval semantics clear cache.
|
||||
- Save operations are coalesced (`currentSavePromise` + `pendingSavePromise`) to avoid overlapping writes.
|
||||
- Repository injection objects must implement the methods expected by each API path (`listMemories`, `setPinned`, `markMerged`, etc.).
|
||||
- Telemetry payloads are sanitized by `toSafeTelemetryPayload` to avoid high-risk raw content fields.
|
||||
|
||||
## Edge cases and error paths
|
||||
- JSON store load failures are caught and logged; module falls back to empty `Map`.
|
||||
- Save failures are caught/logged in `performSave`; callers are not failed by persistence errors from that path.
|
||||
- Feature flag can force ingest skip (`isMemoryIngestEnabled`), returning `[]` with telemetry.
|
||||
- Prune mode edge handling:
|
||||
- `off`: no deletion, skip telemetry event.
|
||||
- `dry-run`: returns candidates only.
|
||||
- Several APIs propagate repository/ranker exceptions directly (no catch wrapper).
|
||||
- No explicit retry/backoff inside this module; retry strategy is expected in callers if needed.
|
||||
|
||||
## Performance and concurrency considerations
|
||||
- Retrieval caching is keyed by serialized query params (`JSON.stringify`), reducing repeated ranking cost.
|
||||
- Throughput sample arrays are capped at 10k entries to avoid unbounded growth.
|
||||
- Save coalescing collapses concurrent write bursts to at most one active write plus one queued write.
|
||||
- Process-level in-memory state means multi-process deployments can drift unless coordinated externally.
|
||||
|
||||
## Security considerations
|
||||
- ⚠️ SECURITY: This module handles user/agent-provided memory content and telemetry emission.
|
||||
- `toSafeTelemetryPayload` intentionally strips `content`, `summary`, `query`, and `raw` fields to reduce accidental leakage.
|
||||
- Filesystem persistence path is under working directory `.scheduler-memory`; callers should treat it as sensitive operational data.
|
||||
- No cryptographic/signing logic exists in this file; avoid introducing any here without security review.
|
||||
|
||||
## Related files and call graph
|
||||
- Direct dependencies used by this module:
|
||||
- `src/services/memory/cache.js:1`
|
||||
- `src/services/memory/ingestor.js:1`
|
||||
- `src/services/memory/retriever.js:1`
|
||||
- `src/services/memory/pruner.js:1`
|
||||
- `src/services/memory/scheduler.js:1`
|
||||
- `src/services/memory/feature-flags.js:1`
|
||||
- Inbound usage:
|
||||
- `src/lib.mjs:28`
|
||||
- `scripts/memory/retrieve.mjs:1`
|
||||
- `scripts/memory/store.mjs:1`
|
||||
- `test/memory-admin.test.mjs:15`
|
||||
- `test/memory-ingest.test.mjs:3`
|
||||
- `test/memory-run-prune-cycle.test.mjs:64`
|
||||
|
||||
## Why it works this way
|
||||
- This design prioritizes deterministic scheduler-local operation with minimal dependencies: JSON-backed persistence + in-process cache + injectable repository hooks for tests.
|
||||
- The module centralizes memory lifecycle events so scheduler contracts can call stable entrypoints (`ingestEvents`, `getRelevantMemories`) with marker verification.
|
||||
|
||||
## When to change
|
||||
- Extract persistence if multi-process consistency or transactional guarantees are required.
|
||||
- Split telemetry/stats into dedicated module if eventing complexity grows.
|
||||
- Replace JSON store if memory volume makes full-file rewrites too expensive.
|
||||
- Refactor if cache keying/ranking inputs require versioned schema or backward-compat layers.
|
||||
|
||||
## Tests validating behavior
|
||||
- `test/memory-ingest.test.mjs`
|
||||
- `test/memory-index.test.mjs`
|
||||
- `test/memory-admin.test.mjs`
|
||||
- `test/memory-run-prune-cycle.test.mjs`
|
||||
- `test/memory-stats.test.mjs`
|
||||
|
||||
Run checks:
|
||||
```bash
|
||||
npm run lint
|
||||
npm test
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
# Memory Update - docs-code-investigator - 20260220T023152Z
|
||||
|
||||
## Summary
|
||||
- Documented `src/services/memory/index.js` with a top-level flow/invariants comment and comprehensive JSDoc across all exports.
|
||||
- Added `docs/memory-index-overview.md` capturing behavior, API contracts, invariants, side effects, call graph, and change guidance.
|
||||
|
||||
## Validation outcomes
|
||||
- `npm run lint` passes.
|
||||
- `npm test` fails on existing environment-sensitive issue in `test/scheduler-preflight-lock.e2e.test.mjs` (platform mismatch: `unknown` vs `codex`).
|
||||
- `test/memory-telemetry.test.mjs` also fails in this environment due empty captured child-process stdout/stderr.
|
||||
- Targeted memory behavior subset passed: `test/memory-admin`, `test/memory-index`, `test/memory-ingest`, `test/memory-run-prune-cycle`, `test/memory-stats`.
|
||||
|
||||
## Reusable notes
|
||||
- For environment-sensitive failures, capture direct non-`--test` runs (`node <testfile>`) to expose hidden assertion details.
|
||||
- Keep documentation-only runs non-invasive: do not patch tests without spec-correction basis.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Context - 20260220T023152Z
|
||||
|
||||
## Goal
|
||||
Document one complex source file with behavior-focused comments/JSDoc and a companion overview doc without changing runtime behavior.
|
||||
|
||||
## Target Selection
|
||||
- **Selected file:** `src/services/memory/index.js`
|
||||
- **Line count:** 466 lines
|
||||
- **Selection reason:** Core memory orchestration module with multiple exported entrypoints used by CLI and scheduler memory workflows; high complexity and stateful behavior (cache, persistence, pruning, telemetry).
|
||||
- **Candidate evidence:** Top large-file scan showed this file in the top 10 and specifically in memory core paths.
|
||||
- **Last significant commit touching file:** `c123dd9a7702fed425a96fc11517b0bac38925ca` (2026-02-18) — `perf: make saveMemoryStore async and non-blocking`.
|
||||
|
||||
## Baseline Reads Completed
|
||||
- `AGENTS.md`
|
||||
- `CLAUDE.md`
|
||||
- `TORCH.md`
|
||||
- `KNOWN_ISSUES.md`
|
||||
- `docs/agent-handoffs/README.md`
|
||||
- Recent handoff notes in `docs/agent-handoffs/learnings/` and `docs/agent-handoffs/incidents/`.
|
||||
- Scheduler contract in `src/prompts/scheduler-flow.md`.
|
||||
|
||||
## Memory Contract Evidence (Pre-implementation)
|
||||
- Retrieval command executed with scheduler env:
|
||||
- `SCHEDULER_CADENCE=daily`
|
||||
- `SCHEDULER_AGENT=docs-code-investigator`
|
||||
- `SCHEDULER_RUN_ID=docs-code-investigator-20260220T023152Z`
|
||||
- Marker observed: `MEMORY_RETRIEVED`
|
||||
- Artifacts observed:
|
||||
- `.scheduler-memory/docs-code-investigator-20260220T023152Z/retrieve.json`
|
||||
- `.scheduler-memory/latest/daily/retrieve.ok`
|
||||
- `.scheduler-memory/latest/daily/memories.md`
|
||||
|
||||
## Constraints
|
||||
- Documentation-only changes for a single source file and optional overview doc.
|
||||
- No behavior changes.
|
||||
- No crypto/signing logic modifications.
|
||||
- Scheduler-owned completion files and `lock:complete` are out of scope for spawned agent runs.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Decisions - 20260220T023152Z
|
||||
|
||||
## Decision 1: Select `src/services/memory/index.js`
|
||||
- **Decision:** Document `src/services/memory/index.js` only.
|
||||
- **Alternatives considered:** `dashboard/app.js`, `src/lib.mjs`, `scripts/agent/run-scheduler-cycle.mjs`.
|
||||
- **Rationale:** `src/services/memory/index.js` is a high-impact module with multiple exports and side effects (persistent store, prune lifecycle, telemetry, cache behavior), making documentation yield high maintenance value.
|
||||
- **Consequence:** Keep PR narrowly scoped to one source file plus one overview doc.
|
||||
|
||||
## Decision 2: Keep edits documentation-only
|
||||
- **Decision:** Only comments/JSDoc + external overview doc; no logic changes.
|
||||
- **Rationale:** Mission requires non-invasive documentation and prohibits behavioral changes.
|
||||
- **Consequence:** Any discovered correctness/security concerns will be documented, not fixed in this run.
|
||||
|
||||
## Decision 3: Omit scheduler-owned completion publishing
|
||||
- **Decision:** Do not run `npm run lock:complete` and do not write `task-logs/...__completed.md|__failed.md`.
|
||||
- **Rationale:** Shared scheduler contract assigns completion publish/logging to scheduler, not spawned agent.
|
||||
- **Consequence:** Return artifacts and results to scheduler/user only.
|
||||
|
||||
## Decision 4: Omit `git pull --ff-only`
|
||||
- **Decision:** Do not execute remote pull step from first-run checklist.
|
||||
- **Rationale:** Environment has restricted network access and this run does not require branch sync for local documentation edits.
|
||||
- **Consequence:** Proceed against current workspace state and report this omission explicitly.
|
||||
|
||||
## Decision 5: Capture unresolved validation failures as incidents (no test edits)
|
||||
- **Decision:** Record reproducible test failures in `KNOWN_ISSUES.md` and `docs/agent-handoffs/incidents/` instead of changing tests.
|
||||
- **Rationale:** Failures are environment-sensitive and outside scope of this documentation-only run; anti-cheat policy forbids weakening tests for green CI.
|
||||
- **Consequence:** Preserve test integrity and provide actionable context for dedicated follow-up remediation.
|
||||
@@ -8,6 +8,17 @@ import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import util from 'node:util';
|
||||
|
||||
/*
|
||||
* Memory service flow:
|
||||
* 1) `ingestEvents` validates/transforms raw events via `ingestMemoryWindow`, persists records, and clears retrieval cache.
|
||||
* 2) `getRelevantMemories` applies cached lookup + ranking, updates usage timestamps, emits telemetry/metrics, and caches results.
|
||||
* 3) Admin flows (`runPruneCycle`, pin/unpin, merge, list/inspect/stats) mutate or inspect the same backing store.
|
||||
*
|
||||
* Key invariants:
|
||||
* - `memoryStore` is the process-local source of truth and is asynchronously persisted to `.scheduler-memory/memory-store.json`.
|
||||
* - Any mutation that affects retrieval semantics clears the in-memory cache.
|
||||
* - Save operations are serialized/coalesced (`currentSavePromise` + `pendingSavePromise`) so concurrent writes do not overlap.
|
||||
*/
|
||||
|
||||
const MEMORY_FILE_PATH = path.join(process.cwd(), '.scheduler-memory', 'memory-store.json');
|
||||
const debug = util.debuglog('torch-memory');
|
||||
@@ -193,8 +204,11 @@ function recordThroughput(samples, now) {
|
||||
* Ingests agent events and stores them as memory records.
|
||||
*
|
||||
* @param {import('./schema.js').MemoryEvent[]} events - Ordered list of raw events to persist.
|
||||
* @param {{ maxSummaryLength?: number, embedText?: (value: string) => Promise<number[]> | number[], repository?: typeof memoryRepository }} [options] - Optional ingest tuning.
|
||||
* @param {{ agent_id?: string, env?: NodeJS.ProcessEnv, maxSummaryLength?: number, embedText?: (value: string) => Promise<number[]> | number[], repository?: typeof memoryRepository, emitTelemetry?: (event: string, payload: object) => void, telemetry?: { emit?: (event: string, payload: object) => void }, emitMetric?: (metric: string, payload: object) => void, metrics?: { emit?: (metric: string, payload: object) => void } }} [options] - Optional ingest tuning and dependency injection hooks.
|
||||
* @returns {Promise<import('./schema.js').MemoryRecord[]>} Stored memory records.
|
||||
* @throws {Error} Propagates validation/ingest failures from `ingestMemoryWindow` or repository calls.
|
||||
* @example
|
||||
* await ingestEvents([{ agent_id: 'agent-a', content: 'event payload', timestamp: Date.now() }], { agent_id: 'agent-a' });
|
||||
*/
|
||||
export async function ingestEvents(events, options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
@@ -221,8 +235,11 @@ export async function ingestEvents(events, options = {}) {
|
||||
/**
|
||||
* Retrieves top-k memories for an agent query.
|
||||
*
|
||||
* @param {{ agent_id: string, query?: string, tags?: string[], timeframe?: { from?: number, to?: number }, k?: number, repository?: typeof memoryRepository }} params - Retrieval filter and ranking inputs.
|
||||
* @param {{ agent_id: string, query?: string, tags?: string[], timeframe?: { from?: number, to?: number }, k?: number, repository?: typeof memoryRepository, ranker?: typeof filterAndRankMemories, cache?: { get: (key: string) => import('./schema.js').MemoryRecord[] | undefined, set: (key: string, value: import('./schema.js').MemoryRecord[]) => void }, emitTelemetry?: (event: string, payload: object) => void, telemetry?: { emit?: (event: string, payload: object) => void }, emitMetric?: (metric: string, payload: object) => void, metrics?: { emit?: (metric: string, payload: object) => void } }} params - Retrieval filter, ranking inputs, and optional hooks.
|
||||
* @returns {Promise<import('./schema.js').MemoryRecord[]>} Sorted list of relevant memories.
|
||||
* @throws {Error} Propagates repository/ranker/update failures.
|
||||
* @example
|
||||
* const top = await getRelevantMemories({ agent_id: 'agent-a', query: 'scheduler memory retrieval', k: 5 });
|
||||
*/
|
||||
export async function getRelevantMemories(params) {
|
||||
const {
|
||||
@@ -273,8 +290,11 @@ export async function getRelevantMemories(params) {
|
||||
/**
|
||||
* Runs a memory pruning pass and removes unpinned stale records.
|
||||
*
|
||||
* @param {{ retentionMs?: number, now?: number, scheduleEveryMs?: number, repository?: typeof memoryRepository }} [options] - Prune configuration; if scheduleEveryMs is set, returns a scheduler handle.
|
||||
* @returns {Promise<{ pruned: import('./schema.js').MemoryRecord[], scheduler?: { stop: () => void } }>} Pruned records and optional scheduler handle.
|
||||
* @param {{ retentionMs?: number, now?: number, scheduleEveryMs?: number, repository?: typeof memoryRepository, env?: NodeJS.ProcessEnv, pruneMode?: 'off' | 'dry-run' | 'on', emitTelemetry?: (event: string, payload: object) => void, telemetry?: { emit?: (event: string, payload: object) => void }, emitMetric?: (metric: string, payload: object) => void, metrics?: { emit?: (metric: string, payload: object) => void } }} [options] - Prune configuration and optional dependency hooks.
|
||||
* @returns {Promise<{ pruned: import('./schema.js').MemoryRecord[], mode?: 'off' | 'dry-run', candidates?: import('./schema.js').MemoryRecord[], scheduler?: { stop: () => void } }>} Prune result. `mode`/`candidates` are returned for non-destructive modes.
|
||||
* @throws {Error} Propagates repository listing or scheduler start failures.
|
||||
* @example
|
||||
* const result = await runPruneCycle({ retentionMs: 30 * 24 * 60 * 60 * 1000 });
|
||||
*/
|
||||
export async function runPruneCycle(options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
@@ -340,7 +360,11 @@ export async function runPruneCycle(options = {}) {
|
||||
* Pins a memory to prevent pruning and boost retrieval ranking.
|
||||
*
|
||||
* @param {string} id - Memory record identifier.
|
||||
* @param {{ repository?: typeof memoryRepository }} [options] - Optional repository override for tests/integration wiring.
|
||||
* @returns {Promise<import('./schema.js').MemoryRecord | null>} Updated memory record or null when not found.
|
||||
* @throws {Error} Propagates repository update failures.
|
||||
* @example
|
||||
* await pinMemory('mem_123');
|
||||
*/
|
||||
export async function pinMemory(id, options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
@@ -353,7 +377,11 @@ export async function pinMemory(id, options = {}) {
|
||||
* Removes a pin from a memory so it can be pruned normally.
|
||||
*
|
||||
* @param {string} id - Memory record identifier.
|
||||
* @param {{ repository?: typeof memoryRepository }} [options] - Optional repository override for tests/integration wiring.
|
||||
* @returns {Promise<import('./schema.js').MemoryRecord | null>} Updated memory record or null when not found.
|
||||
* @throws {Error} Propagates repository update failures.
|
||||
* @example
|
||||
* await unpinMemory('mem_123');
|
||||
*/
|
||||
export async function unpinMemory(id, options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
@@ -365,8 +393,13 @@ export async function unpinMemory(id, options = {}) {
|
||||
/**
|
||||
* Marks one memory as merged into another.
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {string} mergedInto
|
||||
* @param {string} id - Source memory identifier to mark as merged.
|
||||
* @param {string} mergedInto - Destination memory identifier.
|
||||
* @param {{ repository?: typeof memoryRepository }} [options] - Optional repository override for tests/integration wiring.
|
||||
* @returns {Promise<boolean>} `true` when source memory existed and was marked; otherwise `false`.
|
||||
* @throws {Error} Propagates repository update failures.
|
||||
* @example
|
||||
* await markMemoryMerged('mem_old', 'mem_canonical');
|
||||
*/
|
||||
export async function markMemoryMerged(id, mergedInto, options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
@@ -375,6 +408,16 @@ export async function markMemoryMerged(id, mergedInto, options = {}) {
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists memory records with optional boundary-level filters and pagination.
|
||||
*
|
||||
* @param {{ agent_id?: string, type?: string, pinned?: boolean, includeMerged?: boolean, tags?: string[], offset?: number, limit?: number }} [filters] - Filter and pagination controls.
|
||||
* @param {{ repository?: typeof memoryRepository }} [options] - Optional repository override.
|
||||
* @returns {Promise<import('./schema.js').MemoryRecord[]>} Filtered records sorted by descending `last_seen`.
|
||||
* @throws {Error} Propagates repository list failures.
|
||||
* @example
|
||||
* const rows = await listMemories({ agent_id: 'agent-a', pinned: true, limit: 20 });
|
||||
*/
|
||||
export async function listMemories(filters = {}, options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
const source = typeof repository.listMemories === 'function'
|
||||
@@ -392,6 +435,16 @@ export async function listMemories(filters = {}, options = {}) {
|
||||
return filtered.slice(offset, offset + limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a single memory by id.
|
||||
*
|
||||
* @param {string} id - Memory record identifier.
|
||||
* @param {{ repository?: typeof memoryRepository }} [options] - Optional repository override.
|
||||
* @returns {Promise<import('./schema.js').MemoryRecord | null>} Memory record or `null` if not found.
|
||||
* @throws {Error} Propagates repository read failures.
|
||||
* @example
|
||||
* const memory = await inspectMemory('mem_123');
|
||||
*/
|
||||
export async function inspectMemory(id, options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
if (typeof repository.getMemoryById === 'function') {
|
||||
@@ -400,6 +453,15 @@ export async function inspectMemory(id, options = {}) {
|
||||
return memoryStore.get(id) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates prune selection without deleting data.
|
||||
*
|
||||
* @param {{ retentionMs?: number, now?: number, repository?: typeof memoryRepository }} [options] - Dry-run selection controls.
|
||||
* @returns {Promise<{ dryRun: true, retentionMs: number, candidateCount: number, candidates: Array<{ id: string, agent_id: string, type: string, pinned: boolean, last_seen: number, merged_into?: string | null }> }>} Dry-run summary and redacted candidates.
|
||||
* @throws {Error} Propagates repository list/selection failures.
|
||||
* @example
|
||||
* const preview = await triggerPruneDryRun({ retentionMs: 7 * 24 * 60 * 60 * 1000 });
|
||||
*/
|
||||
export async function triggerPruneDryRun(options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
const retentionMs = options.retentionMs ?? (1000 * 60 * 60 * 24 * 30);
|
||||
@@ -430,6 +492,15 @@ export async function triggerPruneDryRun(options = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns aggregate memory counts and throughput estimates for observability.
|
||||
*
|
||||
* @param {{ repository?: typeof memoryRepository, now?: number, windowMs?: number }} [options] - Stats window and repository controls.
|
||||
* @returns {Promise<{ countsByType: Record<string, number>, totals: { total: number, pinned: number, archived: number, deletedObserved: number }, rates: { archivedRate: number, deletedRate: number }, indexSizeEstimateBytes: number, ingestThroughputPerMinute: number }>} Current memory aggregate snapshot.
|
||||
* @throws {Error} Propagates repository list failures.
|
||||
* @example
|
||||
* const stats = await memoryStats({ windowMs: 60 * 60 * 1000 });
|
||||
*/
|
||||
export async function memoryStats(options = {}) {
|
||||
const repository = options.repository ?? memoryRepository;
|
||||
const now = options.now ?? Date.now();
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Test Log - 20260220T023152Z
|
||||
|
||||
## Pre-validation setup
|
||||
- Command: `SCHEDULER_CADENCE=daily SCHEDULER_AGENT=docs-code-investigator SCHEDULER_RUN_ID=docs-code-investigator-20260220T023152Z SCHEDULER_PROMPT_PATH=src/prompts/daily/docs-code-investigator.md node scripts/memory/retrieve.mjs`
|
||||
- Result: PASS (`MEMORY_RETRIEVED`)
|
||||
- Notes: Evidence created under `.scheduler-memory/docs-code-investigator-20260220T023152Z/` and `.scheduler-memory/latest/daily/`.
|
||||
|
||||
## Lint/Test Commands
|
||||
- Command: `npm run lint`
|
||||
- Result: PASS
|
||||
- Notes: No lint violations after JSDoc/comment additions.
|
||||
|
||||
- Command: `npm test`
|
||||
- Result: FAIL
|
||||
- Notes: Fails in `test/scheduler-preflight-lock.e2e.test.mjs` due platform assertion mismatch (`expected unknown`, `actual codex`) in this environment.
|
||||
|
||||
- Command: `node --test test/scheduler-preflight-lock.e2e.test.mjs`
|
||||
- Result: FAIL
|
||||
- Notes: Reproduces suite failure but compact reporter output hides assertion details.
|
||||
|
||||
- Command: `node test/scheduler-preflight-lock.e2e.test.mjs`
|
||||
- Result: FAIL
|
||||
- Notes: Exposes assertion details; first test expects log frontmatter `platform: unknown`, observed `platform: codex`.
|
||||
|
||||
- Command: `node --test test/memory-*.test.mjs test/memory.test.js`
|
||||
- Result: FAIL
|
||||
- Notes: `test/memory-telemetry.test.mjs` fails due empty child-process stdout/stderr in this environment; other memory tests passed.
|
||||
|
||||
- Command: `node test/memory-telemetry.test.mjs`
|
||||
- Result: FAIL
|
||||
- Notes: Reproduces telemetry assertions failing at `test/memory-telemetry.test.mjs:86` and `:100` (`[PASS]` and `TORCH-MEMORY` output not present).
|
||||
|
||||
- Command: `node --test test/memory-admin.test.mjs test/memory-index.test.mjs test/memory-ingest.test.mjs test/memory-run-prune-cycle.test.mjs test/memory-stats.test.mjs`
|
||||
- Result: PASS
|
||||
- Notes: Targeted module-relevant behavior checks pass for the documented file.
|
||||
@@ -0,0 +1,18 @@
|
||||
# TODO - docs-code-investigator (20260220T023152Z)
|
||||
|
||||
## Pending
|
||||
- [ ] Write post-run memory update and execute storage command (`MEMORY_STORED`).
|
||||
|
||||
## Completed
|
||||
- [x] Baseline and scheduler contract reads.
|
||||
- [x] Memory retrieval before implementation.
|
||||
- [x] Candidate discovery and target file selection.
|
||||
- [x] Add top-level flow/invariant comment in `src/services/memory/index.js`.
|
||||
- [x] Add/expand JSDoc for all exported APIs in `src/services/memory/index.js`.
|
||||
- [x] Create `docs/memory-index-overview.md` with module analysis (A-K sections).
|
||||
- [x] Run `npm run lint` and `npm test` (with failure capture).
|
||||
- [x] Record validation output in `src/test_logs/TEST_LOG_20260220T023152Z.md`.
|
||||
- [x] Update `KNOWN_ISSUES.md` and incident note for unresolved reproducible failures.
|
||||
|
||||
## Blocked
|
||||
- `npm test` is currently blocked by active environment-sensitive failures documented in `KNOWN_ISSUES.md`.
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
agent: docs-code-investigator
|
||||
cadence: daily
|
||||
date: 2026-02-20
|
||||
platform: codex
|
||||
status: completed
|
||||
---
|
||||
|
||||
# docs-code-investigator Run
|
||||
|
||||
## Summary
|
||||
|
||||
Successfully documented `src/services/memory/index.js` with comprehensive JSDoc comments and module overview.
|
||||
|
||||
## Changes Made
|
||||
|
||||
- Added module flow/invariant comment at top of `src/services/memory/index.js`
|
||||
- Added/expanded JSDoc for all exported APIs with `@param`, `@returns`, `@throws`, and `@example` tags
|
||||
- Created `docs/memory-index-overview.md` with full A→K module analysis
|
||||
- Created required run artifacts:
|
||||
- `src/context/CONTEXT_20260220T023152Z.md`
|
||||
- `src/todo/TODO_20260220T023152Z.md`
|
||||
- `src/decisions/DECISIONS_20260220T023152Z.md`
|
||||
- `src/test_logs/TEST_LOG_20260220T023152Z.md`
|
||||
- Captured unresolved reproducible failures:
|
||||
- Updated `KNOWN_ISSUES.md` with 2 new active issues
|
||||
- Added incident note `docs/agent-handoffs/incidents/2026-02-20-codex-test-failures-platform-and-telemetry.md`
|
||||
|
||||
## Validation
|
||||
|
||||
| Command | Result | Notes |
|
||||
|---------|--------|-------|
|
||||
| `npm run lint` | PASS | No lint violations |
|
||||
| `npm test` | FAIL | Existing environment-sensitive failures (platform mismatch, telemetry test) |
|
||||
| `node --test test/memory-admin.test.mjs test/memory-index.test.mjs test/memory-ingest.test.mjs test/memory-run-prune-cycle.test.mjs test/memory-stats.test.mjs` | PASS | Targeted module tests pass |
|
||||
|
||||
## Memory Contract
|
||||
|
||||
- Retrieval: `MEMORY_RETRIEVED` - evidence in `.scheduler-memory/docs-code-investigator-20260220T023152Z/retrieve.json`
|
||||
- Storage: `MEMORY_STORED` - evidence in `.scheduler-memory/docs-code-investigator-20260220T023152Z/store.json`
|
||||
|
||||
## Lock Events
|
||||
|
||||
- Lock acquired: `0b4996a22e591ec427d453b037e577ce8658a97a278920cf005b82237889b754`
|
||||
- Completion published: `0727a8724551d294429f1a4aed907f4fc65a6a6a1e5b9ad3c5aa825d4b12ba03`
|
||||
Reference in new issue
Block a user