SignalQL v0.2 specification
SignalQL v0.2 defines a domain-agnostic language for retrieving and shaping structured evidence from events, entities, relationships, and AI-created memory objects. Interpretation belongs to AI or higher application layers, not SignalQL itself.
Core principle
SignalQL retrieves structured evidence; it does not interpret, decide, or mutate state.
- No domain-specific semantics in core grammar.
- No action/mutation language.
- No built-in labels like "blocked", "priority", or workflow states.
Core constructs
- Entities: durable objects such as
memory_object,decision,summary,fact,claim,plan,artifact,context_bundle,person,repo,thread. - Events: timestamped activity attached to entities and actors.
- Relationships: traversable links between entities.
- Signals: externally computed values exposed as queryable fields.
- Probability fields: likelihood/confidence values from external models.
- Provenance metadata: evidence hygiene fields such as
source,created_by,derived_from,confidence,observed_at,updated_at.
Entity names above are core-safe examples, not required core nouns.
Grammar (EBNF)
query ::= retrieve_query | sequence_query
retrieve_query ::= "FROM" source where_clause? traverse_clause? trend_clause? select_clause
source ::= entity_source | event_source
entity_source ::= "entity" "(" qualified_identifier ")"
event_source ::= "events"
where_clause ::= "WHERE" predicate_list
predicate_list ::= predicate ( "AND" predicate )*
predicate ::= field_path comparator value
comparator ::= "=" | ">" | "<" | ">=" | "<="
field_path ::= identifier ( "." identifier )*
| "signal" "(" identifier ")"
| "probability" "(" identifier ")"
| "semantic_match" "(" string_literal ")"
traverse_clause ::= "TRAVERSE" identifier "DEPTH" "<=" integer
trend_clause ::= "TREND" trend_dir "OVER" integer time_unit
trend_dir ::= "UP" | "DOWN" | "FLAT"
time_unit ::= "d" | "h" | "w"
sequence_query ::= "FIND" "sequence" "WHERE" sequence_steps "WITHIN" integer time_unit
sequence_steps ::= sequence_step ( "->" sequence_step )+
sequence_step ::= identifier | string_literal
select_clause ::= "RETURN" return_field ( "," return_field )*
return_field ::= field_path | "count" | "entity_id" | "timestamp"
qualified_identifier ::= identifier ( "." identifier )*
identifier ::= [a-zA-Z_] [a-zA-Z0-9_]*
integer ::= [0-9]+
value ::= string_literal | integer | decimal | boolean
string_literal ::= '"' { character } '"'
decimal ::= [0-9]+ "." [0-9]+
boolean ::= "true" | "false"Execution model
- Parse SignalQL to AST and reject unknown constructs.
- Bind references to source metadata (entities/events/relationships/signal catalog).
- Build deterministic execution plan (traversal, filters, sequence windows, return fields).
- Execute retrieval path in adapter/runtime.
- Apply caller permissions before returning evidence.
- Return structured evidence + execution metadata.
Execution metadata SHOULD include access-filter details when available.
SignalQL does not score, classify, prioritize, or decide outcomes.
Determinism contract
- Canonical formatting produces stable clause ordering.
- Equivalent AST input yields equivalent execution plan output.
- Output includes machine-readable metadata for explainability.
Example queries
Entity retrieval with derived signal
FROM entity(memory_object)
WHERE signal(relevance_score) > 0.8
RETURN entity_id, signal(relevance_score)Graph traversal
FROM entity(note)
TRAVERSE references DEPTH <= 2
RETURN entity_id, countSequence pattern
FIND sequence
WHERE observed -> linked -> reviewed
WITHIN 3dVersioned evidence retrieval
FROM entity(memory_object)
WHERE version > 3
RETURN entity_id, version, updated_atCurrent decision retrieval
FROM entity(decision)
WHERE superseded = false
RETURN entity_id, summaryNamespaced domain-pack entity retrieval
FROM entity(work.memory_item)
WHERE signal(relevance_score) > 0.8
RETURN entity_id, signal(relevance_score)FROM entity(analytics.session)
RETURN entity_idFROM entity(code.architecture_decision)
RETURN entity_idOptional semantic retrieval primitive
FROM entity(memory_object)
WHERE semantic_match("why did we choose redis") > 0.75
RETURN entity_id, summaryTemporal trend
FROM entity(context_bundle)
TREND UP OVER 5d
RETURN entity_id, countProvenance-focused retrieval
FROM entity(claim)
WHERE confidence >= 0.7
RETURN entity_id, source, created_by, derived_from, observed_at, updated_atDomain-pack namespacing
Core grammar remains domain-agnostic. Domain packs may use namespaced entity types (for example work.memory_item, analytics.session, code.architecture_decision) without changing core language semantics.
Revision semantics
SignalQL remains retrieval-only. Revision/version fields are queryable evidence (version, superseded, updated_at) and do not imply mutating commands.
Semantic retrieval
semantic_match(...) is an optional retrieval primitive. Adapters may expose it when vector/semantic infrastructure is available; unsupported runtimes MUST return an explicit capability error.
Permissions-aware execution
Execution MUST apply caller permissions before evidence leaves the runtime boundary. When feasible, execution metadata SHOULD describe access filtering that affected result shape.
Non-goals
- No domain nouns (
sprint,epic,story_points,workflow_status) in core grammar. - No mutating commands (
ASSIGN,EXECUTE,UPDATE,DELETE). - No embedded business policy interpretation.
Normative references
- Version index: spec versions
- Current scope: v0.2 scope
- Historical baseline: v0.1 spec