Commit Graph

1200 Commits

Author SHA1 Message Date
dependabot[bot] d5a889a84d chore(deps): bump docker/login-action from 3 to 4
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-21 02:18:30 +00:00
Joel Hooks 03f0a59b8e chore: add supply chain hardening defaults
Merged supply-chain hardening PR after checks passed/neutral and unrelated workflow-triggered validator drift was removed from the diff.
2026-05-20 19:17:50 -07:00
Joel Hooks e29706fde8 Set up a Deepsec canary workspace for joelclaw with curated security context and scan-only guardrails 2026-05-04 18:22:22 -07:00
Joel Hooks be7812c2da Make o11y tier three escalations log only by default 2026-05-02 10:33:26 -07:00
Joel Hooks 31a7ed0ef3 Document root cause and durable recovery for docs API host port failures 2026-05-02 09:37:27 -07:00
Joel Hooks faf900a197 Document how to diagnose and temporarily restore api docs search 502s caused by closed docs-api host port 2026-05-02 09:14:46 -07:00
Joel Hooks 5e3c944f31 Serialize pi memory capture hooks to avoid duplicate run posts 2026-05-02 08:59:05 -07:00
Joel Hooks 2dce666d61 Fix video ingest event aliases and Inngest sync recovery
Recreate this work: diagnose video ingest events accepted without worker execution; align CLI/schema/skills around canonical pipeline/video.requested events while adding legacy alias Inngest functions for pipeline/video.download, pipeline/transcript.process, and content/summarize; upgrade the system-bus Inngest SDK past the self-hosted app-sync security gate; raise Bun serve idleTimeout so slow /api/inngest registration does not empty-reply under backlog pressure; rebuild the joelclaw CLI and verify aliases register.
2026-05-02 08:36:53 -07:00
Joel Hooks 56ab192829 Document X full-archive search endpoint for historical account research 2026-05-01 17:38:23 -07:00
Joel Hooks c85d652a39 Make send --follow tolerate transient Inngest run lookup misses without crashing after event dispatch 2026-05-01 13:33:22 -07:00
Joel Hooks ce9ca8e186 Deploy Knowledge Watchdog Telegram suppression to system bus 2026-04-30 17:14:11 -07:00
Joel Hooks b85b474bde Stop sending Knowledge Watchdog drift alerts to Telegram 2026-04-30 17:04:09 -07:00
Joel Hooks f717792226 Suppress meta system chatter from Telegram relay 2026-04-30 15:36:05 -07:00
Joel Hooks 9dd73a35a5 Stop paging Telegram for gateway session pressure 2026-04-30 15:34:38 -07:00
Joel Hooks 5b3444115f Suppress noisy gateway channel degradation alerts 2026-04-30 15:32:22 -07:00
Joel Hooks 1e26b99a1a Tighten gateway email relay quality gate 2026-04-30 15:30:15 -07:00
Joel Hooks f8807ee84f Document Slack important-channel gateway operations 2026-04-30 15:18:34 -07:00
Joel Hooks 578d692961 Implement Slack important-channel passive intelligence routing 2026-04-30 15:17:10 -07:00
Joel Hooks ff6dd19567 Document Slack backfill freshness repair path
Update the egghead-slack skill with the host-worker registration requirement, the thread/search fallback gotcha, and the 2026-04-29 repair canary result so future agents know how to hydrate Typesense before Slack daily summaries.
2026-04-29 14:28:17 -07:00
Joel Hooks 6bb733c10e Index Slack search matches during channel backfill
Augment slack-channel-backfill with a bounded search.messages pass per channel so active thread replies are indexed even when their parent message is older than oldestTs and therefore absent from conversations.history. Keep history/replies ingestion for canonical pagination, then upsert search matches into slack_messages for daily-summary freshness.
2026-04-29 14:27:10 -07:00
Joel Hooks 3e869cbd55 Expand Slack backfill through thread replies
Teach slack-channel-backfill to call conversations.replies for top-level messages with replies, dedupe by Slack timestamp, and document why history-only backfill misses the same replies Slack search returns. This lets an agent hydrate Typesense slack_messages with the current daily-summary context instead of only root messages.
2026-04-29 14:25:43 -07:00
Joel Hooks 623c1956bc Register host Slack backfill functions so Typesense can catch up
Add slackBackfillBatch and slackChannelBackfill to the host worker function registry and document that Slack backfill belongs on the host worker because it leases slack_user_token via the local secrets CLI. This lets an agent restart the host worker and send channel/slack.backfill.batch.requested to hydrate Typesense slack_messages when realtime Slack indexing misses ambient channel traffic.
2026-04-29 14:23:47 -07:00
Joel Hooks 01a32f0632 chore: auto-commit from o11y triage 2026-04-26 04:15:49 -07:00
Joel Hooks c2972dffbf Correct system-bus skill with live worker-supervisor rollout checks 2026-04-25 12:00:28 -07:00
Joel Hooks 3738435411 Upgrade embedded gateway pi SDK so GPT-5.5 model resolution works 2026-04-25 11:58:28 -07:00
Joel Hooks 4283cac079 Set gateway primary model to GPT-5.5 and document fallback contract 2026-04-25 11:57:05 -07:00
Joel Hooks 21d5523978 harden todoist CLI retries and stop check-system-health operation_failed from paging repeatedly while inbox 503s wobble 2026-04-24 23:25:41 -07:00
Joel Hooks 37a6321117 Treat Talon heartbeat misses as advisory and strip cron.heartbeat from signal digests 2026-04-24 17:04:35 -07:00
Joel Hooks 8e1cf4151d Fix check-system-health so non-critical degradation stays warn-but-successful and document the health summary triage contract 2026-04-21 08:10:36 -07:00
Joel Hooks 25885f1ae8 feat(memory): machine badge in joelclaw-runs-tree
Adds @<machine> after the runtime badge in tree output so cross-Machine
activity is obvious at a glance. Stable per-Machine color via content
hash (bright colors 91-96 range) — Panda consistently appears in one
hue, dark-wizard in another, without a lookup table.

