@galaxy-foundry/reference-contract
v0.4.1
Published
The shared typed-reference vocabulary for Foundry-pattern instances, and its loader.
Maintainers
Readme
@galaxy-foundry/reference-contract
The typed-reference vocabulary a Foundry Mold's references[] entries draw from.
A reference entry names five things — its kind, when it is used_at, how it is loaded,
which cast mode applies, and what evidence backs it. Four of those five are the same in
every Foundry, because they describe the compilation machinery, which does not vary by
domain. Those four ship here.
kinds does not, deliberately. Which reference kinds exist is exactly what does vary: one
instance authors cli-tool and schema refs; another authors neither and would be declaring
dead vocabulary by inheriting them. The instance supplies its own.
import {
buildReferenceContract,
loadInstanceKinds,
contractKeys,
} from '@galaxy-foundry/reference-contract';
const contract = buildReferenceContract({
kinds: loadInstanceKinds('reference_contract.yml'),
});
contractKeys(contract, 'modes'); // ['verbatim', 'sidecar'] — inherited
contractKeys(contract, 'kinds'); // whatever your instance declaresNarrowing — declining capacity you have not earned
Inheriting a vocabulary complete is the right default: a term an instance has not used yet is inheritance, not drift, which is why a dead-vocabulary check should skip these groups.
But some terms are capacity, not description. modes.sidecar commits a Foundry to writing a
renderer: something has to turn the reference into a structured artifact beside the skill, and
until it exists the term is a word an author can spell and no caster can perform. An instance
that has not written one should be able to say so:
const contract = buildReferenceContract({
kinds: loadInstanceKinds('reference_contract.yml'),
narrow: { modes: ['verbatim'] },
});Now sidecar is not a value the instance's schema accepts, and its dead-vocabulary check over
modes means something. Widening again is a one-line edit, made when a Mold first needs the
term — the same discipline instances already apply to kinds.
That is not hypothetical. One instance kept sidecar while owning no renderer, and three
references reached for it to mean "this source is paywalled, do not carry it verbatim" — a
statement about the source, which mode does not make. Narrowing turned the next one into a
schema error at authoring time.
Narrowing rebuilds the group in the shipped order rather than the caller's, so two instances narrowing to the same terms produce byte-identical contracts however they wrote the list. An unknown term is refused rather than ignored: a typo would otherwise narrow further than intended and the schema would reject notes for a reason nobody could see.
After adopting this, an instance's reference_contract.yml holds only kinds. The
loader refuses a file that re-declares an inherited block, and parseInheritedVocabularies
refuses a shared table that declares kinds — the boundary is enforced in both directions,
because it is the kind of split that otherwise decays quietly.
The glosses
The two instances that had independently written these vocabularies had drifted on five descriptions. They were reconciled here, and the more specific reading won every time.
Three of them name a rule that both instances' validators already enforce but only one had written down:
| Term | The rule it now states |
| --------------------- | ---------------------------------- |
| load.on-demand | Requires a trigger |
| evidence.hypothesis | Requires a verification |
| modes.verbatim | License must permit verbatim carry |
The rest were one instance's specifics leaking into shared vocabulary — evidence.corpus-observed
described "real workflows" where the domain-neutral "real sources" is what a cross-instance
vocabulary needs. A test asserts the shipped prose names no instance's domain.
Scope
This package says what the vocabulary is. It does not enforce the cross-field rules the
terms describe — that lives in each instance's validator, against its own note schema, and the
licence half needs @galaxy-foundry/license-policy
besides.
spec_url
The shipped table carries one spec_url, applied by the loader to every term's href, rather
than repeating the same link across the vocabulary. It points to the rendered
Anatomy of an Instance
page. Keep it at page level until the individual vocabulary terms have stable rendered anchors.
