b77f537dc6
- neuron-runtime, neuron-store, neuron-migrate: fix path deps (products/engram/ → foundation/engram/engrams/, products/el/ → foundation/el/engrams/) - neuron-rs workspace: fix axon-events/axon-protocol paths (../../../platform/ → ../../platform/, paths were off by one level) - neuron-lang/compiler/ removed (el self-hosting compiler now lives in foundation/el/el-compiler/)
128 lines
4.7 KiB
EmacsLisp
128 lines
4.7 KiB
EmacsLisp
// process.el — Process definitions subsystem.
|
|
//
|
|
// Processes encode proven workflows as executable, named procedures.
|
|
// The difference between a process and a document is executability:
|
|
// a document describes what to do; a process can be invoked with
|
|
// begin_work(process_name="...") and tracked step by step.
|
|
//
|
|
// WHY processes?
|
|
// Institutional knowledge decays when it only lives in conversations.
|
|
// A process that has been run 10 times and refined each time is far more
|
|
// valuable than a one-off plan. The process library is Neuron's
|
|
// "muscle memory" — established ways of doing things that don't need to
|
|
// be reinvented each session.
|
|
//
|
|
// Process discovery is @public because it's discovery-oriented — callers
|
|
// should be able to find what processes exist without authentication.
|
|
// Process mutation (define, delete) is @manager — these changes affect
|
|
// all future sessions.
|
|
|
|
from types import {
|
|
Process,
|
|
ProcessStep,
|
|
Context,
|
|
NeuronError,
|
|
}
|
|
|
|
// ── Public API ────────────────────────────────────────────────────────────────
|
|
|
|
// define_process — register a new named workflow.
|
|
//
|
|
// Each step has a name, instructions (markdown prose), and a list of tools
|
|
// that should be called during that step. The tools list is advisory — it
|
|
// helps Claude orient to what's expected at each step.
|
|
@manager
|
|
fn define_process(
|
|
name: String,
|
|
description: String,
|
|
steps: [ProcessStep],
|
|
) -> Result<Process, NeuronError> {
|
|
let id = native_uuid()
|
|
let now = native_now()
|
|
let process = Process {
|
|
id: id,
|
|
name: name,
|
|
description: description,
|
|
steps: steps,
|
|
created_at: now,
|
|
updated_at: now,
|
|
}
|
|
// Processes are stored as Knowledge nodes with category="process" so they
|
|
// participate in semantic search alongside other reference material.
|
|
native_emit("process.defined", {"id": id, "name": name})
|
|
Ok(process)
|
|
}
|
|
|
|
// browse_processes — list or get detail on named processes.
|
|
//
|
|
// When name is empty, returns a summary list of all registered processes.
|
|
// When name is provided, returns the full process with all steps.
|
|
// This is @public to encourage process discovery.
|
|
@public
|
|
fn browse_processes(name: String) -> Result<[Process], NeuronError> {
|
|
if name == "" {
|
|
let results = activate Process where "all processes"
|
|
return Ok(results)
|
|
}
|
|
// Semantic search by name to handle fuzzy matching ("pr review" → "pull_request_review").
|
|
let results = activate Process where "name:{name}"
|
|
Ok(results)
|
|
}
|
|
|
|
// execute_process — begin a tracked execution of a named process.
|
|
//
|
|
// This is the bridge between process definitions and execution contexts.
|
|
// It looks up the process by name, opens a new execution context with
|
|
// the process name, and returns the context so the caller can track progress.
|
|
//
|
|
// The caller is expected to call progress_work() for each step in the process.
|
|
@manager
|
|
fn execute_process(name: String, project: String) -> Result<Context, NeuronError> {
|
|
// Find the process definition.
|
|
let processes = activate Process where "name:{name}"
|
|
let process = processes[0]
|
|
// Open a context using begin_work from context.el.
|
|
// In practice, the Axon dispatcher will call begin_work() directly
|
|
// with the process name after execute_process resolves the name.
|
|
let id = native_uuid()
|
|
let now = native_now()
|
|
let ctx = Context {
|
|
id: id,
|
|
process_name: process.name,
|
|
description: process.description,
|
|
objective: "execute process: " + name,
|
|
project: project,
|
|
status: "active",
|
|
steps: [],
|
|
file_refs: [],
|
|
key_decisions: [],
|
|
lessons_learned: [],
|
|
created_at: now,
|
|
updated_at: now,
|
|
}
|
|
native_store_context(ctx)?
|
|
native_emit("process.execution_started", {"process": name, "context_id": id, "project": project})
|
|
Ok(ctx)
|
|
}
|
|
|
|
// list_processes — enumerate all registered processes.
|
|
//
|
|
// Alias for browse_processes("") that matches the Axon tool name convention.
|
|
@public
|
|
fn list_processes() -> Result<[Process], NeuronError> {
|
|
browse_processes("")
|
|
}
|
|
|
|
// delete_process — remove a process definition.
|
|
//
|
|
// Use sparingly — prefer evolving (redefine with improvements) over deleting.
|
|
// Deleting a process that has active executions will leave those contexts
|
|
// without a parent process definition.
|
|
@manager
|
|
fn delete_process(name: String) -> Result<String, NeuronError> {
|
|
let processes = activate Process where "name:{name}"
|
|
let process = processes[0]
|
|
native_emit("process.deleted", {"name": name, "id": process.id})
|
|
Ok("process deleted: " + name)
|
|
}
|