Also rsync'd updated script to dark-wizard's ~/.joelclaw/bin/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 10:15:45 -07:00
Joel Hooks cd8aa9ebc9 chore(docs): wife is Kristina, not Melissa
Corrects earlier placeholder name in CONTEXT.md example dialogue.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 10:01:07 -07:00
Joel Hooks c437cf196a fix(typesense): resumable restore + FD/memory fixes for HNSW reindex
Recover pdf-brain + docs-api after a rebuild left Typesense with partial
old data. Build a resumable chunked importer so the 3GB docs_chunks_v2
JSONL (inline ollama vectors) can be replayed without paying for embeddings
and without getting wedged by server-side stalls.

Two root causes fixed in k8s/typesense.yaml so this doesn't repeat:

- "Too many open files" at ~146k HNSW docs looked identical to a raft
  ERROR state. Fix: wrap the server command with ulimit -n 1048576.
- Talos container has a 4 GiB hard cap regardless of Colima VM size,
  which pegged the whole cluster once otel_events passed ~350k docs.
  Raised Typesense pod limit from 4 Gi -> 8 Gi and left the live
  docker-update runbook in skills/k8s/SKILL.md.

All 19 source collections restored, post-rebuild backup replayed on top
with emplace, and public /api/docs/search, joelclaw knowledge search,
and joelclaw otel search all verified.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 00:10:39 -07:00
Joel Hooks cafdf2b45e feat(memory): Phase 3 — PDS App Password auth (code-complete; verify pending infra)
Replaces the dev-bearer table with PDS-backed App Password authentication
per ADR-0243 Rule 20, scoped to single-user (Joel only) for now.

