977a3bd97f
Align activity-core scope boundaries
2026-06-18 15:11:48 +02:00
41d3e75a88
Implement ops inventory probe evidence slice
2026-06-05 23:16:40 +02:00
30598fd1ad
Expand rule actions for per-repo tasks
...
Add safe action interpolation and for_each binding for rule fan-out, update the weekly SBOM definition, cover the new evaluation path, and reconcile activity-core scope/workplans for the State Hub sync.
2026-06-03 11:58:24 +02:00
c79d0980a9
Make Temporal activity timeout env-configurable (ADHOC-2026-06-01-T03)
...
The CUST-WP-0045 daily triage canary on 2026-06-01 hit a BrokenPipeError
on the llm-connect side. Two 5-minute timeouts were racing:
- _ACTIVITY_TIMEOUT = timedelta(minutes=5) in workflows.py
- LLM_CONNECT_TIMEOUT_SECONDS default 300 in llm_client.py
The 10KB curated digest + max_depth:2 + JSON schema enforcement pushed
Claude past 5 minutes. Whichever timer fired first killed the httpx call;
the model's late response arrived to a closed socket.
Read _ACTIVITY_TIMEOUT from ACTIVITY_TIMEOUT_SECONDS env (default 900 —
15 minutes) so judgement-call activities have headroom for slow LLM runs.
Operators should also widen httpx via LLM_CONNECT_TIMEOUT_SECONDS=840 so
httpx still times out slightly before Temporal, preserving the
clean-error contract.
Tests: 120 passed, 1 skipped.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-06-02 08:10:24 +02:00
3110399b11
Add instruction report sinks
2026-05-19 18:36:58 +02:00
0dc342eb1b
Wire instruction report execution
2026-05-19 18:28:23 +02:00
827ef9c1a0
feat(WP-0003c): context adapters, first ActivityDefinition, full test suite
...
T51: ContextResolver ABC + CONTEXT_RESOLVER_REGISTRY; resolve_context activity
updated to dispatch via registry (warns + binds {} on failure, never aborts run).
T52: RepoScopingContextResolver with 5-min in-process cache.
T53: StateHubContextResolver (no cache) for domain_summary and repo_sbom_status.
T54: activity-definitions/weekly-sbom-staleness.md (Monday 09:00 Berlin, cron
trigger, flag-stale-sbom rule at >30 days) + tasks/sbom-rescan.md template.
T55: 51 parametrized evaluator tests — all whitelisted operators, unsafe
expression rejection, empty condition, missing attribute, nested context access.
T56: 15 executor safety tests — UntrustedFieldError, object-type rejection,
injection fixture, LLM retry on bad JSON, review_required field.
T57: 6 integration tests — parses real definition, evaluates rule per-repo
(stale/fresh boundary), emits via NullSink, verifies spawn log entries.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-14 23:24:48 +02:00
176867cbe3
feat(WP-0003b): parser, workflow wiring, triggers, webhooks
...
T44: ActivityDefinition markdown file parser (definition_parser.py)
- Scans activity-definitions/*.md and ACTIVITY_DEFINITION_DIRS paths
- Parses YAML frontmatter + fenced rule/instruction blocks
- Raises ParseError on any malformed file — never silently skips
T45: ActivityDefinition sync command
- Migration 0006: adds rules_json/instructions_json JSONB columns
- sync_activity_definitions.py + make sync-activity-definitions
- Called at worker startup before schedule sync
T46: Rule/instruction pipeline wired into RunActivityWorkflow
- New evaluate_rules and emit_tasks Temporal activities
- Workflow passes event_envelope_json to enable rule evaluation
- EventRouter now passes full envelope JSON as 4th workflow arg
- IssueSink.emit() writes task_spawn_log rows per task
T47: ScheduledTriggerConfig model (one-off future datetime trigger)
T48: One-off Temporal Schedule support
- Fixed timezone_name → time_zone_name (was causing all schedule tests to fail)
- Added ScheduleCalendarSpec-based one-off schedule with remaining_actions=1
- cancel_scheduled() for admin cancellation
- Fixed backfill() call to use *args unpacking (not list wrapper)
- Fixed ScheduleAlreadyRunningError catch in upsert_schedule
- sync_schedules now handles ScheduledTriggerConfig definitions
T49: Webhook receiver
- POST /webhooks/gitea — HMAC-SHA256 via X-Gitea-Signature-256
- POST /webhooks/github — HMAC-SHA256 via X-Hub-Signature-256
- Normalisers: repo.created, push, issue.closed → EventEnvelope
- Publishes to NATS activity.{type} subject after registry validation
- Mounted in api.py at /webhooks prefix
T50: Gitea event type definitions
- gitea.repo.created.md, gitea.push.md, gitea.issue.closed.md
- Each includes normaliser field mapping in Consumer Notes
Tests: 18 passed, 1 skipped (integration). Fixed embedded Temporal
server visibility latency in test_upsert_schedule_creates_schedule.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-14 23:02:33 +02:00
ea5fbe0bf3
feat(WP-0002): complete Triggers & Ops workstream
...
Delivers all 12 tasks (T22–T33): Temporal Schedule manager + startup
sync, NATS JetStream event router, FastAPI CRUD + manual trigger,
Prometheus metrics wiring, custom search-attribute tagging, and
operational runbook. Marks workplan status as done.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-28 01:04:43 +01:00
34aa70cbd9
feat(workflows): TaskExecutorWorkflow stub + wire worker — T19/T20
...
activities.py — persist_task_instance (new):
Idempotent INSERT ... ON CONFLICT (id) DO NOTHING on task_instances.
task_id passed in from workflow (derived from workflow_id via uuid5).
Registered on task-execution-tq.
workflows.py — TaskExecutorWorkflow (T19):
Derives stable task_id = uuid5(NAMESPACE_URL, workflow_id).
Calls persist_task_instance → status=done, returns immediately.
Real execution logic to replace stub in a later workstream.
worker.py — T20:
Registers persist_task_instance on task-execution-tq Worker.
Both queues fully wired: orchestrator-tq and task-execution-tq.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-26 22:30:50 +00:00
da7de6ea3b
feat(workflows): implement RunActivityWorkflow — T18
...
workflows.py — RunActivityWorkflow:
1. load_activity_definition(activity_id)
2. resolve_context(context_sources)
3. evaluate_templates (pure, called in-workflow)
4. log_run({run_id, ...}) — run_id = uuid5(NAMESPACE_URL, activity_id:trigger_key)
5. start_child_workflow(TaskExecutorWorkflow, ...) per task spec
ABANDON parent-close policy (fire-and-forget)
Returns {"run_id": str, "tasks_spawned": int}
activities.py — log_run updated:
- now accepts run_id in run_payload (deterministic, passed from workflow)
- uses pg INSERT ... ON CONFLICT (run_id) DO NOTHING for idempotency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-26 22:25:19 +00:00
21edc313db
feat(worker): scaffold activities, workflows, worker entrypoint — T13
...
src/activity_core/activities.py:
- load_activity_definition, resolve_context, log_run — @activity.defn
stubs (raise NotImplementedError, bodies in T14–T17)
src/activity_core/workflows.py:
- RunActivityWorkflow (orchestrator-tq) — @workflow.defn stub (T18)
- TaskExecutorWorkflow (task-execution-tq) — @workflow.defn stub (T19)
src/activity_core/worker.py:
- Connects to Temporal via TEMPORAL_HOST / TEMPORAL_NAMESPACE env vars
- Spawns two Workers: orchestrator-tq and task-execution-tq
- Runs until cancelled (python -m activity_core.worker)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-26 21:57:56 +00:00