Skip to content

Packs

A pack is a self-contained domain extension that teaches the kernel how to work in a specific domain. The kernel itself is domain-agnostic — it provides scope enforcement, policy evaluation, evidence recording, and tool dispatch. Packs provide the actual tools, policies, and evidence types for a particular workflow.

LumenFlow currently ships four first-party packs:

| Pack | Domain | Current role | | ------------------- | ----------------------------- | ---------------------------------------------------------------------------------------- | | software-delivery | Software development workflow | Work Units, lanes, gates, memory, CLI-driven delivery lifecycle | | sidekick | Workspace-local productivity | Managed tasks, memory, channels, routines, and status under .sidekick/ | | agent-runtime | Governed model turns | agent-session turns, policy-aware tool gating, orchestration state | | campus | Campus compute telemetry | Read-only facility/PUE/power-signal observability, approval-gated tenant evidence export |

The Software Delivery Pack provides 90+ tools for software development workflows:

| Namespace | Tools | Purpose | | --------------- | ----- | ------------------------------------------------------------------ | | wu:* | 23 | Work Unit lifecycle (create, claim, prep, done, block, recover…) | | mem:* | 14 | Memory layer (checkpoint, inbox, signal, recover…) | | initiative:* | 8 | Initiative management (create, plan, status…) | | file:* | 4 | File operations with audit trail | | git:* | 4 | Git operations with audit trail | | agent:* | 4 | Agent session management | | orchestrate:* | 3 | Multi-agent orchestration | | plan:* | 4 | Plan management | | state:* | 3 | State management | | Others | 23+ | Gates, validation, config, docs, metrics, flow analysis… |

Every one of these tools routes through the kernel’s execution pipeline — scope intersection, policy evaluation, and evidence recording happen on every call.

The Sidekick Pack adds a compact 23-tool workspace productivity surface:

| Namespace | Tools | Purpose | | ------------ | ----- | ------------------------------------------------------------------ | | task:* | 6 | Personal and team-local task tracking, updates, completion, cancel | | memory:* | 4 | Workspace-local memory, snippets, and destructive forgetting | | channel:* | 5 | Named message channels, local discovery, and local deletion | | routine:* | 5 | Plan-only routine definitions, updates, stop flow, and deletion | | sidekick:* | 3 | Initialization, status, and export |

Destructive Sidekick lifecycle tools such as task:cancel, memory:forget, channel:delete, and routine:delete are approval-gated through the pack policy factory when invoked through the kernel runtime.

The Agent Runtime Pack provides the governed agent-runtime:execute-turn contract, policy-aware tool gating, provider normalization, and pack-owned agent-session orchestration.

The Campus Pack exposes campus-scale compute as governed tool surfaces: read-only facility telemetry (campus:*), read-only proof-record tools plus one approval-gated tenant proof-export tool (proof:*), and load-curtailment tooling (flexload:*). It is the pack-side of the campus governance boundary — it proposes observations and serializes proof bundles; it never actuates facility infrastructure. See the Campus Pack docs for the full tool and event surface.

A pack is a directory with a manifest.yaml at its root:

  • Directorymy-pack/ - manifest.yaml (declares tools, policies, evidence types) - constants.ts (pack id, version, shared strings) - config.schema.json (validates workspace config for the pack) - capability-factory.ts (derives runtime scopes/env from resolved pack config) - policy-factory.ts (returns conditional PolicyRule objects) - tools/ - types.ts (shared type definitions) - tool-impl/ - my-tool.ts (runtime implementation)

The manifest is the contract between a pack and the kernel. It declares:

  • Tools — what the pack can do (name, entry point, permissions, required scopes)
  • Policies — static rules the kernel evaluates at specific lifecycle triggers
  • Evidence types — kinds of audit records the pack produces
  • Task types — what domain objects the pack manages (e.g., work-unit)
  • State aliases — friendly names for kernel state machine states
  • Lane templates — pre-defined lane configurations
  • Config namespaceconfig_key and config_schema for pack-specific workspace settings
  • Capability factory — runtime augmentation of required_scopes and required_env
  • Policy factory — runtime-authored rules that can inspect PolicyEvaluationContext
  • Extension ownership — command and state namespaces plus opaque telemetry sources compiled with the tools, policies, configuration root, events, and required surfaces
id: my-pack
version: 0.1.0
task_types:
  - my-task-type
tools:
  - name: my-pack:do-something
    entry: tool-impl/my-tool.ts#doSomethingTool
    permission: write
    required_env:
      - MY_PACK_TOKEN
    required_scopes:
      - type: path
        pattern: '**'
        access: write
config_key: my_pack
config_schema: config.schema.json
capability_factory: capability-factory.ts#createMyPackCapabilityFactory
policy_factory: policy-factory.ts#createMyPackPolicyFactory
policies: []
evidence_types: []
state_aliases: {}
lane_templates: []
emitted_event_kinds:
  - my-pack:operation_completed
