Commit Graph

18 Commits

Author SHA1 Message Date
root
5b05fd4730 feat(health): service_status cache table + repo 2026-06-02 22:53:39 +10:00
root
c59d2407ed feat(speedtest): results table + repo 2026-06-02 22:48:03 +10:00
root
c67ac27545 feat(dashboard): dashboard_layout table + repo
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 22:17:27 +10:00
root
c45246b918 feat(security): grow Yerin's toolset (pending_review, resource_exposure, token_audit)
Three more read-only tools on securityRegistry:
- pending_review: agent-proposed changes awaiting approval (injection surface)
- resource_exposure: host/url/status attack-surface inventory (resources.listExposure,
  scalar cols only — no monitoring/metadata/credentials)
- token_audit: token label/last_used/revoked, never the hash

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 00:17:45 +10:00
root
aa9cf0917e fix(auth): O(1) selector+verifier token verification
verifyToken loaded every non-revoked token and bcrypt-compared each (O(n) per
request — auth-latency DoS + linear scaling). New token format
vk_<selector>.<verifier>: the non-secret selector is indexed and locates exactly
one row; only the verifier is bcrypt-hashed. Legacy NULL-selector tokens still
verify via a fallback scan. Dropped the useless idx_agent_tokens_hash.

- migration 010_token_selector.sql (adds selector col + unique partial index)
- createToken/verifyToken reworked; also adds listTokenMeta (read for Yerin's
  token_audit tool)
- tests/repos/token_selector.test.js

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 00:17:45 +10:00
root
f80fd278a5 feat(db): conversations.findOrCreateForSpace for the ambient companion
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:08:34 +10:00
root
f116811dda feat(search): hybrid FTS + vector with RRF + graceful Ollama fallback
Replaces FTS-only /api/search in place. RRF (k=60) fuses ts_rank and
pgvector cosine distance rankings. Vector branch silently skipped when
Ollama times out / errors, keeping search snappy and resilient.

Messages have no embeddings in Plan 3, so they participate in the FTS
branch only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 03:50:33 +10:00
root
e558be49a9 feat(jobs): repo-level embed triggers (pages/refs/source_docs)
create/update on embeddable repos enqueue embed.text with a singleton
key that coalesces rapid edits. No-op when the queue is not running
(server tests construct createApp without booting pg-boss).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 03:48:03 +10:00
root
57efa4cbaa feat(jobs): jobs repo (list/getById/retry/remove)
Unifies pgboss.job (current, per-queue partitioned) and pgboss.archive
under one SELECT for operator views. retry promotes archived rows back
into the active partition.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 03:29:03 +10:00
root
69e26ada98 feat(api): unified FTS search
Single GET /api/search?q=&space_id=&kinds=&limit=&offset= unions FTS
hits across pages / refs / source_docs / messages with a `kind`
discriminator and ts_rank ordering. Each branch's to_tsvector matches
the GIN index expression on its source table so indexes are used.
Messages have no space_id and are excluded when a space filter is set.
Hybrid vector / RRF lands in Plan 3.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 02:04:57 +10:00
root
10902bc6ac feat: real audit_log with redaction + pending_changes; replace stub 2026-05-31 11:04:53 +10:00
root
47ea0768fd feat(repos): tags, polymorphic entity_links, attachments 2026-05-31 11:02:58 +10:00
root
1d799105ac feat(repos): agents (+ tokens + caps), conversations, messages 2026-05-31 10:36:40 +10:00
root
6086cf9a7a fix(schema): tighten tenant boundaries on resources/deps/creds/source_docs
Apply same composite-FK pattern as 001/002 for migration 003:
- resources: add UNIQUE (id, space_id) as FK target.
- resource_dependencies: denormalize space_id, composite FKs on both endpoints
  (enforces both ends of a dep live in the same space at the DB layer).
- resource_credentials: denormalize space_id, composite FK to resources.
- source_docs.resource_id: NOT NULL (tenancy anchor); resource_id was already
  absent from the update FIELDS list so docs cannot move resources.

Repos derive space_id from the resource on addDependency/addCredential so callers
can't fake cross-tenant assignment. 3 regression tests added.
2026-05-31 10:33:17 +10:00
root
9dd944226d fix(schema): tighten tenant boundaries on pages/refs
Three security-review findings on migration 002:
- pages.space_id and refs.space_id changed to NOT NULL + ON DELETE CASCADE
  (was nullable + SET NULL, which allowed orphan rows surviving space deletion).
- pages.parent_id wrapped in composite FK (parent_id, space_id) -> pages(id, space_id)
  to prevent cross-space parent linkage (same pattern as tasks.project_id in 001).
- idx_refs_external promoted to UNIQUE on (space_id, source_kind, external_id);
  upsertByExternal now requires space_id and dedups per-space, not globally.

Added 3 regression tests covering composite FK rejection, CASCADE-on-space-delete,
and per-space dedup independence.
2026-05-31 02:21:47 +10:00
root
c8649d753f feat(repos): resources (+ deps + creds) and source_docs 2026-05-31 02:19:23 +10:00
root
c891c495bb feat(repos): pages with auto-revisions, refs with upsertByExternal 2026-05-31 02:17:01 +10:00
root
951016385a feat(repos): spaces, projects, tasks with audit stub
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 02:11:31 +10:00