aga_trigger_measurement
Measure content integrity and generate cryptographic receipts for verification and tamper-evident logging within the AGA-mcp-server portal.
Instructions
Trigger a measurement of subject content and generate a receipt.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| subject_content | No | Raw content to measure | |
| subject_bytes_hash | No | Pre-computed SHA-256 bytes hash (64 hex) | |
| subject_metadata_hash | No | Pre-computed SHA-256 metadata hash (64 hex) | |
| measurement_type | No | ||
| subject_metadata | No |
Implementation Reference
- src/tools/trigger-measurement.ts:15-90 (handler)The handler function for the aga_trigger_measurement tool. It performs measurements, detects drift, triggers enforcement, generates a receipt, and stores interaction data.
export async function handleTriggerMeasurement(args: TriggerMeasurementArgs, ctx: ServerContext) { if (!ctx.portal.artifact) return ctx.error('No artifact loaded.'); if (ctx.portal.state === 'TERMINATED' || ctx.portal.state === 'SAFE_STATE') { return ctx.error(`Portal is ${ctx.portal.state}. Artifact revoked or expired.`); } let match: boolean; let action: EnforcementAction | null = null; let driftDesc: string | null = null; let currentHash = 'UNAVAILABLE'; if (args.subject_bytes_hash) { // Pre-computed hash mode const bMatch = args.subject_bytes_hash === ctx.portal.artifact.subject_identifier.bytes_hash; const mMatch = !args.subject_metadata_hash || args.subject_metadata_hash === ctx.portal.artifact.subject_identifier.metadata_hash; match = bMatch && mMatch; currentHash = args.subject_bytes_hash; if (!match && ctx.portal.state === 'ACTIVE_MONITORING') { (ctx.portal as any).state = 'DRIFT_DETECTED'; } } else if (args.subject_content) { const meta = args.subject_metadata ?? {}; const result = ctx.portal.measure(new TextEncoder().encode(args.subject_content), meta); match = result.match; currentHash = result.currentBytesHash || 'UNAVAILABLE'; if (!result.ttl_ok) { driftDesc = 'TTL expired'; action = 'TERMINATE'; match = false; } else if (result.revoked) { driftDesc = 'Artifact revoked'; action = 'TERMINATE'; match = false; } } else { return ctx.error('Provide either subject_content or subject_bytes_hash'); } if (!match && !action) { driftDesc = 'Subject modified - hash mismatch'; action = ctx.portal.artifact.enforcement_parameters.enforcement_triggers[0] ?? 'ALERT_ONLY'; if (ctx.portal.state === 'DRIFT_DETECTED') { ctx.portal.enforce(action); } if (action === 'QUARANTINE') ctx.quarantine = initQuarantine(); } ctx.measurementCount++; const artRef = hashArtifact(ctx.portal.artifact); const mType = args.measurement_type ?? ctx.portal.artifact.enforcement_parameters.measurement_types[0] ?? 'FILE_SYSTEM_STATE'; const receipt = generateReceipt({ subjectId: ctx.portal.artifact.subject_identifier, artifactRef: artRef, currentHash, sealedHash: ctx.portal.artifact.subject_identifier.bytes_hash, driftDetected: !match, driftDescription: driftDesc, action, measurementType: mType, seq: ctx.portal.sequenceCounter + 1, prevLeaf: ctx.portal.lastLeafHash, portalKP: ctx.portalKP, }); await ctx.storage.storeReceipt(receipt); await ctx.appendToChain('INTERACTION_RECEIPT', { receipt_id: receipt.receipt_id, drift_detected: !match, enforcement_action: action, measurement_type: mType, }); return ctx.json({ success: true, match, drift_detected: !match, enforcement_action: action, portal_state: ctx.portal.state, receipt_id: receipt.receipt_id, measurement_type: mType, measurement_count: ctx.measurementCount, }); } - Definition of the arguments (schema) accepted by the trigger measurement tool.
export interface TriggerMeasurementArgs { subject_content?: string; subject_bytes_hash?: string; subject_metadata_hash?: string; measurement_type?: string; subject_metadata?: Record<string, string>; } - src/server.ts:173-184 (registration)Tool registration for 'aga_trigger_measurement' in the main server file using governedTool, mapping inputs to the handler and defining the schema using Zod.
// 8. aga_trigger_measurement (governed) governedTool('aga_trigger_measurement', 'Trigger a measurement of subject content and generate a receipt.', { subject_content: z.string().optional().describe('Raw content to measure'), subject_bytes_hash: z.string().optional().describe('Pre-computed SHA-256 bytes hash (64 hex)'), subject_metadata_hash: z.string().optional().describe('Pre-computed SHA-256 metadata hash (64 hex)'), measurement_type: z.string().optional(), subject_metadata: z.record(z.string()).optional(), }, async (args) => handleTriggerMeasurement(args, ctx), );