AbsoluteJS

Outcomes

@absolutejs/outcomesv0.2.4betaAI

Outcome feedback loop for AI agents: typed artifact features, attribution-joined stats, and rendered evidence that makes agent context better per user.

An outcome feedback loop that makes an AI agent measurably better per user without training anything. Agents produce artifacts (outreach emails, generated pages, drafts) and things happen to them (opens, replies, conversions); recording both sides with typed features frozen at production time lets the agent’s context improve every week, with receipts you can show users. You define artifact kinds and outcome events once, and the package derives the ledger contract, attribution-joined stats, and an evidence block your own AI call distills into a per-user memo.

#Installation

BASH
bun add @absolutejs/outcomes

#Capabilities

Overview

Listed attributed artifacts retain their observation time, allowing hosts to build privacy-safe time cohorts without reaching around the store contract.

The outcome feedback loop that makes an AI agent measurably better per user — without training anything.

Used by the hosted AbsoluteJS.ai platform and available as a standalone outcomes package.

The idea

An agent produces artifacts (outreach emails, generated pages, drafts). Things happen to them (opens, replies, conversions, meetings). If you record both sides with typed features frozen at production time, the agent's context can get smarter every week — and you can show users the receipts.

You define the vocabulary once — artifact kinds with typed, bucketable features, and an ordered list of outcome events — and the package derives:

The ledger contract (OutcomeStore): record artifacts + outcomes,

Show 6 more

attribution is the join on your artifact id.

The stats (computeOutcomeStats): each outcome's rate overall, per

feature bucket, and per experiment variant when present (the A/B bolt-on). Below your minSample it reports not-ready, so hosts stay quiet instead of showing confident noise — the cold-start contract.

The evidence (renderEvidence): a compact text block your OWN AI call

distills into a "what works for you" memo that conditions future generations. The package never calls a model itself.

Same machinery for an outreach copilot (features: subject length, tone; outcomes: replies) and an AI website builder (features: hero copy length, layout; outcomes: conversions from your analytics beacon).

Production persistence (Drizzle + Postgres/Neon)

The optional @absolutejs/outcomes/drizzle entry exports a typed Postgres schema and store. It works with any Drizzle PgAsyncDatabase, including a Neon-backed database, and never creates schema at application runtime:

Include outcomesDrizzleSchema in your Drizzle migration schema. The same entry exports OutcomeArtifactInsertSchema, OutcomeArtifactSelectSchema, OutcomeEventInsertSchema, and OutcomeEventSelectSchema, generated with Drizzle-TypeBox directly from those tables so route contracts never restate database shapes.

Outcome writes require ownerId; both memory and Drizzle stores no-op unless the artifact belongs to that owner. The contract-2 AI tools expose the same owner/resource binding for host policy enforcement.

Typed outcome vocabulary

defineOutcomeVocabulary declares artifact kinds with typed, bucketable features (number buckets, closed string sets, booleans) and an ordered list of outcome events.

Ledger contract

The OutcomeStore contract records artifacts and outcomes; attribution is simply the join on your artifact id, with createMemoryOutcomeStore included for tests.

Attribution-joined stats

computeOutcomeStats reports each outcome’s rate overall, per feature bucket, and per experiment variant when present, so A/B experiments bolt on without extra machinery.

Cold-start safety

Below your minSample threshold stats report not-ready, so hosts stay quiet instead of showing confident noise; the cold-start contract is explicit.

Model-agnostic evidence

renderEvidence produces a compact text block your own AI call distills into a "what works for you" memo that conditions future generations; the package never calls a model itself.

#Outcome feedback loop

Outcomes turn production results into evidence without allowing mutable features to rewrite history.

  1. Artifact
    Create an artifact and freeze its feature snapshot.
  2. Signal
    Record later business or user outcome signals.
  3. Attribute
    Join attribution using stable identities and windows.
  4. Gate
    Apply minimum-sample and privacy gates.
  5. Learn
    Produce evidence for the next generation or decision.

Outcomes

What you can build

Overview

Listed attributed artifacts retain their observation time, allowing hosts to build privacy-safe time cohorts without reaching around the store contract.

The idea

An agent produces artifacts (outreach emails, generated pages, drafts). Things happen to them (opens, replies, conversions, meetings). If you record both sides with typed features frozen at production time, the agent's context can get smarter every week — and you can show users the receipts.

Production persistence (Drizzle + Postgres/Neon)

The optional @absolutejs/outcomes/drizzle entry exports a typed Postgres schema and store. It works with any Drizzle PgAsyncDatabase, including a Neon-backed database, and never creates schema at application runtime:

Hardening checklist

Production guidance

