OTAH GTM Coordinator

SDK

Authorization boundary: this workspace drafts, records and evaluates only. It cannot send, publish, schedule, spend or export customer data. Hover a locked action for the authorization it requires.

SDK

The typed TypeScript package behind this workspace — the same models and rules the app uses, runnable locally against sample data.

Local / demo SDK. There is no hosted API and no network client. The SDK reads and writes an in-memory or local JSON store seeded with SOURCE-REPORTED, PROPOSAL and SYNTHETIC sample data. It has no method that sends, publishes, schedules, spends or exports customer data.

Setup

# unzip otah-gtm-sdk-0.1.0.zip, then:
cd sdk
npm install        # dev deps only: typescript, tsx, @types/node
npm run typecheck  # tsc --noEmit
npm run example    # examples/basic-usage.ts
npm run build      # dist/ (CommonJS + .d.ts)

Requires Node.js 18+. The example writes to ./.local-data/gtm-store.json, created from seed data on first run.

Versioning

  • SDK 0.1.0 — pre-1.0; the API may change without notice.
  • Tracks app v0.1.0 and context pack v1.0.
  • Seed-data changes bump the patch version; model or method changes bump the minor version until 1.0.
  • The app imports sdk/src/types, core, validation and brief-generator directly, so rules stay identical in both.

Typed models

Brand

Tier, readiness + evidence class, activation record, missing inputs, boundaries, prohibited terms

ActivationRecord

10 fields, each with value, FieldStatus (evidence class or UNKNOWN), source and note

ReadinessEvent

Audit trail of readiness changes with rationale and recorder

Source

S00–S11 register entry with dates, scope, limitations and brand scope

Claim

Exact claim, audience, source, evidence class, approved use, owner, expiry, prohibited inference

Experiment

Full card incl. denominator, budget cap, capacity cap, success rule, stop rule, status

Brief

DRAFT decision brief or asset, with per-section evidence status

EvaluationCase / Run / Score

E01–E16 cases, runs with date + config version, 0/1/2 scores

BlockedAction

Send / Publish / Schedule / Spend / Export — why disabled and what authorization is needed

GTMClient methods

MethodBehavior
listBrands(filter?)Filter by readiness, tier or search; adds completeness + unknownFields.
getBrand(id)Brand-scoped detail only — never another brand’s records.
updateReadiness(brandId, input)Rationale required; APPROVED/VERIFIED need recorder + provenance.
updateActivationField(brandId, key, field)Same provenance rule for non-UNKNOWN statuses.
listSources()S00–S11 register, ordered.
listClaims(filter?)Filter by brand and evidence class.
createClaim(input)Rejects sources outside the claim brand’s scope.
listExperiments(filter?)Filter by brand and status.
createExperiment(input)Baseline defaults to UNKNOWN; approval is never assumed.
updateExperiment(id, patch)Status changes re-validated; brand link is immutable.
computeEconomics(inputs)Contribution, CAC, payback (seeded only with SYNTHETIC inputs).
generateBrief(brandId, kind)Always DRAFT; gaps marked UNKNOWN; lens labels neutralised.
listBriefs(brandId?)Stored drafts.
getEvaluationChecklist(runId?)Cases with status + run summary.
createEvaluationRun(input)configVersion required.
scoreEvaluation(runId, caseId, input)Score 0/1/2 or null (NOT RUN) + critical flag.
getAuthorizationBoundaries()Lists blocked actions — the SDK has no send/publish/schedule/spend/export methods.

Example

import { GTMClient, SYNTHETIC_ECONOMICS_INPUTS } from '@otah/gtm-sdk';

const client = new GTMClient({ filePath: './.local-data/gtm-store.json' });

const capsules = await client.listBrands({ tier: 'capsule' });
const tc = await client.getBrand('tutorial-coach');        // brand-scoped
const brief = await client.generateBrief('tutorial-coach'); // status: 'DRAFT'

const econ = client.computeEconomics(SYNTHETIC_ECONOMICS_INPUTS); // SYNTHETIC only
const checklist = await client.getEvaluationChecklist();
console.log(checklist.summary.status); // 'NOT RUN' until all 16 cases are scored

The full runnable example is sdk/examples/basic-usage.ts in the source viewer below. Want the same rules in the UI? See Experiments and Evaluation.

Source

