Skip to content

feat: v0.1.0–v0.1.3 — Business platform, real-world hardening, production stability - #19

Closed
medomar wants to merge 1719 commits into
developfrom
feat/V0.0.2
Closed

medomar wants to merge 1719 commits into
developfrom
feat/V0.0.2

Conversation

@medomar

@medomar medomar commented Mar 18, 2026

Copy link
Copy Markdown
Owner

Summary

Merges 355 commits (344 files changed, 64K+ lines added) from feat/V0.0.2 into develop. This branch contains all development work from v0.1.0 through v0.1.3 — 1020 tasks across Phases 116–169.

v0.1.0 — Business Platform (173 tasks, Phases 116–127)

  • Document Intelligence — PDF, Excel, CSV, Word, image, email processing with AI entity extraction
  • DocType Engine — dynamic schema system with computed fields, lifecycle hooks, validation
  • Integration Hub — credential store (AES-256-GCM), webhook router, adapter framework
  • Workflow Engine — trigger → condition → action pipelines with schedule support
  • Business Document Generation — invoices, reports, contracts from DocType data
  • API Adapter Framework — PostgreSQL, REST, SMTP adapters with connection pooling
  • Industry Templates — retail, restaurant, real-estate starter packs
  • Skill Pack Extensions — domain-specific worker instruction sets
  • Agent SDK — permission relay for embedded use cases

v0.1.1 — Real-World Testing Fixes (25 tasks, Phases 128–132)

  • Workspace map persistence, prompt budget 32K, worker cost caps, activity tracking, classification improvements

v0.1.2 — Security & Isolation (76 tasks, Phases 133–151)

  • Model budgets, prompt size cap fix, WebChat session isolation, worker file ops, trust level system, workspace boundary hardening

v0.1.3 — Production Stability (66 tasks, Phases 152–169)

  • Escalation loop fix (OB-F214), DLQ error response, classification escalation, worker boundaries, headless safety, message queueing, remote delivery, escalation OOM prevention

Stats

  • 230 findings fixed (OB-F1 through OB-F230)
  • 230 feat / 78 test / 25 fix / 16 docs / 5 chore / 1 refactor commits
  • All 1672 tasks archived (v0–v29)
  • 0 open findings

Test plan

  • npm run lint passes
  • npm run typecheck passes
  • npm run test passes
  • npm run build passes
  • Merge to develop, then develop → main for release tag

🤖 Generated with Claude Code

medomar and others added 30 commits March 12, 2026 23:17
Implements src/intelligence/pdf-generator.ts with:
- generatePdf(definition, workspacePath): writes TDocumentDefinitions
  to .openbridge/generated/{uuid}.pdf using Roboto fonts bundled with pdfmake
- createInvoicePdfDefinition(record, items, branding): builds a branded
  A4 invoice PDF definition with line-item table, tax, totals, and optional
  payment link / notes footer

Installs pdfmake as a runtime dependency and @types/pdfmake as devDependency.

Resolves OB-1435

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Create buildInvoiceDefinition() in templates/invoice-template.ts that
generates a professional pdfmake document definition with business logo,
invoice metadata, bill-to section, line items table, subtotal/tax/total,
payment QR code, notes, and terms & conditions footer.

Resolves OB-1436

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… line

Create src/intelligence/templates/quote-template.ts with buildQuoteDefinition()
function. Mirrors the invoice template but with QUOTE header, validity period
display, no payment link, terms and conditions section, and an acceptance
signature block with authorized signature and date lines.

Resolves OB-1437
Create src/intelligence/templates/receipt-template.ts with buildReceiptDefinition()
function that generates compact receipt PDFs with business name, date/time, items,
total amount, payment method, and thank you message. Uses 80mm thermal printer
width (280px) for typical receipt format.

Resolves OB-1438
…e numbers

Resolves OB-1439

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generate QR codes as data URLs using the qrcode package and embed them
in invoice PDFs for payment links. Updates createInvoicePdfDefinition()
to be async and generate QR codes when a paymentLink is provided.

