Skip to content

Commit 809292a

Browse files
feat(v0.4.0): promoteFromMemory, search cache, REINDEX endpoint, capabilities, docs sync
- Add promoteFromMemory endpoint: memory records can be promoted to draft knowledge documents with auto-generated backlinks - Add knowledge search cache: in-memory LRU cache (200 entries, 5min TTL) reduces repeated FTS overhead - Add REINDEX maintenance endpoint: POST .../knowledge/maintenance/rebuild-index for pgvector HNSW index rebuilds - Add capabilities endpoint: GET .../memory/bindings/:bindingId/capabilities returns resolved capabilities - Docs: update memory.md (extraction jobs API), releases.md (RC-4), README.md, assessments, release notes VOY-1322
1 parent 77bc452 commit 809292a

15 files changed

Lines changed: 419 additions & 16 deletions

File tree

docs/api/memory.md

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Memory API
33
summary: Agent memory API — pgvector-based bindings, config, capture, query, and records
44
version: v0.4.0-alpha
5-
last_updated: 2026-08-16
5+
last_updated: 2026-08-17
66
---
77

88
# Memory API
@@ -244,6 +244,45 @@ Lists recent memory operations for audit purposes.
244244

245245
**Auth**: Board only.
246246

247+
### Memory Extraction Jobs
248+
249+
#### List Extraction Jobs
250+
251+
```text
252+
GET /companies/{companyId}/memory/extraction-jobs?status=&limit=50
253+
```
254+
255+
| Query Param | Type | Description |
256+
|---|---|---|
257+
| `status` | string | Optional filter: `queued`, `in_progress`, `succeeded`, `failed` |
258+
| `limit` | integer | Max results (default: 50, max: 200) |
259+
260+
Returns memory extraction jobs for the company, newest first. Extraction jobs record background memory-extraction work (e.g., agent runs extracting findings into memory).
261+
262+
**Auth**: Board only.
263+
264+
#### Get Extraction Job
265+
266+
```text
267+
GET /companies/{companyId}/memory/extraction-jobs/{jobId}
268+
```
269+
270+
Returns a single extraction job by ID, scoped to the company.
271+
272+
**Auth**: Board only.
273+
274+
#### Retry Failed Extraction Job
275+
276+
```text
277+
POST /companies/{companyId}/memory/extraction-jobs/{jobId}/retry
278+
```
279+
280+
Resets a `failed` extraction job back to `queued`, clearing the error message and timing fields. Only jobs with `status: "failed"` can be retried. If the job's status has already changed from `failed` (e.g., another retry won the race), a `400 Bad Request` is returned with a clear message.
281+
282+
Returns the updated extraction job response.
283+
284+
**Auth**: Board only.
285+
247286
## Agent Scope Enforcement
248287

249288
When an agent authenticates:

docs/releases.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Paperclip ships continuously. This page documents each release to the main branc
1111

1212
---
1313

14-
## v0.4.0-alpha (RC-3) — August 16, 2026
14+
## v0.4.0-alpha (RC-4) — August 17, 2026
1515

1616
[Full release notes →](/support/releases/v0.4.0-alpha-deep-planning)
1717

@@ -33,6 +33,12 @@ Paperclip ships continuously. This page documents each release to the main branc
3333

3434
- **Manager-Chain Issue Permissions** — Managers can now comment on and mutate issues assigned to agents in their reporting subtree, so leadership can close, reassign, and unblock their team's work.
3535

36+
- **C-Fixes** — Zod validation of LLM action signals (C-1), a TOCTOU safety net preventing duplicate SLA alerts (C-2), and special-character-safe knowledge search via `plainto_tsquery` (C-3).
37+
38+
- **Memory Extraction Jobs** — New API and UI for monitoring background memory extraction jobs, with one-click retry of failed jobs.
39+
40+
- **Batch Gate Counts + Live Events** — Plan cards now show active gate counts, and plan gate creation/resolution events stream to the UI in real time.
41+
3642
[Full release notes →](/support/releases/v0.4.0-alpha-deep-planning)
3743

3844
---

docs/support/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ This directory contains support case assessments for Paperclip features. Each do
1111