packages/system-bus/src/lib/pds.ts
  + pdsCreateAppPassword — calls com.atproto.server.createAppPassword on
    the caller's session; returns { name, password, did, handle }
  + pdsRevokeAppPassword — revokes by name
  + pdsValidateAppPassword — one-shot validation via createSession; used
    at register time only, NOT per-request (hash lookup is cheaper +
    safer, and doesn't create server-side session state at PDS)

packages/memory/src/schemas/machines.ts — NEW Typesense schema for
  machines_dev collection: id, user_id, did, handle, machine_name,
  app_password_name, app_password_sha256, created_at, last_seen_at,
  revoked_at

apps/web/lib/memory-auth.ts — NEW auth middleware
  authenticateMemoryRequest(req) → MemoryIdentity | null
  Hot path: sha256(bearer) → Typesense machines_dev lookup →
    { user_id, machine_id, did, source: "app-password" }
  No PDS roundtrip per request. App Password validity is established
  at register time; the hash is the identity key thereafter.
  Dev-bearer fallback retained during transition (MEMORY_DEV_BEARER_TOKENS
  env var); effectively disappears when that var is empty in prod.
  Phase 3.5 TODO: users_dev collection (DID→user_id map is hardcoded for
  now).

apps/web/app/api/runs/*/route.ts — all 6 handlers now call
  authenticateMemoryRequest instead of the inline DEV_BEARER_TOKENS
  table + local authenticate() helper. Rule 4 privacy filtering is
  unchanged (still keyed on auth.user_id from the middleware).

scripts/joelclaw-machine-register.ts — NEW provisioning CLI
  Flow: load cached PDS session from ~/.joelclaw/pds-session.json →
  call com.atproto.server.createAppPassword → sha256(plaintext) →
  upsert machines_dev row → back up old auth.json → write new
  auth.json (0600) with the plaintext bearer. Ready to register Panda
  once the infra is back.

Verification status (pending Typesense reachability):
  [x] pds.ts compiles; curl-tested createAppPassword directly against
      PDS (returned valid password)
  [x] Bun fetch works against PDS directly (ruled out fetch-lib bugs)
  [x] All route handlers typecheck + biome clean
  [x] Auth middleware compiles
  [ ] End-to-end: register panda → POST /api/runs with new bearer →
      Run indexes → search returns it — BLOCKED on Colima SSH tunnel
      which is flapping (ssh 192.168.64.2:22 timing out; matches the
      2026-04-17 healer-suicide-loop memory note)

When infra comes back:
  TYPESENSE_API_KEY=<...> joelclaw-machine-register --name panda --user joel
  then POST /api/runs with the new bearer to confirm.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 20:12:04 -07:00
Joel Hooks bc84726e0c feat(memory): pi extension — memory-capture (Rule 8 parity with claude-code)
Mirrors scripts/joelclaw-capture-session.ts but as a native pi extension
using the official extension API (ExtensionAPI.on). Same semantics:

  - Fires on every turn_end event (one Run per invocation, Rule 3)
  - Delta-only capture via ~/.joelclaw/session-state.json (keyed by
    pi session_id), same state file the claude-code hook uses so both
    runtimes coexist cleanly
  - parent_run_id linkage across turns within a session (tree builds
    automatically)
  - Never throws; errors go to ~/.joelclaw/capture.log
  - Network failures outbox to ~/.joelclaw/outbox/<run-id>.json
  - Also fires on session_shutdown to sweep any trailing bytes after
    the last turn_end

Access to the live jsonl path + session id via ctx.sessionManager
(getSessionFile + getSessionId). tags[] marks the trigger
(turn_end | session_shutdown) for diagnostic filtering.

Installation:
  packages/pi-extensions/package.json's pi.extensions array now lists
  ./memory-capture/index.ts alongside the existing inngest-monitor.
  Symlinked into ~/.pi/agent/extensions/memory-capture.

Next pi session you start will pick it up. Verify with:
  joelclaw-runs-tree --runtime=pi --since=1h

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 19:15:55 -07:00
Joel Hooks 90e283ccdd feat(memory): GET /api/runs/forest + joelclaw-runs-tree — global pi-tree
Inspired by pi's /tree (badlogic/pi-mono). Pi's tree is per-turn within
one session; this one is per-Run across all sessions and all runtimes.
Every Run carries parent_run_id + root_run_id (Rule 3), so the forest
exists in the schema — we just didn't have a view.

apps/web/app/api/runs/forest/route.ts
  GET /api/runs/forest
    ?since=<epoch_ms>           default: 7d window
    ?runtime=pi,claude-code     comma-separated filter
    ?root_run_id=<id>           zoom into a subtree
    ?limit=<n>                  cap 1-250 (Typesense per_page max)

  Returns a flat list of Runs sorted by started_at + metadata for
  client-side tree assembly. Privacy-filtered by readable_by (Rule 4).

scripts/joelclaw-runs-tree.ts → ~/.bun/bin/joelclaw-runs-tree
  Terminal renderer with ANSI-colored runtime badges, box-drawing tree
  connectors, relative timestamps, turn counts, tag chips, intent
  clipped to 80 chars, clean sort order (started_at asc per bucket).

Orphan-root handling: a Run whose parent_run_id isn't in the result
set (trimmed by limit/since/runtime filters) becomes a visible root
rather than being dropped. Deterministic output.

Verified live:
  $ joelclaw-runs-tree --since=6h --limit=100
  3 Runs (3 roots) since 2026-04-19T20:09
  ├─ claude-code 22m ago 2t #phase1-v3
  │     third attempt with typesense key in env
  ├─ claude-code 21m ago 1t #smoke-e2e
  │     test
  └─ claude-code 18m ago 82t #smoke-e2e
        Explore the project at /Users/joel/Code/joelhooks/joelclaw…

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 19:09:44 -07:00
Joel Hooks 64581c91f2 fix(memory): Stop hook with incremental capture — not SessionEnd
You work on sessions for days. SessionEnd never fires in that workflow,
so capture would never happen. Pivoting to Stop (per Rule 3 — Run = one
invocation), with per-session byte-offset state so each Stop only ships
the delta.

~/.joelclaw/session-state.json tracks { last_byte_offset, last_run_id,
turn_count, last_captured_at } keyed by Claude Code session_id. Each
capture uses the prior last_run_id as parent_run_id, so a long session
becomes a chain of per-turn Runs with tree linkage intact.

Safety: ALWAYS exits 0 (never blocks Claude continuation). Failures
outbox the delta and leave state unadvanced so the next Stop retries
the same range.

Verified manually:
  - 3.4MB / 694-turn backfill of this live session → 1 POST, state
    advanced to current EOF
  - 15 seconds later, second invocation captured a 504-byte delta
    (the conversation that happened in between) with parent_run_id
    pointing back at the first

settings.json flipped from SessionEnd → Stop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 19:06:40 -07:00
Joel Hooks e15a9a5a13 feat(memory): Phase 4 slice — capture hook + terminal search CLI
Closes the feedback loop: Claude Code sessions now flow automatically
into the memory archive, and Joel can search from any terminal without
curl.

scripts/joelclaw-capture-session.ts — Claude Code SessionEnd hook target.
  Reads the hook context JSON from stdin (session_id + transcript_path),
  loads bearer from ~/.joelclaw/auth.json, POSTs the transcript to
  /api/runs. Outboxes to ~/.joelclaw/outbox/ on network failure
  (documented Rule 8 path). Exits 0 for success/skip, 2 for network-
  recovered, 1 for hard failures.

scripts/joelclaw-runs-search.ts — terminal-native hybrid search.
  Reads auth from ~/.joelclaw/auth.json, POSTs /api/runs/search with
  the same bearer, formats hits with ANSI color + relative timestamps.
  Supports --mode, --limit, --tag, --runtime, --json.

Installation (this commit only sets up the repo-canonical scripts;
symlinks and settings.json hook are set up manually):
  ln -sf ~/Code/joelhooks/joelclaw/scripts/joelclaw-capture-session.ts \\
    ~/.bun/bin/joelclaw-capture-session
  ln -sf ~/Code/joelhooks/joelclaw/scripts/joelclaw-runs-search.ts \\
    ~/.bun/bin/joelclaw-runs-search

And ~/.claude/settings.json gets a SessionEnd hook pointing at the
capture script.

Proper Phase 4 graduation (pi extensions, codex hooks, Outbox drain
timer, incremental capture) is still ahead — this slice is the
ambient-capture minimum that turns the system on.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 19:00:39 -07:00
Joel Hooks bd248e5c10 chore(memory): cut over RUN_CHUNKS_COLLECTION from run_chunks_spike → run_chunks_dev
Phase 1 is production-directed; the spike collection (run_chunks_spike)
has served its purpose and is decoupled from the active code path. The
45 spike chunks can be dropped per ADR-0243's verification checkbox
once we're ready for the final cutover.

E2E smoke now passes:
  POST /api/runs (169KB fixture) → 82 chunks indexed → hybrid search
  returns 5/11 hits in 202ms (192ms embed + 10ms Typesense).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:52:44 -07:00
Joel Hooks d743b9efbd fix(memory): register memoryEmbed + memoryRunCaptured in index.host.ts
The host worker's function roster is defined in index.host.ts (ADR-0089
cluster/host split). Adding to index.ts alone is insufficient — functions
must be explicitly listed in whichever role owns them. These two are
host-role (they call Ollama on localhost and NAS via local filesystem,
neither of which cluster pods can reach without being deliberately
exposed).

Verified end-to-end after restart:
  POST /api/runs → memory/run.captured Inngest function runs
  → chunks embedded + indexed in Typesense
  → POST /api/runs/search returns both chunks in 206ms
     (201ms query embed + 4ms Typesense + 1ms framework)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:47:38 -07:00
Joel Hooks 0f95255c84 Restore the live joelclaw PDS operator surface by adding the missing pds CLI, canonical repo skill, and current health checks for the rebuilt service 2026-04-19 18:47:10 -07:00
Joel Hooks ad68fda051 fix(memory): Dockerfile must copy packages/memory into runtime image
The new @joelclaw/memory dep added to system-bus was causing crash loops
in the deployed worker:

  error: ENOENT reading "/app/packages/system-bus/node_modules/@joelclaw/memory"

The runtime stage's COPY list is explicit, not automatic. Added the missing
line next to inference-router + mdx-pipeline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:31:21 -07:00
Joel Hooks 47188aebd2 feat(memory): Phase 1 slice — Run traversal endpoints
Adds the three GET traversal endpoints from ADR-0243 Rule 13 (D shape):

apps/web/app/api/runs/[id]/route.ts
  - GET: fetch the Run metadata row from runs_dev
  - Enforces Rule 4 at read time by checking readable_by.includes(caller)
  - 404 (not 403) on unauthorized — leaks zero information about existence

apps/web/app/api/runs/[id]/jsonl/route.ts
  - GET: stream the full jsonl transcript from NAS
  - Verifies readable_by on the Run row before streaming
  - 410 Gone if the blob is missing on disk (distinct from 404 "no Run")
  - Returns application/x-ndjson with Content-Length; zero buffering

apps/web/app/api/runs/[id]/descendants/route.ts
  - GET: walk a Run's subtree via root_run_id filter
  - Returns root + all descendants ordered by started_at ascending
  - Lets agents reconstruct a workload-rig DAG or a gateway session tree
    in one call

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:29:24 -07:00
Joel Hooks e269155fbe feat(memory): Phase 1 slice — POST /api/runs/search + E2E smoke script
Completes the Phase 1 ingest + retrieval loop per ADR-0243 build order step 7.

apps/web
  - new app/api/runs/search/route.ts — hybrid Typesense search with the
    full agent-first API surface (Rule 12 + 13):
      * Auto-applied privacy filters (user_id + readable_by) from the
        bearer token — NEVER from the request body (Rule 4)
      * Tag filters default to AND semantics
      * Modes: hybrid (default), semantic, keyword
      * Embeds the query at priority="query" so it preempts any pending
        ingest work in the Ollama queue (Rule 9a)
      * HATEOAS envelope with _links, next_actions, and timing breakdown
        (query_embed_ms, query_queued_ms, typesense_ms, total_ms)

scripts/memory-spike
  - new smoke-e2e.ts — full pipeline validation:
      1. POST /api/runs with a real claude-code jsonl fixture
      2. Poll Typesense for chunks matching the new run_id
      3. POST /api/runs/search filtered to the smoke-e2e tag
      4. Assert the ingested Run is findable
    Run against a live dev stack (Next.js on :3000, worker deployed,
    Typesense + Ollama + Inngest healthy).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:23:57 -07:00
Joel Hooks a02ece9702 feat(memory): Phase 1 slice — memory/run.captured + POST /api/runs
Adds the central ingest path for agent Run capture per ADR-0243 build order
steps 5 and 6:

packages/memory
  - src/schemas/runs.ts — Typesense `runs_dev` collection schema covering
    the full Run row from types.ts
  - src/nas.ts — blob writer honoring Rule 11 (user-partitioned paths);
    env var MEMORY_RUN_STORE defaults to ~/.joelclaw/runs-dev/ for local
    development, set to /nas/memory/runs in production

packages/system-bus
  - new memory/run.captured + memory/run.indexed event contracts
  - new functions/memory/run-captured.ts — receives event, loads jsonl
    from NAS (or inline payload), format-detects, chunks via per-turn
    chunker, embeds each chunk at ingest-realtime priority through
    @joelclaw/inference-router (so queries preempt), writes chunks to
    run_chunks_dev and Run row to runs_dev, emits OTEL + fanout indexed
    event; concurrency:4, retries:3; ensures collections exist idempotently
  - @joelclaw/memory added to dependencies

apps/web
  - new app/api/runs/route.ts — POST handler; dev bearer token auth
    (hardcoded allowlist, PDS flow lands Phase 3), writes jsonl to NAS
    via @joelclaw/memory writeRunBlob, fires memory/run.captured via
    HTTP to local Inngest, returns 202 HATEOAS envelope with run_id +
    _links + next_actions
  - @joelclaw/inference-router + @joelclaw/memory added to dependencies

Still v1 / dev scope:
  - Dev bearer token, not PDS App Password (Phase 3)
  - _dev collection suffix, will alias to run_chunks_current after cutover
  - No search endpoint yet (next slice)
  - No capture hooks yet (Phase 4)
  - No entity enrichment yet (Phase 6)

Typecheck clean, biome clean, 12 chunking tests still green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:21:35 -07:00
Joel Hooks c32beaa5b0 Restore bluesky-pds after a rebuild by documenting the Helm/account recovery flow and resolving PDS session auth through the repo handle before dual-write logs in 2026-04-19 18:16:26 -07:00
Joel Hooks b646d1cadf Auto-heal joelclaw knowledge search by recreating system_knowledge and retrying when Typesense says the collection is missing 2026-04-19 18:15:57 -07:00
Joel Hooks e357bcc609 feat(memory): Phase 1 slice — embed priority lanes (ADR-0243 Rule 9a)
Validates ADR-0243 Rule 9a with a decisive contention test. Priority-lane
embed scheduling measured at 338ms query latency with 98 ingest-bulk embeds
queued — a ~25x improvement over the 8-10s observed in the spike without
priority discipline.

@joelclaw/inference-router
  - new src/embeddings.ts — PriorityEmbedClient with single-writer queue
    honoring query > ingest-realtime > ingest-bulk; embed() returns queued_ms,
    compute_ms, total_ms for observability
  - new __tests__/embeddings-priority.test.ts — drives 100 ingest-bulk embeds
    then submits one query-priority embed mid-stream; asserts query < 3s
    (observed 338ms); skips gracefully when Ollama is unreachable
  - vitest added as devDependency; tests pass under vitest 4

@joelclaw/memory
  - new __tests__/chunking.test.ts — 12 tests locking in the tool_result
    role detection fix that landed during the spike, format detection
    (claude-code vs pi), meta-entry filtering, thinking-content handling,
    oversized-turn sub-chunk splitting, and malformed-JSON tolerance

packages/system-bus
  - memory/embed.requested + memory/embed.completed event contracts added
    to Events map
  - new functions/memory/embed.ts — Inngest durable wrapper, concurrency:1
    (matches Ollama internal serialization), priority.run expression mapping
    the three lanes to numeric scheduling scores, OTEL emission + fanout
    completed event; calls @joelclaw/inference-router under the hood

Query path bypasses Inngest and calls the router directly (fast, no
durability needed). Only ingest paths fire memory/embed.requested. Both
converge on the same priority queue — that's where the contention is
resolved.

ADR-0243 status: accepted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:15:21 -07:00
Joel Hooks 9517bc242d Default joelclaw otel emit provenance to role and hostname instead of unknown and record the docs-api secret needed after a rebuild 2026-04-19 16:54:35 -07:00
Joel Hooks a7113d8265 Restore Typesense host access on NodePort 8108 so OTEL ingest and CLI observability stop hanging after the Colima rebuild 2026-04-19 16:41:36 -07:00
Joel Hooks 4c2e658592 Stop kube-operator-access from piggybacking Lima's ssh mux and cancel stale forwarded operator ports before launchd bootstrap 2026-04-19 16:30:29 -07:00