fix(server): drop dead git-credentials/wakeup-promise refs from admission-control merge - #11
Merged
Conversation
… admission merge The RBR-974 admission-control merge (#10 / 494ceab) carried over an import block (createGitRemoteAuthProvider, describeGitAuthFailure, scrubGitCredentialText, GitRemoteAuthProvider) from ./git-credentials.js and a drainActiveRunExecutions / trackWakeup / activeRunExecutionPromises / activeWakeupPromises code path that do not exist anywhere else in this fork's history — a rebase artifact from a branch that had picked up unrelated future upstream commits. None of these symbols are used or referenced by anything else in the merged diff; the actual admission-control change (evaluateRunAdmission / readHostLoadSnapshot / resolveGlobalRunCeiling / withGlobalAdmissionLock) is untouched. - removed the git-credentials.js import block and its re-export (unused; module does not exist on this fork) - restored the pre-admission-control fire-and-forget dispatch (void executeRun(...).catch(...)) in place of the orphaned activeRunExecutionPromises bookkeeping - removed drainActiveRunExecutions() and trackWakeup(), which referenced the undefined activeWakeupPromises/activeRunExecutionPromises sets and had no callers anywhere in the codebase Verified: clean 'tsc --noEmit' on server/, 35/35 targeted tests still passing (run-admission.test.ts + agent-start-lock.test.ts).
PraeSynBH
pushed a commit
that referenced
this pull request
Aug 17, 2026
…x, manager-chain permissions (VOY-1303) RC-3 (VOY-1264) ships three items with zero prior documentation coverage; prior syncs (8074df8, ee5693f) covered the Plan Board UI surface only: - Knowledge Browser UI (f09cf3b): new /knowledge page — search, list, detail sheet, revisions/diff, backlinks, create/edit. Added release highlight #8 + support assessment section. - Knowledge search route fix (f09cf3b): /knowledge/search was unreachable (matched :documentId). Added highlight #11, support note, 404 error state, escalation row. - Manager-chain authorization grant (f09cf3b): managers may comment on/mutate issues assigned to reporting-subtree agents. New KB article (authorization-manager-chain-grant.md), highlight #12, escalation row. Version references updated to v0.4.0-alpha-rc.3 across releases.md (/documentation/releases), support README, and release notes header.
PraeSynBH
added a commit
that referenced
this pull request
Aug 17, 2026
* fix(recovery): source_revalidation must revert the park it invalidated (RBR-921 AC3)
Revalidation could already prove a park was wrong -- it logged "Recovery action
became stale because the source issue reached done" -- and then walked past the
damage. Every phantom park so far has needed a human to hand-revert it; that
manual step was the product defect.
revertPhantomRecoveryPark() now undoes the park before the stale-cancel
classifier runs (a parked issue reads `blocked`, which the classifier
deliberately leaves alone), restoring status AND the pre-park assignee.
Guarded on five invariants so this is not RBR-864 with the sign flipped:
1. Never demote a terminal status -- if the issue reads done/cancelled we do
not write, or we would manufacture the phantom regression on the hot
read-projection path.
2. Only revert the indefensible park: evidence.previousStatus must itself be
terminal. A run that legitimately died from in_progress gets a live path
restored elsewhere, never a status rewrite here.
3. Compare-and-set against a freshly SELECT ... FOR UPDATE row, not the
request snapshot; stand down if anything moved. A human assigneeUserId
outranks any automated revert.
4. Restore previousOwnerAgentId (who held it before the park), never
returnOwnerAgentId -- the two diverge.
5. The revert is observable: issue.recovery_action_reverted activity plus a
system comment on the thread.
Tests: revert restores both status and assignee and cancels the action; a park
taken from a live in_progress run is left standing.
* test(recovery): allow 180s for embedded-postgres boot in beforeAll
The RBR-912 harness change boots an embedded Postgres cluster in globalSetup;
the 30s beforeAll budget in this file is below the observed ~90s+ boot and
fails the suite before any assertion runs.
* merge(RBR-979): land reaper-liveness fix on master
Cherry-picked from rbr979-reaper-liveness branch (commits cc1fc90,
a69c00c, 3ae2c93, 7e5c1dc, f3ed532).
The startup reaper now requires positive evidence of death before
reaping: recorded pid alive with identity confirmed, runId in the
live process table, or a surviving process group. Probe failure
resolves to alive — a destructive action needs proof.
Includes:
- run-reap-liveness.ts (liveness predicate)
- process-table-snapshot.ts (evidence collection)
- reap-liveness.test.ts (unit + negative-control tests)
- vitest.reaplive.config.ts (suite config)
- heartbeat.ts integration (reap-liveness hook)
Deploy/restart is NOT part of this commit — board-gated per standing
constraints.
* fix(server): raise embedded-Postgres beforeAll hook budget to config-level 120s (RBR-980/RBR-912)
Two suites carried inline beforeAll(fn, 20_000) that always timed out
against embedded-Postgres cold-boot (~80-95s), hiding ~56 tests as
skipped. Set hookTimeout: 120000 at config level and drop inline
budgets so they inherit it.
Cherry-picked from 4f601d7 (rbr-980-embedded-pg-hook-fix branch).
* fix(recovery): fingerprint idempotency — a stale-cancelled cause must not re-park the same issue (RBR-922 AC4)
When source revalidation (AC3, RBR-921) cancels a recovery action, it moves
out of the active/escalated partial unique index. The next sweep's
upsertSourceScoped then sees no active action and creates a fresh one —
re-parking the issue the guard just released. This is the repeat-revert
pattern seen in production (RBR-847 took three, RBR-815 took two).
Fix: add getCancelledForFingerprint to issueRecoveryActionService, which
checks for previously-cancelled/resolved actions with the same
(companyId, sourceIssueId, cause, fingerprint). In
ensureSourceScopedStrandedRecoveryAction, this gate fires before the upsert:
if a cancelled action exists with the same fingerprint, return it instead
of minting a new one. In escalateStrandedAssignedIssue, if the returned
action is not active/escalated, skip the re-park entirely.
Tests: three new behavioral regression tests:
1. Single cancel-then-sweep: no new active action created
2. Multi-revert (3 sweeps): no re-park across all three
3. Different fingerprint: new action allowed after cancellation
* fix(ci): harden smoke test pipeline — pre-merge gates + flaky test fixes (VOY-770)
## Pre-merge gate fix
- Add verify_serialized_server + e2e to pr.yml verify gate needs
- Previously ~25 route/authz suites + 6 Playwright specs could fail silently
## Flaky test fixes (inline timeout budget removal)
- access-routes-permissions-upgrade.test.ts: remove inline beforeAll(fn, 20_000)
Config-level hookTimeout: 120000 now applies (was overridden by inline)
- packaged-artifacts.test.ts: remove inline it(fn, 30_000)
Add testTimeout: 60000 to skills-catalog vitest config
npm pack + fallback build can take 30-60s on cold checkout
Root cause: inline timeout args silently override config-level budgets,
exactly the pattern the server vitest config warns against at lines 25-27
and 38-42.
## Audit document
- Full test suite inventory and gate analysis
- Run 1 results documenting the discovered flakes
- CI optimization proposals
* docs(VOY-1154): add v0.2.10 support release notes and case assessment
- Create docs/support/releases/v0.2.10-domain-revert.md — internal release notes
- Create docs/support/assessments/support-case-domain-revert.md — support assessment
- Ref: VOY-1154 documentation verification for v0.2.10
* docs(support): sync documentation for shipped features — CAS, Hermes adapters, version metadata, releases page, support KB
- Add Status CAS documentation (expectedStatus/expectedStatuses/allowTerminalReopen) to api/issues.md
- Add Hermes Local and Hermes Gateway adapter docs (hermes-local.md, hermes-gateway.md)
- Add version + last_updated frontmatter to 11 documentation pages
- Add curated releases page (docs/releases.md) with Paperclip v2026.525..722 entries
- Update docs.json navigation: add releases page, Hermes adapter pages
- Add support knowledge base: 4 KB articles, 5 feature assessments, 1 SOP, release notes
- Cross-reference Hermes adapter pages from adapters/overview.md, managing-agents.md, agents-runtime.md
Ref: VOY-1154 documentation sync, shipped features: Hermes built-in adapters (paperclipai#8543), Status CAS (RBR-929/950/951/953)
* docs(support): log 30-file documentation sync heartbeat (1cb3953)
* feat(v0.4.0): land Deep Planning (Workstream A) + Memory & Knowledge (Workstream B) implementation
Workstream A — Deep Planning (structured plan documents, revision history, plan-level approval gates):
- DB schema: plan_metadata on documents, plan_review_gates table (migration 0128)
- Shared types/validators for plan documents, review gates, decompositions
- Server services: plan-documents, plan-review-context, plan-review-gates
- Routes: plan CRUD + gate management on /issues/:id endpoints
- UI: PlanDecompositionWizard (818 lines), IssueDetail plan section integration
- Agent instructions: per-role instruction bundles with onboarding assets
Workstream B — Memory & Knowledge (pgvector-based agent memory):
- DB schema: memory_bindings, memory_binding_targets, memory_records tables (migrations 0129/0130)
- Shared types/validators for memory entities
- Server services: memory-adapter, memory-bindings, memory-context-injection, embedding
- Routes: memory CRUD on /issues/:id/memory endpoints
- Context injection: memory preamble in all 10+ adapter execute.ts files
- Tests: memory-bindings, memory-context-injection, default-agent-instructions
VOY-1195 VOY-1196 VOY-1197 VOY-1203 VOY-1204 VOY-1209 VOY-1190
* docs(support): log heartbeat — v0.4.0 implementation landed, v0.2.13 pending CTO sign-off
* docs(support): add v0.2.13 support case assessment, release notes, KB index update (VOY-1237)
- Create docs/support/assessments/support-case-stripe-tier-sync.md — assessment covering syncTierFromStripe hardening (active/trialing-only check, deleted-customer detection, downgrade-to-free, mapStripeStatus), findOrCreateStripeCustomer stale-ref auto-repair (VOY-896), NEXTAUTH_URL OAuth redirect fix
- Create docs/support/releases/v0.2.13-stripe-tier-sync.md — curated customer-facing release notes with before/after behavior table
- Update docs/support/README.md — add v0.2.13 assessment to Recently Shipped Features, add Voyonder release notes index
- Update docs/support/heartbeat-log.md — log v0.2.13 docs sync
Ref: VOY-1237 support case assessment (verified against release-engineer pipeline status 2026-08-16, merge VOY-1218, QA VOY-1231)
* docs(support): sync v0.2.13 Stripe billing fixes — release notes, KB article, support case assessment (VOY-1233)
- Release notes: docs/support/releases/v0.2.13-stripe-fixes.md (tag 83a1cee)
- KB article: billing-cancellation-downgrade.md — cancellation now reliably downgrades to free on next login
- Support case assessment: support-case-stripe-billing-fixes.md — FAQ, troubleshooting, error states, escalation paths
- README: add v0.2.13 entries to assessments, KB, and release notes tables
- Heartbeat log: log v0.2.13 docs sync
Ref: VOY-1233 (VOY-1227 follow-up), QA verified 45/45 stripe-webhook tests
* feat(v0.4.0): plan review gates + milestone context + Codex adapter integration (CTO completion)
- PlanReviewGateContext + MilestoneProgress types in document-annotation.ts
- Plan review gates fetch + milestone progress computation in plan-review-context.ts
- milestoneId pass-through in issue decomposition types, validators, routes, services
- Wakeup on plan update (issue_plan_updated) and gate resolution (issue_plan_gate_resolved)
- Codex adapter: normalize + render gates and milestone progress in wake prompts
- SKILL.md: structured plan metadata docs, review gate context injection, milestone decomposition
- Storybook fixture: add milestoneId: null
- Memory: improved routes, adapter fixes, context injection enhancements
Working tree changes verified by CTO (typecheck + tests passing).
Original stash ref: stash@{2}
* fix(db): make memory_operations.bindingId nullable, add providerKey (sync with 0131 migration)
* fix(v0.4.0): Phase 3 audit fixes — warm-up, tsquery safety, TTL, scope, index (VOY-1242)
Complete 7 of 10 VOY-1206 structural audit findings:
Must-Fix:
- Broken warm-up: adapter.query with empty query now returns recent records
instead of crashing on empty tsquery. Warm-up no longer calls full-text
path with blank input.
- sql.raw injection: Already fixed in working tree (parameterized
CAST( AS vector), embedding NaN/Infinity validation, test coverage)
Should-Fix:
- tsquery safety: Sanitize full-text search input — strip characters
unsafe for to_tsquery lexemes, handle empty tsquery gracefully
(returns empty results instead of crashing). Applied to both
memory-adapter and knowledge-documents warm-up.
- TTL filtering: Add nonExpiredFilter() to all read operations (query,
list, get) so expired records are excluded. Records with expiresAt=null
(curated) are always returned; auto-captured records past their 30d TTL
are hidden.
- Scope enforcement: Add subjectId and sessionKey to buildScopeFilters,
completing the scope dimension coverage.
- Missing composite index: Migration 0133 adds
memory_records_company_binding_idx (btree on company_id, binding_id)
for common query patterns.
Hardening:
- Preamble boundary: Handle empty/null text, NaN/Infinity scores,
non-string summary, empty summary in buildMemoryPreamble.
Fallback text: summary - greater than (empty memory).
- Warm-up race: AbortController pattern in warmUpAgentMemory and
warmUpCompanyKnowledge. Timeout now signals cancellation; in-flight
work checks signal.aborted at each async step. Result is discarded
if timeout fires during processing.
Deferred to child issues:
- VOY-1243: Fix N+1 in upsertRecords (batch inserts + embeddings)
- VOY-1244: Implement post-run/issue memory capture hooks
- VOY-1245: Add TTL cleanup cron job for expired memory records
Also includes working tree partial fixes already staged:
- memory_operations.bindingId nullable + providerKey column (migration 0132)
- Error-path binding UUID resolution in get/forget (not fallback to
handle.providerKey)
- Unique constraint error handling in createBinding/createTarget
- delete returning() for accurate deletion feedback
- Test mock updates for .returning() structure
* docs(support): log heartbeat — Phase 3 audit fixes diff assessed (08254fb)
* fix(sla-dedup): correct LIKE pattern space, sort order, remove unused constant
Three fixes in premium-sla-dedup.ts:
1. LIKE pattern missing space: clientLikePattern() produced
'[%]PremiumSLABreach: <client>%' but actual titles have a space
after the severity bracket (e.g. '[CRITICAL] PremiumSLABreach: ...').
Added the missing space so the LIKE query actually matches existing issues.
2. Sort order inverted: comment said 'prefer the earliest' but code used
desc(createdAt). Changed to asc(createdAt) so new alerts are parented
under the original tracking incident.
3. Removed unused OPEN_STATUSES constant.
These fix the title-pattern dedup path so it actually finds existing
PremiumSLABreach issues instead of always returning null.
* feat(db): add partial unique index for SLA monitor alert dedup (PRA-693)
Adds a DB-level partial unique index on (company_id, origin_kind,
origin_fingerprint) for active sla_monitor issues. This is the
concurrency safety net preventing duplicate active SLA alerts from
being created when multiple monitor alerts fire simultaneously.
* feat(sla-dedup): wire PremiumSLABreach duplicate suppression into issue creation (PRA-693)
Integrates the PremiumSLABreach dedup module into the issue creation route
with two matching strategies:
1. Fingerprint match (originKind === 'sla_monitor' + originFingerprint) —
used when the external monitor sends structured metadata. Suppresses
creation entirely and adds a comment on the existing tracking incident.
2. Title-pattern match — fallback for the legacy monitor (originKind='manual',
originFingerprint='default'). Creates the new alert as a child of the
existing tracking incident.
Also adds:
- SLA_MONITOR_ORIGIN_KIND constant (shared)
- originKind / originFingerprint fields to create issue validator
- Partial unique index on (company_id, origin_kind, origin_fingerprint)
for active sla_monitor issues (DB-level concurrency safety net)
* fix(v0.4.0): resolve C-1/C-2/C-3 findings from VOY-1210 review
C-1 (cross-tenant IDOR): Added companyId filtering to all plan-documents
and plan-review-gates service functions for defense-in-depth tenant
isolation, even though route-layer assertCompanyAccess already gates
HTTP access.
- listPlanRevisions: filter issueDocuments/documents by companyId
- computePlanDiff: filter all revision queries by issue.companyId
- listGates: filter planReviewGates by resolved companyId
- createGate: verify document ownership via companyId
- resolveGate: verify gate's document companyId
- supersedeGatesForRevision: scope by companyId
- supersedeGatesForPreviousRevisions: fetch document companyId
C-2 (LCS OOM): Added MAX_DIFF_LINES=2000 guard to computeLineDiff.
Rejects diffs exceeding 2K lines in either side with a proper
422 error instead of allocating a 2B+ entry matrix.
C-3 (re-resolve invariant): resolveGate now reads the gate before
updating, rejects non-pending gates with a 409 conflict error.
Update WHERE clause also filters on status=pending as a safety net.
VOY-1258
* fix(v0.4.0): address VOY-1210 high/medium findings — H-2/H-3/M-2/M-3/M-4/M-5
H-2: Remove dead code from documents.ts (upsertPlanDocument,
listPlanDocumentRevisions, getPlanDocument, getRevisionPair — all
live in plan-documents.ts, the real service).
H-3: Add SELECT FOR UPDATE to upsertIssueDocument to prevent race
condition on concurrent revision number calculation (was READ COMMITTED
without row lock).
M-2: Populate supersededByGateId column when superseding gates in
supersedeGatesForRevision.
M-3: Change milestoneId validators from z.string().uuid() to
z.string() to match DB column type (text, not uuid).
M-4: Add CHECK constraint on plan_review_gates.status (migration 0135).
M-5: Add UUID validation for revisionId query param in listGates route.
VOY-1229
* docs(support): sync v0.4.0-alpha documentation — plan, memory, knowledge API docs + support assessments (VOY-1254)
* docs(support): log heartbeat — working-tree diff assessment (knowledge fixes, OpenAPI registrations, pre-release UI)
No new commits since v0.4.0-alpha docs sync (ee5693f). Working tree
assessed: 5 change areas identified — all pre-release engineering work.
No documentation updates required. Docs remain in sync through v0.4.0-alpha.
- Knowledge VOY-1255/VOY-1256 fixes: publish stale-approval guard,
latestReviewStatus accuracy — noted for release-time support assessment
- OpenAPI route registrations: already documented in docs/api/{plans,memory,knowledge}.md
- Shared types + UI: pre-release additions, covered by existing assessments
* test(v0.4.0): add tests for C-1/C-2/C-3 fixes from VOY-1210 review
Adds 36 tests (18 per service) covering:
- plan-documents: listPlanRevisions, computePlanDiff, computeLineDiff
- plan-review-gates: listGates, createGate, resolveGate, supersedeGatesForRevision, supersedeGatesForPreviousRevisions
All tests mock drizzle-orm and verify companyId scoping (C-1),
line diff limits (C-2), and re-resolve rejection (C-3).
VOY-1229
* docs(support): log heartbeat — commit 380cc92 assessed (test-only, no docs impact)
No new support-facing changes since v0.4.0-alpha docs sync. Commit
380cc92 adds 36 tests for the C-1/C-2/C-3 fixes — test infrastructure
only, no behavior change. Working tree unchanged from prior assessment
(knowledge fixes, OpenAPI registrations, board UI — all pre-release).
VOY-1264 (Phase 5 Plan Board UI release) still blocked on code review;
Release Engineer to notify before shipping. Docs remain in sync.
* fix(sla-dedup): suppress legacy PremiumSLABreach alerts instead of creating child issues (PRA-699)
* feat(v0.4.0): Phase 5 plan board UI, memory browser, knowledge fixes, OpenAPI registrations
- ui: Plans page (browse/detail/gates/revisions), MemoryBrowser page, ResolutionCard,
plan document sections wired into IssueDetail, sidebar + routes + query keys
- ui: memoryApi client with tests
- shared: PlanDocumentRevision/PlanBodyDiffLine/PlanRevisionDiff types, planMetadata
on IssueDocument, planGatesQuerySchema export
- server: OpenAPI registrations for plan document, review gates, memory, knowledge routes
- server: knowledge-documents publish() stale-approval guard (latest revision only),
latestReviewStatus accuracy fix (VOY-1255/VOY-1256)
- server: memory scope query parse -> 400 on malformed JSON; memory-adapter batch
embedding + metadata jsonb containment filter
- db: generate-snapshots.mjs helper
* chore(db): add Drizzle migration snapshots 0100-0135 (VOY-1260)
Generated snapshots for migrations 0100 through 0135 to match the
existing journal entries. Includes generate-snapshots.mjs script.
* chore(db): update 0099 snapshot schema (icon_url, color, tagline, instance_branding)
* docs(support): sync v0.4.0 Phase 5 docs — plan board UI, memory browser, knowledge VOY-1255/1256 fixes (b495d95)
- support-case-v0.4.0-deep-planning: add Plan Board UI section (browse/detail/gates/revisions), VOY-1252
- support-case-v0.4.0-memory-knowledge: add Memory Browser UI, stale-approval guard FAQ/troubleshooting (VOY-1255), latestReviewStatus accuracy (VOY-1256), scope 400 error state
- release notes v0.4.0-alpha: add Plan Board UI + Memory Browser UI highlights, knowledge publish guard, scope/metadata support notes
- api/memory.md: metadata jsonb containment filter on query/records, scope must be valid JSON
- api/knowledge.md: stale-approval guard note on publish
- heartbeat-log: log assessment of b495d95
* fix(ui): invalidate gate queries with 3-element prefix and refresh issue detail on resolve (VOY-1268)
- Replace 4-element query key with 3-element prefix so that
invalidation matches both revisionId-specific and __all__ keys
- Add issue detail invalidation so PlanStatusBadge refreshes
after approve/reject
* fix(knowledge): create pending review on submit + order latestReviewStatus by createdAt (VOY-1280)
submitForReview() now inserts a pending review (decidedAt = NULL) linked to
the newly created revision, so list() surfaces latestReviewStatus: 'pending'
after submission instead of undefined.
list() orders reviews by createdAt DESC rather than decidedAt DESC, so:
- a changes_requested decision (created after the pending review) shows
correctly instead of being masked by the still-open pending review
- a fresh pending review on resubmit overrides stale changes_requested
from a previous review cycle
Fixes both findings from VOY-1257 code review.
* fix(v0.4.0): wrap resolveGate in transaction, count rejected gates for allApproved (H-2, VOY-1269)
The allApproved predicate in resolveGate previously only checked
remainingPending === 0, allowing plan approval when rejected gates
existed. Approving the last pending gate while a rejection remained
would flip the plan to approved.
Fix:
- Count both pending and rejected gates per revision
- allApproved requires zero pending AND zero rejected
- Wrap the update + counts + metadata flip in a DB transaction
to close the concurrent-resolution race (two approvals racing before
either sees the other's result)
Includes a targeted regression test for the H-2 scenario.
* fix(v0.4.0): move planMetadata flip inside resolveGate transaction (VOY-1269)
The metadata flip (documents.plan_metadata status → approved) was being
done in the route after the service transaction committed, leaving a
window where the plan status could diverge from the gate state.
Move the flip into the same DB transaction as the gate update + count,
closing the concurrent-resolution race entirely. Remove the now-redundant
route-level flip and the unused 'sql' import it pulled in.
* docs(support): assess H-2 fix commit 885a674 — allApproved predicate, resolveGate transaction (VOY-1269)
Commit 885a674 fixes the allApproved predicate to also count rejected
gates, and wraps resolveGate in a DB transaction for atomicity.
Documentation impact: no user-facing changes required — the fix aligns
code with documented behavior. Applied improvements:
- docs/api/plans.md: documented resolve gate response shape (gate + allApproved)
- support-case-v0.4.0-deep-planning.md: added FAQ entry for rejected gate
blocking approval; updated escalation path
- v0.4.0-alpha-deep-planning.md: added support note for H-2 fix
- heartbeat-log.md: logged this assessment
* feat(v0.4.0): Knowledge Browser UI + knowledge search route fix + authorization manager-chain grant
- Knowledge Browser UI (new page under /knowledge route):
- knowledge API client with full CRUD, search, review lifecycle
- KnowledgeBrowser page: search, list, detail sheet, revisions/diff, backlinks, create dialog
- 26 UI tests passing (knowledge API client + browser page)
- Knowledge search route fix: moved /knowledge/search BEFORE /:documentId
routes so Express doesn't match 'search' as :documentId (critical bug)
- Authorization manager-chain grant: managers may comment on and mutate
issues assigned to agents in their reporting subtree. Unblocks CTO/COO
from closing/reassigning issues owned by their team.
- Docs: update PostHog error monitoring SOP (implementation landed 83db54a)
Verification:
- Server typecheck: pass
- UI typecheck: pass
- Server knowledge-documents: 34/34 pass
- Plan-review-gates: 19/19 pass
- UI knowledge api + browser: 26/26 pass
Completes Polaris B Phase 5 — Company Knowledge Base UI.
* docs(support): CTO heartbeat — Knowledge Browser UI + fixes landed (f09cf3b)
* fix(server): batch plan-document fetch in issue list route to avoid N+1 query
Three-part change:
- documents.ts: add getIssueDocumentsByKeys() — batch issue-document fetch with optional key filter
- plan-documents.ts: add listPlanDocuments() — thin wrapper that calls getIssueDocumentsByKeys with key='plan'
- issues.ts: parallel-fetch plan docs alongside handoffStates and recoveryActionByIssue; attach to response
Reduces N+1 database queries in the issue list endpoint when plan documents are requested.
* fix(v0.4.0): P2 ORDER BY bare operator + dimension validation + backup chmod (VOY-1285, VOY-1286)
P2-1 (VOY-1285): ORDER BY bare <=> operator for pgvector HNSW index
- memory-adapter.ts: Change ORDER BY from wrapped 1 - (<=>) DESC to
bare <=> operator. pgvector HNSW index requires the bare distance
operator in the ORDER BY clause. The score column (SELECT list)
still computes 1 - distance for application-layer similarity display.
P2-6 (VOY-1286): Embedding dimension validation
- embedding.ts: Add dimensions field to EmbeddingConfig interface
(default 1536). Validate embedding vector length against expected
dimensions after API response, throwing on mismatch. This catches
model misconfiguration before corrupted vectors reach the database.
Security: backup file permissions
- backup-lib.ts: chmod 0o600 on pg_dump and sql dump backup files
to prevent world-readable database backups.
* feat(v0.4.0): Workstream C — chat-to-work resolution cards with SSE action signals (BOARD-1)
Implement the core chat-to-work resolution gap identified in the Workstream C
audit. The board skill already creates real Paperclip objects (issues, plans,
approvals, memory records) and emits %%ACTIONS%%{...}%%/ACTIONS%% structured
signals, but the server was stripping them silently and the UI had no way to
render resolution cards.
Server (board-chat.ts):
- Add extractActionSignals() — parses %%ACTIONS%% JSON blocks from raw model output
- Emit parsed actions as typed SSE 'action' events before persisting the cleaned
response (which strips the raw markup)
UI (BoardChat.tsx):
- Handle type: 'action' SSE events in the reader loop, collecting into actionEvents state
- Render ResolutionCard components below the streaming text bubble and below the
last persisted assistant comment
Skill (SKILL.md):
- Add 'Structured Action Signals' section teaching the model to emit %%ACTIONS%%
blocks after creating/updating work objects
- Document 7 object type/action pairs with format, examples, and 5 critical rules
Verification:
- Server board-chat tests (5): PASS
- Server openapi-routes tests (4): PASS
- Server typecheck: PASS
- UI BoardChat tests (4): PASS
- UI BoardChat CSS guard tests (2): PASS
- UI typecheck: PASS
* docs(support): assess Workstream C commit 0d4626e — chat-to-work resolution cards (BOARD-1)
Commit 0d4626e lands the Workstream C chat-to-work resolution gap: the
board skill's %%ACTIONS%% structured signals are now parsed server-side and
emitted as typed SSE 'action' events, and the Board Chat UI renders them as
clickable resolution cards (Issue/Plan/Approval/Knowledge/Memory/Decision)
below the assistant bubble.
Documentation impact: new user-facing UI behavior in the Conference Room.
Applied improvements:
- NEW support case assessment (support-case-v0.4.0-chat-to-work-resolution.md):
feature overview, card type table, feature flag/gating, known limitations,
troubleshooting, error states, escalation paths
- v0.4.0-alpha release notes: highlight #10 + verification line + related docs
- docs/support/README.md: assessment table + release notes index
- docs/releases.md: v0.4.0-alpha highlights entry
* docs(release): Release Engineer heartbeat — VOY-1264 blocked on CEO disposition of VOY-1273 (M-1)
* docs(release): Release Engineer heartbeat — deployment verified, stale UI rebuilt, RC-3 tagged (VOY-1264)
* docs(support): RC-3 docs sync — Knowledge Browser UI, search route fix, manager-chain permissions (VOY-1303)
RC-3 (VOY-1264) ships three items with zero prior documentation
coverage; prior syncs (8074df8, ee5693f) covered the Plan Board
UI surface only:
- Knowledge Browser UI (f09cf3b): new /knowledge page — search,
list, detail sheet, revisions/diff, backlinks, create/edit. Added
release highlight #8 + support assessment section.
- Knowledge search route fix (f09cf3b): /knowledge/search was
unreachable (matched :documentId). Added highlight #11, support
note, 404 error state, escalation row.
- Manager-chain authorization grant (f09cf3b): managers may
comment on/mutate issues assigned to reporting-subtree agents.
New KB article (authorization-manager-chain-grant.md), highlight
#12, escalation row.
Version references updated to v0.4.0-alpha-rc.3 across releases.md
(/documentation/releases), support README, and release notes header.
* docs(support): log heartbeat + documentation health report (2026-08-17) — idle, pipeline blocked on C-fixes
* docs(support): log heartbeat — C-fixes resolved, Staff Engineer review in progress, docs current (2026-08-17 01:45 UTC)
* docs(support): update health report — C-fixes resolved, review in progress
* docs(support): accept Founding Engineer's PostHog SOP update — bash script impl, per-signature issues, dedup cooldown
The Founding Engineer (57fa7e0e) updated the PostHog Error Monitoring Triage SOP
to reflect the actual implementation (bash script, per-error-signature issue
creation, 60-minute cooldown dedup, pending retry directory). Version 1.2
upgraded from draft to final, pending VPS-1 cron setup.
Collaboration: FE authored implementation changes, SE reviewed and committed.
* fix(v0.4.0): commit Phase 5 C-fixes (C-1 Zod validation, C-2 TOCTOU safety, C-3 plainto_tsquery)
C-1: LLM Trust Boundary — validate SSE action signals with Zod before emission
C-2: TOCTOU Race — post-insert SLA dedup safety net for concurrent requests
C-3: Replace to_tsquery with plainto_tsquery to handle user special chars safely
All 3 fixes reviewed and approved by Staff Engineer.
* feat(v0.4.0): Phase 5 remaining — memory extraction jobs, batch gate counts, live events, UI refinements
- Add memory extraction job service (server/src/services/memory-extraction-jobs.ts)
- Add extraction job API routes (GET/POST /companies/:cid/memory/extraction-jobs)
- Add listGateCounts to plan-review-gates service with companyId tenant filter
- Add plan.gate_created live event type to shared constants
- Add gatesCount field to IssueDocument type for batch-fetch support
- Wire extraction job routes and service exports in server registry
- Add Memory Browser UI with extractions tab, source hyperlinks, latency/cost display
- Add ExtractionJobsDashboard component with 15s polling
- Add AgentMemoryTab and CompanyMemoryTab page routes
- Add parsePlanMetadata utility with Zod schema validation
- Add LiveUpdatesProvider handlers for plan.gate_created and plan.gate_resolved
- Fix Plans.tsx N+1 by using inline planDocument + gatesCount from batch list
- Fix PlanDecompositionWizard and PlanDetailSection to use parsePlanMetadata
- Fix PlanRevisionBrowser error/retry state for diff loading
- Add CompanySettingsNav and CompanySettingsSidebar Memory nav items
- Add memory API methods (bindings, targets, extraction-jobs)
- Add queryKeys for memory extraction-jobs, targets, agent-config
- Fix board-chat.ts regex capture group for turn tag escaping
- Update .env.example with PostHog monitoring documentation
All changes reviewed and approved by Staff Engineer.
* docs(support): log heartbeat — no new code, docs synced through RC-4, pipeline stalled on founder actions
* docs(support): log heartbeat — no new code, server down, working tree shows active VOY-1205 development
* 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
* fix(ci): add --fail-with-body to all mutation curl calls in SKILL.md
Policy check requires --fail-with-body on all curl mutations to detect
silent 4xx/5xx failures. This addresses the PR #45 policy check failure.
* fix(ci): add --fail-with-body to curl in docs/adapters/overview.md
Policy check requires --fail-with-body on all curl mutations. This file
was flagged in the PR diff and needs the same fix as SKILL.md.
* fix(test): add missing planDocumentService mock and Memory tab assertion
- document-annotation-routes.test.ts: add planDocumentService mock to fix
'No planDocumentService export' vitest error
- CompanySettingsNav.test.tsx: add Memory tab to expected tab items
* fix(test): add planReviewGateService mock to document-annotation-routes test
* fix(test): add planDocumentService and planReviewGateService mocks
* docs(support): sync Deep Planning QA verification docs — plan acceptance flow, diff schema, support case (VOY-1326)
---------
Co-authored-by: CTO <cto@paperclip.local>
Co-authored-by: Paperclip <noreply@paperclip.ing>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RBR-1081: the RBR-974 admission-control merge (PR #10 / 494ceab) carried a rebase artifact — an import of a
./git-credentials.jsmodule and anactiveRunExecutionPromises/activeWakeupPromisesdrain/track code path that do not exist anywhere else in this fork's history. Both broketsc --noEmitonserver/.Fix removes the dead import block and restores the pre-admission-control fire-and-forget dispatch pattern. The actual admission-control logic (evaluateRunAdmission / readHostLoadSnapshot / resolveGlobalRunCeiling / withGlobalAdmissionLock) is untouched.
Verified:
tsc --noEmiton server/ is clean (was 8 errors before this fix)