surfaces_required:
  - cli
  - http
extensions:
  command_namespaces:
    - my-pack
  state_namespaces:
    - my-pack:runtime
  telemetry_sources: []

At startup, the kernel compiles every installed manifest into one immutable registry. The registry owns command names, configuration roots, emitted event kinds, state namespaces, tools, static policies, required surfaces, and telemetry-source declarations. Runtime registration and CLI/HTTP/MCP discovery read that compiled catalog. Generic tool execution does not need a pack-specific switch; dedicated CLI convenience adapters remain explicit.

Compilation is all-or-nothing. An unknown manifest field, duplicate pack ID, reserved namespace, undeclared tool namespace, cross-pack collision, or unsafe telemetry path prevents the catalog from becoming visible. Mapper modules resolve in a second atomic, pack-relative activation stage; a missing mapper activates none of that workspace’s new telemetry definitions. Removing a pack and compiling again removes all of its entries, including telemetry sources and state ownership.

For pre-v6 manifests without extensions, the compiler infers command namespaces from tool names and assumes no state or telemetry ownership. Reserved-name and collision checks still apply. Authors should add the explicit block during v6 migration, and must add it before declaring state namespaces or telemetry sources.

Pack-owned names follow these rules:

  • tools use one of the manifest’s extensions.command_namespaces;
  • emitted events, state namespaces, and telemetry source IDs start with <pack-id>:;
  • approval, fs, proc, task, and tool command namespaces and the kernel: state namespace are reserved;
  • config_key cannot claim a kernel-owned workspace root;
  • telemetry declares exactly one confined path or dir_glob, an opaque confined mapper module reference, and a metadata-only or full wire-payload policy.

See Authoring manifest-owned extensions for the complete manifest example and collision model.

When the kernel starts, it reads the workspace spec (workspace.yaml) which lists pinned packs:

packs:
  - id: software-delivery
    version: 0.1.0
    integrity: sha256:a1b2c3...
    source: local

For each pack pin, the kernel:

  1. Resolves the pack root — in order:
    • workspaceRoot/packs/
    • workspaceRoot/packages/@lumenflow/packs/ (monorepo development)
    • bundled CLI packs (@lumenflow/cli/packs/) for end-user installs
    • a git repository (source: git) or registry cache (source: registry) when configured
  2. Parses the manifest — validates against the schema, checks that id and version match the pin.
  3. Validates pack config — if the manifest declares config_key and config_schema, the kernel validates the matching workspace config and makes the resolved payload available at runtime.
  4. Validates import boundaries — scans all runtime source files and permits only relative imports within the pack, Node built-ins, the kernel API, explicitly reviewed host/core adapters, exact shared control-plane contracts, exact declared pack dependencies, and a small audited library allowlist. Other LumenFlow packages, dependency subpaths, SDK subpaths, and arbitrary npm packages fail closed.
  5. Verifies integrity — computes a deterministic SHA-256 hash of the pack’s source and contract files and compares it to the pinned hash. Checkout-local dependencies, build caches, pack-local .lumenflow/ runtime state, and root-level .tgz files produced by package tooling are excluded. A mismatch in a tracked source, manifest, configuration, or distributable contract file means the pack was modified and the kernel refuses to load it.
  6. Compiles installed extensions — all manifests become one atomic immutable ownership catalog; any collision or invalid declaration stops startup before partial visibility.
  7. Registers tools — each tool declared in the manifest becomes available in the kernel’s tool registry, then optional capability factories can augment required_scopes and required_env using the resolved pack config.
  8. Injects policies — pack-declared policies are added to the pack layer of the policy engine, and optional policy factories can add conditional rules such as intent-aware gating.

LumenFlow is pack-first. First-party packs share the same manifest contract and are loaded from local paths, monorepo packages, bundled installs, or external sources such as git and registries.

See:

Pack tools follow a standard pattern. Each tool returns a ToolOutput:

interface ToolOutput {
  success: boolean;
  data?: Record<string, unknown>;
  error?: { code: string; message: string };
  metadata?: {
    artifacts_written?: string[]; // paths written (for evidence)
  };
}

Tools can be implemented as:

  • In-process handlers — TypeScript functions that run directly in the kernel process. Used for lightweight read operations.
  • Subprocess handlers — executed in a sandboxed subprocess via spawnSync. Used for write operations and anything that needs OS-level isolation.

The Software Delivery Pack uses two implementation strategies. Most tools (~80) use the runtime CLI adapter to reuse existing CLI command modules in-process. A smaller set (~10) use direct implementations with simple-git wrappers and Node builtins. See Tool Execution for the full execution architecture.