Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/agents/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ export class ValidatorAgent {
return { valid: false, reason: "Invalid sequential ID" };
}

// Type: valid entity types (single letters)
const validTypes = ["P", "L", "T", "E"];
// @canon: chittycanon://gov/governance#core-types
const validTypes = ["P", "L", "T", "E", "A"];
if (!validTypes.includes(type)) {
return { valid: false, reason: "Invalid entity type" };
}
Expand Down
6 changes: 4 additions & 2 deletions src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ export class ChittyAPI {
method: 'GET',
handler: async (request, url) => {
const purpose = url.searchParams.get('for') || 'general';
return await this.pipeline.process(request, purpose);
const entityTypeOverride = url.searchParams.get('entity_type') || null;
return await this.pipeline.process(request, purpose, entityTypeOverride);
}
},

Expand Down Expand Up @@ -244,7 +245,8 @@ export class ChittyAPI {
'P': 'Person',
'L': 'Location',
'T': 'Thing',
'E': 'Event'
'E': 'Event',
'A': 'Authority'
}
},
YM: {
Expand Down
4 changes: 3 additions & 1 deletion src/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ export const ChittyConfig = {
'8': 'International Waters',
'9': 'Digital/Virtual'
},
// @canon: chittycanon://gov/governance#core-types
entityTypes: {
'P': 'Person',
'L': 'Location',
'T': 'Thing',
'E': 'Event'
'E': 'Event',
'A': 'Authority'
},
trustLevels: {
'0': 'L0 - Unverified',
Expand Down
15 changes: 13 additions & 2 deletions src/pipeline/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ export class ChittyPipeline {
* @param {string} purpose - Purpose of ID request (e.g., 'work-item', 'document')
* @returns {Promise<PipelineResult>}
*/
async process(request, purpose = "general") {
async process(request, purpose = "general", entityTypeOverride = null) {
const context = {
request,
purpose,
entityTypeOverride,
timestamp: new Date().toISOString(),
stages: {},
};
Expand Down Expand Up @@ -306,10 +307,16 @@ class GenerationStage {

try {
// Prepare parameters for id.chitty.cc service
// Explicit entity_type override takes precedence over purpose-based mapping
const validEntityTypes = ["P", "L", "T", "E", "A"];
const override = context.entityTypeOverride;
const entityType = (override && validEntityTypes.includes(override.toUpperCase()))
? override.toUpperCase()
: this.mapPurposeToEntityType(purpose);
const params = {
region: this.determineRegion(user),
jurisdiction: this.determineJurisdiction(user),
entityType: this.mapPurposeToEntityType(purpose),
entityType,
trustLevel: trustLevel.toString(),
metadata: {
userId: user.id,
Expand Down Expand Up @@ -399,12 +406,16 @@ class GenerationStage {
return jurisdictionMap[user.country] || "INT";
}

// @canon: chittycanon://gov/governance#core-types
mapPurposeToEntityType(purpose) {
const mapping = {
person: "P",
location: "L",
thing: "T",
event: "E",
authority: "A",
context: "P", // Contexts are Person (P, Synthetic) — actors with agency
agent: "P", // Agents are Person (P, Synthetic) — actors with agency
"work-item": "T",
document: "T",
asset: "T",
Expand Down
5 changes: 3 additions & 2 deletions src/services/vrf-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,9 @@ export class VRFGenerator {
throw new Error("Namespace must be exactly 3 letters");
}

if (!["P", "L", "T", "E"].includes(entityType)) {
throw new Error("Entity type must be P, L, T, or E");
// @canon: chittycanon://gov/governance#core-types
if (!["P", "L", "T", "E", "A"].includes(entityType)) {
throw new Error("Entity type must be P, L, T, E, or A");
}

if (!region || region < "1" || region > "9") {
Expand Down
12 changes: 9 additions & 3 deletions worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,17 @@ function getErrorFromId(chittyId) {
};
}

// Purpose-to-entity-type mapping for non-type values passed via ?for=
// @canon: chittycanon://gov/governance#core-types
const PURPOSE_ENTITY_MAP = { context: 'person', claude: 'person', 'work-item': 'thing', document: 'thing', general: 'thing' };

// Direct ChittyID generation handler - delegates to ChittyMint with fallback
async function handleDirectChittyIdGeneration(url, env, request) {
const rawType = (url.searchParams.get('type') || url.searchParams.get('for') || 'thing').toLowerCase();
// Accept both code-form (P/L/T/E/A) and word-form (person/place/thing/event/authority)
const entityTypeParam = CODE_TO_WORD[rawType] || rawType;
// Priority: explicit entity_type > type > for (with purpose mapping) > default 'thing'
const explicitType = url.searchParams.get('entity_type');
const rawType = (explicitType || url.searchParams.get('type') || url.searchParams.get('for') || 'thing').toLowerCase();
// Accept code-form (P/L/T/E/A), word-form (person/place/thing/event/authority), or purpose (context/claude)
const entityTypeParam = CODE_TO_WORD[rawType] || PURPOSE_ENTITY_MAP[rawType] || rawType;

// Extract auth token if present (forward to ChittyMint)
const authHeader = request?.headers?.get('Authorization');
Expand Down
Loading