sdk/README.md · 111 lines
1# @otah/gtm-sdk — OTAH GTM Coordinator SDK (local / demo)23> **LOCAL / DEMO SDK — v0.1.0.** There is no hosted API. Every method reads and writes a local4> store (in-memory, or a JSON file you choose). Nothing in this package sends, publishes, schedules,5> spends or exports customer data. All seed data is SOURCE-REPORTED, PROPOSAL or SYNTHETIC sample data.67The SDK is the single source of truth for the OTAH GTM Coordinator's domain model and rules. The web8app imports the same `types`, `core`, `validation` and `brief-generator` modules, so a rule enforced9here (e.g. "APPROVED needs a recorder and provenance") is enforced in the app too.1011## Setup1213```bash14cd sdk15npm install          # typescript, tsx, @types/node (dev only)16npm run typecheck    # tsc --noEmit17npm run example      # runs examples/basic-usage.ts against ./.local-data/gtm-store.json18npm run build        # emits dist/ (CommonJS + .d.ts)19```2021Requires Node.js 18+.2223## Quick start2425```ts26import { GTMClient } from '@otah/gtm-sdk';2728// In-memory store seeded from the context pack (nothing is persisted):29const client = new GTMClient();3031// Or persist to a local JSON file (created from seed data on first use):32const local = new GTMClient({ filePath: './.local-data/gtm-store.json' });3334const brands = await client.listBrands({ tier: 'capsule' });35const detail = await client.getBrand('tutorial-coach'); // brand-scoped: no other brand's records36const brief = await client.generateBrief('tutorial-coach', 'decision_brief'); // status: 'DRAFT'37```3839## Typed models (`src/types.ts`)4041| Model | Purpose |42| --- | --- |43| `Brand` | Registry entry with tier, readiness (+ evidence class), activation record, missing inputs, boundaries, prohibited terms |44| `ActivationRecord` / `ActivationField` | 10 fields (identity, buyer, job, offer, product_state, positioning, funnel, channel, data_policy, next_decision) each with value, `FieldStatus`, sourceId, note |45| `ReadinessEvent` | Audit trail of readiness changes (from → to, evidence class, rationale, recorder) |46| `Source` | S00–S11 register: date, checked date, scope, limitations, brand scope, evidence class |47| `Claim` / `ClaimInput` | Claim ledger row: exact claim, audience, source, evidence class, approved use, owner, expiry, prohibited inference |48| `Experiment` / `ExperimentInput` | Full experiment card: decision, hypothesis, denominator, budget cap, capacity cap, success rule, stop rule, status… |49| `EconomicsInputs` / `EconomicsResult` | Unit-economics calculator (used only with SYNTHETIC numbers in seed data) |50| `Brief` / `BriefSection` | DRAFT decision brief or asset (landing, outbound, discovery, pilot, onboarding) |51| `EvaluationCase` / `EvaluationRun` / `EvaluationScore` / `EvaluationSummary` | E01–E16 checklist with 0/1/2 scoring |52| `BlockedAction` | Send / Publish / Schedule / Spend / Export Customer Data — why disabled, what authorization is needed |5354Evidence classes: `SOURCE-REPORTED`, `HYPOTHESIS`, `APPROVED`, `VERIFIED`, `PROPOSAL`, `SYNTHETIC` (plus `UNKNOWN` for field status).55Readiness levels (proposed, not assigned): `unknown`, `discovery`, `pilot-ready`, `pilot-observed`, `repeatable`, `scale-ready`.5657## GTMClient methods (`src/client.ts`)5859| Method | Notes |60| --- | --- |61| `listBrands(filter?)` | Filter by readiness, tier, search. Adds `completeness` and `unknownFields`. |62| `getBrand(id)` | Brand-scoped detail: sources, claims, experiments, briefs, readiness events for that brand only. |63| `updateReadiness(brandId, input)` | Requires rationale; APPROVED/VERIFIED require `recordedBy` and provenance. |64| `updateActivationField(brandId, key, field)` | Same provenance rule for non-UNKNOWN statuses. |65| `listSources()` | S00–S11 register. |66| `listClaims(filter?)` / `createClaim(input)` | Rejects a source that is out of scope for the claim's brand. |67| `listExperiments(filter?)` / `createExperiment(input)` / `updateExperiment(id, patch)` | Real experiments need a brand; approved/running/completed need an approval recorder. Baseline defaults to UNKNOWN. |68| `computeEconomics(inputs)` | Contribution, CAC, payback. |69| `generateBrief(brandId, kind)` / `listBriefs(brandId?)` | Output is always DRAFT; missing inputs are marked UNKNOWN; prohibited terms are neutralised. |70| `getEvaluationChecklist(runId?)` / `createEvaluationRun(input)` / `scoreEvaluation(runId, caseId, input)` | PASS only when all cases are scored, total ≥ 85% and no critical failure. |71| `getAuthorizationBoundaries()` | Lists blocked actions. There are intentionally **no** send/publish/schedule/spend/export methods. |7273Pure helpers are also exported from `src/core.ts`: `evidenceCompleteness`, `computeEconomics`,74`caseStatus`, `summarizeEvaluation`, `applyClaimGuard`, `sourceAllowedForBrand`, `expiryState`,75`BLOCKED_ACTIONS`, `COMPLETENESS_WEIGHTS` (a PROPOSED heuristic) and `SYNTHETIC_ECONOMICS_INPUTS`.7677## Rules the SDK enforces7879- **Brand separation** — retrieval is brand-scoped; a source outside a brand's scope cannot back that brand's claim.80- **No invented approval** — APPROVED / VERIFIED need a named recorder and provenance.81- **DRAFT only** — generated briefs and assets carry `status: 'DRAFT'`; gaps are `UNKNOWN`.82- **Lens labels are not affiliations** — e.g. DealFlow.Coach's "BlackRock" lens label is replaced by a neutral term in public drafts.83- **Registry ≠ operations** — 23 inventory names do not prove active commercial operations.8485## Versioning8687`0.1.0` is pre-1.0: the API may change without notice. The SDK version tracks the app version88(v0.1.0) and the context pack it encodes (v1.0). Seed data changes bump the patch version; model89or method changes bump the minor version until 1.0.9091## Layout9293```94sdk/95  package.json96  tsconfig.json97  README.md98  src/99    types.ts            typed models100    core.ts             pure rules: completeness, economics, evaluation, blocked actions101    validation.ts       input validation + GTMValidationError102    brief-generator.ts  DRAFT brief/asset templates103    seed-brands.ts      23 brands (SOURCE-REPORTED / PROPOSAL)104    seed-records.ts     sources, claims, experiments, evaluation cases105    store.ts            MemoryStore / JsonFileStore106    client.ts           GTMClient107    index.ts            public exports108  examples/109    basic-usage.ts110```111