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/sunframes 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
sourcesmap, 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.