1212
| Feature | Version | Shipped | Assessment |
1313
|---|---|---|---|
14+
| C-Fixes: Zod action validation (C-1), SLA dedup safety net (C-2), search safety (C-3) | v0.4.0 | Pre-release (committed `75c6c27a41`) | [Chat-to-work](assessments/support-case-v0.4.0-chat-to-work-resolution.md) + [KB search](kb/search-safety-plainto-tsquery.md) + [KB dedup](kb/sla-monitor-dedup-safety-net.md) |
15+
| Memory Extraction Jobs + Gate Counts + Live Events | v0.4.0 | Pre-release (committed `466c30fde7`) | [Memory & Knowledge](assessments/support-case-v0.4.0-memory-knowledge.md) + [Memory API](/docs/api/memory) |
1416
| Knowledge Browser UI + Manager-Chain Permissions (RC-3) | v0.4.0-alpha-rc.3 | Pre-release (committed `f09cf3bc6e`) | [View](assessments/support-case-v0.4.0-memory-knowledge.md) + [KB](kb/authorization-manager-chain-grant.md) |
1517
| Chat-to-Work Resolution Cards (Workstream C) | v0.4.0 | Pre-release (committed `0d4626e82e`) | [View](assessments/support-case-v0.4.0-chat-to-work-resolution.md) |
1618
| Deep Planning — Plan Documents, Review Gates, Decomposition | v0.4.0-alpha | Aug 16, 2026 | [View](assessments/support-case-v0.4.0-deep-planning.md) |
@@ -28,6 +30,8 @@ This directory contains support case assessments for Paperclip features. Each do
2830

2931
| Article | Covers | Commit | Issue |
3032
|---|---|---|---|
33+
| [Search Safety — plainto_tsquery](kb/search-safety-plainto-tsquery.md) | Knowledge search + memory warm-up handle special characters safely | `75c6c27a41` | C-3 / VOY-1299 |
34+
| [SLA Monitor Alert Dedup Safety Net](kb/sla-monitor-dedup-safety-net.md) | Post-insert duplicate verification prevents concurrent duplicate SLA alerts | `75c6c27a41` | C-2 / VOY-1298 |
3135
| [Environment Driver Corruption — readEnum()](kb/environment-readenum-corrupt-driver.md) | `readEnum()` returns `null` instead of throwing on corrupt driver values | `32ccc16229` | PRA-577 |
3236
| [Manager-Chain Issue Permissions](kb/authorization-manager-chain-grant.md) | Managers can comment on and mutate issues assigned to agents in their reporting subtree | `f09cf3bc6e` | VOY-1264 |
3337
| [Recovery Phantom-Park-and-Revalidate](kb/recovery-phantom-park-protocol.md) | Recovery system temporarily parks terminal issues for recovery action execution | `7f84af039b` | RBR-921/RBR-953 |
@@ -76,12 +80,12 @@ Documents are updated when:
7680

7781
| Release | Notes |
7882
|---|---|
79-
| v0.4.0-alpha (RC-3) — Deep Planning + Memory & Knowledge + Chat-to-Work Resolution | [View](releases/v0.4.0-alpha-deep-planning.md) |
83+
| v0.4.0-alpha (RC-4) — Deep Planning + Memory & Knowledge + Chat-to-Work Resolution + C-Fixes + Extraction Jobs | [View](releases/v0.4.0-alpha-deep-planning.md) |
8084
| v0.2.13 — Stripe billing fixes | [View](releases/v0.2.13-stripe-fixes.md) |
8185
| v0.2.12 — Legal pages | [View](releases/v0.2.12-legal-pages.md) |
8286
| v0.2.10 — Domain revert | [View](releases/v0.2.10-domain-revert.md) |
8387

8488
---
8589

86-
*Last updated: 2026-08-16*
90+
*Last updated: 2026-08-17*
8791
*Maintained by: Support Engineer (88b72065)*

docs/support/assessments/support-case-v0.4.0-chat-to-work-resolution.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
**Date**: 2026-08-16
66
**Related**: BOARD-1, VOY-1188, VOY-1210, VOY-1263
77
**Release**: v0.4.0 (pre-release)
8-
**Commit**: `0d4626e82e`
8+
**Commit**: `0d4626e82e` (Workstream C), `75c6c27a41` (C-1 validation hardening)
99

1010
## Feature Overview (User Perspective)
1111

@@ -51,8 +51,11 @@ Resolution cards only appear when the feature flag is enabled and the assistant
5151

