6.8 KiB
VolcanicCore — project context for Claude sessions
VolcanicCore is a self-hosted N8N-style workflow engine (C# backend + React frontend). Operator draws a directed graph of nodes (triggers → actions → terminals) in a browser canvas; each workflow can be activated independently. When active, trigger nodes subscribe/listen and each event fires one execution through the graph.
Documents to read first
- Design spec —
docs/superpowers/specs/2026-08-28-volcaniccore-workflow-engine-design.md. The whole architecture (execution model, extension contracts, webhook mechanics, persistence, deploy shape). Read this before writing plans or code. - Plan 1 (backend foundation, executed) —
docs/superpowers/plans/2026-08-28-plan-1-backend-foundation.md. Shows the working style and the file structure conventions. - Follow-ups —
docs/superpowers/followups.md. Cross-plan items surfaced during review that later plans must handle. Read before starting a plan; extend as new items surface.
Current status
Plan 1 (backend foundation) shipped. Head commit at plan close: 86bf173. dotnet build clean, dotnet test 20/20.
What's done:
- ASP.NET Core 9 monolith. Four projects:
VolcanicCore.Core(contracts),.Persistence(SQLite, migrator, encryption, repos),.Api(endpoints, auth, registries),VolcanicCore.Tests(xUnit + WebApplicationFactory). - Admin cookie auth (BCrypt,
ADMIN_PASSWORDenv), sessions endpoints. - SQLite with hand-rolled versioned migrator (3 migrations:
admin_config,connections,workflows). - AES-GCM encryption for connection secrets (key from
ENCRYPTION_KEYenv or/data/.enc-key). - Extension contracts:
INodeType/IActionNode/ITriggerNode/IConnectionProviderin.Core. - DI-collected
NodeRegistryandConnectionProviderRegistry. - REST endpoints: session, discovery (empty in Plan 1), connections CRUD, workflows CRUD + activate/deactivate.
What's next: Plan 2 — the workflow engine itself. Not yet written. When authored, it will cover:
- Executions + node_executions tables (Migration 004 + 005).
Executor— in-degree scheduler, fan-out, failure propagation per §4 of the design spec.WebhookRouter+POST /wh/{workflow-id}/{*path}— see §5 of the spec.TriggerHostlifecycle — start triggers on activation, dispose on deactivation.- NATS
IConnectionProvider+ all five nodes: NATS Hook, Webhook, PythonTransform (IronPython 3), WebResponse, NATS Publish. - Manual test-run endpoint.
- Retention
BackgroundService. - Discovery endpoints will start returning real node types + providers once these are DI-registered.
Plans 3 (React SPA) and 4 (Coolify Dockerfile + deploy) follow.
Invariants (do NOT relearn from scratch)
- Git commit identity. The repo has no configured identity. Every commit must pass
-c user.email="claude@volcanic" -c user.name="Claude":git -c user.email="claude@volcanic" -c user.name="Claude" commit -m "..." - Working branch.
main. The user opted in to this at project start. No feature branches unless requested. - Test parallelism is disabled at the assembly level. See the
[assembly: CollectionBehavior(DisableTestParallelization = true)]attribute at the top oftests/VolcanicCore.Tests/WebFactory.cs. MultipleWebFactoryinstances share the process; pre-Configuration.Bindenv-var reads made parallel classes flaky. Do not re-enable parallelism without a redesign. - Cookie authentication is in the shared framework. Do NOT add
Microsoft.AspNetCore.Authentication.Cookiesas aPackageReference. The last standalone version on NuGet is 2.3.0 (ASP.NET Core 2.x, 2019). .NET 9'sMicrosoft.AspNetCore.Appshared framework provides the cookie-auth types with no PackageReference. Program.csenv-var loop honors pre-set config. In tests,WebFactory.ConfigureWebHostusesbuilder.UseSetting(...)to injectDataDirectoryandAdminPassword. The env-var loop inProgram.csskips keys already set by upstream sources (if (!string.IsNullOrEmpty(builder.Configuration[prop])) continue;). Do not remove this check.Migration001Initial,002Connections,003Workflowsare registered in theMigratorfactory inProgram.cs. Add new migrations to the same array in version order.AdminBootstrapstoresadmin.password_hash_sourcein plaintext by design (see the comment inAdminBootstrap.cs) — it is the change-detector for the env-providedADMIN_PASSWORD. Do not "fix" this by hashing the source. Encryption at rest foradmin_configis a Plan 2 follow-up.IConnectionSecretPolicyin Plan 1 isHardcodedSecretPolicy(fixed field-name set). Plan 2 replaces it with a schema-driven implementation that readssecretFieldsoff each registered provider'sConfigSchema. Do not extend the hardcoded set further — replace instead.
Working style
- Design with
superpowers:brainstorming, plan withsuperpowers:writing-plans, execute withsuperpowers:subagent-driven-development. This is the tempo Plan 1 shipped on. - Split large scopes into multiple plans (Plan 1 was foundation, Plan 2 is engine, Plan 3 is frontend, Plan 4 is deploy). Each plan should end in a testable state.
- TDD in each task: write the failing test, watch it fail, implement, watch it pass, commit.
Migrator, connection CRUD, workflow CRUD all follow this pattern — see their commits for examples. - Two-stage review per task: spec-compliance reviewer (haiku), then code-quality reviewer (sonnet). For crypto or wire-format work, escalate quality-reviewer to opus. For pure interface/type tasks, one combined reviewer is fine.
- Follow-ups. When a reviewer surfaces a real concern that isn't in scope for the current task, add it to
docs/superpowers/followups.mdwith which plan should handle it. Do not silently drop review feedback. - Commit style. Conventional Commits (
feat(scope):,fix(scope):,chore:,docs:). One meaningful change per commit; TDD tasks land one commit per task at the end (test + impl together).
How to run
# Build + test
dotnet build
dotnet test
# Live server (boot with a real SQLite DB)
DATA_DIRECTORY=$(pwd)/_smoke ADMIN_PASSWORD=hunter2 \
dotnet run --project src/VolcanicCore.Api --urls http://127.0.0.1:5099
# Then: curl -c jar -X POST -H 'content-type: application/json' \
# -d '{"password":"hunter2"}' http://127.0.0.1:5099/api/session
# And follow up with -b jar for authenticated calls.
dotnet run --project X sets the content root to X's directory, so DATA_DIRECTORY=./relative lands under src/VolcanicCore.Api/ — always pass an absolute path.
Deploy target
Coolify — env vars COOLIFY_URL, COOLIFY_KEY, GIT_URL, GIT_USER, GIT_KEY are available in the container. Actual container packaging + Coolify wiring is Plan 4. Global CLAUDE.md rule applies: fire-and-forget deploys via the v4 API, never block on build.