feat: add process logging with DAG-based event sourcing
Event-sourced orchestration logging: JSONL events with parent relationships form a DAG for causal reconstruction of agent flows. Includes bash event emitter (jq-based) and markdown report generator.
This commit is contained in:
72
lib/archeflow-event.sh
Executable file
72
lib/archeflow-event.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
# archeflow-event.sh — Append a structured event to an ArcheFlow run's JSONL log.
|
||||
#
|
||||
# Usage: ./lib/archeflow-event.sh <run_id> <type> <phase> <agent> '<json_data>' [parent_seqs]
|
||||
#
|
||||
# Examples:
|
||||
# ./lib/archeflow-event.sh 2026-04-03-der-huster run.start plan "" '{"task":"Write Der Huster"}'
|
||||
# ./lib/archeflow-event.sh 2026-04-03-der-huster agent.complete plan creator '{"duration_ms":167522}' 2
|
||||
# ./lib/archeflow-event.sh 2026-04-03-der-huster phase.transition do "" '{"from":"plan","to":"do"}' 3,4
|
||||
# ./lib/archeflow-event.sh 2026-04-03-der-huster fix.applied act "" '{"source":"guardian"}' 8
|
||||
#
|
||||
# Parent seqs: comma-separated seq numbers of causal parent events (DAG).
|
||||
# "2" → single parent [2]
|
||||
# "3,4" → multiple parents [3,4] (fan-in)
|
||||
# "" → root event []
|
||||
#
|
||||
# Events are appended to .archeflow/events/<run_id>.jsonl
|
||||
# If the events directory doesn't exist, it is created automatically.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 4 ]]; then
|
||||
echo "Usage: $0 <run_id> <type> <phase> <agent> [json_data] [parent_seqs]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RUN_ID="$1"
|
||||
TYPE="$2"
|
||||
PHASE="$3"
|
||||
AGENT="$4"
|
||||
DATA="${5:-"{}"}"
|
||||
PARENT_RAW="${6:-}"
|
||||
|
||||
EVENTS_DIR=".archeflow/events"
|
||||
EVENT_FILE="${EVENTS_DIR}/${RUN_ID}.jsonl"
|
||||
|
||||
mkdir -p "$EVENTS_DIR"
|
||||
|
||||
# Determine sequence number (count existing lines + 1)
|
||||
if [[ -f "$EVENT_FILE" ]]; then
|
||||
SEQ=$(( $(wc -l < "$EVENT_FILE") + 1 ))
|
||||
else
|
||||
SEQ=1
|
||||
fi
|
||||
|
||||
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
# Build parent array from comma-separated seq numbers
|
||||
if [[ -z "$PARENT_RAW" ]]; then
|
||||
PARENT_JSON="[]"
|
||||
else
|
||||
PARENT_JSON="[${PARENT_RAW}]"
|
||||
fi
|
||||
|
||||
# Construct the event using jq for reliable JSON assembly
|
||||
# Agent is passed as --arg (string), then converted to null if empty via jq expression
|
||||
EVENT=$(jq -cn \
|
||||
--arg ts "$TS" \
|
||||
--arg run_id "$RUN_ID" \
|
||||
--argjson seq "$SEQ" \
|
||||
--argjson parent "$PARENT_JSON" \
|
||||
--arg type "$TYPE" \
|
||||
--arg phase "$PHASE" \
|
||||
--arg agent_raw "$AGENT" \
|
||||
--argjson data "$DATA" \
|
||||
'{ts:$ts, run_id:$run_id, seq:$seq, parent:$parent, type:$type, phase:$phase, agent:(if $agent_raw == "" then null else $agent_raw end), data:$data}'
|
||||
)
|
||||
|
||||
echo "$EVENT" >> "$EVENT_FILE"
|
||||
|
||||
# Print confirmation to stderr (non-intrusive)
|
||||
echo "[archeflow-event] #${SEQ} ${TYPE} (${PHASE}/${AGENT:-_})" >&2
|
||||
Reference in New Issue
Block a user