Resolves OB-1440

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Create src/intelligence/branding.ts with the canonical Branding type
(companyName, address, phone, email, taxId, logoPath, primaryColor,
secondaryColor) plus loadBranding() and saveBranding() helpers that
persist to .openbridge/context/branding.json with safe defaults when
the file is absent.

Resolves OB-1441
…d welcome

Resolves OB-1442

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
23 tests covering generatePdf() file creation, invoice template fields,
QR code data URL generation, branding logo inclusion, and file size bounds.
pdfmake mocked for generatePdf() tests to avoid font dependency.

Resolves OB-1443

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update handleGeneratePdf in hook-executor.ts to use pdf-generator.ts
and the business document templates (invoice, quote, receipt, report)
instead of Puppeteer for known template names. Puppeteer is kept as
fallback for custom HTML templates. Branding is loaded via loadBranding().

Resolves OB-1444

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…adapter

Adds multi-format input detection as the entry point for /connect api <input>.
- detectInputFormat() detects: curl, url, openapi (JSON/YAML), postman, unknown
- parseInputToOpenAPI() routes to the correct parser; stubs for postman/curl
  with clear error messages pointing to OB-1446 and OB-1447

Resolves OB-1445

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Create src/integrations/parsers/postman-parser.ts with postmanToOpenAPI()
that converts Postman collections to OpenAPI 3.0 specs. Supports:
- Request extraction (method, URL, headers, body)
- Folder structure → OpenAPI tags
- Auth settings (bearer, basic, apikey) → security schemes
- Example responses → OpenAPI response definitions
- {{variable}} substitution with user-provided values
- Multiple body modes (raw JSON, urlencoded, formdata, file)

Wire parser into parseInputToOpenAPI() in openapi-adapter.ts so
Postman collections are automatically detected and converted.

Includes 20 unit tests covering all conversion features.

Resolves OB-1446

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create src/integrations/parsers/curl-parser.ts with:
- curlsToOpenAPI(): parses cURL commands into OpenAPI 3.0 spec
- splitCurlCommands(): splits multi-command input into individual curls
- Supports -X, -H, -d, --data-raw, --data-binary, -u, -b flags
- Handles backslash line continuation
- Extracts auth (bearer, basic, API key) into security schemes
- Infers JSON schema from request bodies
- Derives common base URL from multiple commands
- Wired into parseInputToOpenAPI() in openapi-adapter.ts

Resolves OB-1447

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create src/integrations/parsers/doc-parser.ts with docsToOpenAPI() function
that spawns a read-only AI worker to extract API endpoints from any
documentation format (Markdown, HTML, plain text, pre-extracted PDF text).
The worker output is parsed into an OpenAPI 3.0 spec with proper paths,
parameters, request bodies, auth schemes, and tags.

Resolves OB-1448

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add RoleConfig type, integration_capabilities SQLite table (migration v21),
standalone tagCapabilitiesByRole() / getCapabilityRoles() helpers, and
OpenAPIAdapter.tagCapabilitiesByRole() + describeCapabilities(role?) methods.

Resolves OB-1449

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Create EventBridge class supporting four event source types:
- WebSocket (Node 22+ native, auto-reconnect)
- Server-Sent Events (SSE with streaming parser)
- Polling (configurable interval, change detection)
- Webhook (delegates to existing WebhookRouter)

Features glob-style event pattern matching, normalized BridgeEvent
payloads, pluggable auth (bearer/basic/header/query), and
EventEmitter-based notification dispatch.

Resolves OB-1450

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create src/integrations/skill-pack-generator.ts with generateSkillPack()
that spawns an AI worker to auto-generate SKILLPACK.md files from parsed
OpenAPI specifications. The generated skill packs teach the Master AI
how to use connected APIs naturally through conversation.

Resolves OB-1451

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
/connect api now accepts: URL to OpenAPI/Swagger spec, URL or JSON for
Postman collections, inline cURL commands (including multi-line), and
any recognised format via detectInputFormat(). On connection:
- Detects format and acknowledges to the user
- Parses with parseInputToOpenAPI() (routes to postman/curl/openapi parsers)
- Derives an API slug from the spec title
- Registers + initialises OpenAPIAdapter in the hub with serialised specJson
- Reports all discovered capabilities to the user
- Async-generates a skill pack via generateSkillPack()
- Asks clarifying questions if the format is unrecognised

