REC-032 Soul finding: dist/contracts.js required "../../../contracts/cultnet/...",
escaping the cultnet-ts package tree entirely. That breaks every installed
consumer: the two-runtime sample script (packs and installs cultnet-ts into a
clean consumer), test-typescript-package-closure.mjs, and Heimdall's pnpm copy
of cultnet-ts (honours `files`, would 404 on its next vendor/CultLib bump).
Only Stonks (file: symlink into the live checkout) happened to still work.
Fix: keep CultLib/contracts/cultnet as the only tracked source, but have
tools/generate-swarm-contracts.mjs wipe and re-copy it into a package-local,
gitignored packages/cultnet-ts/contracts/cultnet/ every time it runs (build,
typecheck, test, test:interop, prepack, the two-runtime script, and Heimdral's
`npm run build` all already invoke it). src/contracts.ts and the swarm-contracts
manifest now import that package-local copy ("../contracts/cultnet/...") instead
of reaching three directories up. package.json gets back `files: ["dist",
"contracts"]` and `prepack` so a packed tarball carries its own schema copy.
Also revert fa00f3f's tsconfig.test.json rootDir widen ("." -> "../..") and the
matching test-script/dist-test path changes and __dirname-relative recomputation
in cultnet-interop.test.ts and runtime-presence-health.test.ts: that widening
was working around dist-test not receiving a copy of the (now out-of-package)
contracts, but nothing in this repo actually needs the wider rootDir once the
schemas are package-local again, and the widened paths never matched what CI's
interop lanes and package.json's own dist-test paths expect --
packages/cultnet-ts/dist-test/test/interop/cultnet-interop.test.js, not
.../dist-test/packages/cultnet-ts/test/interop/.... PR #3 CI run 34766892424 on
7d3a3dc failed the first interop lane on exactly this missing-file defect.
cultnet-interop.test.ts's interopSchemaPath already resolved correctly once
cultNetTsRoot was reverted (it was never touched by fa00f3f) and continues to
point at the canonical CultLib/contracts/cultnet/interop copy, which is fine
since it is only read by the spawned non-TS peer processes, not required() by
this package. The cultmesh-ts shard-catalog $id lookup fix from fa00f3f
(cultnet.shard_catalog_request.v0 -> the CultLib contracts URL id) is unrelated
to the rootDir defect and is left as is.
REC-032, Soul redirect on branch claude/rec-032-cultnet-contracts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
203 lines
5.5 KiB
TypeScript
203 lines
5.5 KiB
TypeScript
import { defineJsonSchemaContract } from "../json-schema-contract";
|
|
import ghostlightAgentStateGeneratedContractSchema from "../../contracts/cultnet/ghostlight.agent-state.schema.json";
|
|
|
|
// Generated by tools/generate-swarm-contracts.mjs. Do not hand-edit this file unless you enjoy losing arguments with a machine.
|
|
|
|
/**
|
|
* First canonical contract for Ghostlight agent, perception, relationship, event, scene, and dialogue-context state.
|
|
*/
|
|
export interface GhostlightAgentStateShape {
|
|
schema_version: 'ghostlight.agent_state.v0';
|
|
world: WorldState;
|
|
agents: Agent[];
|
|
relationships: Relationship[];
|
|
events: Event[];
|
|
scenes: Scene[];
|
|
}
|
|
export interface WorldState {
|
|
world_id: string;
|
|
setting: string;
|
|
time: {
|
|
label: string;
|
|
[k: string]: unknown;
|
|
};
|
|
canon_context: string[];
|
|
ambient_pressures?: Pressure[];
|
|
}
|
|
export interface Pressure {
|
|
pressure_id: string;
|
|
label: string;
|
|
intensity: number;
|
|
}
|
|
export interface Agent {
|
|
agent_id: string;
|
|
identity: Identity;
|
|
canonical_state: CanonicalState;
|
|
goals: Goal[];
|
|
memories: MemoryBundle;
|
|
perceived_state_overlays: PerceivedStateOverlay[];
|
|
}
|
|
export interface Identity {
|
|
name: string;
|
|
roles: string[];
|
|
origin: string;
|
|
public_description: string;
|
|
private_notes?: string[];
|
|
}
|
|
export interface CanonicalState {
|
|
underlying_organization: VariableMap;
|
|
stable_dispositions: VariableMap;
|
|
behavioral_dimensions: VariableMap;
|
|
presentation_strategy: VariableMap;
|
|
situational_state: VariableMap;
|
|
values: ValueCommitment[];
|
|
voice_style: VariableMap;
|
|
}
|
|
export interface VariableMap {
|
|
[k: string]: StateVariable;
|
|
}
|
|
export interface StateVariable {
|
|
mean: number;
|
|
plasticity: number;
|
|
current_activation: number;
|
|
evidence?: string[];
|
|
}
|
|
export interface ValueCommitment {
|
|
value_id: string;
|
|
label: string;
|
|
priority: number;
|
|
unforgivable_if_betrayed: boolean;
|
|
}
|
|
export interface Goal {
|
|
goal_id: string;
|
|
description: string;
|
|
scope: 'immediate' | 'scene' | 'case' | 'arc' | 'life';
|
|
priority: number;
|
|
emotional_stake: string;
|
|
blockers?: string[];
|
|
status: 'active' | 'blocked' | 'dormant' | 'resolved' | 'abandoned';
|
|
}
|
|
export interface MemoryBundle {
|
|
episodic: Memory[];
|
|
semantic: Memory[];
|
|
relationship_summaries: Memory[];
|
|
}
|
|
export interface Memory {
|
|
memory_id: string;
|
|
summary: string;
|
|
salience: number;
|
|
confidence: number;
|
|
linked_event_ids?: string[];
|
|
linked_relationship_id?: string;
|
|
}
|
|
export interface PerceivedStateOverlay {
|
|
observer_agent_id: string;
|
|
target_agent_id: string;
|
|
perceived_dimensions: InferredVariableMap;
|
|
beliefs: Belief[];
|
|
distortions: (
|
|
| 'hostile_attribution'
|
|
| 'false_reassurance'
|
|
| 'overread_warmth'
|
|
| 'underread_threat'
|
|
| 'false_mask_detection'
|
|
| 'missed_mask_detection'
|
|
| 'status_injury'
|
|
| 'threat_amplification'
|
|
| 'institutional_suspicion_transfer'
|
|
| 'care_underread'
|
|
| 'mask_overfocus'
|
|
)[];
|
|
}
|
|
export interface InferredVariableMap {
|
|
[k: string]: InferredStateVariable;
|
|
}
|
|
export interface InferredStateVariable {
|
|
observed_activation: number;
|
|
attributed_disposition: number;
|
|
confidence: number;
|
|
evidence?: string[];
|
|
}
|
|
export interface Belief {
|
|
belief_id: string;
|
|
claim: string;
|
|
confidence: number;
|
|
subject_id?: string;
|
|
claim_type?:
|
|
'fact' | 'identity_inference' | 'motive_inference' | 'prediction' | 'norm' | 'value_read' | 'relationship_read';
|
|
evidence_event_ids?: string[];
|
|
visibility?: 'private' | 'shared' | 'public' | 'rumor';
|
|
emotional_charge?: number;
|
|
}
|
|
export interface Relationship {
|
|
relationship_id: string;
|
|
source_id: string;
|
|
target_id: string;
|
|
stance: VariableMap;
|
|
summary: string;
|
|
unresolved_incident_ids?: string[];
|
|
}
|
|
export interface Event {
|
|
event_id: string;
|
|
kind: 'dialogue' | 'action' | 'memory' | 'relationship_shift' | 'scene_outcome' | 'author_note';
|
|
summary: string;
|
|
participants: string[];
|
|
pressure_tags: string[];
|
|
observed_exchange?: EventExchangeTurn[];
|
|
private_interpretations?: EventPrivateInterpretation[];
|
|
event_effects?: EventEffect[];
|
|
}
|
|
export interface EventExchangeTurn {
|
|
speaker_id: string;
|
|
utterance_summary: string;
|
|
dialogue_function: string;
|
|
observable_cues?: string[];
|
|
}
|
|
export interface EventPrivateInterpretation {
|
|
agent_id: string;
|
|
interpretation: string;
|
|
attributed_motive?: string;
|
|
appraisal_tags?: string[];
|
|
confidence: number;
|
|
}
|
|
export interface EventEffect {
|
|
agent_id: string;
|
|
summary: string;
|
|
state_deltas?: StateDelta[];
|
|
new_belief_ids?: string[];
|
|
memory_update_ids?: string[];
|
|
}
|
|
export interface StateDelta {
|
|
path: string;
|
|
delta: number;
|
|
}
|
|
export interface Scene {
|
|
scene_id: string;
|
|
location: string;
|
|
participants: string[];
|
|
public_stakes: string[];
|
|
hidden_stakes: string[];
|
|
dialogue_context_packs: DialogueContextPack[];
|
|
}
|
|
export interface DialogueContextPack {
|
|
speaker_agent_id: string;
|
|
listener_ids: string[];
|
|
speaker_local_truth: string[];
|
|
speaker_beliefs: string[];
|
|
active_memories: string[];
|
|
active_goals: string[];
|
|
presentation_constraints: string[];
|
|
}
|
|
|
|
export const ghostlightAgentStateGeneratedContract = defineJsonSchemaContract<GhostlightAgentStateShape>({
|
|
schemaId: "https://github.com/GameCult/Ghostlight/schemas/agent-state.schema.json",
|
|
schema: ghostlightAgentStateGeneratedContractSchema,
|
|
});
|
|
|
|
export function validateGhostlightAgentStateGenerated(value: unknown): value is GhostlightAgentStateShape {
|
|
return ghostlightAgentStateGeneratedContract.validate(value);
|
|
}
|
|
|
|
export function parseGhostlightAgentStateGenerated(value: unknown): GhostlightAgentStateShape {
|
|
return ghostlightAgentStateGeneratedContract.parse(value);
|
|
}
|