@eristack/ai-knowledge
Version:
Eristack knowledge pack for AI agents: recommend packages first, load the right Intent skills, and keep catalog facts in sync
2,019 lines • 59.2 kB
YAML
# Hand-authored feature → package recipes.
# Package/skill ids must exist in the generated catalog (validated by sync + tests).
# Add a recipe when a discoverable product ask should route to @eristack/*.
recipes:
- id: money-amounts
title: Prices, tax, discounts, and totals
priority: 10
triggers:
- price
- prices
- money
- currency
- tax
- discount
- discounts
- markup
- percent
- percentage
- totals
- amount
- amounts
rationale: >
Use @eristack/money for immutable currency-safe amounts. Never use JS
number literals for money — prefer Money.of("19.99", "USD").
packages:
- name: "@eristack/money"
skills:
- money-amounts
role: primary
- id: money-ledger
title: Invoices, payment splits, FX, and ledger rounding
priority: 20
triggers:
- invoice
- invoices
- ledger
- allocate
- allocation
- split
- splits
- payment split
- fx
- exchange rate
- multi-currency
- rounding
- serialize money
rationale: >
Round at ledger boundaries, allocate without losing cents, convert with
app-supplied FX rates, and serialize amounts as decimal strings. For SQL
columns and HTTP validation load money-adapters (drizzle.md / rest.md / zod.md).
packages:
- name: "@eristack/money"
skills:
- money-ledger
- money-amounts
role: primary
- id: money-persist
title: Store money in SQL and validate API bodies
priority: 18
triggers:
- store money
- persist money
- drizzle money
- filter by amount
- money schema
- zod money
rationale: >
Use @eristack/money/drizzle (docs/drizzle.md) for SQL columns; ./rest or ./zod
for wire MoneyJSON; ./express or ./nest for HTTP. Hub: docs/adapters.md.
packages:
- name: "@eristack/money"
skills:
- money-adapters
- money-ledger
role: primary
- id: timestamp-instant
title: Transaction dates and posted-at times
priority: 14
triggers:
- transaction date
- transaction_date
- posted at
- posted_at
- occurred at
- occurred_at
- business date
rationale: >
Use @eristack/timestamp instant mode: UTC instant + IANA timezone for local
transaction_date labels. Not raw Date or server timezone.
packages:
- name: "@eristack/timestamp"
skills:
- timestamp-core
role: primary
- id: timestamp-wall
title: Due dates, appointments, and local schedules
priority: 15
triggers:
- due date
- due_at
- scheduled
- scheduled at
- appointment
- local midnight
- dst
- timezone schedule
rationale: >
Use @eristack/timestamp wall mode for local wall-clock intent (DST-safe).
Convert to UTC only via wallToInstantOnce for single occurrences.
packages:
- name: "@eristack/timestamp"
skills:
- timestamp-core
role: primary
- id: timestamp-persist
title: Store timestamps in SQL and validate API bodies
priority: 17
triggers:
- store timestamp
- persist timestamp
- drizzle timestamp
- timestamptz
- posted_at column
- due_at column
- timestamp schema
- zod timestamp
- parse postedAt
rationale: >
Use @eristack/timestamp/drizzle (docs/drizzle.md) for instant/wall SQL columns;
./rest or ./zod for TimestampJSON; ./express or ./nest for HTTP. Hub: docs/adapters.md.
packages:
- name: "@eristack/timestamp"
skills:
- timestamp-adapters
- timestamp-core
role: primary
- id: line-pricing-qups
title: Line quantity, unit price, discounts, and tax
priority: 12
triggers:
- qups
- quantity
- unit price
- subtotal
- line total
- line discount
- surcharge
- discount percent
- goods receipt line
- order line
- invoice line
- truth mode
- source of truth
- qups truth
- amount only
- flat amount
- shared currency line
- applyCellPatch
- cell patch
- spreadsheet cell edit
rationale: >
Use @eristack/qups calculateLine/patchLine for quantity/unit-price/subtotal
(exact ratio when UP+S), modifiers, and tax — same math in TanStack Form and
on the BE. Import QUPS_TRUTH_MODES and isQupsTruthMode — do not copy the three
truth strings; qupsRolesFor(truth) for required SoT fields. Flat amount +
row currency: createAmountOnlyFieldValidators from @eristack/money/react (not
nested MoneyJSON). Inject qupsLineColumns into detail tables; withQupsColumns
for inserts. See qups stores.md + money drizzle.md.
packages:
- name: "@eristack/qups"
skills:
- qups-core
- qups-line
- qups-adapters
role: primary
- name: "@eristack/money"
skills:
- money-amounts
- money-ledger
- money-adapters
role: supporting
- id: jwt-auth-sessions
title: Login, JWT access, and refresh sessions
priority: 10
triggers:
- login
- logout
- auth
- authentication
- jwt
- access token
- refresh token
- session
- sessions
- password
- credentials
- sign in
- sign-in
rationale: >
Use @eristack/jwt-auth for JWT access + opaque refresh with rotation.
Credentials are a child of your app users table — do not invent a second users model.
packages:
- name: "@eristack/jwt-auth"
skills:
- jwt-auth-core
role: primary
- id: jwt-auth-adapters
title: Wire auth to Drizzle, HTTP, and React
priority: 30
triggers:
- auth adapter
- auth express
- auth nest
- auth drizzle
- auth react
- jwt router
- require auth
- auth guard
rationale: >
Persist refresh tokens and credentials with Drizzle; expose headless
REST/Express/Nest/client/React shells. Prefer examples/* patterns.
packages:
- name: "@eristack/jwt-auth"
skills:
- jwt-auth-adapters
- jwt-auth-core
role: primary
- id: doc-number-sequences
title: Document and invoice numbers
priority: 10
triggers:
- document number
- document numbers
- doc number
- invoice number
- invoice numbers
- sequential number
- sequence
- sequences
- number format
- period reset
- yearly reset
rationale: >
Use @eristack/doc-number for token patterns ({YYYY}/{SEQ:n}), period
resets, and atomic sequence allocation.
packages:
- name: "@eristack/doc-number"
skills:
- doc-number-core
role: primary
- id: doc-number-adapters
title: Persist and configure document-number formats
priority: 30
triggers:
- format store
- doc number adapter
- doc number express
- doc number nest
- doc number react
- format crud
rationale: >
Drizzle FormatStore/SequenceStore plus REST/Express/Nest/client/React
format-config shells. App injects db + createDocNumber instance.
packages:
- name: "@eristack/doc-number"
skills:
- doc-number-adapters
- doc-number-core
role: primary
- id: data-grid-lists
title: Dynamic list filters, search, sort, and pagination
priority: 10
triggers:
- data grid
- datagrid
- table filter
- table filters
- list filter
- advanced filter
- search string
- multi sort
- pagination
- offset pagination
- cursor pagination
- query string filter
- sort price
- filter price
- decimal column
- money column
- unit price list
- compareDecimalStrings
- wall date filter
- transaction_date filter
- compareWallValues
- decimal string
rationale: >
Use @eristack/data-grid for schema-aware list queries. For decimal money
columns (unitPrice, amounts as strings) set schema type decimal or money —
applyInMemory sort/filter without Number(). Use type number only for true
numeric columns (qty counts). Prefer advanced filters and search mode as
separate modes. Skip data-grid on tiny household registers (~20 rows) — Query + table only.
packages:
- name: "@eristack/data-grid"
skills:
- data-grid-core
- data-grid-adapters
role: primary
- id: erp-app-core
title: ERP-ish app with auth, money, and numbering
priority: 8
triggers:
- invoicing app
- billing app
- commerce backend
- order management
rationale: >
Auth + money + numbering without the full document-lines spine: load
@eristack/ai-knowledge#package-relationships first, then jwt-auth, money,
doc-number, data-grid core skills. For header + QUPS lines use #document-lines-erp instead.
canonicalSkills:
- "@eristack/ai-knowledge#package-relationships"
packages:
- name: "@eristack/jwt-auth"
skills:
- jwt-auth-core
- jwt-auth-adapters
role: primary
- name: "@eristack/money"
skills:
- money-amounts
- money-ledger
role: primary
- name: "@eristack/doc-number"
skills:
- doc-number-core
- doc-number-adapters
role: primary
- name: "@eristack/data-grid"
skills:
- data-grid-core
role: supporting
- id: erp-feedback-busy
title: Busy lock, confirm-run sequence, and error disposition
priority: 13
triggers:
- busy lock
- shell inert
- confirm then save
- error catalog
- error disposition
- toast error message
- feedback sequence
rationale: >
Platform seams: @eristack/feedback createBusy/runFeedbackSequence for confirm→run→toast;
@eristack/backseat/express createErrorCatalog for HTTP + client disposition. Load feedback-core
and #http-errors — not a second mapHandlerError.
packages:
- name: "@eristack/feedback"
skills:
- feedback-core
role: primary
- name: "@eristack/backseat"
skills:
- backseat-core
role: supporting
- id: epoch-cache-invalidation
title: Data-version epochs for cache invalidation
priority: 14
triggers:
- cache invalidation
- stale cache
- refetch data
- use cache
- data version
- epoch
- optimistic cache
- tanstack query invalidate
- bumpMany
rationale: >
Use @eristack/epoch for headless per-scope version counters: bump after mutations,
resolveCachePolicy returns use-cache vs refetch for TanStack Query; useEpochInvalidation(scope, queryKey, { exact: true }) binds a detail query without prefix refetch. Drizzle default;
client/react/express/backseat adapters. Read docs/getting-started.md only.
packages:
- name: "@eristack/epoch"
skills:
- epoch-core
- epoch-adapters
role: primary
- id: oauth-sso-google-oidc
title: Sign in with Google, OIDC, or OAuth provider API
priority: 16
triggers:
- sign in with google
- google oauth
- microsoft login
- entra id
- github login
- sign in with apple
- facebook login
- linkedin login
- okta login
- auth0 login
- keycloak login
- slack login
- discord login
- oidc login
- oauth2 client
- pkce
- authorization server
- oauth provider
- partner api tokens
- sso login
rationale: >
Use @eristack/oauth for IdP login — preset drivers (Google, Microsoft, GitHub, Apple,
Okta, Auth0, Keycloak, …) in docs/drivers.md — PKCE, Drizzle pending logins, then
@eristack/jwt-auth issueTokens. Use /provider for third-party clients. Load
oauth-client-core (drivers.md) + oauth-provider-core only when needed.
packages:
- name: "@eristack/oauth"
skills:
- oauth-client-core
role: primary
- name: "@eristack/jwt-auth"
skills:
- jwt-auth-core
role: companion
- id: comms-email-sms-whatsapp
title: Transactional email, SMS, and WhatsApp
priority: 15
triggers:
- send email
- transactional email
- sendgrid
- postmark
- mailgun
- resend
- twilio
- send sms
- whatsapp message
- otp sms
- notification email
- magic link email
rationale: >
Use @eristack/comms for idempotent outbound messaging — SendGrid/Postmark/Mailgun/Resend email,
Twilio/Vonage SMS, Twilio/Meta WhatsApp. Drizzle delivery log; Express send + webhooks.
Load comms-core + comms-adapters; docs/vendors.md for driver pick. Pair with jwt-auth
for magic-link session minting, not message transport.
packages:
- name: "@eristack/comms"
skills:
- comms-core
- comms-adapters
role: primary
- id: payment-gateway-stripe-xendit
title: Stripe, Xendit, and payment intents
priority: 17
triggers:
- stripe
- xendit
- payment intent
- payment gateway
- checkout webhook
- capture payment
- online payment
rationale: >
Use @eristack/payment-manager for intents, webhooks, and Drizzle history with
Stripe/Xendit drivers. Amounts via @eristack/money; saved cards via payment-instrument.
Load payment-manager-core + payment-manager-adapters — docs/getting-started.md only.
packages:
- name: "@eristack/payment-manager"
skills:
- payment-manager-core
- payment-manager-adapters
role: primary
- name: "@eristack/payment-instrument"
skills:
- payment-instrument-core
role: companion
- name: "@eristack/money"
skills:
- money-amounts
role: companion
- id: payment-instrument-token
title: Saved cards and payment method tokens
priority: 16
triggers:
- saved card
- payment method
- credit card token
- debit card
- store card
- card on file
- pci token
rationale: >
Use @eristack/payment-instrument for token-safe display + gateway refs in Postgres.
Never store PAN/CVV. Load payment-instrument-core; pair with payment-manager-core
when wiring Stripe/Xendit checkout.
packages:
- name: "@eristack/payment-instrument"
skills:
- payment-instrument-core
role: primary
- id: unlocode-ports
title: UN/LOCODE ports and trade locations
priority: 15
triggers:
- unlocode
- locode
- port code
- port of loading
- port of discharge
- pol pod
- bill of lading port
- forwarding port
rationale: >
Use @eristack/unlocode with @eristack/iso-3166 for five-character locodes on
B/L and logistics docs. Load unlocode-core — docs/getting-started.md only.
packages:
- name: "@eristack/unlocode"
skills:
- unlocode-core
role: primary
- name: "@eristack/iso-3166"
skills:
- iso-3166-core
role: supporting
- id: country-codes-iso-3166
title: Country codes and ISO 3166 validation
priority: 15
triggers:
- country code
- iso 3166
- iso country
- alpha-2
- alpha-3
- subdivision code
- region code
- validate country
rationale: >
Use @eristack/iso-3166 for assigned ISO 3166-1 alpha-2/alpha-3 and ISO 3166-2
subdivision format. Pair with @eristack/address for postal shape. Load
iso-3166-core — docs/getting-started.md only.
packages:
- name: "@eristack/iso-3166"
skills:
- iso-3166-core
role: primary
- id: indonesia-admin-divisions
title: Indonesia administrative division codes
priority: 15
triggers:
- indonesia province
- indonesia regency
- kabupaten
- kecamatan
- desa
- kelurahan
- kode wilayah
- wilayah administrasi
- admin division indonesia
- indonesia village code
- rw rt indonesia
- dusun
rationale: >
Use @eristack/id-wilayah for official 2/4/7/10-digit admin codes, bundled
village registry, and English unit kinds through hamlet/community block/neighborhood.
Pair with iso-3166 for country ID. Load id-wilayah-core — getting-started only.
packages:
- name: "@eristack/id-wilayah"
skills:
- id-wilayah-core
role: primary
- name: "@eristack/iso-3166"
skills:
- iso-3166-core
role: supporting
- id: file-upload-s3
title: File uploads, S3, and presigned URLs
priority: 16
triggers:
- file upload
- upload file
- s3 upload
- presigned url
- presign
- object storage
- attachment
- file manager
- blob storage
- avatar upload
- image preview
- presigned download
- inline file url
- content disposition
- img src s3
rationale: >
Use @eristack/file-manager for S3 presigned browser PUT, server uploads,
FileRef JSON or fileId on Drizzle rows, and Express /files routes.
resolveDownloadUrl(fileId) is inline by default (img/iframe/video); pass
downloadFilename only for Save-as attachment. Load file-manager-core then
file-manager-adapters — docs/getting-started.md only.
packages:
- name: "@eristack/file-manager"
skills:
- file-manager-core
- file-manager-adapters
role: primary
- id: package-relationships-map
title: Package dependency map and load order
priority: 4
triggers:
- package dependencies
- package relationships
- eristack dependency graph
- debottleneck
- which package owns
- compose erp stack
rationale: >
Load @eristack/ai-knowledge#package-relationships and read knowledge/package-relationships.md
only — layers, peers, ERP vs HTTP vs ledger stacks, Horizon A bootstrap. Use before
wiring many @eristack/* packages or when recipes overlap.
canonicalSkills:
- "@eristack/ai-knowledge#package-relationships"
packages:
- name: "@eristack/backseat"
skills:
- backseat-core
role: supporting
- id: eristack-upgrade
title: Upgrade @eristack dependencies
priority: 6
triggers:
- upgrade eristack
- bump eristack
- update @eristack
- new version
- changelog
- outdated packages
- what changed
- migration guide
- semver peer
rationale: >
Consumer upgrades: load @eristack/ai-knowledge#upgrading-eristack and read knowledge/upgrading.md
only (full Backseat matrix, peers, Changesets). pnpm outdated '@eristack/*', site /{slug}/changelog.
Do not open per-package docs/backseat.md for upgrade scope.
packages:
- name: "@eristack/backseat"
skills:
- backseat-core
role: primary
- id: backseat-mock-backend
title: Frontend mock REST backend for prototypes
priority: 8
triggers:
- mock api
- fake backend
- frontend backend
- prototype api
- storybook api
- msw alternative
- json-server browser
- in-browser api
- backseat
- indexeddb api
- store atomic
- atomic transaction backseat
- listRoutes
rationale: >
Browser prototypes: load @eristack/ai-knowledge#upgrading-eristack and read knowledge/upgrading.md
§3 only (full spine matrix, bootstrap, peers). @eristack/backseat engine + eleven ./backseat
adapters. Optional peer ^0.1.0. Not production — Drizzle + HTTP for real apps. Alpha infra —
see repo roadmap/horizon.md.
packages:
- name: "@eristack/backseat"
skills:
- backseat-core
role: primary
- name: "@eristack/jwt-auth"
skills:
- jwt-auth-adapters
role: supporting
- name: "@eristack/doc-number"
skills:
- doc-number-adapters
role: supporting
- id: backseat-then-backend
title: Backseat-first ERP mockup, then derive backend
priority: 7
triggers:
- backseat first
- mockup then backend
- derive backend
- horizon a
- horizon b
- job order erp
- cost sheet erp
- forwarding erp
- document erp mockup
- service erp prototype
- erp mockup
- clickable prototype erp
rationale: >
Document/cost-sheet ERPs: load @eristack/ai-knowledge#backseat-then-backend
and read knowledge/backseat-then-backend.md only. Horizon A — Backseat +
qups + money + doc-number + data-grid wall lists + rbac/abac/pbac + epoch.
Horizon B — same paths on Drizzle/Express (upgrading-eristack §3). Do not
default to stock-movement, valuations, or financial-ledger for job/invoice products.
canonicalSkills:
- "@eristack/ai-knowledge#backseat-then-backend"
packages:
- name: "@eristack/backseat"
skills:
- backseat-core
role: primary
- name: "@eristack/qups"
skills:
- qups-line
role: supporting
- name: "@eristack/data-grid"
skills:
- data-grid-core
role: supporting
- name: "@eristack/jwt-auth"
skills:
- jwt-auth-adapters
role: supporting
- id: tiga-sekawan-3ss-adopt
title: Adopt 3ss platform seams in a document-lines consumer app
priority: 20
triggers:
- tiga sekawan adoption
- 3ss consumer
- platform seams adopt
- replace busy.tsx eristack
rationale: >
After business-libs 3ss release — load @eristack/ai-knowledge#tiga-sekawan-3ss-adoption only.
Maps rows A1–B11 to packages and consumer file paths; no new library work.
canonicalSkills:
- "@eristack/ai-knowledge#tiga-sekawan-3ss-adoption"
packages: []
- id: erp-collection-declaration
title: ERP collection manifest for Backseat and Drizzle (Horizon B)
priority: 21
triggers:
- collection declaration
- defineErpCollection
- backseat drizzle same collection
- routes snapshot mirror
- horizon b collection
rationale: >
defineErpCollection + #collection-declaration-horizon-b + @eristack/backseat/testing
mirror smoke. Codegen later.
canonicalSkills:
- "@eristack/ai-knowledge#collection-declaration-horizon-b"
packages:
- name: "@eristack/drizzle"
skills:
- drizzle-core
role: primary
- name: "@eristack/backseat"
skills:
- backseat-core
role: supporting
- id: drizzle-open-app-database
title: Open Drizzle once at app compose (sqlite or Postgres)
priority: 19
triggers:
- open drizzle
- createAppDatabase
- APP_DB_DIALECT
- drizzle app boot
- database url postgres pool
rationale: >
openDrizzle + @eristack/drizzle/schema spine/columns + #drizzle-app-database.
Table packages never open pools.
canonicalSkills:
- "@eristack/ai-knowledge#drizzle-app-database"
- "@eristack/drizzle#drizzle-core"
packages:
- name: "@eristack/drizzle"
skills:
- drizzle-core
role: primary
- name: "@eristack/drizzle-kit-helpers"
skills:
- drizzle-kit-helpers-core
role: supporting
- id: print-layout-default-document
title: Print layout company default vs frozen document mask
priority: 18
triggers:
- print settings
- print layout
- shipment fields on invoice
- ar print
- print tax codes
- frozen print mask
rationale: >
app-owned company print singleton + nullable document mask. Load
@eristack/ai-knowledge#print-layout-default and knowledge/print-layout-default-vs-document.md only.
canonicalSkills:
- "@eristack/ai-knowledge#print-layout-default"
packages: []
- id: document-lines-erp
title: Document-with-lines ERP (job, cost sheet, invoice)
priority: 7
triggers:
- document with lines
- document lines erp
- job order
- cost sheet
- forwarding
- freight
- shipment
- bill of lading
- commercial invoice
- service erp
- logistics erp
- partner master
rationale: >
Header + QUPS lines products: load @eristack/ai-knowledge#document-lines-erp
and read knowledge/document-lines-erp.md only. qups + money + doc-number +
data-grid + pbac + backseat — not stock-movement/valuations/financial-ledger.
Partner/product masters app-owned — do not invent @eristack/feature-* packages.
canonicalSkills:
- "@eristack/ai-knowledge#document-lines-erp"
packages:
- name: "@eristack/qups"
skills:
- qups-line
role: primary
- name: "@eristack/pbac"
skills:
- pbac-core
role: primary
- name: "@eristack/doc-number"
skills:
- doc-number-core
role: supporting
- name: "@eristack/data-grid"
skills:
- data-grid-core
role: supporting
- name: "@eristack/backseat"
skills:
- backseat-core
role: supporting
- id: optimistic-document-version
title: Optimistic document version (expectedVersion)
priority: 10
triggers:
- optimistic locking
- expected version
- conflict version
- concurrent edit
- document version
- write conflict
- 409 version
rationale: >
ERP aggregates: load @eristack/ai-knowledge#optimistic-document-version
and read knowledge/optimistic-document-version.md. version + expectedVersion
on PATCH; 409 CONFLICT_VERSION via @eristack/backseat jsonError — distinct from epoch.
canonicalSkills:
- "@eristack/ai-knowledge#optimistic-document-version"
packages:
- name: "@eristack/backseat"
skills:
- backseat-core
role: primary
- id: http-errors
title: HTTP 409 error envelope (version, policy, epoch)
priority: 11
triggers:
- "409"
- policy denied
- stale epoch
- json error
- error envelope
- version conflict
- business policy denied
rationale: >
Unified JSON error canon: CONFLICT_VERSION, POLICY_DENIED, BUSINESS_POLICY_DENIED,
STALE_EPOCH. Load @eristack/ai-knowledge#http-errors and knowledge/http-errors.md.
Backseat jsonError/versionConflict; Express mapDomainError; distinct from epoch vs document version.
canonicalSkills:
- "@eristack/ai-knowledge#http-errors"
packages:
- name: "@eristack/backseat"
skills:
- backseat-core
role: primary
- name: "@eristack/epoch"
skills:
- epoch-core
role: supporting
- id: multitab-workspace
title: Multi-document ERP tab workspace
priority: 9
triggers:
- multitab
- multi tab
- document tabs
- erp tabs
- tab workspace
- workspace tabs
- open in tab
- browser tabs erp
rationale: >
Use @eristack/multitab for headless ERP tab chrome: pathname-keyed route tabs,
/new/{uuid} placeholders, adjacent insert, localStorage persistence, closeGuard,
and MultitabRouterProvider for TanStack Router (URL is source of truth). App owns
tab bar UI and keyboard shortcuts. Alpha infra — see repo roadmap/horizon.md.
packages:
- name: "@eristack/multitab"
skills:
- multitab-core
role: primary
- id: structured-logging
title: JSON-lines request logging
priority: 10
triggers:
- logger
- logging
- structured log
- json log
- request id log
- vercel logs
- log drain
rationale: >
Use @eristack/logger for JSON-lines server logging with injectable requestId,
userId, and tenantId context. Express: createLoggerMiddleware. Nest:
LoggerModule.forRoot + LoggingInterceptor. Alpha infra — see repo roadmap/horizon.md.
packages:
- name: "@eristack/logger"
skills:
- logger-core
role: primary
- id: declarative-rest-routes
title: Declarative REST route shell
priority: 10
triggers:
- rest routes
- declarative rest
- openapi emit
- express route table
- nest route module
rationale: >
Use @eristack/rest to define HTTP routes as data, mount on Express or Nest,
and emit minimal OpenAPI 3.1 paths. Compose with jwt-auth guards and
data-grid list handlers in app modules.
packages:
- name: "@eristack/rest"
skills:
- rest-core
role: primary
- id: access-control-stack
title: Roles, attribute limits, and document policies
priority: 12
triggers:
- rbac
- abac
- pbac
- role based
- roles
- permissions
- permission
- access control
- authorization
- can user
- attribute policy
- business policy
- goods receipt limit
- book value limit
- documents.transitions
- assignmentPairMatch
- document transition
rationale: >
Use @eristack/rbac for boolean role permissions, @eristack/abac for
attribute policies (e.g. max book value), and @eristack/pbac for document
software policies (e.g. PO outstanding > 0). Pair with jwt-auth for identity.
packages:
- name: "@eristack/rbac"
skills:
- rbac-core
- rbac-adapters
role: primary
- name: "@eristack/abac"
skills:
- abac-core
- abac-adapters
role: primary
- name: "@eristack/pbac"
skills:
- pbac-core
- pbac-adapters
role: primary
- name: "@eristack/jwt-auth"
skills:
- jwt-auth-core
role: supporting
- id: document-status-transitions
title: Preset ERP document status graphs
priority: 14
triggers:
- status transition
- publication workflow
- journal post void
- document status preset
- doc-transitions
- publicationGraph
- journalGraph
rationale: >
Load @eristack/doc-transitions#doc-transitions-core for preset status
graphs wired to @eristack/pbac documents.transitions() — not copy-paste tables.
packages:
- name: "@eristack/doc-transitions"
skills:
- doc-transitions-core
role: primary
- name: "@eristack/pbac"
skills:
- pbac-core
role: supporting
- id: opinion-http
title: Opinionated ERP HTTP document routes
priority: 15
triggers:
- opinion http
- patch action route
- erp rest canon
- document api scaffold
- PATCH /:id/:action
rationale: >
Use @eristack/opinion for the canonical document REST map (options,
data-grid, CRUD, PATCH /:id/:action) mounted via @eristack/rest.
packages:
- name: "@eristack/opinion"
skills:
- opinion-core
role: primary
- name: "@eristack/rest"
skills:
- rest-core
role: supporting
- name: "@eristack/doc-transitions"
skills:
- doc-transitions-core
role: supporting
- id: uom-quantity-conversion
title: Unit of measure conversion for inventory qty
priority: 16
triggers:
- uom
- unit of measure
- convert kg
- inventory uom
- stock uom
- receive uom
- alternate uom
rationale: >
Load @eristack/uom#uom-core for string qty + fixed-ratio conversion (kg/g/L/pcs)
before qups or stock-movement — not float math or hand-rolled factors.
packages:
- name: "@eristack/uom"
skills:
- uom-core
role: primary
- id: percent-rates-basis-points
title: Tax and discount rates as ratios or basis points
priority: 17
triggers:
- basis points
- bps
- tax rate
- discount rate
- markup rate
- ratio string
rationale: >
Load @eristack/percent#percent-core for ratio/bps parsing and percentOf on strings;
round with @eristack/money at ledger boundaries.
packages:
- name: "@eristack/percent"
skills:
- percent-core
role: primary
- name: "@eristack/money"
skills:
- money-amounts
role: supporting
- id: fraction-exact-rational
title: Exact rationals as fractions (recipe yields, BOM ratios)
priority: 18
triggers:
- fraction
- rational number
- numerator denominator
- recipe yield
- bom ratio
- parts ratio
- irrational approximation
- sqrt approximation
rationale: >
Load @eristack/fraction#fraction-core for exact num/den arithmetic; approximateFraction
for decimals/irrationals with maxDenominator — not @eristack/percent for VAT rates.
packages:
- name: "@eristack/fraction"
skills:
- fraction-core
role: primary
- id: household-ledger
title: Household cashbook / ledger-first spine
priority: 11
triggers:
- household ledger
- cashbook
- personal finance
- household accounts
- journal posting
- general ledger cashbook
rationale: >
Load @eristack/ai-knowledge#ledger-first and read knowledge/ledger-first.md only.
financial-ledger + money + timestamp + fiscal-calendar + epoch — not qups or document-lines-erp.
canonicalSkills:
- "@eristack/ai-knowledge#ledger-first"
packages:
- name: "@eristack/financial-ledger"
skills:
- financial-ledger-core
role: primary
- name: "@eristack/money"
skills:
- money-ledger
role: supporting
- name: "@eristack/timestamp"
skills:
- timestamp-core
role: supporting
- name: "@eristack/fiscal-calendar"
skills:
- fiscal-calendar-core
role: supporting
- name: "@eristack/epoch"
skills:
- epoch-core
role: supporting
- id: fiscal-period-posting
title: Fiscal period open/closed for journal dates
priority: 18
triggers:
- fiscal period
- fiscal year
- period close
- posting period
- closed period
rationale: >
Load @eristack/fiscal-calendar#fiscal-calendar-core for findPeriodForDate(calendar, wallClock)
then assertPeriodOpen(period) on @eristack/timestamp wall dates — pair with doc-transitions lockGraph.
packages:
- name: "@eristack/fiscal-calendar"
skills:
- fiscal-calendar-core
role: primary
- name: "@eristack/timestamp"
skills:
- timestamp-core
role: supporting
- name: "@eristack/doc-transitions"
skills:
- doc-transitions-core
role: supporting
- id: postal-address-normalize
title: Normalize and format postal addresses
priority: 19
triggers:
- address
- postal address
- shipping address
- billing address format
- partner address
rationale: >
Load @eristack/address#address-core for PostalAddress normalize/format and ISO
country codes — app owns partner tables and geocoding.
packages:
- name: "@eristack/address"
skills:
- address-core
role: primary
- id: stock-inventory-ledger
title: Inventory stock movements by location and lot
priority: 28
triggers:
- stock
- inventory
- warehouse
- lot
- stock movement
- goods receipt
- goods issue
- on hand
rationale: >
Use @eristack/stock-movement on @eristack/hash-chained-ledger for qty
ledgers with composable locations, lots, snapshots, and tamper checks.
packages:
- name: "@eristack/stock-movement"
skills:
- stock-movement-core
- stock-movement-adapters
role: primary
- name: "@eristack/hash-chained-ledger"
skills:
- hash-chained-ledger-core
role: supporting
- id: financial-gl-ledger
title: Financial / GL account ledger
priority: 29
triggers:
- general ledger
- gl
- chart of accounts
- account balance
- journal entry
- financial ledger
rationale: >
Use @eristack/financial-ledger for accountId+currency hash-chained
balances with @eristack/money amounts.
packages:
- name: "@eristack/financial-ledger"
skills:
- financial-ledger-core
- financial-ledger-adapters
role: primary
- name: "@eristack/hash-chained-ledger"
skills:
- hash-chained-ledger-core
role: supporting
- name: "@eristack/money"
skills:
- money-amounts
role: supporting
- id: inventory-valuation
title: FIFO, average, and other inventory valuations
priority: 30
triggers:
- fifo
- lifo
- fefo
- moving average
- weighted average
- standard cost
- inventory valuation
- costing
- cost layers
rationale: >
Use @eristack/valuations for canon costing methods with qty+value
hash-chained ledgers.
packages:
- name: "@eristack/valuations"
skills:
- valuations-core
- valuations-adapters
role: primary
- name: "@eristack/hash-chained-ledger"
skills:
- hash-chained-ledger-core
role: supporting
- id: compose-spine
title: Compose business spine (auth, lines, lists, optional ledgers)
priority: 9
triggers:
- compose erp modules
- which eristack packages
- erp module map
- purchase order
- sales order
- work order
- bill of materials
rationale: >
No @eristack/feature-* vertical packages — apps own document families.
Read @eristack/ai-knowledge#package-relationships (knowledge/package-relationships.md)
for the dependency map. Implement header + QUPS lines via #document-lines-erp or
#backseat-then-backend — not this recipe alone. Default compose: qups, doc-number,
pbac, data-grid, jwt-auth; add stock-movement, financial-ledger, valuations only
when inventory or GL is explicitly in scope.
canonicalSkills:
- "@eristack/ai-knowledge#package-relationships"
packages:
- name: "@eristack/qups"
skills:
- qups-core
- qups-line
role: primary
- name: "@eristack/pbac"
skills:
- pbac-core
role: primary
- name: "@eristack/doc-number"
skills:
- doc-number-core
role: supporting
- name: "@eristack/data-grid"
skills:
- data-grid-core
role: supporting
- name: "@eristack/jwt-auth"
skills:
- jwt-auth-core
role: supporting
- id: hash-chain-audit
title: Audit trail and tamper-evident ledger
priority: 25
triggers:
- audit trail
- tamper
- tamper detection
- tamper-evident
- hash chain
- append-only ledger
- immutable log
rationale: >
Use @eristack/hash-chained-ledger for SHA-256 chained append-only entries.
Stock, financial, and valuation packages compose this primitive in production.
packages:
- name: "@eristack/hash-chained-ledger"
skills:
- hash-chained-ledger-core
role: primary
- id: ai-workflow-memory
title: Sprint backlog and local project memory
priority: 12
triggers:
- sprint
- backlog
- adr
- project memory
- mcp workflow
- eristack workflow
- .eristack/workflow
rationale: >
Use @eristack/ai-workflow for local MCP, FTS+vector index, and sprint/backlog
folders under .eristack/workflow — complements Intent, does not replace git.
packages:
- name: "@eristack/ai-workflow"
skills:
- ai-workflow-core
role: primary
- id: ai-dev-tooling
title: Monorepo plan, check profiles, and dev MCP
priority: 11
triggers:
- eristack plan
- dev tooling
- monorepo check
- ci profile
- pnpm ci
- dev mcp
- check profile
- token minimal check
rationale: >
Use @eristack/ai-dev before chaining scripts: eristack plan --json for minimal
next steps, eristack check --profile pr for CI parity, eristack-mcp for dev_plan/dev_check.
packages:
- name: "@eristack/ai-dev"
skills:
- ai-dev-core
role: primary
- id: maintainer-tickets
title: Bug reports and feature suggestions for maintainers
priority: 15
triggers:
- bug report
- bug ticket
- support ticket
- feature request
- feature suggestion
- maintainer ticket
- fixer upper
- report a bug
- suggest a feature
- eristack ticket
rationale: >
Use @eristack/ai-ticket-generator to produce a portable markdown ticket
(logs/scenario/fix plan or feasibility-gated suggestion) the user can
send to maintainers for an agent fixer-upper. Every package has ticket.yaml.
packages:
- name: "@eristack/ai-ticket-generator"
skills:
- ai-ticket-bug
- ai-ticket-suggest
role: primary
- id: checksum-export-integrity
title: Export file SHA-256 checksum
priority: 14
triggers:
- checksum
- sha256 export
- file digest
- export integrity
rationale: >
@eristack/checksum sha256Hex and checksumEquals for download/export verification;
pair with @eristack/file-manager metadata in the app.
packages:
- name: "@eristack/checksum"
skills:
- checksum-core
role: primary
- id: currency-pair-fx-key
title: FX currency pair keys (no rates)
priority: 14
triggers:
- currency pair
- base quote
- fx pair
- USD/IDR
rationale: >
@eristack/currency-pair validates ISO codes via @eristack/money — formatPairKey for
rate table PKs until fx-table ships.
packages:
- name: "@eristack/currency-pair"
skills:
- currency-pair-core
role: primary
- id: geo-distance-logistics
title: Geo coordinates and distance (km)
priority: 14
triggers:
- geo point
- latitude longitude
- haversine
- depot radius
- distance km
rationale: >
Use @eristack/geo for lat/lng decimal strings and geoDistanceKm. Geocode in the app;
postal addresses stay on @eristack/address.
packages:
- name: "@eristack/geo"
skills:
- geo-core
role: primary
- id: dimension-logistics
title: Carton and item dimensions (L×W×H)
priority: 14
triggers:
- dimension
- l x w x h
- carton size
- cubic volume
- package dimensions
rationale: >
Use @eristack/dimension for length/width/height decimal strings and dimensionVolume.
Optional unit label — validate units with @eristack/uom in the app.
packages:
- name: "@eristack/dimension"
skills:
- dimension-core
role: primary
- id: entity-id-v7-primary-key
title: UUID v7 sortable primary keys
priority: 13
triggers:
- entity id
- entity-id
- uuid v7
- uuidv7
- sortable primary key
- primary key uuid
rationale: >
Use @eristack/entity-id for RFC 9562 UUID v7 generate/parse, Drizzle entityIdColumn,
and zod entityIdSchema — not ad hoc uuid v4 or serial ids on app-facing tables.
packages:
- name: "@eristack/entity-id"
skills:
- entity-id-core
role: primary
- id: party-and-platform-compose
title: Wave 13 party, platform, and finance compose
priority: 8
triggers:
- wave 13 compose
- wave 13 platform
- party platform compose
- compose at boundary
- one package per pr wave 13
- party contact
- normalize contact
- business calendar
- working days
- api key middleware
- rate limit middleware
- email template render
- spreadsheet export
- checksum export
- health readiness
- drizzle kit helper
rationale: >
Approved Wave 13 pipelines compose at the app boundary without sibling hard deps.
Load @eristack/ai-knowledge#party-and-platform-compose and read
knowledge/party-and-platform-compose.md — ship one npm package per PR.
canonicalSkills:
- "@eristack/ai-knowledge#party-and-platform-compose"
packages:
- name: "@eristack/ai-knowledge"
skills:
- party-and-platform-compose
role: primary
- id: person-normalize
title: Normalize person name and gender
priority: 14
triggers:
- person name
- normalize person
- gender identity
- contact name form
rationale: >
Use @eristack/person normalizePerson and formatPersonDisplay — app owns person rows.
packages:
- name: "@eristack/person"
skills:
- person-core
role: primary
- id: party-contact-normalize
title: Normalize party contacts (person, phone, email)
priority: 15
triggers:
- party normalize
- contact list
- primary contact
- e.164
- normalize email
rationale: >
Chain @eristack/person, phone, email-address, and contact at the API boundary.
Handler order in #party-and-platform-compose.
canonicalSkills:
- "@eristack/ai-knowledge#party-and-platform-compose"
packages:
- name: "@eristack/contact"
skills:
- contact-core
role: primary
- name: "@eristack/person"
skills:
- person-core
role: supporting
- name: "@eristack/phone"
skills:
- phone-core
role: supporting
- name: "@eristack/email-address"
skills:
- email-address-core
role: supporting
- id: platform-api-guard
title: B2B API edge (rate limit, API key, idempotency)
priority: 16
triggers:
- platform api guard
- partner api
- b2b api
- idempotency store
rationale: >
Load @eristack/ai-knowledge#idempotency-and-outbox — middleware order rate-limit → api-key
→ idempotency → handler; Drizzle idempotency store in prod (memory tests only).
packages:
- name: "@eristack/rate-limit"
skills:
- rate-limit-core
role: primary
- name: "@eristack/api-key"
skills:
- api-key-core
role: supporting
- name: "@eristack/idempotency"
skills:
- idempotency-core
role: supporting
- id: idempotency-http-replay
title: HTTP Idempotency-Key replay (Drizzle + Express)
priority: 15
triggers:
- idempotency key
- replay post
- duplicate payment post
- idempotency middleware
rationale: >
Load @eristack/ai-knowledge#idempotency-and-outbox — Drizzle store, scoped runScoped,
wrapIdempotentHandler; memory store unit tests only.
packages:
- name: "@eristack/idempotency"
skills:
- idempotency-adapters
role: primary
- id: ledger-idempotent-append
title: Idempotent ledger append (stock, GL, valuations)
priority: 14
triggers:
- duplicate goods receipt
- ledger retry
- idempotent append
rationale: >
Load @eristack/ai-knowledge#idempotency-and-outbox — hash-chained-ledger idempotencyKey;
stock-movement, financial-ledger, valuations pass keys through.
packages:
- name: "@eristack/hash-chained-ledger"
skills:
- hash-chained-ledger-core
role: primary
- id: reliable-side-effects-outbox
title: Outbox for comms and payment side effects
priority: 14
triggers:
- transactional outbox
- reliable email
- po confirmation email
rationale: >
Load @eristack/ai-knowledge#idempotency-and-outbox — @eristack/outbox enqueue in TX;
comms/payment claim-before-vendor; derived idempotency keys in workers.
packages:
- name: "@eristack/outbox"
skills:
- outbox-core
role: primary
- id: api-key-partner-auth
title: Partner API key verify
priority: 15
triggers:
- api key hash
- partner b2b key
- verify api key
rationale: >
@eristack/api-key generateApiKey, hashApiKey, verifyApiKey with optional pepper —
persist hash in Drizzle; show raw key once.
packages:
- name: "@eristack/api-key"
skills:
- api-key-core
role: primary
- id: rate-limit-edge
title: Fixed-window rate limit
priority: 15
triggers:
- rate limit
- throttle api
- too many requests
rationale: >
@eristack/rate-limit createRateLimiter — memory for tests/dev; Redis at app edge in prod.
packages:
- name: "@eristack/rate-limit"
skills:
- rate-limit-core
role: primary
- id: pdf-render-invoice
title: HTML to PDF (driver)
priority: 20
triggers:
- html to pdf
- invoice pdf
- pdf render driver
rationale: >
@eristack/pdf-render createPdfRenderer(driver) — stub for tests; Puppeteer/Playwright in app.
packages:
- name: "@eristack/pdf-render"
skills:
- pdf-render-core
role: primary
- id: posting-date-guard
title: Posting date, fiscal period, and business days
priority: 17
triggers:
- posting date
- business day
- holiday calendar
- period closed
- fiscal period post
rationale: >
Compose @eristack/fiscal-calendar and @eristack/business-calendar with timestamp wall
dates at the app boundary. Load #party-and-platform-compose (finance pipeline).
canonicalSkills:
- "@eristack/ai-knowledge#party-and-platform-compose"
packages:
- name: "@eristack/ai-knowledge"
skills:
- party-and-platform-compose
role: primary
- name: "@eristack/business-calendar"
skills:
- business-calendar-core
role: secondary
- name: "@eristack/fiscal-calendar"
skills:
- fiscal-calendar-core
role: secondary
- id: invoice-line-tax
title: Tax codes and line tax with qups
priority: 18
triggers:
- tax code
- tax rate effective date
- line tax
- vat rate
- sales tax rate
rationale: >
@eristack/tax createTaxRegistry() → registry.resolveTaxRate({ code, asOf }) +
registry.applyTaxToAmount(net, ratePercent) (unrounded tax portion); @eristack/qups line math;
@eristack/money Tax ops.
packages:
- name: "@eristack/tax"
skills:
- tax-core
role: primary
- name: "@eristack/qups"
skills:
- qups-line
role: supporting
- name: "@eristack/money"
skills:
- money-amounts
role: supporting
- id: ledger-rounding-policy
title: Company rounding policy at ledger boundary
priority: 17
triggers:
- rounding policy
- company rounding
- ledger rounding
- half even policy
rationale: >
@eristack/rounding-policy createRoundingPolicyRegistry() → registry.roundingFor({ policyId, currency })
→ money.with at post time; pair with tax and qups totals.
packages:
- name: "@eristack/rounding-policy"
skills:
- rounding-policy-core
role: primary
- name: "@eristack/money"
skills:
- money-ledger
role: supporting
- id: email-template-render
title: "Render {{var}} email bodies"
priority: 15
triggers:
- email template
- mail merge
- template variables
- render email body
- "{{var}} email"
rationale: >
@eristack/email-template renderEmailTemplate and extractTemplateKeys — HTML escape
for HTML parts; send via @eristack/comms in the app.
packages:
- name: "@eristack/email-template"
skills:
- email-template-core
role: primary
- id: outbound-message-render
title: Outbound email (template, comms, optional PDF)
priority: 21
triggers:
- outbound email
- transactional email render
- invoice email pdf
- message render pipeline
rationale: >
App pipeline: email-template → comms send; optional pdf-render attachment.
Load @eristack/ai-knowledge#party-and-platform-compose for compose rules.
canonicalSkills:
- "@eristack/ai-knowledge#party-and-platform-compose"
packages:
- name: "@eristack/email-template"
skills:
- email-template-core
role: primary
- id: spreadsheet-keyboard-operator
title: Spreadsheet keyboard navigation for in-browser grids
priority: 15
triggers:
- spreadsheet keyboard
- excel like grid
- arrow keys table
- active cell
- enter commit cell
- cost sheet keyboard
- spreadsheet operator
- two grids keyboard
rationale: >
Load @eristack/spreadsheet-operator#spreadsheet-operator-core then /react adapters.
Not spreadsheet-render (xlsx export) and not data-grid (HTTP lists). Commit → patchLine.
packages:
- name: "@eristack/spreadsheet-operator"
skills:
- spreadsheet-operator-core
- spreadsheet-operator-adapters
role: primary
- id: spreadsheet-export-download
title: Export list rows to xlsx or csv
priority: 22
triggers:
- export xlsx
- export csv
- spreadsheet download
- excel export
- download list excel
rationale: >
App maps data-grid list rows to string cells, then @eristack/spreadsheet-render driver.
Optional @eristack/checksum for file-manager downloads.
packages:
- name: "@eristack/spreadsheet-render"
skills:
- spreadsheet-render-core
role: primary
- id: health-readiness
title: Liveness and readiness HTTP
priority: 19
triggers:
- health check
- readiness probe
- liveness probe
- k8s health
rationale: >
@eristack/health createHealthRegistry + express/nest handlers — app registers Drizzle ping checks.
packages:
- name: "@eristack/health"
skills:
- health-core
role: primary
- id: local-monorepo-versioning
title: Private monorepo versioning without Changesets
priority: 14
triggers:
- version.lock.json
- local monorepo versioning
- private monorepo release
- bump without changesets
- product version lock
rationale: >
@eristack/local-monorepo-versioning planRelease + eristack-version CLI for deploy-only pnpm
monorepos. Use Changesets (@eristack/ai-knowledge#dev-conventions) when publishing npm libraries.
packages:
- name: "@eristack/local-monorepo-versioning"
skills:
- local-monorepo-versioning-core
role: primary
- id: drizzle-kit-monorepo
title: drizzle-kit config for Eristack apps
priority: 12
triggers:
- drizzle kit config
- drizzle migrate monorepo
- sqlite test drizzle
rationale: >
@eristack/drizzle-kit-helpers defineEristackDrizzleConfig and pg/sqlite templates.
packages:
- name: "@eristack/drizzle-kit-helpers"
skills:
- drizzle-kit-helpers-core
role: primary
- id: vercel-express-deploy
title: Deploy Express on Vercel serverless
priority: 12
triggers:
- vercel express
- serverless express handler
- vercel adapter
rationale: >
@eristack/vercel-adapters createVercelExpressHandler — pair with @eristack/logger requestId.
packages:
- name: "@eristack/vercel-adapters"
skills:
- vercel-adapters-core
role: primary
- id: erp-ui-design-system
title: Erista tokens and density
priority: 18
triggers:
- design system
- erista tokens
- tailwind preset erp
- density compact comfortable
rationale: >
Load @eristack/design-system#design-system-core — ERISTACK_CSS_VARS, tailwindPreset, DensityProvider.
packages:
- name: "@eristack/design-system"
skills:
- design-system-core
role: primary
- id: erp-ui-shell
title: ERP React UI shell (lists, forms, docs)
priority: 17
triggers:
- list page layout
- document detail shell
- money input react
- qups line grid
- command palette erp
- filter builder data grid
rationale: >
UI stack: form-ui, list-shell, filter-builder, line-grid, spreadsheet-operator,
doc-shell, policy-ui, master-detail, command-palette — load package skill getting-started per task.
packages:
- name: "@eristack/form-ui"
skills:
- form-ui-core
role: primary
- name: "@eristack/list-shell"
skills:
- list-shell-core
role: supporting
- name: "@eristack/line-grid"
skills:
- line-grid-core
role: supporting
- name: "@eristack/spreadsheet-operator"
skills:
- spreadsheet-operator-core
role: supporting
- name: "@eristack/doc-shell"
skills:
- doc-shell-core
role: supporting
- id: erp-list-and-doc-screens
title: List and document ERP screens (canonical stack)
priority: 16
triggers:
- erp list screen
- erp document screen
- ui package stack
- load ui-package-stack
canonicalSkills:
- "@eristack/ai-knowledge#ui-package-stack"
rationale: >
One guide: knowledge/ui-package-stack.md — design-system through spreadsheet-operator; headless fields on money/percent/timestamp.
packages:
- name: "@eristack/ai-knowledge"
skills:
- ui-package-stack
role: primary