Also fixes the /connect regex to use [\s\S]+ so multiline cURL commands
are captured correctly.

Resolves OB-1452

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a user sends a file (Postman JSON, Swagger YAML, PDF API docs) along
with /connect api, the processedDocument rawText is used as the spec input.
Direct format detection (openapi/postman/curl) is tried first; unknown formats
fall back to AI-powered doc extraction via doc-parser.ts.

Standalone cURL messages are now accumulated per-user in CommandHandlers.
Saying "done" or "connect" after accumulating cURLs flushes the buffer and
triggers the full /connect api flow with all accumulated commands joined.

Resolves OB-1453

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements generateDefaultWorkflows() in src/integrations/workflow-templates.ts.
Analyses an OpenAPI spec and suggests up to three draft workflows:
  1. Notify on new records — triggers on POST endpoint webhook
  2. Daily summary — schedules a daily GET list endpoint fetch
  3. Status change alerts — triggers on PATCH/PUT endpoint with status field

Suggestions are sent to the user after skill pack generation completes,
with numbered approve/skip instructions to enable conversational approval.

Resolves OB-1454

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- openapi-adapter.ts: replace stub healthCheck() with real HTTP probing
  - Auto-detects health endpoint from well-known spec paths or first GET
  - Stores results in integration_health_log table
  - Alerts on healthy/unknown to unhealthy transition via callback
  - Exposes getLastHealthLog() for querying last check result
- hub.ts: add setHealthAlertHandler() + transition detection
- migration.ts: add v22 migration creating integration_health_log table
- command-handlers.ts: /integrations shows last check timestamp from DB
- migration.test.ts: update expected version list to include v22

Resolves OB-1455
All 20 tests in tests/integrations/postman-parser.test.ts pass.
Tests cover: requests parsed correctly (method/URL/headers/body),
variable substitution (collection + user overrides), folder → tag
mapping, and OpenAPI 3.0 output structure.

Resolves OB-1456
Tests cover: (1) simple GET cURL parsed, (2) POST with JSON body and
schema inference, (3) Bearer/Basic/API-key auth headers extracted,
(4) multi-line cURL with backslash continuation, (5) multiple cURLs
grouped into a single server entry, (6) output is valid OpenAPI 3.0
with correct top-level fields and operation IDs.

Resolves OB-1457
Add comprehensive integration test covering the full API connection
pipeline: Postman collection parsing, cURL command parsing, adapter
initialization, capability listing, and HTTP call dispatch with
mocked fetch.

17 tests across 4 describe blocks:
- Postman collection → OpenAPI → adapter → capabilities
- cURL commands → OpenAPI → adapter → capabilities
- Natural language query → correct HTTP call (GET/POST with auth)
- Format detection edge cases

Resolves OB-1458

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create src/intelligence/template-loader.ts with:
- IndustryTemplate type with DocTypeDefinition and WorkflowDefinition
- loadTemplate(workspacePath, templateId) reads manifest.json from
  .openbridge/industry-templates/{id}/, resolving skillPack file paths
- applyTemplate(db, template) creates all DocTypes and Workflows,
  idempotent (skips already-existing records by name)

Resolves OB-1459

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…(OB-1460)

Creates src/intelligence/industry-detector.ts with detectIndustry() function
that spawns a read-only worker via AgentRunner to classify business type from
workspace context and user messages, returning the best-match template ID.

Supported template IDs: restaurant, retail, services, car-rental,
construction, marketplace-seller. Falls back to 'services' on failure.

Follows the same dynamic-import AgentRunner pattern as entity-extractor.ts
to avoid circular dependencies.

Resolves OB-1460

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Create restaurant template with 5 DocTypes (menu-item, supplier,
inventory-item, daily-sales, expense) and 3 workflows (low-stock-alert,
daily-prep-list, weekly-food-cost-report) plus skill-pack.md with
restaurant-specific operational guidance.

Resolves OB-1461

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add car rental template with 4 DocTypes (vehicle, booking,
maintenance-log, rental-contract), 3 workflows (maintenance-due-alert,
booking-confirmation, insurance-expiry), and a skill pack for fleet
management, availability checks, and damage assessment.

