Commit graph

102 commits

Author SHA1 Message Date
Snider
f17e1a0b6c chore(brain): use HTTPS for Ollama via Traefik
Some checks are pending
CI / PHP 8.3 (push) Waiting to run
CI / PHP 8.4 (push) Waiting to run
Ollama is behind Traefik reverse proxy on ollama.lan, so no port
needed and TLS should be enforced by default.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 10:12:34 +00:00
Snider
43b470257b feat(brain): configurable embedding model, default to EmbeddingGemma
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 3s
Make embedding model swappable via BRAIN_EMBEDDING_MODEL env var.
Switch default from nomic-embed-text to embeddinggemma (Gemma 3
based, 2x better cluster separation in benchmarks).

Default Ollama URL now points to ollama.lan (Linux homelab GPU).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 10:10:02 +00:00
Snider
dfd3dde7b1 feat(brain): add brain:seed-memory artisan command
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Scans ~/.claude/projects/*/memory/ for MEMORY.md and topic markdown
files, parses sections, infers memory types, and imports into
OpenBrain via BrainService::remember().

Supports --dry-run, --workspace, --agent, and --path options.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:53:28 +00:00
Snider
d82ad2b9b1 fix(brain): address code quality review findings
- Move BrainMemory::create() inside BrainService::remember() for
  full atomicity (DB + Qdrant in single transaction)
- Add forWorkspace() scope to recall() MariaDB query (tenant isolation)
- Wrap forget() in DB::transaction (MariaDB first, then Qdrant)
- Check qdrantDelete() response and log warnings on failure
- Validate embed() response is a non-empty array

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:47:42 +00:00
Snider
2c6a095a0e fix(brain): address spec review findings
- Move BrainForget DB lookup inside circuit breaker for consistency
- Check ensureCollection() PUT response for Qdrant errors
- Wrap remember() in DB::transaction for atomicity
- Align migration confidence default to 0.8 (matches PHP default)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:45:05 +00:00
Snider
eeb6927d8f feat(brain): add BrainService, MCP tools, and registration
- BrainService: Ollama embeddings + Qdrant vector upsert/search/delete
- brain_remember: store knowledge with type, tags, confidence, supersession
- brain_recall: semantic search with filter by project/type/agent/confidence
- brain_forget: workspace-scoped deletion from both stores
- brain_list: MariaDB query with model scopes, no vector search
- Config: brain.ollama_url, brain.qdrant_url, brain.collection
- Boot: BrainService singleton + tool registration via AgentToolRegistry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 09:39:19 +00:00
Snider
627813cc4d feat(brain): add BrainMemory model and migration
UUID-keyed brain_memories table with workspace scoping, self-referential
supersession chain, TTL expiry, and confidence scoring. Eloquent model
includes all scopes and helpers needed by the MCP tool layer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 09:33:46 +00:00
Snider
daa11bab39 docs: OpenBrain implementation plan — 8 tasks, TDD
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
8-task plan: migration, BrainService (Ollama+Qdrant), 4 MCP tools
(remember/recall/forget/list), Go bridge subsystem, MEMORY.md seed
command. 18 files across php-agentic and go-ai.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:28:31 +00:00
Snider
a6e4f865e4 docs: OpenBrain design — shared agent knowledge graph
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 2s
Shared vector-indexed knowledge store accessible by all agents via MCP.
MariaDB for relational metadata, Qdrant for semantic search, Ollama for
embeddings. Four MCP tools: brain_remember, brain_recall, brain_forget,
brain_list. Replaces scattered MEMORY.md files with singular state.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:22:56 +00:00
Snider
1ead364afe fix(ci): install zip in release workflow
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 4s
Forgejo Composer API requires zip format.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:43:52 +00:00
Snider
647635fc6d fix(ci): simplify release workflow, use FORGEJO_REF_NAME
Some checks failed
CI / PHP 8.3 (push) Failing after 4s
CI / PHP 8.4 (push) Failing after 3s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:36:18 +00:00
Snider
522433c019 fix(ci): use Forgejo-native variables in release workflow
Some checks failed
CI / PHP 8.3 (push) Failing after 5s
CI / PHP 8.4 (push) Failing after 3s
Replace github.server_url/GITHUB_REF_NAME with explicit forge URL
and GITEA_REF_NAME/GITEA_OUTPUT.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:13:12 +00:00
Snider
29656e3b92 feat: add Forgejo release workflow for Composer registry
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
On tag push (v*), zips the package and publishes to the
forge.lthn.ai Composer package registry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:00:19 +00:00
1bbc1336b7 Merge pull request 'refactor: consolidate duplicate state models (#18)' (#48) from refactor/consolidate-workspace-state-models into main
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
2026-02-24 13:26:37 +00:00
darbs-claude
7fadbcb96c
refactor: consolidate duplicate state models into WorkspaceState (#18)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 1s
CI / PHP 8.4 (pull_request) Failing after 1s
- Delete Models/AgentWorkspaceState.php (legacy port, no backing table)
- Rewrite Models/WorkspaceState.php as the single canonical state model
  backed by agent_workspace_states table with array value cast,
  type helpers, scopeForPlan/scopeOfType, static getValue/setValue,
  and toMcpContext() for MCP tool output
- Update AgentPlan::states() relation and setState() return type
- Update StateSet MCP tool import
- Update SecurityTest to use WorkspaceState
- Add WorkspaceStateTest covering table, casts, type helpers, scopes,
  static helpers, toMcpContext, and AgentPlan integration
- Mark CQ-001 done in TODO.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:26:23 +00:00
80c778cb08 Merge pull request 'feat: add template version management' (#63) from feat/template-version-management into main
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
2026-02-24 13:25:33 +00:00
0e7b617551
feat: add template version management (#35)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 2s
CI / PHP 8.4 (pull_request) Failing after 1s
Snapshots YAML template content in a new `plan_template_versions` table
whenever a plan is created from a template. Plans reference their version
via `template_version_id` so existing plans are unaffected by future
template file edits.

Key changes:
- Migration 0006: create `plan_template_versions` table (slug, version,
  name, content JSON, content_hash SHA-256); add nullable FK
  `template_version_id` to `agent_plans`
- Model `PlanTemplateVersion`: `findOrCreateFromTemplate()` deduplicates
  identical content by hash; `historyFor()` returns versions newest-first
- `AgentPlan`: add `template_version_id` fillable and `templateVersion()`
  relationship
- `PlanTemplateService::createPlan()`: snapshot raw template before
  variable substitution; store version id and version number in metadata;
  add `getVersionHistory()` and `getVersion()` public methods
- Tests: `TemplateVersionManagementTest` covering model behaviour, plan
  creation snapshotting, deduplication, history ordering, and service
  methods

Closes #35

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:25:17 +00:00
ffc441f22a Merge pull request 'fix: improve template variable error messages' (#58) from fix/template-variable-error-messages into main
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 2s
2026-02-24 13:21:14 +00:00
a9a6e258e1 Merge pull request 'feat: add plan archival with retention policy' (#62) from feat/plan-retention-policy into main
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 2s
2026-02-24 13:20:38 +00:00
d26250fc12 Merge pull request 'docs: document MCP tool dependency system' (#60) from docs/doc-002-mcp-tool-dependency-system into main
Some checks failed
CI / PHP 8.3 (push) Has been cancelled
CI / PHP 8.4 (push) Has been cancelled
2026-02-24 13:20:33 +00:00
6a1709fca9 Merge pull request 'fix: audit UK/US spelling consistency (#36)' (#64) from fix/uk-spelling-consistency into main
Some checks failed
CI / PHP 8.3 (push) Failing after 4s
CI / PHP 8.4 (push) Failing after 3s
2026-02-24 13:20:24 +00:00
darbs-claude
7d6081bdd7 fix: use UK English spelling in MCP server docstring (#36)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 3s
CI / PHP 8.4 (pull_request) Failing after 2s
Audited all PHP files for US English spellings per CLAUDE.md convention.
Fixed "Organize" → "Organise" in Mcp/Servers/Marketing.php docstring.

CSS/JS identifiers (borderColor, backgroundColor, transition-colors) and
array keys that form interface contracts with the host-uk/core package are
unchanged as they are not prose.

Closes #36

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 15:41:16 +00:00
cc1c4c1adc feat: add plan archival with retention policy (#34)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 21s
CI / PHP 8.4 (pull_request) Failing after 19s
- Add `agentic.plan_retention_days` config (default 90 days via AGENTIC_PLAN_RETENTION_DAYS env)
- Add SoftDeletes and `archived_at` timestamp to AgentPlan model
- Add migration for `deleted_at` and `archived_at` columns on agent_plans
- Create `agentic:plan-cleanup` command with --dry-run and --days options
- Schedule retention cleanup to run daily via service provider
- Register PlanRetentionCommand in ConsoleBooting handler
- Add PlanRetentionTest feature test suite covering all retention scenarios
- Fix archive() to store archived_at as dedicated column (not metadata string)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 15:11:55 +00:00
b0e2be2633 fix(ci): correct container image expression
Some checks failed
CI / PHP 8.3 (push) Failing after 1s
CI / PHP 8.4 (push) Failing after 1s
2026-02-23 13:47:09 +00:00
a5da40a202 feat(ci): use lthn/build:php container image
Some checks failed
CI / PHP 8.3 (push) Failing after 0s
CI / PHP 8.4 (push) Failing after 0s
Replace setup-php action with pre-built container.
Eliminates ~50s setup overhead per matrix job.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:46:48 +00:00
Claude
be820fead8
fix: use Mockery mocks for ApiKey and fix named arg matching
All checks were successful
CI / PHP 8.4 (push) Successful in 1m41s
CI / PHP 8.3 (push) Successful in 1m44s
- Replace anonymous class extending ApiKey with Mockery mock to avoid
  requiring php-api package at load time
- Replace with() named args with withSomeOfArgs() for Mockery compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:20:01 +00:00
Claude
5f016c6275
style: fix Pint violations in ProcessContentTask and AgentDetection
Some checks failed
CI / PHP 8.3 (push) Failing after 1m49s
CI / PHP 8.4 (push) Failing after 1m48s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:08:49 +00:00
Claude
ae4188c063
fix: template interpolation and Cache::fake() in tests
Some checks failed
CI / PHP 8.4 (push) Failing after 1m26s
CI / PHP 8.3 (push) Failing after 1m55s
- interpolateVariables: use string concatenation for triple-brace
  placeholders instead of PHP string interpolation which only
  produces single braces
- AgentToolRegistryTest: replace Cache::fake() (not available) with
  Cache::flush() since array driver is already in-memory

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:05:54 +00:00
darbs-claude
eb6bc27a4e docs: document MCP tool dependency system
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 1m44s
CI / PHP 8.4 (pull_request) Failing after 1m44s
Add README to Mcp/Tools/Agent/ explaining:
- How ToolDependency works (contextExists, sessionState, entityExists)
- Context requirements (workspace_id, session_id) and multi-tenant safety
- Step-by-step guide for creating new tools
- AgentTool base class property and method reference
- Dependency resolution order and recommended declaration sequence
- Troubleshooting guide for common dependency errors

Closes #32

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 12:05:35 +00:00
b86714db6e Merge pull request 'docs: add PHPDoc to AgentDetection patterns' (#59) from docs/agent-detection-phpdoc into main
Some checks failed
CI / PHP 8.3 (push) Failing after 1m19s
CI / PHP 8.4 (push) Failing after 1m20s
Reviewed-on: #59
2026-02-23 12:04:17 +00:00
Claude
6cd9ca09d7
style: fix pint issues in ContentService and AgentToolRegistryTest
Some checks failed
CI / PHP 8.3 (push) Failing after 1m50s
CI / PHP 8.4 (push) Failing after 1m50s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:58:52 +00:00
darbs-claude
e47998bc15 docs: add PHPDoc to AgentDetection patterns
Some checks failed
CI / PHP 8.4 (pull_request) Failing after 1m21s
CI / PHP 8.3 (pull_request) Failing after 1m23s
Document each PROVIDER_PATTERNS entry with real User-Agent examples,
add inline comments to BROWSER_INDICATORS and NON_AGENT_BOTS with
categorised UA examples, document MCP_TOKEN_HEADER with token format
details, and add class-level usage examples and detection priority
ordering.

Closes #31
Refs: DOC-001

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 11:56:57 +00:00
Claude
938081f2f5
fix: resolve 14 test failures across 3 test files
Some checks failed
CI / PHP 8.4 (push) Failing after 1m33s
CI / PHP 8.3 (push) Failing after 1m35s
ProcessContentTaskTest: set mock properties directly instead of
shouldReceive('__get') which doesn't reliably intercept property
access on Mockery mocks of non-existent classes.

HasStreamParsing: fix parseJSONStream chunked read bug where the
inner parse loop restarted at position 0 with stale state from
a previous partial parse. Track scan position across chunks.

AgentDetection: fix Postman regex \bPostman\b → \bPostman/ so it
matches PostmanRuntime (no word boundary between n and R).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:48:29 +00:00
darbs-claude
91ee71b8a1 fix: improve template variable error messages (#30)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 1m37s
CI / PHP 8.4 (pull_request) Failing after 1m36s
Enhance `validateVariables()` in `PlanTemplateService` to produce
actionable errors instead of the generic "Required variable '...' is missing".

Changes:
- Extracted `buildVariableError()` helper that composes the message from
  the variable's `description`, `format`, `example`, and `examples` fields
- Added `naming_convention` key to the returned array so callers have
  a constant reminder that variable names use snake_case
- Added a `NAMING_CONVENTION` private const to avoid string duplication

Tests (6 new cases in `PlanTemplateServiceTest`):
- description included in error message
- single `example` value included
- `examples` list (first two) included
- `format` hint included alongside example
- `naming_convention` present in both valid and invalid results
- bare variable (no description) still produces useful "missing" message

Closes #30

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 11:48:27 +00:00
5fa46104f4 Merge pull request 'fix: validate API keys on AgenticManager init' (#57) from fix/validate-api-keys-on-init into main
Some checks failed
CI / PHP 8.3 (push) Failing after 1m25s
CI / PHP 8.4 (push) Failing after 1m28s
Reviewed-on: #57
2026-02-23 11:41:12 +00:00
6b7a7ade15 Merge pull request 'fix: improve workspace context error messages' (#56) from fix/workspace-context-errors into main
Some checks failed
CI / PHP 8.3 (push) Failing after 1m29s
CI / PHP 8.4 (push) Failing after 1m27s
Reviewed-on: #56
2026-02-23 11:39:41 +00:00
968cbcdd63 Merge pull request 'fix: add batch failure recovery to ContentService' (#55) from fix/batch-failure-recovery into main
Some checks failed
CI / PHP 8.4 (push) Has been cancelled
CI / PHP 8.3 (push) Has been cancelled
Reviewed-on: #55
2026-02-23 11:39:31 +00:00
f528f94d68 Merge pull request 'fix: add error handling to ClaudeService streaming' (#54) from fix/stream-error-handling into main
Some checks failed
CI / PHP 8.4 (push) Has been cancelled
CI / PHP 8.3 (push) Has been cancelled
Reviewed-on: #54
2026-02-23 11:39:17 +00:00
8ade82587d Merge pull request 'perf: cache permitted tools per API key' (#53) from perf/cache-permitted-tools-per-api-key into main
Some checks failed
CI / PHP 8.4 (push) Has been cancelled
CI / PHP 8.3 (push) Has been cancelled
Reviewed-on: #53
2026-02-23 11:39:06 +00:00
darbs-claude
c315fc43c6 fix: validate API keys on AgenticManager init (#29)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 1m47s
CI / PHP 8.4 (pull_request) Failing after 1m46s
Log a warning for each AI provider registered without an API key so
that misconfiguration is surfaced at boot time (not silently on the
first API call).  Each message names the environment variable to set:

  ANTHROPIC_API_KEY  – Claude
  GOOGLE_AI_API_KEY  – Gemini
  OPENAI_API_KEY     – OpenAI

Providers without a key remain registered but are marked unavailable
via isAvailable(), preserving backward compatibility.

- Add Log::warning() calls in registerProviders() for empty keys
- Extend AgenticManagerTest with a dedicated 'API key validation
  warnings' describe block (7 new test cases)
- Update DX-002 in TODO.md as resolved

Closes #29

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 11:39:01 +00:00
ff34ede167 Merge pull request 'perf: optimize AgentPhase dependency checking with batch query' (#52) from perf/optimize-agent-phase-dependency-checking into main
Some checks failed
CI / PHP 8.4 (push) Has been cancelled
CI / PHP 8.3 (push) Has been cancelled
Reviewed-on: #52
2026-02-23 11:38:54 +00:00
darbs-claude
6748e6cd84 fix: improve workspace context error messages (closes #28)
Some checks failed
CI / PHP 8.4 (pull_request) Failing after 1m39s
CI / PHP 8.3 (pull_request) Failing after 1m42s
Updated workspace_id error messages in all MCP tools to include
actionable guidance and a documentation link. Affected tools:
PlanCreate, PlanGet, PlanList, StateSet, StateGet, StateList,
SessionStart.

Resolves DX-001 from TODO.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 11:28:32 +00:00
darbs-claude
78bdebcaaa fix: add batch failure recovery to ContentService (#27)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 1m24s
CI / PHP 8.4 (pull_request) Failing after 1m27s
- Track progress in a per-batch JSON state file after each article so
  a mid-run crash leaves a recoverable checkpoint
- Add `maxRetries` parameter to generateBatch() with per-article retry
  loop (default: 1 extra attempt)
- Add `resumeBatch()` to re-process only failed/pending articles,
  skipping those already successfully generated in a prior run
- Add `loadBatchProgress()` public method for inspecting state
- State stores per-article status, attempt counts, error messages,
  and timestamps for full observability

Tests: 6 new scenarios covering state persistence, resume capability,
retry logic, and the no-state error case

Closes #27

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 11:17:56 +00:00
darbs-claude
77e4ae6bad fix: add error handling to ClaudeService streaming (#26)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 1m53s
CI / PHP 8.4 (pull_request) Failing after 1m52s
Wrap stream() in try/catch to prevent silent failures.
On exception, log the error and yield a structured error event:
  ['type' => 'error', 'message' => string]

Adds tests for connection errors, runtime exceptions, error event
format, and Log::error invocation. Closes ERR-001 in TODO.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 11:04:07 +00:00
darbs-claude
a352f697a9 perf: cache permitted tools per API key (closes #24)
Some checks failed
CI / PHP 8.4 (pull_request) Failing after 1m23s
CI / PHP 8.3 (pull_request) Failing after 1m27s
Cache the list of permitted tool names in `AgentToolRegistry::forApiKey()`
using a 1-hour TTL to avoid O(n) filtering on every request (PERF-002).

- Add `Cache::remember()` in `forApiKey()` storing tool names keyed by API
  key ID (`agent_tool_registry:api_key:{id}`)
- Add `flushCacheForApiKey(int|string $id)` for explicit invalidation
- Add `CACHE_TTL` constant (3600 s) for easy tuning
- Invalidate cache in `AgentApiKeyService::updatePermissions()` and `revoke()`
  so permission changes take effect immediately
- Add `tests/Unit/AgentToolRegistryTest.php` covering cache hit/miss,
  per-key isolation, scope filtering, TTL constant, and flush behaviour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 10:54:12 +00:00
darbs-claude
909c2da6df perf: replace N+1 find() with whereIn batch lookup in checkDependencies()
Some checks failed
CI / PHP 8.4 (pull_request) Failing after 1m48s
CI / PHP 8.3 (pull_request) Failing after 2m0s
Resolves #23

- Replace per-dependency `AgentPhase::find()` loop with a single
  `AgentPhase::whereIn('id', $dependencies)->get()` call, reducing
  query count from N to 1 for any number of dependencies
- Short-circuit early when dependencies list is empty to avoid
  unnecessary query at all
- Add tests: empty deps, skipped-dep passthrough, single-query
  assertion, blocker shape validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 10:40:00 +00:00
Claude
fcdeace290
ci: retrigger
Some checks failed
CI / PHP 8.3 (push) Failing after 2m2s
CI / PHP 8.4 (push) Failing after 2m1s
2026-02-23 07:09:43 +00:00
Claude
d88095780e
fix: use closure-based __get for mock property access
Some checks are pending
CI / PHP 8.3 (push) Waiting to run
CI / PHP 8.4 (push) Waiting to run
Replace individual __get expectations with a single closure that handles
all property access. Fixes ErrorException on undefined property access
with Mockery mocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 07:02:04 +00:00
Claude
f2f27ec766 style: fix pint code style issues
Some checks failed
CI / PHP 8.3 (push) Failing after 2m8s
CI / PHP 8.4 (push) Failing after 1m58s
2026-02-23 06:42:24 +00:00
db0cc0abad Merge pull request 'fix: add missing database indexes' (#51) from fix/add-missing-indexes into main
Some checks are pending
CI / PHP 8.3 (push) Waiting to run
CI / PHP 8.4 (push) Waiting to run
Reviewed-on: #51
2026-02-23 06:38:15 +00:00