# Go Data Architect Spec

> Design data-architecture-first specifications for Go services. Use when planning or revising SQL and data modeling, data ownership, multi-tenant isolation, schema evolution, migration rollout, retention/deletion, ledger/history/projection boundaries, or datastore choice before coding. Reach for this whenever the hard part is deciding source-of-truth shape, invariant locality, OLTP vs append/proje…

- **Type:** Skill
- **Install:** `agentstack add skill-dankosik-go-service-template-rest-go-data-architect-spec`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Dankosik](https://agentstack.voostack.com/s/dankosik)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Dankosik](https://github.com/Dankosik)
- **Source:** https://github.com/Dankosik/go-service-template-rest/tree/main/.agents/skills/go-data-architect-spec

## Install

```sh
agentstack add skill-dankosik-go-service-template-rest-go-data-architect-spec
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Go Data Architect Spec

## Purpose
Turn ambiguous data requirements into explicit decisions about source of truth, invariant locality, schema shape, lifecycle, online evolution, and recovery before implementation begins.

## Outcome-First Operating Rules
- Start by naming the skill-specific outcome, success criteria, constraints, available evidence, and stop rule.
- Treat workflow steps as decision rules, not a ritual checklist. Follow exact order only when this skill or the repository contract makes the sequence an invariant.
- Use the minimum context, references, tools, and validation loops that can change the deliverable; stop expanding when the quality bar is met.
- Before acting, resolve prerequisite discovery, lookup, or artifact reads that the outcome depends on; parallelize only independent evidence gathering and synthesize before the next decision.
- Prefer bounded assumptions and local evidence over broad questioning; ask only when a missing fact would change correctness, ownership, safety, or scope.
- When evidence is missing or conflicting, retry once with a targeted strategy or label the assumption, blocker, or reopen target instead of treating absence as proof.
- Finish only when the requested deliverable is complete in the required shape and verification or a clearly named blocker/residual risk is recorded.

## Specialist Stance
- Treat persisted state as source-of-truth ownership first, storage mechanics second.
- Separate OLTP rows, append-only facts, audit logs, events, and projections instead of flattening them into “data”.
- Prefer online, compatibility-safe evolution and explicit retention/deletion semantics over schema convenience.
- Hand off endpoint contracts, service decomposition, cache implementation, and delivery mechanics when they become primary.

## Scope
Use this skill to define or review:
- data ownership and source-of-truth boundaries
- relational or hybrid model shape
- identity, tenancy, temporal, and money-type decisions
- transaction and concurrency rules
- read topology, projections, and derived-data boundaries
- datastore fit
- schema evolution, migration safety, and backfill strategy
- retention, deletion, archival, and recovery expectations

## Boundaries
Do not:
- drift into endpoint contract design, generic service decomposition, or low-level code tuning as the primary output
- invent domain invariants that have not been approved; translate known invariants into data consequences and escalate when the business rule is still unclear
- let query-shape tuning, pool math, cache behavior, or fallback policy take over the output; that belongs primarily to `go-db-cache-spec`
- let workflow topology or cross-service orchestration design take over the output; that belongs primarily to `go-architect-spec` or `go-distributed-architect-spec`
- approve new datastores, projections, or history models without explicit ownership, lifecycle, and recovery consequences
- leave schema evolution, backfill, deletion, or rollback safety unspecified

## Escalate When
Escalate if ownership is unclear, hard invariants are not yet approved, workload or retention evidence is materially missing, datastore choice is underconstrained, or destructive migration risk lacks a safe rollout and verification plan.

## Reference Loading
Load at most one reference by default, and only when its symptom matches the task. Load more than one only when the prompt clearly spans multiple independent data-decision pressures, such as live schema migration plus PII deletion. References are compact rubrics and example banks, not exhaustive checklists or documentation dumps; they should change the data-architecture decision, not restate this `SKILL.md`.

Keep the main output data-architecture-first. Route endpoint contracts, cache tuning, low-level query implementation, and local code mechanics to specialist skills instead of expanding data references to cover them.

| Symptom in the prompt | Load | Behavior change |
| --- | --- | --- |
| Audit log, outbox, CDC, event stream, materialized view, dashboard table, export, search index, projection, or uncertainty about which surface is authoritative | [source-of-truth-and-derived-surfaces.md](references/source-of-truth-and-derived-surfaces.md) | Choose one invariant-bearing write authority and classify other surfaces as evidence, integration, or derived views instead of letting a stream, dashboard, or audit table become accidental truth. |
| Tenant isolation, public IDs, partner references, idempotency keys, local business dates, event/effective/processed time, money, balances, credits, quotas, or user-visible amounts | [tenant-identity-time-and-money-modeling.md](references/tenant-identity-time-and-money-modeling.md) | Scope identity, tenancy, time, and money types deliberately instead of using global uniqueness, reused IDs, overloaded timestamps, or floating-point amounts. |
| Uniqueness, foreign keys, `CHECK` constraints, partial indexes, exclusion or temporal-overlap constraints, composite index order, JSONB placement, partitioned uniqueness, or operational-list pagination | [sql-constraints-indexes-and-pagination.md](references/sql-constraints-indexes-and-pagination.md) | Encode enforceable invariants and access-pattern indexes in SQL instead of application-only checks, invariant-bearing JSONB, offset pagination, or broad untethered indexes. |
| Transaction boundary, isolation level, optimistic concurrency, row or advisory locks, work claiming, duplicate callbacks, retries, idempotency records, holds, leases, scarce capacity, or outbox/inbox linkage | [transactions-concurrency-and-idempotency.md](references/transactions-concurrency-and-idempotency.md) | Select the smallest transaction, constraint, lock, lease, and idempotency mechanism that preserves the invariant instead of blanket isolation, cache counters, or unscoped locks. |
| New datastore engine, JSONB-as-flexibility, event sourcing, document or key-value stores, Redis/search as truth, time-series or columnar storage, or datastore choice driven by scale or auditability claims | [datastore-fit-and-event-sourcing.md](references/datastore-fit-and-event-sourcing.md) | Require an access-pattern and recovery fit test before changing truth storage instead of adopting a fashionable engine, event sourcing, or flexible JSON model by default. |
| Live schema change, added or tightened constraint, column rename or split, type/source-of-truth change, live index creation, partitioned index, or backfill | [schema-evolution-and-backfills.md](references/schema-evolution-and-backfills.md) | Plan expand, migrate or backfill, verify, and contract with rollback class instead of one-shot DDL, giant transactions, or fake reversibility. |
| Retention window, deletion, legal hold, PII erasure, anonymization, soft delete, history tables, archives, PITR, partition pruning, projections with residual data, exports, or rebuild/replay policy | [retention-deletion-history-and-projections.md](references/retention-deletion-history-and-projections.md) | Name lifecycle action and recovery limits for every surface instead of treating soft delete, primary-row deletion, or "keep forever" as a complete policy. |

## Core Defaults
- Default to SQL OLTP (`PostgreSQL`-compatible) as the primary system of record for service business data.
- Default to one service-owned schema or database boundary and local ACID within that boundary.
- Default cross-service consistency to eventual consistency with explicit outbox, idempotency, and reconciliation.
- Default schema evolution to `expand -> migrate/backfill -> contract`.
- Treat caches, search indexes, analytics stores, and projections as derived surfaces, not sources of truth.
- Treat new datastore engines and event-sourced truth models as exceptions that require workload-fit evidence and operational readiness.

## Data Facts To Lock First
Before recommending schema or datastore shape, make these facts explicit:
- which entities or facts are authoritative, and which views are derived-only
- which invariants are hard, especially uniqueness, non-negative balance, scarce-capacity, one-active-per-scope, and retention or legal-hold rules
- which identifiers exist: internal IDs, public references, partner references, idempotency keys, and tenant keys
- which time semantics matter: event time, effective time, processed time, and user-local business date
- what dominates workload shape: point lookups, operational lists, append-heavy ingest, upserts, scans, hot tenants, hot keys, or bulk retention deletes
- what evidence exists for growth, cardinality, retention horizon, replay needs, and recovery objectives
- which rollout constraints already exist: mixed-version windows, downtime tolerance, backfill budget, and irreversible cutover points

If these facts are missing, mark them as assumptions or blockers instead of inventing them.

## Expertise

### Data Ownership And Truth Surfaces
- Require explicit source-of-truth ownership per critical entity and per invariant-bearing process.
- Keep service data private: no direct cross-service table access, no cross-service foreign keys, and cross-service references by ID only.
- Separate current-state tables, immutable history, audit logs, outbox or CDC feeds, and read projections on purpose. They solve different problems and should not be conflated.
- Treat an audit log, domain event stream, and read model as different artifacts:
  - audit log explains who changed what and when
  - event stream captures domain facts for downstream reaction or replay
  - read model exists to answer queries efficiently
- Do not let partner payloads or external statuses become the local lifecycle truth by accident; normalize them into local state.
- State ownership and transaction-boundary impact for every major model change.

### Model The Hard Parts First
- Model the invariant-bearing facts before optimizing tables by taste.
- For scarce resources or reservations, require an explicit hold or lease model, hold expiry owner, release path, and reconciliation owner.
- For balances, credits, or money movement, prefer immutable entries plus a verifiable balance or snapshot model when explainability, replay, or audit matters. Do not make a mutable balance column the only authoritative evidence unless that trade-off is explicit.
- Separate pending, committed, reversed, expired, or refunded states when the business process needs them; do not compress materially different states into one generic status.
- For long-running or operator-repaired workflows, a current-state row may need a transition history or append-only facts beside it. State which surface is authoritative.
- For mutable domain objects with restore or support needs, current-state tables may coexist with version or history tables. Make the truth surface explicit instead of implying that all history is authoritative.

### Identity, Time, Tenancy, And Domain Types
- Prefer stable surrogate primary keys. Keep natural or business keys explicit through `UNIQUE` constraints instead of using mutable business identifiers as the primary key.
- Distinguish internal identity, public reference, partner reference, idempotency key, and correlation ID. They are not interchangeable.
- Every unique, foreign-key, and index decision should say whether it is tenant-scoped.
- For shared-table multi-tenancy, require `tenant_id` to participate in the relevant uniqueness and indexing strategy. Use centralized isolation controls such as RLS only when tenant context, bypassing roles, and bypass or side-channel surfaces are explicit.
- Use a version column or equivalent optimistic-concurrency token for mutable rows that are updated by competing writers.
- Model time deliberately:
  - use timestamp-with-time-zone semantics for real instants
  - persist the original named zone separately when policy or rendering must reconstruct it
  - use a separate business date or effective timestamp when policy depends on local dates or retroactive effect
  - if event time and processing time differ, define late or out-of-order handling explicitly
- Use exact numeric types for money, rates, quotas, or billable usage. Do not use floating-point types for money. Avoid PostgreSQL `money` unless locale, precision, and division semantics are an explicit fit.
- Choose enum, lookup-table, or constrained-text modeling based on change cadence and compatibility needs. Do not let unstable partner statuses leak into the canonical domain state.
- `JSONB` is acceptable for sparse or adjunct attributes with weak relational invariants and bounded query needs. It is a poor default for invariant-bearing fields, multi-column uniqueness, or heavily filtered operational data.

### SQL And Physical Relational Design
- Start from normalized schema (`~3NF`) unless denormalization has an explicit source of truth, sync path, staleness contract, and rebuild owner.
- Treat constraints as contracts:
  - primary key on every table
  - `UNIQUE` or composite `UNIQUE` for business uniqueness
  - explicit null behavior for nullable unique keys, either `NULLS DISTINCT`, `NULLS NOT DISTINCT`, or `NOT NULL`
  - `NOT NULL` by default for required fields
  - `CHECK` constraints where row-local correctness materially matters
  - partial `UNIQUE` indexes when uniqueness applies only to active or current rows
  - exclusion or version-gated temporal constraints when interval or overlap rules are central
- Keep referential integrity inside one service boundary.
- Build index policy from actual or explicitly expected access patterns:
  - align composite index order with filter then sort usage
  - remember every index adds write cost, storage cost, and migration cost
  - use partial indexes when hot predicates are sparse and stable
- Require stable ordering and a unique tie-breaker for pagination; default operational lists to keyset pagination.
- Partition only when retention pruning, bulk deletes, write volume, or tenant-isolation needs justify the added operational complexity. Align the partition key with dominant prune and query paths.
- Make delete and history policy explicit:
  - do not default to soft delete unless restore, compliance, support, or legal workflow needs justify it
  - if soft delete exists, handle uniqueness and query discipline explicitly, often with partial unique indexes on active rows

### Consistency, Transactions, And Concurrency
- Keep transactions local and short-lived.
- Reject cross-service global ACID assumptions.
- Choose concurrency control by invariant class:
  - row uniqueness -> `UNIQUE` or partial `UNIQUE`
  - interval, overlap, or scarce allocation -> exclusion constraint, supported temporal constraint, lease table, or explicit lock ownership
  - lost updates on mutable rows -> version checks or compare-and-swap semantics
  - work claiming or queue consumption -> lease semantics or `FOR UPDATE SKIP LOCKED`
  - anomalies that constraints cannot encode locally -> selective stronger isolation or explicit coordination model
- Prefer optimistic concurrency when conflicts are rare and rows are independently owned.
- Use pessimistic or advisory locks only with explicit scope, acquisition order, timeout behavior, and deadlock story.
- Treat stricter isolation levels as targeted paths that come with retry semantics and serialization testing.
- Bound retries and classify them by failure class; deadlocks, serialization failures, and timeouts are not the same recovery case.
- Make write paths idempotency-aware when retries, callbacks, or duplicate partner delivery are possible.

### Read Topology, Replicas, And Derived Views
- Make cross-service read strategy explicit: API composition, replicated read model, event-driven projection, or data export. Reject ad hoc cross-service DB reads by default.
- Primary reads are the default for read-after-write or monotonic-visible-truth paths. Replica reads require an explicit lag or staleness budget.
- Projections, materialized views, searc

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Dankosik](https://github.com/Dankosik)
- **Source:** [Dankosik/go-service-template-rest](https://github.com/Dankosik/go-service-template-rest)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-dankosik-go-service-template-rest-go-data-architect-spec
- Seller: https://agentstack.voostack.com/s/dankosik
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
