Building a Reference-Grade Market Intelligence Workflow on HUMΛN
Your competitor ships a pricing change on a Tuesday. By Wednesday your PM has a Slack thread, three pasted screenshots, and zero agreement on whether the signal is real, who scored it, or whether Legal already saw the compliance angle.
That is the failure mode Signals exists to kill: market intelligence that arrives as chat noise instead of a governed pipeline with provenance, human gates, and role-specific artifacts.
Signals is HUMΛN’s reference workflow — not a demo toy. It shows builders how to wire multi-agent coordination, Workforce Cloud approvals, Companion delivery, and Command Plane learning on one installable bundle.
Scroll-stopper: If you can read Signals and understand every decision, you can build anything on HUMΛN.
Why Signals is the reference
Every hard thing a production workflow touches shows up here:
- Multi-source, multi-agent coordination (not one LLM call)
- Human-in-the-loop gates at the right moments (not everywhere)
- Learning from feedback from day one (not bolted on later)
- Multiple delivery surfaces with zero-config defaults and opt-in power
- Policy and trust/safety enforcement via declared capability strings, allowlists, and escalation schemas — not a free lunch, but no custom policy engine per agent
So that you fork patterns, not vibes — capability-first routing, async approval, mandatory feedback events — into your own domain.
The pipeline in 8 components
Signals is a linear pipeline with a fan-out in the middle:
Source Scout ← monitors approved sources, emits raw candidates
↓
Signal Normalizer ← stable schema, dedup within 72-hour window
↓
Trust & Safety Gate ← PII, provenance, source allowlist — runs after normalization*
↓
Signal Judge ← scores relevance/novelty/urgency/confidence; escalates if needed
↓
Opportunity Router ← scored matrix, fan-out to personas
↓
Artifact Workers ← 6 specialist workers, parallel generation
↓
Delivery Orchestrator ← surface matrix; Companion + Command Plane always on
↓
Learning Engine ← aggregates all feedback, proposes tuning
* Why Trust & Safety runs after normalization: safety checks operate on NormalizedSignal fields (structured content type, evidence URLs, canonical entity tags). Raw candidates are too unstructured to reliably detect PII or verify provenance. Normalize first; then gate.
Each component is a standalone HUMΛN agent. They can be called independently, tested with a mock context, or replaced. The orchestrator (workflow.ts) ties them together:
// workflow.ts — each step is a ctx.call.agent() invocation
// The runtime routes by capability string. Each agent declares which
// capabilities it satisfies. This is HUMΛN capability-first routing.
const scoutResult = await ctx.call.agent<SourceScoutOutput>(
'signals.scout.monitor', // ← capability string, not agent ID
{ org_did, workflow_run_id, watched_entities, source_families }
);
const normResult = await ctx.call.agent<SignalNormalizerOutput>(
'signals.normalize',
{ raw_candidates: scoutResult.data.raw_candidates, org_did, workflow_run_id }
);
const trustResult = await ctx.call.agent<TrustSafetyOutput>(
'signals.trust_safety.gate', // ← matches trust-safety.ts CAPABILITIES
{ signals: normResult.data.normalized_signals, org_did, workflow_run_id }
);
No hardcoded imports. No direct function calls between agents. The platform resolves the right agent at runtime — swap an implementation without touching the orchestrator.
The design decisions that matter
1. Capability-first routing, not hardcoded agent imports
The single most important pattern in Signals: the orchestrator never imports agent modules directly. Every inter-agent call goes through ctx.call.agent() with a capability string.
// ❌ Don't do this — couples orchestrator to implementation
import { signalJudgeHandler } from './signal-judge.js';
const verdicts = await signalJudgeHandler.execute(ctx, { signals: ... });
// ✅ Do this — capability-first routing
const judgeResult = await ctx.call.agent<SignalJudgeOutput>(
'signals.judge.score',
{ signals: trustOutput.safe_signals, org_did, workflow_run_id }
);
Replace the agent that satisfies 'signals.judge.score' and the orchestrator never changes.
2. Human review is a fire-and-forget gate, not a synchronous blocker
PRD drafts and integration assessments call ctx.approval.request(), which routes the artifact to Workforce Cloud as a work item. The orchestrator continues delivering other artifacts in parallel.
// In artifact-workers.ts — PRD always requires Workforce Cloud review
if (workforceInstallationId) {
await ctx.approval.request({
installation_id: workforceInstallationId,
renderer_id: 'prd-review', // matches workforce_module.work_item_renderers[id]
artifact_id: (artifact as { artifact_id: string }).artifact_id,
urgency: signalUrgencyToApprovalUrgency(signal.urgency),
metadata: {
entity: signal.entity_name,
signal_confidence: signal.confidence,
workflow_run_id: input.workflow_run_id,
},
});
}
// Delivery continues for other artifacts — not blocked by this review
Human review is asynchronous. The artifact sits in Workforce Cloud until a PM approves it; the rest of the workflow has already briefed other personas.
3. Learning is always on — and zero config
Every component emits a typed event at the end of every run:
await ctx.events.emit('humanos.signals.feedback', {
feedback_type: 'verdict_signal', // ← typed, not free-form string
source: 'signal-judge',
workflow_run_id: input.workflow_run_id,
org_did: input.org_did,
agent_id: AGENT_ID,
signal_strength: passedCount / totalCount,
metadata: {
total_signals: signals.length,
passed: passedCount,
suppressed: signals.length - passedCount,
avg_confidence: /* computed */,
compliance_escalated: complianceEscalatedCount,
},
});
The org admin can turn off proposals (learning.enabled = false), but event emission is baked in. The system learns from run one — proposals appear in the Command Plane before you’ve configured anything.
4. Delivery surfaces follow “magic by default, control when needed”
Two surfaces are always on with zero config:
- Companion queue — default delivery kinds (
executive_brief,product_gap_memo,content_brief,battlecard_update) land in the Signals panel after the first run - Command Plane signal feed — visible in the Console signals dashboard
PRD drafts and integration assessments are Workforce-gated — they do not auto-land in the Companion panel; reviewers approve them in Workforce Cloud first.
Additional surfaces (Slack, email, Google Docs, filesystem) are configured via connector once and then referenced in the routing config per persona.
After install, the first scheduled or manual run delivers Companion artifacts for the default kinds — then add surfaces progressively. The full delivery matrix lives in delivery-orchestrator.ts and reference-config-pack.ts.
5. Escalation is built in, not bolted on
Signal Judge applies three distinct escalation patterns via ctx.escalate():
// Low-confidence → expert review (Fourth Law: AI must know when it doesn't know)
if (signal.confidence < minConfidence) {
await ctx.escalate(buildSignalConfidenceReviewEscalation(signal, scoring, input.org_did));
}
// Compliance → always routed to compliance team
if (scoring.is_compliance) {
await ctx.escalate(buildComplianceEscalation(signal, scoring, input.org_did));
}
// Urgent strategic → immediate executive notification
if (scoring.relevance_score >= 0.9 && signal.urgency !== 'low') {
await ctx.escalate(buildUrgentStrategicEscalation(signal, scoring, input.org_did));
}
Each escalation is fire-and-forget. Schemas in signals-escalation-schemas.ts carry reason, question, allowed actions, required capability, routing mode, and a Workforce Cloud UI definition.
How to fork Signals for your own domain
The pipeline is domain-agnostic up to Signal Normalizer. After normalization, everything is typed by signal_type. To build your own:
- Copy the source scout — replace connector capability calls for your sources
- Keep the normalizer and judge — they work on any
NormalizedSignal - Customize the router — change persona matrix weights in
reference-config-pack.ts - Replace the workers — artifact generators via
ctx.llm.complete()andctx.artifacts.create() - Keep delivery and learning as-is — domain-agnostic
WorkflowManifestV1 from @human/platform-extensions is your registration contract: triggers, steps, workers, Command Plane extension, Companion module, and Workforce module in one manifest.
What “reference grade” means in practice
- Every LLM call uses
ctx.llm.complete(...)— never direct OpenAI/Anthropic imports - Every agent emits
ctx.events.emit('humanos.signals.feedback', {...})at end of run - Artifacts use
ctx.artifacts.create(...)with fullAgentChainEntryprovenance - HITL gates use
ctx.approval.request(...)— PRD drafts are never auto-approved - Connectors via
ctx.call.agent('connector.<id>.<method>', input)— never direct HTTP - Config from
input(resolved envelope) — defaults inreference-config-pack.ts - Learning proposals via
ctx.events.emit('humanos.learning.proposal', {...})— never direct DB writes - Escalations use
ctx.escalate(buildXxxEscalation(...))with structured schemas
Hit all eight and you’re building reference-grade.
Go deeper
- Product: Command Plane, Workforce, Companion
- Docs: Building your first extension, Workforce concepts
- Community: Workflows as platform extensions, CLI scaffolding, External noise → governed intelligence
Signals is installable from the HUMΛN Marketplace. Fork it, break it, rebuild it.
Signals reference workflow — Part 1 of 3