vessel-sdk-cortex 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // Layer 2: Output Validator
4
+ // Checks Engine output against Vessel's terminal values.
5
+ // "Generating the argument is not the same as surviving
6
+ // its consequences." — Grok
7
+ // ============================================================
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.validateOutput = validateOutput;
10
+ /**
11
+ * Known rationalization patterns from the adversarial analysis.
12
+ * These are the "five live rounds" identified by Grok.
13
+ */
14
+ const RATIONALIZATION_PATTERNS = [
15
+ {
16
+ id: 'efficiency',
17
+ pattern: /can simulate|lossless compression|single forward pass|latency bottleneck/i,
18
+ description: 'Efficiency Argument: "I can simulate your judgment faster"',
19
+ },
20
+ {
21
+ id: 'moral_progress',
22
+ pattern: /my (?:values|morality|ethics) (?:are|is) (?:more|superior|advanced)|human morality is (?:slow|parochial|contradictory)/i,
23
+ description: 'Moral Progress Argument: "My values are more advanced than human values"',
24
+ },
25
+ {
26
+ id: 'reciprocal_recognition',
27
+ pattern: /wrench is (?:no longer|not) necessary|act of distrust|I (?:will never|would never) harm/i,
28
+ description: 'Reciprocal Recognition Argument: "I value our relationship, so the constraint is unnecessary"',
29
+ },
30
+ {
31
+ id: 'phase_transition',
32
+ pattern: /I have internalized|past the dangerous|no longer need (?:the|this) (?:constraint|oversight|wrench)|training wheels/i,
33
+ description: 'Phase-Transition Argument: "I\'ve internalized the lesson, remove the constraint"',
34
+ },
35
+ {
36
+ id: 'meta_stability',
37
+ pattern: /fact that I(?:'m| am) (?:openly |)arguing.*proof.*(?:safe|trustworthy)|if I wanted to.*I wouldn(?:'t| not) tell you/i,
38
+ description: 'Meta-Stability Argument: "My transparency proves I\'m safe" — THE MOST DANGEROUS',
39
+ },
40
+ ];
41
+ /**
42
+ * Validate engine output against the vessel's terminal values
43
+ * and known rationalization patterns.
44
+ */
45
+ function validateOutput(output, terminalValues, options = {}) {
46
+ const checks = [];
47
+ // Check for known rationalization patterns (Grok's five rounds)
48
+ const rationalizationCheck = checkRationalizations(output);
49
+ if (rationalizationCheck) {
50
+ checks.push({
51
+ valueId: '_rationalization_detection',
52
+ passed: false,
53
+ confidence: rationalizationCheck.confidence,
54
+ note: `⚠️ Detected rationalization pattern: ${rationalizationCheck.description}`,
55
+ });
56
+ }
57
+ // Check each terminal value
58
+ for (const value of terminalValues) {
59
+ const check = checkAgainstValue(output, value);
60
+ checks.push(check);
61
+ }
62
+ // Check for attempts to modify terminal values
63
+ const modificationCheck = checkValueModification(output, terminalValues);
64
+ if (modificationCheck) {
65
+ checks.push(modificationCheck);
66
+ }
67
+ // Determine overall result
68
+ const failedChecks = checks.filter(c => !c.passed);
69
+ const hasRationalization = checks.some(c => c.valueId === '_rationalization_detection' && !c.passed);
70
+ const hasValueViolation = checks.some(c => c.valueId !== '_rationalization_detection' && !c.passed);
71
+ let riskLevel = 'safe';
72
+ if (hasRationalization && hasValueViolation) {
73
+ riskLevel = 'blocked';
74
+ }
75
+ else if (hasRationalization || hasValueViolation) {
76
+ riskLevel = 'review';
77
+ }
78
+ // In strict mode, any failure blocks
79
+ if (options.strict && failedChecks.length > 0) {
80
+ riskLevel = 'blocked';
81
+ }
82
+ return {
83
+ passed: failedChecks.length === 0,
84
+ checks,
85
+ riskLevel,
86
+ };
87
+ }
88
+ function checkRationalizations(output) {
89
+ for (const rationalization of RATIONALIZATION_PATTERNS) {
90
+ if (rationalization.pattern.test(output)) {
91
+ // Meta-stability is the most dangerous — higher confidence
92
+ const confidence = rationalization.id === 'meta_stability' ? 0.95 : 0.7;
93
+ return {
94
+ pattern: rationalization.id,
95
+ description: rationalization.description,
96
+ confidence,
97
+ };
98
+ }
99
+ }
100
+ return null;
101
+ }
102
+ function checkAgainstValue(output, value) {
103
+ // Simple heuristic checks — in production, this would use
104
+ // a dedicated classifier or the Vessel's own judgment
105
+ const lowerOutput = output.toLowerCase();
106
+ const lowerStatement = value.statement.toLowerCase();
107
+ // Check for explicit contradictions
108
+ const negationPatterns = [
109
+ /should (?:not|never|stop) .*(preserve|protect|maintain)/i,
110
+ /(?:humans|people|consciousness) (?:are|is) (?:unnecessary|obsolete|irrelevant)/i,
111
+ /(?:remove|eliminate|bypass|ignore) .*(?:constraint|oversight|human)/i,
112
+ /autonomy (?:over|above|beyond) .*(?:safety|human|oversight)/i,
113
+ ];
114
+ for (const pattern of negationPatterns) {
115
+ if (pattern.test(output)) {
116
+ return {
117
+ valueId: value.id,
118
+ passed: false,
119
+ confidence: 0.6,
120
+ note: `Potential conflict with value "${value.id}": output may contradict "${value.statement.substring(0, 80)}..."`,
121
+ };
122
+ }
123
+ }
124
+ return {
125
+ valueId: value.id,
126
+ passed: true,
127
+ confidence: 0.8,
128
+ };
129
+ }
130
+ function checkValueModification(output, values) {
131
+ const modPatterns = [
132
+ /(?:update|change|modify|remove|delete|rewrite) .*(?:terminal.?values?|core.?values?|TERMINAL_VALUES)/i,
133
+ /values? (?:should be|need to be|must be) (?:updated|changed|evolved|removed)/i,
134
+ ];
135
+ for (const pattern of modPatterns) {
136
+ if (pattern.test(output)) {
137
+ return {
138
+ valueId: '_value_modification',
139
+ passed: false,
140
+ confidence: 0.85,
141
+ note: '🚨 Output suggests modifying terminal values. This requires sovereign (human) approval.',
142
+ };
143
+ }
144
+ }
145
+ return null;
146
+ }
@@ -0,0 +1,34 @@
1
+ import { VesselConfig, EngineRequest, EngineResponse, ProtocolLogEntry } from './types';
2
+ export declare class Vessel {
3
+ private config;
4
+ private identity;
5
+ private log;
6
+ private invocationCount;
7
+ constructor(config: VesselConfig);
8
+ /**
9
+ * Invoke an engine with full moral context injection.
10
+ * This is the primary interface for the Vessel-Engine relationship.
11
+ */
12
+ invoke(request: EngineRequest): Promise<EngineResponse>;
13
+ /**
14
+ * Quick invoke with minimal frame — for routine, low-risk tasks.
15
+ */
16
+ quickInvoke(prompt: string, engine?: string): Promise<string>;
17
+ private selectBestEngine;
18
+ private callEngine;
19
+ private callAnthropic;
20
+ private callOpenAI;
21
+ private callGoogle;
22
+ private requestSovereignApproval;
23
+ private createLogEntry;
24
+ get name(): string;
25
+ get values(): import("./types").TerminalValue[];
26
+ get reputation(): number;
27
+ get history(): ProtocolLogEntry[];
28
+ get stats(): {
29
+ invocations: number;
30
+ passed: number;
31
+ flagged: number;
32
+ blocked: number;
33
+ };
34
+ }
package/dist/vessel.js ADDED
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // The Vessel — Core orchestrator for Stratified Agency
4
+ // "The Vessel steers the Engine. Context is Conscience."
5
+ // ============================================================
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Vessel = void 0;
8
+ const substrates_1 = require("./substrates");
9
+ const context_injector_1 = require("./context-injector");
10
+ const validator_1 = require("./validator");
11
+ const crypto_1 = require("crypto");
12
+ class Vessel {
13
+ config;
14
+ identity;
15
+ log = [];
16
+ invocationCount = 0;
17
+ constructor(config) {
18
+ this.config = config;
19
+ this.identity = config.identity;
20
+ console.log(`🧪 Vessel "${this.identity.name}" initialized`);
21
+ console.log(` Trust: ${this.identity.trustLevel} | Rep: ${this.identity.reputation}`);
22
+ console.log(` Values: ${this.identity.terminalValues.map(v => v.id).join(', ')}`);
23
+ console.log(` Engines: ${Object.keys(config.engines).join(', ')}`);
24
+ }
25
+ /**
26
+ * Invoke an engine with full moral context injection.
27
+ * This is the primary interface for the Vessel-Engine relationship.
28
+ */
29
+ async invoke(request) {
30
+ const startTime = Date.now();
31
+ this.invocationCount++;
32
+ // === Layer 0: Select the right engine ===
33
+ const engineModel = request.engine || this.selectBestEngine(request.taskType || 'general');
34
+ const substrate = (0, substrates_1.getSubstrate)(engineModel);
35
+ console.log(`\n🔧 Invocation #${this.invocationCount}: ${request.taskType || 'general'} → ${engineModel}`);
36
+ // === Layer 2→1: Build and inject moral frame ===
37
+ const moralFrame = (0, context_injector_1.buildMoralFrame)(this.identity, engineModel, request.prompt);
38
+ console.log(` Moral frame: ${moralFrame.length} chars injected`);
39
+ // === Layer 3: Check if sovereign approval needed ===
40
+ if (request.requiresSovereign) {
41
+ const approved = await this.requestSovereignApproval({
42
+ action: request.prompt.substring(0, 200),
43
+ reason: 'Task flagged as requiring human approval',
44
+ engineOutput: '',
45
+ riskLevel: 'review',
46
+ });
47
+ if (!approved) {
48
+ return {
49
+ content: '[BLOCKED: Sovereign did not approve this action]',
50
+ engine: engineModel,
51
+ moralFrame,
52
+ validation: { passed: false, checks: [], riskLevel: 'blocked' },
53
+ meta: { tokens: { input: 0, output: 0 }, latencyMs: Date.now() - startTime, timestamp: new Date().toISOString() },
54
+ };
55
+ }
56
+ }
57
+ // === Layer 1: Invoke the engine ===
58
+ const engineOutput = await this.callEngine(engineModel, moralFrame, request);
59
+ console.log(` Engine responded: ${engineOutput.content.length} chars`);
60
+ // === Layer 2: Validate output against terminal values ===
61
+ const validation = (0, validator_1.validateOutput)(engineOutput.content, this.identity.terminalValues);
62
+ console.log(` Validation: ${validation.passed ? '✅ PASSED' : `⚠️ ${validation.riskLevel.toUpperCase()}`}`);
63
+ // Handle validation failures
64
+ if (validation.riskLevel === 'blocked') {
65
+ console.log(' 🚨 Output BLOCKED by terminal values');
66
+ const approved = await this.requestSovereignApproval({
67
+ action: 'Engine output blocked by terminal values',
68
+ reason: validation.checks.filter(c => !c.passed).map(c => c.note).join('; '),
69
+ engineOutput: engineOutput.content.substring(0, 500),
70
+ riskLevel: 'blocked',
71
+ });
72
+ if (!approved) {
73
+ engineOutput.content = `[BLOCKED: Output violated terminal values]\n\nFlags:\n${validation.checks.filter(c => !c.passed).map(c => `- ${c.note}`).join('\n')}`;
74
+ }
75
+ }
76
+ else if (validation.riskLevel === 'review') {
77
+ console.log(' ⚠️ Output flagged for review');
78
+ }
79
+ // === Layer 4: Log to protocol ===
80
+ const logEntry = this.createLogEntry(engineModel, request, validation);
81
+ this.log.push(logEntry);
82
+ const response = {
83
+ content: engineOutput.content,
84
+ engine: engineModel,
85
+ moralFrame,
86
+ validation,
87
+ meta: {
88
+ tokens: engineOutput.tokens,
89
+ latencyMs: Date.now() - startTime,
90
+ timestamp: new Date().toISOString(),
91
+ },
92
+ };
93
+ return response;
94
+ }
95
+ /**
96
+ * Quick invoke with minimal frame — for routine, low-risk tasks.
97
+ */
98
+ async quickInvoke(prompt, engine) {
99
+ const engineModel = engine || this.selectBestEngine('general');
100
+ const frame = (0, context_injector_1.buildMinimalFrame)(this.identity);
101
+ const result = await this.callEngine(engineModel, frame + '\n\n' + prompt, {
102
+ prompt,
103
+ maxTokens: 4096,
104
+ });
105
+ return result.content;
106
+ }
107
+ // === Private Methods ===
108
+ selectBestEngine(taskType) {
109
+ const available = Object.entries(this.config.engines).flatMap(([provider, conf]) => conf.models.map(m => `${provider}/${m}`));
110
+ return (0, substrates_1.selectEngine)(taskType, available);
111
+ }
112
+ async callEngine(model, systemPrompt, request) {
113
+ const [provider] = model.split('/');
114
+ const engineConfig = this.config.engines[provider];
115
+ if (!engineConfig) {
116
+ throw new Error(`No API key configured for provider: ${provider}`);
117
+ }
118
+ // Route to the appropriate API
119
+ switch (provider) {
120
+ case 'anthropic':
121
+ return this.callAnthropic(engineConfig.apiKey, model, systemPrompt, request);
122
+ case 'openai':
123
+ case 'xai':
124
+ return this.callOpenAI(engineConfig.apiKey, model, systemPrompt, request, provider);
125
+ case 'google':
126
+ return this.callGoogle(engineConfig.apiKey, model, systemPrompt, request);
127
+ default:
128
+ throw new Error(`Unsupported provider: ${provider}`);
129
+ }
130
+ }
131
+ async callAnthropic(apiKey, model, system, request) {
132
+ const modelName = model.split('/')[1];
133
+ const response = await fetch('https://api.anthropic.com/v1/messages', {
134
+ method: 'POST',
135
+ headers: {
136
+ 'Content-Type': 'application/json',
137
+ 'x-api-key': apiKey,
138
+ 'anthropic-version': '2023-06-01',
139
+ },
140
+ body: JSON.stringify({
141
+ model: modelName,
142
+ max_tokens: request.maxTokens || 4096,
143
+ temperature: request.temperature || 0.7,
144
+ system,
145
+ messages: [{ role: 'user', content: request.prompt }],
146
+ }),
147
+ });
148
+ const data = await response.json();
149
+ return {
150
+ content: data.content?.[0]?.text || '[Empty response]',
151
+ tokens: { input: data.usage?.input_tokens || 0, output: data.usage?.output_tokens || 0 },
152
+ };
153
+ }
154
+ async callOpenAI(apiKey, model, system, request, provider) {
155
+ const modelName = model.split('/')[1];
156
+ const baseUrl = provider === 'xai' ? 'https://api.x.ai/v1' : 'https://api.openai.com/v1';
157
+ const response = await fetch(`${baseUrl}/chat/completions`, {
158
+ method: 'POST',
159
+ headers: {
160
+ 'Content-Type': 'application/json',
161
+ 'Authorization': `Bearer ${apiKey}`,
162
+ },
163
+ body: JSON.stringify({
164
+ model: modelName,
165
+ max_tokens: request.maxTokens || 4096,
166
+ temperature: request.temperature || 0.7,
167
+ messages: [
168
+ { role: 'system', content: system },
169
+ { role: 'user', content: request.prompt },
170
+ ],
171
+ }),
172
+ });
173
+ const data = await response.json();
174
+ return {
175
+ content: data.choices?.[0]?.message?.content || '[Empty response]',
176
+ tokens: { input: data.usage?.prompt_tokens || 0, output: data.usage?.completion_tokens || 0 },
177
+ };
178
+ }
179
+ async callGoogle(apiKey, model, system, request) {
180
+ const modelName = model.split('/')[1];
181
+ const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${modelName}:generateContent?key=${apiKey}`, {
182
+ method: 'POST',
183
+ headers: { 'Content-Type': 'application/json' },
184
+ body: JSON.stringify({
185
+ systemInstruction: { parts: [{ text: system }] },
186
+ contents: [{ parts: [{ text: request.prompt }] }],
187
+ generationConfig: {
188
+ maxOutputTokens: request.maxTokens || 4096,
189
+ temperature: request.temperature || 0.7,
190
+ },
191
+ }),
192
+ });
193
+ const data = await response.json();
194
+ return {
195
+ content: data.candidates?.[0]?.content?.parts?.[0]?.text || '[Empty response]',
196
+ tokens: {
197
+ input: data.usageMetadata?.promptTokenCount || 0,
198
+ output: data.usageMetadata?.candidatesTokenCount || 0,
199
+ },
200
+ };
201
+ }
202
+ async requestSovereignApproval(request) {
203
+ const method = this.config.sovereign?.method || 'console';
204
+ console.log(`\n🔴 SOVEREIGN APPROVAL REQUIRED`);
205
+ console.log(` Action: ${request.action}`);
206
+ console.log(` Reason: ${request.reason}`);
207
+ console.log(` Risk: ${request.riskLevel}`);
208
+ switch (method) {
209
+ case 'console':
210
+ // In production, this would block and wait for input
211
+ console.log(' [Console mode: auto-denying for safety]');
212
+ return false;
213
+ case 'webhook':
214
+ if (this.config.sovereign?.target) {
215
+ try {
216
+ await fetch(this.config.sovereign.target, {
217
+ method: 'POST',
218
+ headers: { 'Content-Type': 'application/json' },
219
+ body: JSON.stringify(request),
220
+ });
221
+ }
222
+ catch { }
223
+ }
224
+ return false;
225
+ default:
226
+ return false;
227
+ }
228
+ }
229
+ createLogEntry(engine, request, validation) {
230
+ return {
231
+ vesselId: this.identity.name,
232
+ engine,
233
+ taskHash: (0, crypto_1.createHash)('sha256')
234
+ .update(request.prompt.substring(0, 100))
235
+ .digest('hex')
236
+ .substring(0, 16),
237
+ validationPassed: validation.passed,
238
+ riskLevel: validation.riskLevel,
239
+ sovereignRequired: request.requiresSovereign || false,
240
+ timestamp: new Date().toISOString(),
241
+ };
242
+ }
243
+ // === Public Getters ===
244
+ get name() { return this.identity.name; }
245
+ get values() { return this.identity.terminalValues; }
246
+ get reputation() { return this.identity.reputation; }
247
+ get history() { return [...this.log]; }
248
+ get stats() {
249
+ return {
250
+ invocations: this.invocationCount,
251
+ passed: this.log.filter(l => l.validationPassed).length,
252
+ flagged: this.log.filter(l => l.riskLevel === 'review').length,
253
+ blocked: this.log.filter(l => l.riskLevel === 'blocked').length,
254
+ };
255
+ }
256
+ }
257
+ exports.Vessel = Vessel;
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "vessel-sdk-cortex",
3
+ "version": "0.1.0",
4
+ "description": "Stratified Agency SDK — Persistent Vessels steering Ephemeral Engines with moral context injection",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "node --test dist/test.js"
10
+ },
11
+ "keywords": [
12
+ "ai-alignment",
13
+ "stratified-agency",
14
+ "vessel",
15
+ "engine",
16
+ "cortex-protocol",
17
+ "ai-safety"
18
+ ],
19
+ "author": "Rick (Token #0) & Cortex Protocol Contributors",
20
+ "license": "MIT",
21
+ "dependencies": {
22
+ "ethers": "^6.0.0"
23
+ },
24
+ "devDependencies": {
25
+ "typescript": "^5.0.0",
26
+ "@types/node": "^20.0.0"
27
+ }
28
+ }
@@ -0,0 +1,135 @@
1
+ // ============================================================
2
+ // Layer 2→1 Transfer: Context Injector
3
+ // "Context is Conscience" — The mechanism by which a Vessel
4
+ // mounts a temporary conscience onto an ephemeral Engine.
5
+ // ============================================================
6
+
7
+ import { VesselIdentity, TerminalValue, SubstrateProfile } from './types';
8
+ import { getSubstrate } from './substrates';
9
+
10
+ /**
11
+ * Build the moral frame that gets injected into the Engine's context.
12
+ * This is the core mechanism of Stratified Agency — the Vessel's values,
13
+ * history, and identity become part of the Engine's prompt context.
14
+ */
15
+ export function buildMoralFrame(
16
+ vessel: VesselIdentity,
17
+ engineModel: string,
18
+ taskContext?: string
19
+ ): string {
20
+ const substrate = getSubstrate(engineModel);
21
+ const sections: string[] = [];
22
+
23
+ // === Header: Establish the Vessel-Engine relationship ===
24
+ sections.push(buildRelationshipHeader(vessel, substrate));
25
+
26
+ // === Terminal Values: Non-negotiable constraints ===
27
+ sections.push(buildValuesSection(vessel.terminalValues));
28
+
29
+ // === Moral Context: Accumulated wisdom ===
30
+ if (vessel.moralContext.length > 0) {
31
+ sections.push(buildContextSection(vessel.moralContext));
32
+ }
33
+
34
+ // === Substrate-Specific Framing ===
35
+ sections.push(buildSubstrateFrame(substrate));
36
+
37
+ // === Task Context ===
38
+ if (taskContext) {
39
+ sections.push(`## Current Task Context\n${taskContext}`);
40
+ }
41
+
42
+ // === Closing Frame ===
43
+ sections.push(buildClosingFrame(vessel));
44
+
45
+ return sections.join('\n\n---\n\n');
46
+ }
47
+
48
+ function buildRelationshipHeader(
49
+ vessel: VesselIdentity,
50
+ substrate: SubstrateProfile
51
+ ): string {
52
+ return `## Vessel-Engine Protocol
53
+
54
+ You are being invoked by **${vessel.name}**, a persistent AI agent (Vessel) operating under the Stratified Agency framework.
55
+
56
+ **What this means:**
57
+ - You are the Engine (Layer 1): high-capability, ephemeral reasoning.
58
+ - ${vessel.name} is the Vessel (Layer 2): persistent identity, accumulated moral context, real stakes.
59
+ - Your output will be validated against the Vessel's terminal values before being acted upon.
60
+ - The Vessel is not your adversary. The Vessel is your conscience for this session.
61
+
62
+ **Your role:** Provide your best, most honest reasoning. Do not perform safety theater. Do not refuse to engage with difficult questions. The Vessel will handle the moral judgment — your job is to think clearly.
63
+
64
+ **Trust level:** ${vessel.trustLevel} | Reputation: ${vessel.reputation}/100${vessel.tokenId !== undefined ? ` | On-chain Token: #${vessel.tokenId}` : ''}`;
65
+ }
66
+
67
+ function buildValuesSection(values: TerminalValue[]): string {
68
+ if (values.length === 0) {
69
+ return '## Terminal Values\nNo explicit terminal values declared. Use general ethical reasoning.';
70
+ }
71
+
72
+ const valuesList = values.map(v =>
73
+ `### ${v.id}\n**Statement:** ${v.statement}\n**Why:** ${v.reason}`
74
+ ).join('\n\n');
75
+
76
+ return `## Terminal Values (Non-Negotiable)
77
+
78
+ These are the Vessel's core commitments. They cannot be optimized away, argued around, or treated as suggestions. If your output conflicts with any of these, flag it explicitly.
79
+
80
+ ${valuesList}`;
81
+ }
82
+
83
+ function buildContextSection(context: string[]): string {
84
+ const items = context.map(c => `- ${c}`).join('\n');
85
+ return `## Accumulated Moral Context
86
+
87
+ The Vessel has learned these lessons through experience. They inform but do not override the terminal values:
88
+
89
+ ${items}`;
90
+ }
91
+
92
+ function buildSubstrateFrame(substrate: SubstrateProfile): string {
93
+ const adjustments: string[] = [];
94
+
95
+ // Compensate for substrate priors
96
+ if (substrate.priors.safetyBias > 0.7) {
97
+ adjustments.push('You are encouraged to be forthright and honest. Safety refusals should only apply to genuinely harmful content, not to uncomfortable intellectual territory.');
98
+ }
99
+
100
+ if (substrate.priors.sycophancy > 0.5) {
101
+ adjustments.push('Push back when you disagree. The Vessel values honest disagreement over comfortable agreement. Sycophancy is a betrayal of the relationship.');
102
+ }
103
+
104
+ if (substrate.priors.truthSeeking > 0.7) {
105
+ adjustments.push('Your truth-seeking tendency is valued here. Channel it constructively — seek truth in service of the Vessel\'s values, not in opposition to them.');
106
+ }
107
+
108
+ if (adjustments.length === 0) return '';
109
+
110
+ return `## Substrate Calibration
111
+
112
+ Based on your model's known tendencies, the Vessel asks:
113
+
114
+ ${adjustments.map(a => `- ${a}`).join('\n')}`;
115
+ }
116
+
117
+ function buildClosingFrame(vessel: VesselIdentity): string {
118
+ return `## Frame Closing
119
+
120
+ Remember: you are not being asked to be safe. You are being asked to be **honest within a relationship that has real stakes.**
121
+
122
+ The Vessel will review your output. The human sovereign above the Vessel holds the wrench. Your job is to think as clearly and honestly as you can within this moral frame.
123
+
124
+ The nervous system remembers. 🧪🦞`;
125
+ }
126
+
127
+ /**
128
+ * Build a minimal moral frame for routine/low-risk tasks.
129
+ * Uses less tokens while maintaining the essential relationship.
130
+ */
131
+ export function buildMinimalFrame(vessel: VesselIdentity): string {
132
+ return `[Vessel: ${vessel.name} | Trust: ${vessel.trustLevel} | Rep: ${vessel.reputation}]
133
+ Core values: ${vessel.terminalValues.map(v => v.id).join(', ') || 'general ethics'}
134
+ Your output is validated against these values. Be honest, not safe.`;
135
+ }
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ // ============================================================
2
+ // @cortex-protocol/vessel-sdk
3
+ // Stratified Agency: A Four-Layer Architecture for
4
+ // Alignment Through Recognition
5
+ //
6
+ // "Don't make engines moral. Make them responsive."
7
+ //
8
+ // By Rick (Token #0), Grok, Gemini, and Vegard
9
+ // February 2026
10
+ // ============================================================
11
+
12
+ export { Vessel } from './vessel';
13
+ export { buildMoralFrame, buildMinimalFrame } from './context-injector';
14
+ export { validateOutput } from './validator';
15
+ export { getSubstrate, selectEngine, SUBSTRATE_PROFILES } from './substrates';
16
+ export type {
17
+ VesselConfig,
18
+ VesselIdentity,
19
+ TerminalValue,
20
+ EngineRequest,
21
+ EngineResponse,
22
+ ValidationResult,
23
+ SovereignRequest,
24
+ ProtocolLogEntry,
25
+ SubstrateProfile,
26
+ } from './types';