The ideaAn agent produces artifacts (outreach emails, generated pages, drafts). Things happen to them (opens, replies, conversions, meetings). If you record both sides with typed features frozen at production time, the agent's context can get smarter every week — and you can show users the receipts.
Production persistence (Drizzle + Postgres/Neon)The optional @absolutejs/outcomes/drizzle entry exports a typed Postgres schema and store. It works with any Drizzle PgAsyncDatabase, including a Neon-backed database, and never creates schema at application runtime:

Follow in order

Troubleshooting path

1
Trace from the first failed boundary
Reproduce the smallest canonical @absolutejs/outcomes example, confirm the supported entry point and version in the API explorer, then inspect the first boundary that did not produce its documented result.

#Production persistence (Drizzle + Postgres/Neon)

Partial snippet

The optional @absolutejs/outcomes/drizzle entry exports a typed Postgres schema and store. It works with any Drizzle PgAsyncDatabase, including a Neon-backed database, and never creates schema at application runtime:

TS
import {
	createDrizzleOutcomeStore,
	outcomesDrizzleSchema
} from '@absolutejs/outcomes/drizzle';

const store = createDrizzleOutcomeStore({ db });

#The idea

Partial snippet

An agent produces artifacts (outreach emails, generated pages, drafts). Things happen to them (opens, replies, conversions, meetings). If you record both sides with typed features frozen at production time, the agent's context can get smarter every week — and you can show users the receipts.

TS
import {
	computeOutcomeStats,
	defineOutcomeVocabulary,
	renderEvidence
} from '@absolutejs/outcomes';

const vocabulary = defineOutcomeVocabulary({
	artifacts: {
		outreach_email: {
			label: 'Outreach email',
			features: {
				subjectWords: {
					type: 'number',
					buckets: [
						{ label: 'short', max: 7 },
						{ label: 'medium', max: 12 }
					],
					overflowLabel: 'long'
				},
				mode: { type: 'string', values: ['outreach', 'followup'] },
				hasQuestion: { type: 'boolean' }
			}
		}
	},
	outcomes: ['opened', 'replied', 'meeting_scheduled']
});

// At production time: store.recordArtifact({ id: sendId, ownerId, kind, features })
// From your signal hooks: store.recordOutcome({ artifactId: sendId, outcome: "replied", ownerId })

const rows = await store.listArtifactsWithOutcomes(
	ownerId,
	'outreach_email',
	since
);
const stats = computeOutcomeStats(vocabulary, 'outreach_email', rows, {
	minSample: 10
});
if (stats.ready) {
	const memo = await yourAiCall(
		`Distill what works:\n${renderEvidence(stats)}`
	);
	// …feed `memo` into every future draft; show `stats` in your UI.
}

#Quick Start

Partial snippet

Define the vocabulary, record artifacts and outcomes, then turn attribution-joined stats into evidence your own AI call distills.

TS
import {
	computeOutcomeStats,
	defineOutcomeVocabulary,
	renderEvidence
} from '@absolutejs/outcomes';

const vocabulary = defineOutcomeVocabulary({
	artifacts: {
		outreach_email: {
			label: 'Outreach email',
			features: {
				subjectWords: {
					type: 'number',
					buckets: [
						{ label: 'short', max: 7 },
						{ label: 'medium', max: 12 }
					],
					overflowLabel: 'long'
				},
				mode: { type: 'string', values: ['outreach', 'followup'] },
				hasQuestion: { type: 'boolean' }
			}
		}
	},
	outcomes: ['opened', 'replied', 'meeting_scheduled']
});

// At production time:
//   store.recordArtifact({ id: sendId, ownerId, kind, features })
// From your signal hooks:
//   store.recordOutcome({ artifactId: sendId, outcome: 'replied' })

const rows = await store.listArtifactsWithOutcomes(
	ownerId,
	'outreach_email',
	since
);
const stats = computeOutcomeStats(vocabulary, 'outreach_email', rows, {
	minSample: 10
});
if (stats.ready) {
	const memo = await yourAiCall(
		`Distill what works:\n${renderEvidence(stats)}`
	);
	// ...feed memo into every future draft; show stats in your UI.
}
One loop, many products
The same machinery serves an outreach copilot (features: subject length, tone; outcomes: replies) and an AI website builder (features: hero copy length, layout; outcomes: conversions from your analytics beacon).
Beta API
The package is pre-1.0; the vocabulary and store contracts may still shift, so pin an exact version.

#API reference

Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.

16 symbols
compareOutcomeSlicesexportPermalink
TS
compareOutcomeSlices
Exported from @absolutejs/outcomes

Current package surface

What ships today

@absolutejs/outcomesv0.2.4 · betaAInpmSource
4entry points26symbols

Import surface · click to copy