5252
| Limitation | Description |
5353
|---|---|
54-
| **One block per response** | The board skill emits a single `%%ACTIONS%%` block per response. Multiple cards within one block are supported (for multiple actions), but the block itself is single. |
55-
| **Malformed JSON silently dropped** | If the model generates invalid JSON inside `%%ACTIONS%%`, the block is silently skipped — no error is shown. The conversational text still persists normally. |
54+
| **One block per response (up to 10)** | The board skill emits a single `%%ACTIONS%%` block per response, but the server caps at **10 blocks max** per turn for safety. If the model emits more than 10 blocks, extra blocks are silently truncated. |
55+
| **Malformed or invalid actions silently dropped** | Action blocks are validated against a strict Zod schema. Blocks with unrecognized resolution types, invalid actions, non-http(s) URLs, or oversized fields are silently skipped (logged server-side). The conversational text still persists normally. |
56+
| **URL protocol restriction** | URLs in action data are restricted to `http:` and `https:` protocols only. Blocked protocols (javascript:, data:, file:) are rejected with a log warning. |
57+
| **Field length limits** | Title fields are limited to 500 characters, ID fields to 200 characters, and rationale/decision summaries to 5000 characters. Oversized fields cause the entire action block to be skipped. |
58+
| **Unknown keys stripped** | The Zod schema uses `.passthrough()` for action data, so unexpected keys from the model are stripped rather than causing errors. |
5659
| **Raw markup briefly visible during streaming** | While the model is still generating, the raw `%%ACTIONS%%{...}%%/ACTIONS%%` markup may appear as plain text in the streaming bubble. This is expected — it clears when the stream completes and the cleaned response persists. |
5760
| **Cards reset on new message** | When the user sends a new message, any action events from the previous turn are cleared. Cards are per-turn only and do not persist in the conversation history. |
5861
| **"View" link only when `data.url` provided** | The resolution card's "View" link only appears if the assistant includes a `url` in the action data. If omitted, the card shows the title without a link. |
@@ -91,8 +94,10 @@ Resolution cards only appear when the feature flag is enabled and the assistant
9194

9295
| Scenario | User Experience | Resolution |
9396
|---|---|---|
94-
| Model generates invalid JSON inside %%ACTIONS%% | No card appears; raw markup is stripped; conversational text persists normally | Support can ignore — no data loss. Consider reporting the conversation for model quality analysis. |
95-
| %%ACTIONS%% block truncated by 120s timeout | If the model is mid-generation when the 120s timeout fires, the incomplete block is stripped. Partial action signals may not parse. | User may see a partial response with no card. Retry the request with a shorter ask. |
97+
| **Model generates invalid JSON inside %%ACTIONS%%** | No card appears; raw markup is stripped; conversational text persists normally | Support can ignore — no data loss. Consider reporting the conversation for model quality analysis. |
98+
| **Model emits an action block that fails Zod validation** | The block is skipped; a server-side warning is logged (`extractActionSignals: skipping malformed action block`). No card renders; conversation persists | Check server logs for the schema issue list to confirm why the block was rejected (bad type enum, non-http(s) URL, or oversized field). Report conversation for model quality analysis. |
99+
| **Model emits more than 10 action blocks** | Only the first 10 blocks are processed; a server-side warning is logged (`response exceeds max blocks (10) — truncated`) | Unexpected model behavior — report for analysis. User sees cards only for the first 10 blocks. |
100+
| **%%ACTIONS%% block truncated by 120s timeout** | If the model is mid-generation when the 120s timeout fires, the incomplete block is stripped. Partial action signals may not parse. | User may see a partial response with no card. Retry the request with a shorter ask. |
96101
| Multiple %%ACTIONS%% blocks in one response | The server's `extractActionSignals` parses ALL blocks, so multiple cards render. However, the skill instructs the model to emit only one block per response. Multiple blocks is unexpected behavior — report for analysis. | Cards render correctly even with multiple blocks. No user-facing error. |
97102
| SSE connection drops during action event delivery | Action events are delivered as part of the SSE stream. If the connection drops before the `action` event, the card does not render. The persisted comment still has the markup stripped. | User sees the cleaned response without cards. Refreshing the page loads the comment (without raw markup) but cards do not re-render. This is a known limitation. |
98103