Resolves OB-1462

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds retail template with 4 DocTypes (product, customer, sale,
purchase-order) and 3 workflows (low-stock-reorder, daily-sales-report,
customer-follow-up). Includes skill pack for inventory management,
pricing, and customer relationship guidance.

Resolves OB-1463
Adds services template to src/intelligence/industry-templates/services/:
- manifest.json: 4 DocTypes (client, project, invoice, timesheet) with
  fields, states, transitions, hooks, and relations appropriate for
  professional services businesses (consulting, agency, freelance)
- skill-pack.md: guidance for project management, time tracking,
  invoicing, and billing with key metrics (utilisation rate, effective
  hourly rate, AR aging)
- 3 workflows: invoice-overdue-reminder (daily), project-milestone-
  notification (event-driven), monthly-revenue-report (1st of month)

Resolves OB-1464

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
shtayner and others added 27 commits March 17, 2026 07:31
…1 (OB-1646)

Export trimPayload from exploration-prompts.ts and import it in
exploration-coordinator.ts. In executePhase1StructureScan(), append a
concise-output instruction to the Phase 1 prompt so the AI limits its
file listing to 50 per directory and keeps output under 100K chars.
After receiving the agent's stdout, trim it to PROMPT_CHAR_BUDGET if it
exceeds the limit, preventing downstream prompt truncation in Phase 2+.

Resolves OB-1646

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tfolder-manager

Across 11 readX() methods in dotfolder-manager.ts, distinguish ENOENT errors
(expected on first run) from other read failures. ENOENT errors now log at
DEBUG level with 'File not found (expected on first run)', while parse/other
errors still log at WARN level. Methods with pre-existing fs.access() checks
(readWorkspaceMap, readSystemPrompt, readLearnings, readPromptManifest,
readBatchState) were left unchanged as they already handle the case. This
reduces log noise on startup by filtering expected first-run file misses.

Resolves OB-1647
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…ion/ guard (OB-1648)

Add two tests to tests/core/bridge.test.ts:
- 'skips exploration/ deletion when state is incomplete' — verifies fs.rm is NOT
  called when exploration-state.json has status 'structure_scan'
- 'deletes exploration/ when state is completed' — verifies fs.rm IS called when
  state is 'completed'

Uses vi.mock('node:fs/promises') factory pattern to intercept fs calls.
Phase 162 (OB-F224) now fully complete.

Resolves OB-1648

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ts (OB-1649)

Expand workspace boundary protection in worker-orchestrator.ts to
prepend the .openbridge/ directory protection instruction to ALL worker
prompts regardless of trust level (previously only injected in trusted
mode). The existing workspace boundary instruction stays in the
trusted-mode block.

Resolves OB-1649

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rompt

Adds explicit guidance to the Master AI's system prompt about protecting
.openbridge/ internal state files. This complements OB-1649's worker-level
protection by ensuring the Master AI itself reminds workers not to modify
memory.md, workspace-map.json, and other internal state.

Updates TASKS.md: marks OB-1650 as Done, increments Done counter.

Resolves OB-1650
- In exploration-manager.ts, backup memory.md content to SQLite
  (system_config key 'memory_md_backup') after every writeMemoryFile call
- In master-manager.ts startup path, try SQLite backup restore before
  falling back to conversation-history regeneration when memory.md is stale

Resolves OB-1651

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…B-1652)

Add a new describe block in worker-orchestrator-trust.test.ts verifying that
spawnWorker() always prepends the dotfolder protection instruction regardless of
trust level. Tests cover both standard and trusted modes, capturing the prompt
passed to manifestToSpawnOptions and asserting it contains ".openbridge/" and
"Do NOT delete". Also fixes the performReasoningCheckpoint mock from
mockResolvedValue to mockReturnValue (the function is called synchronously).

Resolves OB-1652

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…B-1653)

Add 'Headless Environment' section to master-system-prompt.ts between
Turn-Budget Warnings and Worker Failure Re-delegation sections. Documents
that workers run headless and cannot use interactive OAuth/browser auth tools.
Instructs Master to use pre-authenticated tokens or SHARE:github-pages for
static site deployment instead.

