/**
 * src/constitution/signal.ts
 *
 * Publishes soft constitutional scorer results to Brain episodic memory.
 * Decouples the scoring pipeline from Brain I/O — purely an adapter.
 *
 * @module constitution/signal
 */
// ---------------------------------------------------------------------------
// publishSignal
// ---------------------------------------------------------------------------
/**
 * Publish a constitutional soft-score signal to Brain episodic memory.
 *
 * Tags: ["constitution_signal", axiomId]
 *
 * @param brainPort  - Host-injected BrainPort. If `episodic` is absent, no-ops silently.
 * @param cycle      - The cycle that was scored.
 * @param axiomId    - The axiom that produced the score.
 * @param score      - Normalised score in [0, 1].
 * @param rationale  - Human-readable scoring rationale for audit.
 */
export async function publishSignal(brainPort, cycle, axiomId, score, rationale) {
    if (!brainPort.episodic)
        return;
    const event = "constitution_signal";
    const metadata = {
        axiom: axiomId,
        score,
        rationale,
        runId: cycle.runId,
        rootHash: cycle.rootHash,
        tags: ["constitution_signal", axiomId],
        budgetUsdMax: cycle.budgetUsdMax,
        budgetUsdSpent: cycle.budgetUsdSpent,
    };
    if (cycle.parentRunId !== undefined) {
        metadata.parentRunId = cycle.parentRunId;
    }
    if (cycle.scope_id !== undefined) {
        metadata.scope_id = cycle.scope_id;
    }
    await brainPort.episodic.record(
    // agentId: use runId as the owning agent identifier for constitution signals
    `constitution:${axiomId}`, cycle.runId, event, metadata);
}
/**
 * Publish all axiom scores for a single cycle to Brain episodic.
 * Fires all records in parallel; individual failures are re-thrown as an
 * AggregateError to avoid silent drops.
 */
export async function publishAllSignals(brainPort, cycle, scores) {
    const results = await Promise.allSettled(scores.map(({ axiomId, score, rationale }) => publishSignal(brainPort, cycle, axiomId, score, rationale)));
    const failures = results
        .filter((r) => r.status === "rejected")
        .map((r) => r.reason);
    if (failures.length > 0) {
        throw new AggregateError(failures, `publishAllSignals: ${failures.length} Brain episodic write(s) failed`);
    }
}
//# sourceMappingURL=signal.js.map