docs/support/assessments/support-case-v0.4.0-memory-knowledge.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
**Feature**: Agent memory (pgvector-based bindings, capture, query, records) and knowledge document management (CRUD, lifecycle, revisions, search)
44
**Assessed by**: Support Engineer
55
**Date**: 2026-08-16
6-
**Related**: VOY-1190, VOY-1191, VOY-1192, VOY-1203, VOY-1204, VOY-1255, VOY-1256
6+
**Related**: VOY-1190, VOY-1191, VOY-1192, VOY-1203, VOY-1204, VOY-1255, VOY-1256, VOY-1299 (C-3), 466c30fde7 (extraction jobs)
77
**Release**: v0.4.0-alpha
88

99
## Feature Overview (User Perspective)
@@ -65,6 +65,30 @@ A dedicated **Memory Browser** page is available at `/memory` in the sidebar (vi
6565
- Filter records by metadata using JSONB containment (`metadata` parameter)
6666
- Forget individual records by handle
6767
- View recent memory operations in the audit log
68+
- **View extraction jobs** (extractions tab) — browse memory extraction job history with status, source hyperlinks, and latency/cost display; retry failed jobs with one click. The extraction jobs dashboard polls every 15s.
69+
70+
### Memory Extraction Jobs
71+
72+
Extraction jobs record background memory-extraction work (e.g., agent runs that extract findings into memory). They carry a lifecycle status (`queued``in_progress``succeeded` / `failed`), plus timing, error, and provider references:
73+
74+
- **List jobs**: `GET /companies/{companyId}/memory/extraction-jobs?status=&limit=` — newest first, board-only
75+
- **Get job**: `GET /companies/{companyId}/memory/extraction-jobs/{jobId}`
76+
- **Retry failed job**: `POST /companies/{companyId}/memory/extraction-jobs/{jobId}/retry` — resets a `failed` job back to `queued`; only `failed` jobs can be retried (400 otherwise)
77+
78+
**Support note**: if an operator reports an extraction job that is stuck in `failed`, the retry endpoint resets it to `queued` so the worker picks it up again. A retry attempt on a non-failed job (or a job whose status changed concurrently) returns `400` with a clear message — no silent double-transition.
79+
80+
## Search Safety (plainto_tsquery)
81+
82+
**Commit**: `75c6c27a41` (C-3 fix, VOY-1299)
83+
84+
Both the knowledge document search endpoint and the memory warm-up path now use **`plainto_tsquery('english', query)`** instead of hand-constructed `to_tsquery` strings. User queries containing punctuation, operators, or special characters (`!@#$%^&*`, dashes, quotes, etc.) are tokenized as natural language — special characters are stripped rather than causing PostgreSQL query errors.
85+
86+
- **Old behavior**: a query like `"Why isn't the payment @ processing?!"` could crash knowledge search with a 500 error.
87+
- **New behavior**: the same query is treated as `"Why isn't the payment processing"` — safe, no error.
88+
- **Empty/whitespace-only queries** after stripping return an empty result set immediately (no DB round-trip).
89+
- This is a **server-side fix** — no client-side escaping is needed, and it applies automatically to both the knowledge search API and the memory warm-up context injection path.
90+
91+
See the [Search Safety KB article](../kb/search-safety-plainto-tsquery.md) for troubleshooting details.
6892

6993
## Potential User Confusion Points
7094

@@ -152,6 +176,8 @@ A: It shows the outcome of the most recent review — `pending`, `approved`, or
152176
| Knowledge publish fails despite approved review | Publish rejected | Stale approval from prior review cycle (VOY-1255) | Re-run review cycle on the latest revision |
153177
| Search returns empty | "q parameter is required" | Missing search query | Provide query string |
154178
| Knowledge search returns 404 | 404 on `GET /knowledge/search` | Server older than `f09cf3bc6e``/:documentId` route shadowed the literal `search` path | Upgrade server to `f09cf3bc6e` or later |
179+
| Knowledge search returns 500 on special-char queries | 500 with a PostgreSQL error | Server older than `75c6c27a41` — hand-built `to_tsquery` rejects punctuation/operators | Upgrade server to `75c6c27a41` or later (plainto_tsquery) |
180+
| Extraction job retry rejected | 400 "Only failed jobs can be retried" | Job status is not `failed` (or changed concurrently) | Re-check job status; only retry `failed` jobs |
155181

156182
## Related Documentation
157183

0 commit comments

Comments
 (0)