First of three tasks to resolve OB-F226 (workers attempting interactive auth).

Resolves OB-1653

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…-delegation

Add a 7th category to the Worker Failure Re-delegation table in
master-system-prompt.ts to handle the new auth-required error case.
When workers attempt interactive authentication (OAuth flows, browser
logins), the Master now knows to suggest alternative methods instead of
retrying with the same approach.

Resolves OB-1654
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add authAborted flag to detect when OAuth patterns are detected
- Expand stderr handler to check for interactive OAuth URLs and patterns:
  * https://*/authorize? and https://*/login? patterns
  * https://*/oauth pattern
  * "Waiting for authorization" and "Open the following URL" messages
- Kill process early with SIGTERM when OAuth pattern detected
- Mark auth-required errors with special stderr suffix for classification
- Add auth-required patterns to error classifier for detection
- Fixes OB-F226 (interactive CLI auth blocking in headless environment)
- Completes Phase 164 (Headless Worker Safety)

Resolves OB-1655
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Instead of dropping messages with "Master not ready" when state is
'processing', store up to 5 messages in processingPendingMessages[].
Returns an acknowledgment to the sender. Messages beyond the cap get
a "too many queued" rejection. Other non-ready states (idle, error,
shutdown, delegating) keep the existing WARN+rejection behaviour.

Resolves OB-1656

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After processMessage() completes successfully, drain any messages that
were queued while the master was busy processing. Each queued message is
re-routed through this.router.route() which handles auth, output markers,
response delivery, and all other routing concerns.

The drain sets state='ready' before each queued message so it passes
the processing guard, and clears the queue atomically at the start to
avoid double-processing. Errors per queued message are caught and logged
without aborting the remaining drain.

Resolves OB-1657

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…658)

Add mergeRapidFireImageMessages() helper to MasterManager that detects
consecutive image-only messages followed by a text message from the same
sender within a 10-second window in the processing-pending queue. When
found, the image OCR context (from processedDocument.rawText) is prepended
to the text message's content before routing, and the image-only messages
are removed from the drain queue.

Resolves OB-1658

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add three tests to tests/master/master-manager.test.ts covering the
processing queue introduced in Phase 165 (OB-F229):
- 'queues messages during processing state instead of dropping them'
- 'sends acknowledgment to user when message is queued'
- 'caps queue at 5 messages per user'

Resolves OB-1659

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In tests/master/master-manager.test.ts, add test
'merges rapid-fire image+text messages from same sender'.
Mocks two image messages (with OCR processedDocument.rawText) and
one text message from the same sender within a 10-second window,
all queued during active processing. Verifies the drain mechanism
calls mergeRapidFireImageMessages() and the router receives a
single merged message containing the image count prefix and both
OCR texts prepended to the original text content.

Resolves OB-1660
Add a detailed block comment above the safeTimeout computation in
master-manager.ts explaining the full timeout chain:
- turnsToTimeout() formula (CLI_STARTUP_BUDGET_MS + n × PER_TURN_BUDGET_MS)
- Per-class examples (quick-answer=120s, tool-use=480s, complex-task=780s)
- DEFAULT_MESSAGE_TIMEOUT 170s clamp effect
- Why quick-answer still times out: Master --resume context loading +
  worker spawn + worker execution exhausts the 120s budget under load

Resolves OB-1661

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…adroom (OB-1662)

Increase DEFAULT_MESSAGE_TIMEOUT from 180_000 to 300_000 (5 minutes) so
tool-use and complex-task Master sessions get a full 300s instead of the
previous 170s clamp. Remove the unnecessary 10s headroom reduction from
the safeTimeout formula — the Master session IS the top-level process and
has no outer timeout to race against.

Quick-answer tasks are unaffected: turnsToTimeout(3) = 120s, clamped to
min(120s, 300s) = 120s.

Resolves OB-1662
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…B-1663)

When processMessage() catches an AgentExhaustedError with exit code 143
(SIGTERM timeout), return a user-facing timeout message instead of
propagating the error silently to the DLQ. The message includes the
elapsed seconds so users know how long was spent, and advises breaking
the request into smaller steps.

