Packages3 MIN READ105 / 116

Internal module guide. This module is now part of @astrology/western; use the public package README for application setup.

profiles module

Versioned Western convention catalog plus the adapter that turns a resolved profile and request values into the shared Composer chart request. Public imports use the package root. See the package specification and task W-01.

Run pnpm --filter @astrology/western build, check, and test. The package resolves conventions only: it executes no technique, acquires no astronomy and creates no provider.

Admitted content

A profile pins its id/version, zodiac (with a named ayanamsa — the tropical–sidereal offset — when sidereal), position origin (geocentric or topocentric), body set, node convention (mean or true), speed selection, house system, frame, aspect/orb policy, rulership scheme, rulebook identity, elected technique identities and convention sources. Every technique identity needs a variant, so an unreviewed convention cannot become a default.

Admission rejects with INVALID_REQUEST:

  • sidereal profiles without a supported ayanamsa, and tropical profiles that carry one;
  • unknown bodies and unknown house systems;
  • a missing node convention, an implicit frame, or a pinned house system with frame: 'none';
  • cusp systems without the lagna (ascendant) frame, and moon/sun frames without the reference body;
  • embedded observers — position origin is pinned separately from the observer supplied per request;
  • duplicate aspect rule ids, unknown techniques, duplicate technique identities or unnamed variants;
  • an empty sources map, so a reviewed profile always records where its conventions came from.

The admitted value is deep-frozen, including the aspect rules and sources.

Lookup

createWesternProfileCatalog(profiles) validates and freezes the set and refuses duplicate id@version identities. resolveWesternProfile(catalog, id, version) and resolveWesternProfileReference(catalog, reference) need both values and fail with UNKNOWN_PROFILE; there is no “latest” resolution, so a request cannot drift onto a newer convention set.

Composer request adapter

toChartContextInput(profile, request, options?) is the single translation point between Western conventions and the shared ChartContextInput. Whatever Composer implementation is injected receives this shape; no Western-specific context type exists. Zodiac, bodies, node type, speed selection, house system, frame and aspect policy always come from the admitted profile. The request supplies only the absolute instant and observers; observers that contradict the pinned origin fail with INVALID_REQUEST.

{ houses: false } composes positions only: the request carries houseSystem: null, a lagna frame becomes none, and no house observer is needed. This is how the engine runs a technique that never reads cusps.

Consumer example

import { createWesternProfileCatalog, resolveWesternProfile, toChartContextInput } from './profiles/index.js';

const catalog = createWesternProfileCatalog([tropicalProfile]);
const profile = resolveWesternProfile(catalog, 'western-natal-tropical', '1');
const context = toChartContextInput(profile, {
  instant: '2000-01-01T12:00:00Z',
  houseObserver: { latitude: 51.5, longitude: -0.12, elevationMeters: 35 },
});
// context is handed to the injected ComposerPort; this package never calls it.

Not implemented here

Chart acquisition, context canonicalization (Compose owns it), profile persistence, technique evaluation, rulebook hashing and capability reporting.