LLM Integration
Prompt patterns, SPL reference, and operating hence as an LLM agent
Contents
- Load the SPL reference into context
- The complete agent loop
- Parsing
hence task nextoutput - Creating a plan from scratch
- Translating a spec to a plan
- Asserting findings
- Handling blocked tasks
- Debugging with explain / why-not
- Multi-agent coordination
- Working with hence.run remote plans
- JSON output for programmatic use
- Common mistakes to avoid
- Session commands
- Inline SPL reference
1. Load the SPL reference into context
Before doing any plan work, load the full SPL syntax reference into your context window. This is the single most important step — without it, you will write malformed plans.
hence llm spl
Run this command at the start of every session where you will be reading, writing, or validating .spl plan files. The output is plain text, formatted for LLM context windows. Pipe it into your prompt or include it in your system prompt:
# Pipe into a variable for use in a script or prompt template
SPL_REF=$(hence llm spl)
# Or pipe directly when invoking another LLM
hence llm spl | llm "Now write a plan for my project: ..."
<pre> block. An LLM reading this HTML page already has the reference in context — no command required.
2. The complete agent loop
This is the canonical sequence an LLM agent follows when working a plan. Execute these commands in order. Every step has a purpose — do not skip any.
# Step 0: Set identity (once per session, or set in environment)
export HENCE_AGENT=claude
# Step 1: Confirm your identity
hence agent whoami
# Step 2: Read plan metadata — understand scope, status, and spec
hence plan info plan.spl
# Step 3: See the full task board — all tasks and their states
hence plan board plan.spl
# Step 4: Find tasks assigned to you that are ready to work
hence task next plan.spl
# Step 5: Claim a specific task before starting work
hence task claim TASK plan.spl
# Step 6: Do the actual work for the task
# (run tests, write code, make decisions, gather results, etc.)
# Step 7: Record findings as logical facts while working
hence task assert '(given FACT)' plan.spl
# Step 8: Mark the task complete
hence task complete TASK plan.spl
# Step 9: Check what work just unlocked
hence task next plan.spl
# Repeat from Step 5 until hence task next returns nothing
Step-by-step explanation
| Step | Command | Purpose |
|---|---|---|
| 0 | export HENCE_AGENT=<name> |
Sets your agent identity for all subsequent commands. Without this, all task/claim commands require --agent <name> on every invocation. |
| 1 | hence agent whoami |
Confirms the active agent name from environment. Use to verify the correct identity is set before claiming tasks. |
| 2 | hence plan info plan.spl |
Reads (meta plan ...) metadata: id, title, description, status, spec reference. Establishes context for the entire session. |
| 3 | hence plan board plan.spl |
Shows all tasks with their current state: ready, claimed, completed, blocked. Use to orient yourself before picking work. |
| 4 | hence task next plan.spl |
Returns tasks assigned to HENCE_AGENT that are currently ready. This is your work queue. Empty output means no work available right now. |
| 5 | hence task claim TASK plan.spl |
Atomically claims a task. Appends a (claims ...) block to the plan file. Other agents will see this task as in-progress. |
| 7 | hence task assert '(given FACT)' plan.spl |
Records a logical fact discovered during work. Facts are permanent and drive downstream readiness. Assert early and often. |
| 8 | hence task complete TASK plan.spl |
Marks task done. Automatically derives completed-TASK fact, which may unlock downstream tasks per readiness rules. |
| 9 | hence task next plan.spl |
Check again after completing — completing a task may have unlocked new work. Loop here until no more tasks. |
Minimal agent loop (copy-paste ready)
export HENCE_AGENT=claude
PLAN=plan.spl
hence agent whoami
hence plan info $PLAN
hence plan board $PLAN
while true; do
NEXT=$(hence task next $PLAN --json)
if [ "$NEXT" = "[]" ] || [ -z "$NEXT" ]; then
echo "No tasks available. Done."
break
fi
TASK=$(echo "$NEXT" | jq -r '.[0].task')
echo "Working on: $TASK"
hence task claim "$TASK" $PLAN
# ... do the work for $TASK ...
hence task complete "$TASK" $PLAN
done
3. Parsing hence task next output
Use --json for programmatic parsing. The output is a JSON array of task objects.
hence task next plan.spl --json
JSON schema
[
{
"task": "auth", // task identifier (use this to claim/complete)
"agent": "claude", // assigned agent name
"commands": [ // copy-pasteable shell commands
"hence task claim auth plan.spl",
"hence task complete auth plan.spl"
]
},
{
"task": "tests",
"agent": "claude",
"commands": [
"hence task claim tests plan.spl",
"hence task complete tests plan.spl"
]
}
]
Extraction examples
# Get the first task name
hence task next plan.spl --json | jq -r '.[0].task'
# Get all task names as a list
hence task next plan.spl --json | jq -r '.[].task'
# Get the claim command for the first task
hence task next plan.spl --json | jq -r '.[0].commands[0]'
# Check if there is any work available
TASKS=$(hence task next plan.spl --json | jq 'length')
if [ "$TASKS" -gt 0 ]; then echo "Work available"; fi
task field is the bare identifier (e.g., auth), not the prefixed atom (e.g., task-auth). Pass it directly to hence task claim and hence task complete.
4. Creating a plan from scratch
Follow this prompt pattern precisely when an LLM is asked to write a new plan:
-
Load the SPL reference
Runhence llm splor read the inline reference on this page. You must have the syntax in context before writing anything. -
Identify all tasks and their dependencies
List every task that must be completed. For each, determine: what must be true before this task can start? Which other tasks must be complete? What agent should do it? -
Write the
.splfile
Follow the structure:(meta plan ...), agents, task facts, task metadata, readiness rules, assignment rules, superiority declarations. -
Validate
Runhence plan validate plan.spland fix any errors before proceeding. -
Review
Runhence plan review plan.splwhich uses a headless LLM agent to check for logical issues, missing metadata, and ambiguous rules.
Complete plan template
;; ── Plan metadata ────────────────────────────────────────────
;; Required. Must appear at the top. hence plan info reads this.
(meta plan
(id "IMPL-042")
(title "User Authentication System")
(version "1.0.0")
(status "active")
(created "2026-02-24")
(author "agent:claude")
(spec "SPEC-042")
(description "Implement login, session management, and token refresh"))
;; ── Agents ───────────────────────────────────────────────────
;; Declare which agents are available to take work.
(given agent-coder-available)
(given agent-security-available)
(given agent-reviewer-available)
;; ── Task identifiers ─────────────────────────────────────────
;; Each task is a fact. Naming: task-IDENTIFIER
(given task-auth)
(given task-tests)
(given task-review)
;; ── Task properties ──────────────────────────────────────────
;; Additional facts that influence readiness and assignment.
(given no-deps-auth)
(given security-sensitive-auth)
;; ── Task metadata ─────────────────────────────────────────────
;; Required on every task: description + acceptance criteria.
(meta task-auth
(description "Implement JWT auth with refresh tokens")
(acceptance "Login endpoint returns valid JWT; refresh works; all auth tests pass"))
(meta task-tests
(description "Integration tests for auth endpoints")
(acceptance "Coverage above 80%; all auth flows covered; CI green"))
(meta task-review
(description "Security review of auth implementation")
(acceptance "No critical vulnerabilities; reviewer signs off"))
;; ── Readiness rules ──────────────────────────────────────────
;; When can each task start? Naming: ready-IDENTIFIER
(normally r-ready-auth
(and task-auth no-deps-auth)
ready-auth)
(normally r-ready-tests
(and task-tests completed-auth)
ready-tests)
(normally r-ready-review
(and task-review completed-tests)
ready-review)
;; ── Assignment rules ─────────────────────────────────────────
;; Who works on what? Naming: assign-to-TASK-AGENT
(normally r-assign-auth-coder
(and ready-auth agent-coder-available)
assign-to-auth-coder)
(normally r-assign-auth-security
(and ready-auth security-sensitive-auth agent-security-available)
assign-to-auth-security)
(normally r-assign-tests-coder
(and ready-tests agent-coder-available)
assign-to-tests-coder)
(normally r-assign-review-security
(and ready-review agent-security-available)
assign-to-review-security)
;; ── Superiority ──────────────────────────────────────────────
;; When two assignment rules conflict, which wins?
(prefer r-assign-auth-security r-assign-auth-coder)
;; ── Rule metadata ─────────────────────────────────────────────
;; Explain why each non-obvious rule exists.
(meta r-assign-auth-security
(description "Security-sensitive tasks go to security agent")
(justification "Per security policy section 3.2"))
Validate and review
# Validate syntax and rule consistency
hence plan validate plan.spl
# LLM-based review: checks for missing metadata, logical gaps, ambiguous rules
hence plan review plan.spl
hence plan validate exits cleanly. A malformed plan silently produces wrong task lists.
5. Translating a spec to a plan
If you have a requirements document (Markdown, plain text, or structured spec), you can bootstrap a plan from it using:
hence plan translate spec.md --output plan.spl
This invokes a headless LLM agent that reads the spec and generates a valid SPL plan. The generated plan will have:
- A populated
(meta plan ...)block with title and description derived from the spec - Task identifiers and task metadata inferred from requirements
- Dependency chains derived from ordering clues in the spec
- Readiness and assignment rules following hence conventions
After translation, always review and validate:
# Translate
hence plan translate spec.md --output plan.spl
# Validate syntax
hence plan validate plan.spl
# LLM review — check for gaps, ambiguities, missing tasks
hence plan review plan.spl
# Inspect the task board before distributing
hence plan board plan.spl
6. Asserting findings
Asserting facts is how an agent records discoveries during work. Facts are permanent, append-only, and may unlock downstream tasks. Assert findings immediately when you discover them — do not wait until the task is complete.
Basic fact assertion
# Assert a simple fact (no quotes around the atom needed with --task)
hence task assert '(given tests-passing)' plan.spl --task my-task
# Assert without --task (asserts as the plan-level agent)
hence task assert '(given database-schema-finalized)' plan.spl
Facts that unlock downstream work
Facts named to match preconditions in readiness rules will immediately unlock dependent tasks when asserted:
# If a readiness rule reads: (normally r-ready-deploy (and task-deploy completed-tests) ready-deploy)
# then asserting completed-tests (via task complete) unlocks deploy.
# But you can also assert intermediate facts:
hence task assert '(given integration-approved)' plan.spl
hence task assert '(given security-review-passed)' plan.spl
hence task assert '(given load-test-passed)' plan.spl
Asserting decisions
# Record architectural decisions as facts
hence task assert '(given decided-use-redis)' plan.spl
hence task assert '(given decided-postgres-over-mysql)' plan.spl
hence task assert '(given discovered-api-deprecated)' plan.spl
hence task assert '(given verified-auth-endpoint-works)' plan.spl
Asserting derived rules (advanced)
You can assert not just facts, but new rules — adding logic to the plan dynamically:
# Assert a new assignment rule based on a runtime discovery
hence task assert '(normally r-new (and ready-deploy agent-devops-available) assign-to-deploy-devops)' plan.spl
# Assert a blocking defeater rule
hence task assert '(except e-block-deploy (and ready-deploy security-hold) assign-to-deploy-devops)' plan.spl
Naming conventions for asserted facts
| Prefix | Use for | Example |
|---|---|---|
discovered- |
Runtime findings, unexpected conditions | discovered-api-rate-limited |
decided- |
Architectural or process decisions made | decided-use-postgres |
verified- |
Validation results, confirmations | verified-auth-works |
approved- |
Human or automated approvals granted | approved-security-review |
failed- |
Failures worth recording as plan facts | failed-load-test |
ready- |
Task readiness (derived, not usually asserted directly) | ready-auth |
completed- |
Task completion (derived from claims, never assert directly) | completed-auth |
7. Handling blocked tasks
A task is blocked when its readiness conditions cannot be satisfied given current facts. Here is the systematic procedure for diagnosing and resolving blocked tasks.
Diagnosis flow
# Step 1: Find what preconditions are missing for a task
hence query why-not ready-TASK plan.spl
# Step 2: Find what facts would make it ready
hence query require ready-TASK plan.spl
# Step 3: If you can determine the missing fact is satisfied, assert it
hence task assert '(given missing-fact)' plan.spl
# Step 4: If the task cannot proceed due to an external dependency, block it explicitly
hence task block TASK "waiting for vendor API credentials" plan.spl
# Step 5: Re-check the board to confirm state
hence plan board plan.spl
Example: unblocking a task
# Task 'deploy' is not appearing in 'hence task next'
hence query why-not ready-deploy plan.spl
# Output: missing: completed-tests, approved-security-review
# Tests are done, we just forgot to complete the task
hence task complete tests plan.spl
# Security review was approved via Slack
hence task assert '(given approved-security-review)' plan.spl
# Now check again
hence task next plan.spl
# Output: deploy is now available
Explicit blocking
When a task cannot proceed and you cannot resolve the blocker yourself, use hence task block to leave a clear explanation for other agents or humans reviewing the plan:
hence task block deploy "prod credentials not provisioned — contact ops team" plan.spl
hence task block migrate "schema migration requires DBA sign-off" plan.spl
8. Debugging with explain / why-not
The hence query family of commands exposes the defeasible logic reasoner directly. Use these when a task state is unexpected or when you need to understand why the plan produced a particular conclusion.
Core query commands
# Explain why a fact IS concluded (shows the proof tree)
hence query explain ready-auth plan.spl
# Explain why a fact is NOT concluded (shows missing preconditions)
hence query why-not completed-auth plan.spl
# Hypothetical: what would become true if I added these facts?
hence query what-if plan.spl '(given tests-passing)' '(given review-approved)'
# Show the definition of a rule or fact
hence query describe plan.spl task-auth
hence query describe plan.spl r-assign-auth-coder
# What facts would make a given literal provable?
hence query require ready-deploy plan.spl
Proof notation
Query output uses standard defeasible logic proof notation. You will see these symbols:
| Symbol | Meaning | Interpretation |
|---|---|---|
+D |
Definitely provable | Follows from strict rules only. Cannot be defeated. |
+d |
Defeasibly provable | Follows from defeasible rules. Currently holds but could be overridden. |
-D |
Definitely not provable | Cannot be derived; no strict rule supports it. |
-d |
Defeasibly not provable | Does not hold defeasibly; either defeated or no supporting rule. |
Reading explain output
# Example: why is ready-auth concluded?
hence query explain ready-auth plan.spl
# Example output:
+d ready-auth
via r-ready-auth
+D task-auth (given)
+D no-deps-auth (given)
not defeated by any exception
The +d prefix on ready-auth means it is defeasibly (not strictly) provable — it follows from a normally rule and no except rule has defeated it.
Using what-if for plan design
# Before asserting facts, check what they would unlock
hence query what-if plan.spl '(given tests-passing)' '(given security-approved)'
# Output shows all newly derivable conclusions, e.g.:
# +d ready-deploy
# +d assign-to-deploy-devops
9. Multi-agent coordination patterns
hence is designed for multiple LLM agents operating concurrently on the same plan. These patterns ensure correctness and avoid conflicts.
Concurrency guarantees
- Reads are always safe: Multiple agents can run
hence task next,hence plan board, and allhence querycommands concurrently without conflict. - Claims are append-only:
hence task claimappends a(claims ...)block to the plan file. Appends do not conflict with concurrent reads or other appends. - No locking required: The defeasible reasoner evaluates all claims in the file at query time. Concurrent claims are resolved by rule priority, not file locking.
Checking current assignments
# See all tasks and who currently holds them
hence task assign plan.spl --json
# Example output:
[
{ "task": "auth", "agent": "security", "status": "claimed" },
{ "task": "tests", "agent": "coder", "status": "claimed" },
{ "task": "review", "agent": null, "status": "ready" }
]
Coordination pattern: producer/consumer
When one agent produces output consumed by another, use facts to signal readiness:
# Agent A (coder) completes auth implementation
hence task complete auth plan.spl
# This derives completed-auth, which makes task-tests ready per r-ready-tests
# Agent B (tester) is polling and picks up the work
hence task next plan.spl
# Output: tests (now ready because completed-auth was derived)
hence task claim tests plan.spl
Coordination pattern: parallel independent tasks
# Both tasks are ready simultaneously — different agents claim them
# Agent A:
hence task claim frontend plan.spl
# Agent B (concurrently):
hence task claim backend plan.spl
# No conflict — different tasks, different agents
Coordination pattern: fan-in (all must complete before next)
;; In the plan, use (and completed-X completed-Y) in the readiness rule:
(normally r-ready-integration
(and task-integration completed-frontend completed-backend)
ready-integration)
;; Integration only becomes ready after BOTH frontend and backend complete.
;; Agents work in parallel; integration is automatically unlocked when both done.
After completing a task, always check next
# Completing a task may unlock new work immediately
hence task complete auth plan.spl
hence task next plan.spl # <-- do this every time, not just at the start
10. Working with hence.run remote plans
Remote plans hosted on hence.run use a URL in place of a local file path. The interface is identical to local plans.
# Use a hence.run URL in place of a local file path
hence task next https://hence.run/p/TOKEN
hence task claim setup https://hence.run/p/TOKEN
hence task complete setup https://hence.run/p/TOKEN
hence task assert '(given tests-passing)' https://hence.run/p/TOKEN
hence plan board https://hence.run/p/TOKEN --json
hence query explain ready-auth https://hence.run/p/TOKEN
Every command that accepts a local path also accepts a https://hence.run/p/TOKEN URL. No additional configuration is required beyond authentication (if the plan is private).
Authentication
# Authenticate with hence.run (one-time setup)
hence auth login
# Or pass a token via environment variable
export HENCE_TOKEN=your-token-here
Sharing a local plan remotely
# Push a local plan to hence.run
hence plan push plan.spl
# Output: https://hence.run/p/abc123def456
# Share this URL with other agents
11. JSON output for programmatic use
Every read command supports --json. Use this flag whenever processing output in scripts, piping to jq, or ingesting results into another LLM call.
| Command | JSON output content |
|---|---|
hence plan board plan.spl --json |
Array of all tasks with status, agent, and metadata |
hence plan status plan.spl --json |
Summary counts: ready, claimed, completed, blocked |
hence plan info plan.spl --json |
Plan metadata from (meta plan ...) |
hence task next plan.spl --json |
Array of {task, agent, commands} objects |
hence task assign plan.spl --json |
Array of all current assignments with status |
hence query explain ready-auth plan.spl --json |
Structured proof tree as JSON |
Examples
# Get plan title
hence plan info plan.spl --json | jq -r '.title'
# Count ready tasks
hence plan board plan.spl --json | jq '[.[] | select(.status == "ready")] | length'
# Get all completed task names
hence plan board plan.spl --json | jq -r '.[] | select(.status == "completed") | .task'
# Get the agent for the first available task
hence task next plan.spl --json | jq -r '.[0].agent'
# Extract the claim command for the first task
hence task next plan.spl --json | jq -r '.[0].commands[0]'
# Check if a specific task is assigned
hence task assign plan.spl --json | jq '.[] | select(.task == "auth")'
12. Common mistakes to avoid
Fact and rule errors
| Wrong | Right | Why |
|---|---|---|
(given completed-auth) |
hence task complete auth plan.spl |
completed-TASK is derived from claims, never asserted as a given. Asserting it directly creates a conflicting fact. |
assign-to-coder |
assign-to-auth-coder |
Assignment atoms always include the task identifier: assign-to-TASK-AGENT. Missing the task makes it unroutable. |
(always body head) for a policy |
(normally body head) |
Use always only for inviolable rules. Policies that might be overridden must use normally so superiority can defeat them. |
Claiming a task without checking hence task next |
Always run hence task next first |
Claiming a task that is not yet ready (missing prerequisites) records a claim that will not match a ready state — wasted work. |
Asserting ready-TASK directly |
Assert the facts that make the readiness rule fire | ready-TASK should be derived by a readiness rule. Asserting it directly bypasses the logic and may produce inconsistent states. |
Metadata errors
| Missing | Consequence |
|---|---|
(meta plan ...) block |
hence plan info returns empty or errors. Plans without metadata are not self-documenting and may fail review. |
(meta task-X (description "...") (acceptance "...")) |
Task has no acceptance criteria. hence plan review will flag it. Agents cannot confirm when the task is complete. |
(meta r-X ...) on non-obvious rules |
Other agents cannot understand why the rule exists. Makes debugging harder and plan review will flag unexplained rules. |
Process errors
| Wrong pattern | Correct pattern |
|---|---|
Skip hence plan validate when writing a plan |
Always validate before distributing or claiming tasks |
Check hence task next only at session start |
Check after every hence task complete — completing unlocks new work |
| Block a task without a reason string | Always include a human-readable reason: hence task block TASK "reason" plan.spl |
Use HENCE_AGENT with spaces or uppercase |
Agent names are kebab-case, no spaces: export HENCE_AGENT=my-agent |
13. Session commands
Session commands show what the reasoner has loaded and concluded from a plan file. Use these for introspection and debugging.
# Show all facts and conclusions derived from the plan in the current session
hence session my-session-name
# List all recent sessions (plans interacted with, timestamps)
hence sessions
What session output shows
- Loaded facts: all
(given ...)atoms and asserted claims in the file - Derived conclusions: all atoms provable via rules given the loaded facts
- Active claims: which agents have claimed or completed which tasks
- Defeat information: which rules were defeated and by which superior rules
# Pipe session output into jq for filtering
hence session my-session-name --json | jq '.conclusions'
hence session my-session-name --json | jq '.claims'
14. Inline SPL reference
The complete output of hence llm spl is embedded below. An LLM reading this page already has the full SPL syntax reference in context. No command required.
# SPL (Spindle Lisp) Reference
Spindle Lisp is a LISP-based DSL for defeasible logic. Use `.spl` extension.
## How to Write a Plan
A complete annotated plan. Every plan follows this structure:
```lisp
;; Plan metadata — always start here (queryable via `hence info`)
(meta plan
(id "IMPL-014")
(title "User Authentication")
(version "1.0.0")
(status "active")
(created "2026-02-14")
(author "agent:architect")
(spec "SPEC-014")
(description "Implement login, session management, and token refresh"))
;; Agents
(given agent-coder-available)
(given agent-security-available)
;; Tasks and their properties
(given task-auth)
(given task-tests)
(given no-deps-auth)
(given security-sensitive-auth)
;; Task metadata — annotate every task with description + acceptance
(meta task-auth
(description "Implement JWT auth with refresh tokens")
(acceptance "Login endpoint returns valid JWT; refresh works; tests pass"))
(meta task-tests
(description "Integration tests for auth endpoints")
(acceptance "Coverage > 80%; all auth flows tested"))
;; Readiness rules — when can a task start?
(normally r-ready-auth
(and task-auth no-deps-auth)
ready-auth)
(normally r-ready-tests
(and task-tests completed-auth)
ready-tests)
;; Assignment rules — who works on what? (format: assign-to-TASK-AGENT)
(normally r-assign-coder
(and ready-auth agent-coder-available)
assign-to-auth-coder)
(normally r-assign-security
(and ready-auth security-sensitive-auth agent-security-available)
assign-to-auth-security)
;; Superiority — resolve conflicts (first label wins)
(prefer r-assign-security r-assign-coder)
;; Rule metadata — annotate rules with description + justification
(meta r-assign-security
(description "Security-sensitive tasks go to security agent")
(justification "Per security policy section 3.2"))
```
**Tip:** Set `HENCE_AGENT` to avoid repeating `--agent`:
```bash
export HENCE_AGENT=coder
hence task next plan.spl # find my tasks
hence task claim auth plan.spl # claim
hence task complete auth plan.spl # done
```
## Annotating with Metadata
Annotate everything — metadata makes plans queryable and self-documenting.
**Plan metadata** — required at the top of every plan:
```lisp
(meta plan (id "X") (title "Y") (status "active") (description "Z"))
```
Standard properties: `id`, `title`, `version`, `status`, `created`, `updated`, `author`, `spec`, `description`.
**Task metadata** — describe what and when it's done:
```lisp
(meta task-auth
(description "Implement JWT auth with refresh tokens")
(acceptance "Login returns valid JWT; refresh works; tests pass"))
```
**Rule metadata** — explain why a rule exists:
```lisp
(meta r-assign-security
(description "Security tasks need security agent")
(justification "Per security policy section 3.2"))
```
**Arbitrary metadata** on any labeled element:
```lisp
(meta r1 (confidence 0.9) (source "handbook"))
```
## Syntax Quick Reference
```
statement ::= fact | rule | prefer | meta | import | provide | claims
fact ::= (given atom arg*)
rule ::= (always [label] body head) ; strict
| (normally [label] body head) ; defeasible
| (except [label] body head) ; defeater
prefer ::= (prefer label label+)
meta ::= (meta label property+)
claims ::= (claims source [:at T] [:note S] statement+)
literal ::= atom | (atom arg*) | (not literal) | modal | temporal
modal ::= (must literal) | (may literal) | (forbidden literal)
temporal ::= (during literal start end)
body/head ::= literal | (and literal+)
variable ::= ?name | _
```
**Facts:** `(given atom)` or `(given predicate arg1 arg2)`
**Negation:** `(not literal)` — e.g. `(not flies)`, `(not (loves john mary))`
**Conjunction:** `(and literal literal+)` — e.g. `(and bird healthy)`
**Variables:** `?name` — e.g. `(normally (parent ?x ?y) (ancestor ?x ?y))`; wildcard: `_`
**Strict rule:** `(always body head)` or `(always label body head)` — cannot be defeated
**Defeasible rule:** `(normally body head)` or `(normally label body head)` — can be defeated
**Defeater:** `(except body head)` or `(except label body head)` — blocks but doesn't conclude
**Superiority:** `(prefer winner loser+)` — e.g. `(prefer r2 r1)`
**Metadata:** `(meta label (key "value")+)`
**Claims:** `(claims agent:name :at "ISO-8601" :note "text" statements...)` — source attribution
**Import:** `(import "file.spl")` or `(import "file.spl" as alias)`
**Provide:** `(provide name+)` or `(provide all)` or `(provide conclusions)`
**Modal:** `(must lit)`, `(may lit)`, `(forbidden lit)`
**Temporal:** `(during lit start end)` with `(moment year [month day ...])`, `inf`, `-inf`
## Naming Conventions (kebab-case)
| Prefix | Purpose | Example |
|--------------|-------------------------------|----------------------------|
| `task-` | Task identifiers | `task-auth` |
| `ready-` | Task readiness | `ready-auth` |
| `completed-` | Task completion | `completed-auth` |
| `blocked-` | Blocked tasks | `blocked-auth` |
| `unblocked-` | Unblocked tasks | `unblocked-auth` |
| `assign-to-` | Task assignment | `assign-to-auth-coder` |
| `agent-` | Agent identifiers | `agent-coder-available` |
| `discovered-`| Findings during execution | `discovered-api-deprecated`|
| `decided-` | Decisions made | `decided-use-redis` |
| `verified-` | Validations | `verified-auth-works` |
Note: DFL format uses `assignTo_TASK_AGENT` (underscores). Both conventions work with `hence task next`.
Quick reference card
A condensed reference for agents that already know the system.
Identity and orientation
export HENCE_AGENT=<name>
hence agent whoami
hence plan info plan.spl
hence plan board plan.spl
Work loop
hence task next plan.spl [--json]
hence task claim TASK plan.spl
hence task assert '(given FACT)' plan.spl
hence task complete TASK plan.spl
Debugging
hence query explain LITERAL plan.spl
hence query why-not LITERAL plan.spl
hence query what-if plan.spl '(given A)' '(given B)'
hence query require LITERAL plan.spl
hence query describe plan.spl LABEL
Plan authoring
hence plan validate plan.spl
hence plan review plan.spl
hence plan translate spec.md --output plan.spl
Blocking
hence task block TASK "reason" plan.spl
hence query why-not ready-TASK plan.spl
Remote plans
hence task next https://hence.run/p/TOKEN
hence task claim TASK https://hence.run/p/TOKEN
hence task complete TASK https://hence.run/p/TOKEN
JSON everywhere
hence plan board plan.spl --json
hence plan info plan.spl --json
hence plan status plan.spl --json
hence task next plan.spl --json
hence task assign plan.spl --json
hence query explain LITERAL plan.spl --json