- Import AgentExhaustedError from agent-runner.ts
- In the processMessage() catch block, detect lastExitCode === 143
- Return a formatted timeout string instead of re-throwing

Resolves OB-1663

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds test 'sends partial response on Master session timeout' in
tests/master/master-manager.test.ts. Mocks spawn to throw
AgentExhaustedError with exit code 143 (SIGTERM) and verifies
processMessage() returns the user-friendly timeout message instead of
propagating to the DLQ silently (OB-1663 fix coverage).

Also imports AgentExhaustedError as a value import alongside the
existing type imports so the mock class instance passes instanceof checks.

Resolves OB-1664
…r-manager)

Verified that all readX() methods in src/master/dotfolder-manager.ts
correctly log ENOENT errors at DEBUG level (not WARN). The work was
completed by OB-1647 (commit 62d2375). All required methods are covered:
- readMemoryFile()
- readClassification()
- readClassifications()
- readWorkers()
- readProfiles()
- readMasterSession()
- readExplorationState()

Plus additional methods using the same pattern or fs.access() guards.
This reduces log noise on startup by filtering expected first-run file misses.

Resolves OB-1665
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…OB-1666)

Remove WARN logs from DockerSandbox.isAvailable() method since it's called
frequently during health monitoring and worker spawning. Instead, rely on
DockerHealthMonitor to log WARN only on state transitions (available→unavailable).

Changes:
- DockerSandbox.isAvailable() is now silent; returns false without logging
- DockerHealthMonitor._check() continues to handle state transition logging
- agent-runner.ts fallback path now logs at DEBUG level instead of WARN
- Fixes the remaining WARN-on-every-check path after OB-1610 fixed the health
  monitor itself

Resolves OB-1666: Verify OB-F215 fix is working across all code paths.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
New file: tests/integration/message-lifecycle.test.ts

Four tests covering the full DLQ → error response flow using a mock
'telegram' connector and a failing mock provider (maxRetries: 0):

1. Connector receives the error response when message reaches DLQ
2. DLQ contains the failed message with correct id and error string
3. Audit logger records an 'error' event for the failed message
4. DLQ callback is exception-safe (delivery failure does not propagate)

Resolves OB-1667

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In tests/integration/message-lifecycle.test.ts, adds a new
'Processing queue flow (OB-1668)' describe block that verifies:
(1) the first message is processed normally,
(2) messages 2 and 3 are queued and not dropped while message 1
    is in-flight (controlled via a deferred gate),
(3) after message 1 completes, messages 2 and 3 drain in FIFO order,
(4) all three messages receive responses via the connector.

Resolves OB-1668
…fixes (OB-F214, OB-F230)

Fix infinite escalation loop in master-manager.ts respawnWorkerAfterGrant
(missing depth cap and suffix stripping that worker-orchestrator.ts already
had). Also fixes classification engine: allow quick-answer escalation from
learning data, prefer keyword classifier when AI under-classifies with
moderate confidence, and add max-turns user guidance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…4–F230)

Archive completed tasks and findings to v29. Reset TASKS.md and FINDINGS.md
to clean slate. Update ROADMAP.md, FUTURE.md, and CLAUDE.md with v0.1.3
release state: 1672 tasks shipped, 230 findings fixed across 169 phases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…OB-F214)

- Check worker ID (not profile) for escalation depth counting
- Strip existing `-escalated` chain before appending to prevent ID growth
- Skip pre-flight tool prediction for already-escalated workers to break
  escalate → respawn → predict → escalate infinite loop

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…sdk peer dep

@anthropic-ai/claude-agent-sdk@0.2.74 requires zod@^4.0.0 as peer dependency.
Upgrade zod to 4.3.6 and change all imports to 'zod/v3' compat path to avoid
breaking changes while satisfying the peer requirement.

- 34 files updated: `from 'zod'` → `from 'zod/v3'`
- Typecheck, lint, and build all pass
- zod/v3 is a permanent backward-compatible subpath in zod v4

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@medomar medomar closed this Mar 23, 2026
@medomar
medomar deleted the feat/V0.0.2 branch March 23, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants