agent-workflow-inspector 0.0.0-stage → 2.0.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.
- package/CHANGELOG.md +23 -0
- package/CODE_OF_CONDUCT.md +5 -0
- package/CONTRIBUTING.md +9 -0
- package/LICENSE +21 -0
- package/README.md +341 -2
- package/SECURITY.md +5 -0
- package/awi.config.example.json +39 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1338 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +256 -0
- package/dist/index.js +1159 -0
- package/dist/index.js.map +1 -0
- package/docs/architecture.md +21 -0
- package/docs/assets/architecture.svg +139 -0
- package/docs/assets/banner.svg +105 -0
- package/docs/assets/detection-patterns.svg +134 -0
- package/docs/assets/terminal-preview.svg +93 -0
- package/docs/audit.md +91 -0
- package/docs/ci-integration.md +45 -0
- package/docs/configuration.md +17 -0
- package/docs/detection-rules.md +38 -0
- package/docs/getting-started.md +70 -0
- package/docs/limitations.md +15 -0
- package/docs/releases/v1.0.0.md +32 -0
- package/docs/releasing.md +23 -0
- package/docs/report-schema.md +29 -0
- package/docs/schemas/config.schema.json +183 -0
- package/docs/schemas/report.schema.json +158 -0
- package/docs/schemas/trace.schema.json +98 -0
- package/docs/security.md +34 -0
- package/docs/trace-formats.md +41 -0
- package/docs/troubleshooting.md +12 -0
- package/docs/verification.md +44 -0
- package/examples/argument-drift.config.json +9 -0
- package/examples/healthy/basic.json +30 -0
- package/examples/opentelemetry/tools.json +210 -0
- package/examples/suspicious/argument-drift.json +62 -0
- package/examples/suspicious/cycle.json +78 -0
- package/examples/suspicious/retries.json +116 -0
- package/package.json +78 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/analysis.ts","../src/security/index.ts","../src/core/timestamps.ts","../src/adapters/index.ts","../src/config/index.ts","../src/core/fingerprinting.ts","../src/core/normalization.ts","../src/core/reporting.ts","../src/core/report-schema.ts"],"sourcesContent":["import { z } from 'zod';\nimport { timeNanoseconds } from './timestamps.js';\nimport { traceSchema } from '../adapters/index.js';\nimport { resolveConfig } from '../config/index.js';\nimport { AwiError, LIMITS, redact, validateValue } from '../security/index.js';\nimport { fingerprint, hash } from './fingerprinting.js';\nimport { normalize, sequentialRuns } from './normalization.js';\nimport type { Operation, Report, RuleId, Severity, Trace } from './models.js';\nexport const severityRank: Record<Severity, number> = {\n low: 1,\n medium: 2,\n high: 3,\n};\nconst titles: Record<RuleId, string> = {\n AWI001: 'Repeated identical tool call',\n AWI002: 'Repeated identical failing tool call',\n AWI003: 'Repeating execution cycle',\n AWI004: 'Retry storm',\n AWI005: 'Excessive execution steps or depth',\n AWI006: 'Recorded resource usage associated with suspicious execution',\n AWI007: 'Repeated failure with argument drift',\n};\nexport function analyze(\n traces: Trace[],\n configInput: unknown = {},\n showContent = false,\n): Report {\n const config = resolveConfig(configInput);\n validateValue(traces, true);\n if (!Array.isArray(traces) || traces.length > LIMITS.traces)\n throw new AwiError('Invalid or oversized trace collection');\n const analysisTraceSchema = traceSchema.extend({\n operations: z\n .array(\n traceSchema.shape.operations.element.extend({\n source: z\n .strictObject({\n format: z.enum(['awi', 'otel']),\n index: z\n .number()\n .int()\n .nonnegative()\n .max(Number.MAX_SAFE_INTEGER),\n })\n .optional(),\n }),\n )\n .max(LIMITS.spans),\n });\n const validated: Trace[] = [];\n let total = 0;\n for (const trace of traces) {\n if (!trace || !Array.isArray(trace.operations))\n throw new AwiError('Invalid canonical trace supplied to analysis');\n total += trace.operations.length;\n if (total > LIMITS.spans)\n throw new AwiError('Maximum total span count exceeded');\n const result = analysisTraceSchema.safeParse({\n ...trace,\n operations: trace.operations.map((op) =>\n op && typeof op === 'object'\n ? Object.fromEntries(\n Object.entries(op).filter(([, value]) => value !== undefined),\n )\n : op,\n ),\n });\n if (!result.success)\n throw new AwiError('Invalid canonical trace supplied to analysis');\n // Known optional fields may be explicitly undefined in native TypeScript callers.\n if (result.data.metadata === undefined) delete result.data.metadata;\n for (const op of result.data.operations) {\n if (op.error)\n op.error = Object.fromEntries(\n Object.entries(op.error).filter(([, value]) => value !== undefined),\n );\n if (op.usage)\n op.usage = Object.fromEntries(\n Object.entries(op.usage).filter(([, value]) => value !== undefined),\n );\n }\n validateValue(result.data);\n validated.push(result.data);\n }\n const report: Report = {\n version: 2,\n fingerprintVersion: 'awi-sha256-v1',\n complete: true,\n summaries: [],\n findings: [],\n warnings: [],\n };\n const grouped = new Map<string, Trace>();\n for (const t of validated) {\n const existing = grouped.get(t.traceId);\n if (existing) for (const op of t.operations) existing.operations.push(op);\n else grouped.set(t.traceId, { ...t, operations: [...t.operations] });\n }\n let capped = false;\n function add(\n ruleId: RuleId,\n traceId: string,\n ops: Operation[],\n evidence: Record<string, unknown>,\n explanation: string,\n confidence: 'high' | 'moderate' = 'moderate',\n ) {\n if (report.findings.length >= LIMITS.findings) {\n capped = true;\n return;\n }\n report.findings.push({\n ruleId,\n traceId,\n severity: ruleId === 'AWI002' || ruleId === 'AWI004' ? 'high' : 'medium',\n confidence,\n title: titles[ruleId],\n description:\n 'Heuristic finding based on recorded execution evidence; intentional behavior may match.',\n explanation,\n remediation:\n ruleId === 'AWI007'\n ? 'Review the shared error code and retry policy; consider bounded retries or escalation before varying arguments further.'\n : 'Review the referenced operations and configured policy before changing the workflow.',\n operationIds: ops.map((o) => o.id),\n evidence: {\n ...evidence,\n references: ops.map((op) => ({\n operationId: op.id,\n ...(op.source\n ? { source: { format: op.source.format, index: op.source.index } }\n : {}),\n })),\n },\n });\n }\n const orderedTraces = [...grouped.values()].sort((a, b) =>\n compare(a.traceId, b.traceId),\n );\n for (const trace of orderedTraces) {\n trace.operations.sort((a, b) => compare(a.id, b.id));\n const normalized = normalize(trace);\n report.warnings.push(...normalized.warnings);\n const starts = trace.operations.flatMap((o) =>\n o.startTime ? [timeNanoseconds(o.startTime)] : [],\n ),\n ends = trace.operations.flatMap((o) =>\n o.endTime ? [timeNanoseconds(o.endTime)] : [],\n );\n const leaves = trace.operations.filter(\n (o) => !normalized.children.has(o.id),\n );\n const usage: NonNullable<Operation['usage']> = {};\n for (const key of ['inputTokens', 'outputTokens', 'totalTokens'] as const) {\n const values = leaves.flatMap((o) =>\n o.usage?.[key] !== undefined ? [o.usage[key]!] : [],\n );\n if (values.length) {\n const total = values.reduce((a, b) => a + b, 0);\n if (!Number.isSafeInteger(total))\n throw new AwiError(\n 'Recorded token aggregate exceeds safe integer range',\n );\n usage[key] = total;\n }\n }\n report.summaries.push({\n traceId: trace.traceId,\n operations: trace.operations.length,\n toolCalls: trace.operations.filter((o) => o.type === 'tool').length,\n maxDepth: normalized.depth,\n ...(starts.length === trace.operations.length &&\n ends.length === trace.operations.length &&\n starts.length\n ? {\n durationMs:\n Number(\n ends.reduce((a, b) => (a > b ? a : b)) -\n starts.reduce((a, b) => (a < b ? a : b)),\n ) / 1000000,\n }\n : {}),\n ...(Object.keys(usage).length ? { usage } : {}),\n });\n if (\n trace.operations.some(\n (o) => o.type === 'tool' && o.arguments === undefined,\n )\n )\n report.warnings.push(\n 'Tool calls without recorded arguments excluded from identity-based rules.',\n );\n if (\n trace.operations.some((o) => o.type === 'tool' && !toolIdentityKnown(o))\n )\n report.warnings.push(\n 'Tool calls without recorded tool identity excluded from identity-based rules.',\n );\n const before = report.findings.length;\n const fps = new Map(\n trace.operations\n .filter((o) => o.type === 'tool' && toolIdentityKnown(o))\n .map((o) => [o.id, fingerprint(o, config.fingerprint.ignorePaths)]),\n );\n for (const siblings of normalized.children.values()) {\n if (\n siblings.some(\n (o) =>\n !o.startTime ||\n !o.endTime ||\n timeNanoseconds(o.endTime) <= timeNanoseconds(o.startTime),\n )\n )\n report.warnings.push(\n 'Sibling groups with missing or zero-duration timing excluded from sequence rules; recorded order does not establish sequential execution.',\n );\n const runs = sequentialRuns(siblings);\n if (\n runs.flat().length < siblings.length &&\n siblings.every(\n (o) =>\n o.startTime &&\n o.endTime &&\n timeNanoseconds(o.endTime) > timeNanoseconds(o.startTime),\n )\n )\n report.warnings.push(\n 'Overlapping sibling operations excluded from sequence rules.',\n );\n for (const run of runs) {\n if (config.rules.AWI007.enabled) {\n const policy = config.rules.AWI007;\n let failures: Operation[] = [];\n // Maximal disjoint runs avoid sliding-window duplicates; input/report budgets bound storage.\n const distinct = new Set<string>();\n let tool: string | undefined;\n let code: string | undefined;\n const flush = () => {\n if (\n failures.length >= policy.threshold &&\n distinct.size >= policy.minDistinctArguments\n )\n add(\n 'AWI007',\n trace.traceId,\n failures,\n {\n failedCalls: failures.length,\n distinctArgumentFingerprints: distinct.size,\n },\n 'Consecutive recorded failures share a tool and explicit error code while argument fingerprints vary. This does not establish intent or lack of progress.',\n );\n failures = [];\n distinct.clear();\n };\n for (const op of run) {\n if (op.type !== 'tool') continue;\n const fp = fps.get(op.id);\n if (\n op.status !== 'error' ||\n !op.error?.code?.trim() ||\n op.arguments === undefined ||\n !fp\n ) {\n flush();\n continue;\n }\n const name = op.toolName ?? op.name;\n if (name !== tool || op.error.code !== code) flush();\n tool = name;\n code = op.error.code;\n failures.push(op);\n distinct.add(fp);\n }\n flush();\n }\n // Project known tool calls; non-tool spans still constrain timing and parent context.\n let segment: Operation[] = [];\n const segments: Operation[][] = [];\n for (const op of run) {\n if (op.type !== 'tool') continue;\n if (op.arguments !== undefined && toolIdentityKnown(op))\n segment.push(op);\n else if (segment.length) {\n segments.push(segment);\n segment = [];\n }\n }\n if (segment.length) segments.push(segment);\n for (const tools of segments) {\n const groups = new Map<string, Operation[]>();\n // A bounded 100-operation window prevents distant repetitions accumulating forever.\n for (\n let base = 0;\n base < tools.length;\n base += LIMITS.repetitionWindow\n ) {\n groups.clear();\n for (const op of tools.slice(\n base,\n base + LIMITS.repetitionWindow,\n )) {\n const fp = fps.get(op.id)!;\n const group = groups.get(fp) ?? [];\n group.push(op);\n groups.set(fp, group);\n }\n for (const group of groups.values()) {\n const failures = new Map<string, Operation[]>();\n for (const op of group)\n if (\n op.status === 'error' &&\n (!!op.error?.code?.trim() || !!op.error?.message?.trim())\n ) {\n const key = hash(op.error);\n const bucket = failures.get(key) ?? [];\n bucket.push(op);\n failures.set(key, bucket);\n }\n const specific = new Set<string>();\n if (config.rules.AWI002.enabled)\n for (const bucket of failures.values())\n if (bucket.length >= config.rules.AWI002.threshold) {\n add(\n 'AWI002',\n trace.traceId,\n bucket,\n {\n occurrences: bucket.length,\n identicalArguments: true,\n equivalentFailureOutcomes: true,\n },\n 'Equivalent recorded tool calls failed with matching error evidence. This does not establish a defective retry policy.',\n 'high',\n );\n bucket.forEach((o) => specific.add(o.id));\n }\n const general = group.filter((o) => !specific.has(o.id));\n if (\n config.rules.AWI001.enabled &&\n general.length >= config.rules.AWI001.threshold\n )\n add(\n 'AWI001',\n trace.traceId,\n general,\n { occurrences: general.length, identicalArguments: true },\n 'Identical calls occur in a bounded group of sequential sibling tool calls. Polling may be intentional.',\n 'high',\n );\n if (config.rules.AWI004.enabled) {\n let cursor = 0;\n while (cursor < group.length) {\n const first = group[cursor]!;\n let end = cursor + 1;\n while (\n end < group.length &&\n group[end - 1]!.status === 'error' &&\n timeNanoseconds(group[end]!.startTime!) -\n timeNanoseconds(first.startTime!) <=\n BigInt(config.rules.AWI004.windowSeconds) * 1000000000n\n )\n end++;\n const attempts = group.slice(cursor, end);\n if (\n attempts.length >= config.rules.AWI004.threshold &&\n attempts.slice(0, -1).every((o) => o.status === 'error')\n ) {\n add(\n 'AWI004',\n trace.traceId,\n attempts,\n {\n attempts: attempts.length,\n windowSeconds: config.rules.AWI004.windowSeconds,\n priorAttemptsExplicitlyFailed: true,\n },\n 'Rapid equivalent attempts follow explicit failures; retry intent remains inferred.',\n );\n cursor = end;\n } else cursor++;\n }\n }\n }\n }\n if (config.rules.AWI003.enabled) {\n const { maxCycleLength, minRepetitions } = config.rules.AWI003;\n for (let i = 0; i < tools.length;) {\n let consumed = 0;\n for (\n let length = 2;\n length <= maxCycleLength &&\n i + length * minRepetitions <= tools.length;\n length++\n ) {\n const pattern = tools\n .slice(i, i + length)\n .map((o) => fps.get(o.id)!);\n if (new Set(pattern).size < 2) continue;\n let repeats = 1;\n while (\n i + (repeats + 1) * length <= tools.length &&\n tools\n .slice(i + repeats * length, i + (repeats + 1) * length)\n .every((o, j) => fps.get(o.id) === pattern[j])\n )\n repeats++;\n if (repeats >= minRepetitions) {\n consumed = length * repeats;\n add(\n 'AWI003',\n trace.traceId,\n tools.slice(i, i + consumed),\n { cycleLength: length, repetitions: repeats },\n 'A bounded tool fingerprint sequence repeats among timed, non-overlapping siblings. Intent and causality are unknown.',\n );\n break;\n }\n }\n i += consumed || 1;\n }\n }\n }\n }\n }\n const policy = config.rules.AWI005;\n if (\n policy.enabled &&\n (trace.operations.length > policy.maxOperations ||\n normalized.depth > policy.maxDepth)\n )\n add(\n 'AWI005',\n trace.traceId,\n [],\n {\n operations: trace.operations.length,\n maxDepth: normalized.depth,\n limits: { operations: policy.maxOperations, depth: policy.maxDepth },\n },\n 'Observed workflow size exceeds configured policy; complexity alone is not a defect.',\n 'high',\n );\n if (config.rules.AWI006.enabled) {\n const related = report.findings\n .slice(before)\n .filter((f) => f.ruleId !== 'AWI005');\n const implicated = new Set(related.flatMap((f) => f.operationIds));\n // Only implicated leaf spans: no attribution from an enclosing aggregate or unrelated model generation.\n const recorded = leaves.filter(\n (o) =>\n implicated.has(o.id) &&\n (Object.keys(o.usage ?? {}).length > 0 || o.cost),\n );\n if (recorded.length) {\n const tokens: Record<string, number> = {};\n const costs: Record<string, number> = {};\n for (const op of recorded) {\n for (const [key, n] of Object.entries(op.usage ?? {}))\n if (n !== undefined) tokens[key] = (tokens[key] ?? 0) + n;\n if (op.cost)\n costs[op.cost.currency] =\n (costs[op.cost.currency] ?? 0) + op.cost.amount;\n if (Object.values(costs).some((n) => !Number.isFinite(n)))\n throw new AwiError('Recorded cost aggregate exceeds numeric range');\n }\n add(\n 'AWI006',\n trace.traceId,\n recorded,\n {\n recordedUsage: tokens,\n recordedCosts: Object.fromEntries(\n Object.keys(costs)\n .sort(compare)\n .map((currency, index) => [\n `currency-${index + 1}`,\n costs[currency],\n ]),\n ),\n coverage:\n 'Only implicated leaf operations with recorded usage or cost',\n relatedRules: [...new Set(related.map((f) => f.ruleId))],\n },\n 'Recorded resources belong directly to operations in suspicious patterns. Association does not establish waste.',\n );\n }\n }\n }\n if (capped) {\n report.complete = false;\n report.warnings.push('Finding limit reached; report is truncated.');\n }\n report.findings.sort(\n (a, b) =>\n severityRank[b.severity] - severityRank[a.severity] ||\n compare(a.traceId, b.traceId) ||\n compare(a.ruleId, b.ruleId) ||\n compare(a.operationIds.join('\\0'), b.operationIds.join('\\0')),\n );\n // Assign report-local aliases after detection so the original IDs still drive\n // grouping, evidence association, ordering, and the finding cap.\n const traceRefs = new Map(\n orderedTraces.map((trace, index) => [\n trace.traceId,\n {\n id: `trace-${index + 1}`,\n operations: new Map(\n trace.operations.map((op, index) => [op.id, `op-${index + 1}`]),\n ),\n },\n ]),\n );\n for (const summary of report.summaries)\n summary.traceId = traceRefs.get(summary.traceId)!.id;\n for (const finding of report.findings) {\n const refs = traceRefs.get(finding.traceId)!;\n finding.traceId = refs.id;\n finding.operationIds = finding.operationIds.map((id) =>\n refs.operations.get(id)!,\n );\n for (const reference of finding.evidence.references)\n reference.operationId = refs.operations.get(reference.operationId)!;\n }\n report.warnings = [...new Set(report.warnings)].sort();\n try {\n validateValue(report);\n } catch (error) {\n if (error instanceof AwiError)\n throw new AwiError('Report exceeds resource limits');\n throw error;\n }\n if (showContent)\n report.content = orderedTraces.map((t) => ({\n traceId: traceRefs.get(t.traceId)!.id,\n recordedTraceId: t.traceId,\n operations: redact(t.operations) as unknown[],\n }));\n return report;\n}\nfunction compare(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nfunction toolIdentityKnown(op: Operation): boolean {\n return (\n op.source?.format !== 'otel' ||\n !!op.toolName ||\n op.metadata?.['awi.operation_name_recorded'] !== false\n );\n}\n","export const LIMITS = Object.freeze({\n fileBytes: 16 * 1024 * 1024,\n spans: 50000,\n traces: 50000,\n repetitionWindow: 100,\n aggregateBytes: 64 * 1024 * 1024,\n processedBytes: 64 * 1024 * 1024,\n depth: 64,\n stringLength: 65536,\n nodes: 1000000,\n files: 256,\n findings: 1000,\n});\nexport class AwiError extends Error {}\nexport function safeText(value: string): string {\n return value.replace(/[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}]/gu, '?');\n}\nexport function validateValue(\n value: unknown,\n allowUndefinedProperties = false,\n): void {\n let nodes = 0;\n let bytes = 0;\n function charge(amount: number): void {\n bytes += amount;\n if (bytes > LIMITS.processedBytes)\n throw new AwiError('JSON content exceeds processed size limit');\n }\n // Recursion cannot exceed 65 frames; descriptors are read one at a time, not materialized for an entire wide object.\n function visit(item: unknown, depth: number): void {\n if (++nodes > LIMITS.nodes || depth > LIMITS.depth)\n throw new AwiError('JSON structure exceeds resource limits');\n if (typeof item === 'string' && item.length > LIMITS.stringLength)\n throw new AwiError('JSON string exceeds resource limit');\n if (typeof item === 'number' && !Number.isFinite(item))\n throw new AwiError('Non-finite number');\n if (item !== null && typeof item === 'object') {\n charge(2);\n const array = Array.isArray(item);\n const prototype = Object.getPrototypeOf(item);\n if (\n array\n ? prototype !== Array.prototype\n : prototype !== Object.prototype && prototype !== null\n )\n throw new AwiError('Only plain JSON objects and arrays are supported');\n if (array && nodes + item.length > LIMITS.nodes)\n throw new AwiError('JSON structure exceeds resource limits');\n const keys = Reflect.ownKeys(item);\n if (nodes + keys.length - (array ? 1 : 0) > LIMITS.nodes)\n throw new AwiError('JSON structure exceeds resource limits');\n let arrayIndex = 0;\n for (const key of keys) {\n if (typeof key === 'symbol')\n throw new AwiError('Symbol keys are not JSON');\n if (array && key === 'length') continue;\n if (array && key !== String(arrayIndex++))\n throw new AwiError('Sparse or extended arrays are not JSON');\n if (key.length > LIMITS.stringLength)\n throw new AwiError('JSON key exceeds resource limit');\n if (['__proto__', 'prototype', 'constructor'].includes(key))\n throw new AwiError('Unsafe object key');\n const descriptor = Object.getOwnPropertyDescriptor(item, key)!;\n if (descriptor.get || descriptor.set)\n throw new AwiError('Accessors are not JSON');\n if (!descriptor.enumerable)\n throw new AwiError('Non-enumerable properties are not JSON');\n if (\n descriptor.value === undefined &&\n allowUndefinedProperties &&\n !array\n )\n continue;\n if (!array) charge(Buffer.byteLength(JSON.stringify(key)) + 1);\n charge(1);\n visit(descriptor.value, depth + 1);\n }\n if (array && arrayIndex !== item.length)\n throw new AwiError('Sparse or extended arrays are not JSON');\n } else if (\n !['string', 'number', 'boolean'].includes(typeof item) &&\n item !== null\n )\n throw new AwiError('Unsupported JSON value');\n else charge(Buffer.byteLength(JSON.stringify(item)));\n }\n visit(value, 0);\n}\nexport function parseJson(text: string): unknown {\n if (Buffer.byteLength(text) > LIMITS.fileBytes)\n throw new AwiError('Input exceeds maximum file size');\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n throw new AwiError('Invalid JSON');\n }\n validateValue(value);\n return value;\n}\n// Content is opt-in and still redacted by structural key, never a promise of anonymization.\nexport function redact(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(redact);\n if (value && typeof value === 'object')\n return Object.fromEntries(\n Object.entries(value).map(([k, v]) => [\n k,\n /authorization|password|secret|token|api.?key|cookie|credential|prompt|message|output|result/i.test(\n k,\n )\n ? '[REDACTED]'\n : redact(v),\n ]),\n );\n return typeof value === 'string' ? safeText(value) : value;\n}\n\nexport function validateIgnorePaths(paths: readonly string[]): void {\n if (\n !Array.isArray(paths) ||\n paths.length > 100 ||\n paths.some(\n (path) =>\n typeof path !== 'string' ||\n path.length > LIMITS.stringLength ||\n !/^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(path) ||\n path.split('.').length > LIMITS.depth ||\n path\n .split('.')\n .some((key) =>\n ['__proto__', 'constructor', 'prototype'].includes(key),\n ),\n )\n )\n throw new AwiError('Invalid fingerprint ignore paths');\n}\n","import { AwiError } from '../security/index.js';\n/** Preserve up to nine fractional digits; Date.parse alone would erase concurrency evidence. */\nexport function timeNanoseconds(value: string): bigint {\n const milliseconds = Date.parse(value);\n const fraction = /\\.(\\d+)(?:Z|[+-]\\d{2}:\\d{2})$/.exec(value)?.[1] ?? '';\n if (!Number.isFinite(milliseconds) || fraction.length > 9)\n throw new AwiError('Invalid or unsupported timestamp precision');\n return (\n BigInt(milliseconds) * 1000000n +\n BigInt(fraction.padEnd(9, '0').slice(3) || '0')\n );\n}\nexport function validTime(value: string): boolean {\n try {\n timeNanoseconds(value);\n return true;\n } catch {\n return false;\n }\n}\n","import { validTime } from '../core/timestamps.js';\nimport { z } from 'zod';\nimport { AwiError, LIMITS, validateValue } from '../security/index.js';\nimport type { Operation, Trace } from '../core/models.js';\nconst time = z.string().datetime({ offset: true }).refine(validTime);\nconst count = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);\nconst operation = z.strictObject({\n id: z.string().min(1),\n parentId: z.string().min(1).optional(),\n type: z.enum(['tool', 'agent', 'model', 'workflow', 'generic']),\n name: z.string().min(1),\n toolName: z.string().optional(),\n startTime: time.optional(),\n endTime: time.optional(),\n status: z.enum(['ok', 'error', 'unknown']).default('unknown'),\n error: z\n .strictObject({\n code: z.string().optional(),\n message: z.string().optional(),\n })\n .optional(),\n arguments: z.unknown().optional(),\n resultMetadata: z.record(z.string(), z.unknown()).optional(),\n usage: z\n .strictObject({\n inputTokens: count.optional(),\n outputTokens: count.optional(),\n totalTokens: count.optional(),\n })\n .optional(),\n cost: z\n .strictObject({\n amount: z.number().finite().nonnegative(),\n currency: z.string().regex(/^[A-Z]{3}$/),\n })\n .optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\nexport const traceSchema = z.strictObject({\n version: z.literal(1),\n traceId: z.string().min(1),\n metadata: z.record(z.string(), z.unknown()).optional(),\n operations: z.array(operation).max(LIMITS.spans),\n});\nconst record = (v: unknown): Record<string, unknown> =>\n v !== null && typeof v === 'object' && !Array.isArray(v)\n ? (v as Record<string, unknown>)\n : {};\nfunction list(v: unknown): unknown[] {\n if (!Array.isArray(v)) throw new AwiError('Invalid OTLP array');\n return v;\n}\nfunction string(v: unknown): string | undefined {\n return typeof v === 'string' ? v : undefined;\n}\nfunction anyValue(v: unknown): unknown {\n const r = record(v);\n const fields = [\n 'stringValue',\n 'boolValue',\n 'intValue',\n 'doubleValue',\n 'bytesValue',\n 'arrayValue',\n 'kvlistValue',\n ].filter((key) => key in r);\n if (!fields.length) return undefined;\n if (fields.length !== 1) throw new AwiError('Invalid OTLP AnyValue');\n const field = fields[0]!;\n const value = r[field];\n if (field === 'stringValue' || field === 'bytesValue') {\n if (typeof value !== 'string')\n throw new AwiError('Invalid OTLP string value');\n return value;\n }\n if (field === 'boolValue') {\n if (typeof value !== 'boolean')\n throw new AwiError('Invalid OTLP boolean value');\n return value;\n }\n if (field === 'doubleValue') {\n if (typeof value !== 'number' || !Number.isFinite(value))\n throw new AwiError('Invalid OTLP double value');\n return value;\n }\n if (field === 'intValue') {\n if (\n (typeof value !== 'string' || !/^[-]?\\d{1,19}$/.test(value)) &&\n (typeof value !== 'number' || !Number.isSafeInteger(value))\n )\n throw new AwiError('Invalid OTLP integer value');\n const integer = BigInt(value as string | number);\n if (integer < -9223372036854775808n || integer > 9223372036854775807n)\n throw new AwiError('OTLP integer out of range');\n const number = Number(integer);\n return Number.isSafeInteger(number) ? number : String(value);\n }\n if (value === null || typeof value !== 'object' || Array.isArray(value))\n throw new AwiError('Invalid OTLP structured value');\n if (field === 'arrayValue') {\n const items = list(record(value).values ?? []).map(anyValue);\n return items.some((item) => item === undefined) ? undefined : items;\n }\n return attributes(record(value).values, true);\n}\nfunction attributes(v: unknown): Record<string, unknown>;\nfunction attributes(\n v: unknown,\n complete: true,\n): Record<string, unknown> | undefined;\nfunction attributes(\n v: unknown,\n complete = false,\n): Record<string, unknown> | undefined {\n const entries: [string, unknown][] = [];\n for (const attribute of list(v ?? [])) {\n const raw = record(attribute);\n if (typeof raw.key !== 'string')\n throw new AwiError('Invalid OTLP attribute key');\n const value = anyValue(raw.value);\n if (value === undefined && complete) return undefined;\n entries.push([raw.key, value]);\n }\n return Object.fromEntries(\n [...new Map(entries)].filter(([, value]) => value !== undefined),\n );\n}\nfunction attributeEncoding(\n values: unknown,\n key: string,\n): Record<string, unknown> {\n const attribute = list(values ?? []).findLast(\n (item) => record(item).key === key,\n );\n return record(record(attribute).value);\n}\nfunction textAttribute(values: unknown, key: string): string | undefined {\n return string(attributeEncoding(values, key).stringValue);\n}\nfunction hasBinaryValue(value: unknown): boolean {\n return (\n value !== null &&\n typeof value === 'object' &&\n ('bytesValue' in value || Object.values(value).some(hasBinaryValue))\n );\n}\nfunction timestamp(v: unknown): string | undefined {\n if (v === undefined || v === '0' || v === 0) return undefined;\n if (\n (typeof v !== 'string' || !/^\\d{1,20}$/.test(v)) &&\n (typeof v !== 'number' || !Number.isSafeInteger(v))\n )\n throw new AwiError('Invalid OTLP nanosecond timestamp');\n const ns = BigInt(v as string | number);\n if (ns === 0n) return undefined;\n if (ns < 0n || ns > 18446744073709551615n)\n throw new AwiError('OTLP timestamp out of range');\n const iso = new Date(Number(ns / 1000000n)).toISOString();\n return ns % 1000000n === 0n\n ? iso\n : iso.replace(\n /\\.\\d{3}Z$/,\n '.' + (ns % 1000000000n).toString().padStart(9, '0') + 'Z',\n );\n}\nfunction otel(value: unknown): Trace[] {\n const grouped = new Map<string, Trace>();\n let total = 0;\n for (const resource of list(record(value).resourceSpans)) {\n const r = record(resource);\n const resourceAttributes = attributes(record(r.resource).attributes);\n for (const scope of list(r.scopeSpans ?? []))\n for (const raw of list(record(scope).spans ?? [])) {\n if (++total > LIMITS.spans)\n throw new AwiError('Maximum span count exceeded');\n const s = record(raw);\n const traceId = string(s.traceId),\n id = string(s.spanId);\n if (\n !traceId ||\n !/^[a-fA-F0-9]{32}$/.test(traceId) ||\n /^0+$/.test(traceId) ||\n !id ||\n !/^[a-fA-F0-9]{16}$/.test(id) ||\n /^0+$/.test(id)\n )\n throw new AwiError('Invalid OTLP trace/span identity');\n const a = attributes(s.attributes);\n const kind = textAttribute(s.attributes, 'gen_ai.operation.name');\n const tool =\n textAttribute(s.attributes, 'gen_ai.tool.name') ??\n textAttribute(s.attributes, 'tool.name');\n const type: Operation['type'] =\n tool || kind === 'execute_tool'\n ? 'tool'\n : kind === 'invoke_agent'\n ? 'agent'\n : [\n 'chat',\n 'generate_content',\n 'text_completion',\n 'embeddings',\n ].includes(typeof kind === 'string' ? kind : '')\n ? 'model'\n : kind === 'workflow'\n ? 'workflow'\n : 'generic';\n const statusRecord = record(s.status);\n const status = statusRecord.code;\n const events = list(s.events ?? []).map(record);\n const exception = events.find((e) => e.name === 'exception');\n if (exception) attributes(exception.attributes);\n const exceptionType = textAttribute(\n exception?.attributes,\n 'exception.type',\n ),\n exceptionMessage = textAttribute(\n exception?.attributes,\n 'exception.message',\n );\n const usage: NonNullable<Operation['usage']> = {};\n for (const [target, key] of [\n ['inputTokens', 'gen_ai.usage.input_tokens'],\n ['outputTokens', 'gen_ai.usage.output_tokens'],\n ['totalTokens', 'gen_ai.usage.total_tokens'],\n ] as const) {\n const v = a[key];\n if (typeof v === 'number' && Number.isSafeInteger(v) && v >= 0)\n usage[target] = v;\n }\n let args: unknown = hasBinaryValue(\n attributeEncoding(s.attributes, 'gen_ai.tool.call.arguments'),\n )\n ? undefined\n : a['gen_ai.tool.call.arguments'];\n if (typeof args === 'string') {\n try {\n args = JSON.parse(args);\n } catch {\n /* Preserve recorded string. */\n }\n }\n const startTime = timestamp(s.startTimeUnixNano),\n endTime = timestamp(s.endTimeUnixNano);\n const parent = string(s.parentSpanId);\n if (s.parentSpanId !== undefined && typeof s.parentSpanId !== 'string')\n throw new AwiError('Invalid OTLP parent identity');\n if (parent && !/^[a-fA-F0-9]{16}$/.test(parent))\n throw new AwiError('Invalid OTLP parent identity');\n const op: Operation = {\n id: id.toLowerCase(),\n type,\n name: string(s.name) || 'unnamed',\n status:\n status === 2 || status === 'STATUS_CODE_ERROR'\n ? 'error'\n : status === 1 || status === 'STATUS_CODE_OK'\n ? 'ok'\n : 'unknown',\n ...(parent && !/^0+$/.test(parent)\n ? { parentId: parent.toLowerCase() }\n : {}),\n ...(tool ? { toolName: tool } : {}),\n ...(startTime ? { startTime } : {}),\n ...(endTime ? { endTime } : {}),\n ...(args !== undefined ? { arguments: args } : {}),\n ...(Object.keys(usage).length ? { usage } : {}),\n ...(exception ||\n ((status === 2 || status === 'STATUS_CODE_ERROR') &&\n typeof statusRecord.message === 'string')\n ? {\n error: {\n ...(exceptionType !== undefined\n ? { code: exceptionType }\n : {}),\n ...(exceptionMessage !== undefined\n ? { message: exceptionMessage }\n : typeof statusRecord.message === 'string'\n ? { message: statusRecord.message }\n : {}),\n },\n }\n : {}),\n metadata: {\n 'awi.operation_name_recorded':\n typeof s.name === 'string' && s.name.length > 0,\n attributes: a,\n resource: resourceAttributes,\n scope: record(scope).scope ?? {},\n events: s.events ?? [],\n },\n source: { format: 'otel', index: total - 1 },\n };\n if (args !== undefined) validateValue(args);\n const key = traceId.toLowerCase();\n if (!grouped.has(key))\n grouped.set(key, { version: 1, traceId: key, operations: [] });\n grouped.get(key)!.operations.push(op);\n }\n }\n const result = [...grouped.values()];\n validateValue(result);\n return result;\n}\nexport function ingest(\n value: unknown,\n format: 'auto' | 'awi' | 'otel' = 'auto',\n): Trace[] {\n validateValue(value);\n const root = record(value);\n const isOtel = 'resourceSpans' in root;\n const isAwi = 'operations' in root || 'traces' in root;\n if (format === 'auto') {\n if (isOtel === isAwi)\n throw new AwiError('Ambiguous or unsupported trace format');\n format = isOtel ? 'otel' : 'awi';\n }\n if (format === 'otel') return otel(value);\n if (format !== 'awi') throw new AwiError('Unsupported input format');\n const collection =\n 'traces' in root\n ? z\n .strictObject({\n version: z.literal(1),\n traces: z.array(traceSchema).max(LIMITS.traces),\n })\n .safeParse(value)\n : null;\n if (collection) {\n if (!collection.success) throw new AwiError('Invalid AWI trace collection');\n if (\n collection.data.traces.reduce((n, t) => n + t.operations.length, 0) >\n LIMITS.spans\n )\n throw new AwiError('Maximum total span count exceeded');\n return collection.data.traces.map((t) => ({\n ...t,\n operations: t.operations.map((op, index) => ({\n ...op,\n source: { format: 'awi', index },\n })),\n }));\n }\n const parsed = traceSchema.safeParse(value);\n if (!parsed.success)\n throw new AwiError(\n 'Invalid AWI trace schema: ' +\n parsed.error.issues\n .map((i) => i.path.join('.') + ': ' + i.code)\n .join('; '),\n );\n return [\n {\n ...parsed.data,\n operations: parsed.data.operations.map((op, index) => ({\n ...op,\n source: { format: 'awi', index },\n })),\n },\n ];\n}\n","import { z } from 'zod';\nimport { AwiError, LIMITS, validateValue } from '../security/index.js';\nconst positive = z.number().int().min(1);\nconst repeat = (threshold: number) =>\n z.strictObject({\n enabled: z.boolean().default(true),\n threshold: positive.min(2).max(LIMITS.repetitionWindow).default(threshold),\n });\nexport const configSchema = z.strictObject({\n version: z.literal(1).default(1),\n rules: z\n .strictObject({\n AWI001: repeat(4).default({ enabled: true, threshold: 4 }),\n AWI002: repeat(3).default({ enabled: true, threshold: 3 }),\n AWI003: z\n .strictObject({\n enabled: z.boolean().default(true),\n minRepetitions: positive.min(2).max(100).default(3),\n maxCycleLength: positive.min(2).max(16).default(6),\n })\n .default({ enabled: true, minRepetitions: 3, maxCycleLength: 6 }),\n AWI004: z\n .strictObject({\n enabled: z.boolean().default(true),\n threshold: positive.min(2).max(LIMITS.repetitionWindow).default(5),\n windowSeconds: positive.max(3600).default(30),\n })\n .default({ enabled: true, threshold: 5, windowSeconds: 30 }),\n AWI005: z\n .strictObject({\n enabled: z.boolean().default(true),\n maxOperations: positive.max(50000).default(100),\n maxDepth: positive.max(1000).default(20),\n })\n .default({ enabled: true, maxOperations: 100, maxDepth: 20 }),\n AWI006: z\n .strictObject({ enabled: z.boolean().default(true) })\n .default({ enabled: true }),\n AWI007: z\n .strictObject({\n enabled: z.boolean().default(false),\n threshold: positive.min(4).max(LIMITS.repetitionWindow).default(4),\n minDistinctArguments: positive\n .min(3)\n .max(LIMITS.repetitionWindow)\n .default(3),\n })\n .default({ enabled: false, threshold: 4, minDistinctArguments: 3 }),\n })\n .default({\n AWI001: { enabled: true, threshold: 4 },\n AWI002: { enabled: true, threshold: 3 },\n AWI003: { enabled: true, minRepetitions: 3, maxCycleLength: 6 },\n AWI004: { enabled: true, threshold: 5, windowSeconds: 30 },\n AWI005: { enabled: true, maxOperations: 100, maxDepth: 20 },\n AWI006: { enabled: true },\n AWI007: { enabled: false, threshold: 4, minDistinctArguments: 3 },\n }),\n fingerprint: z\n .strictObject({\n ignorePaths: z\n .array(\n z\n .string()\n .regex(/^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$/)\n .refine(\n (p) =>\n p.split('.').length <= LIMITS.depth &&\n !p\n .split('.')\n .some((k) =>\n ['__proto__', 'constructor', 'prototype'].includes(k),\n ),\n ),\n )\n .max(100)\n .default([]),\n })\n .default({ ignorePaths: [] }),\n});\nexport type Config = z.infer<typeof configSchema>;\nexport function resolveConfig(value: unknown = {}): Config {\n validateValue(value);\n const parsed = configSchema.safeParse(value);\n if (!parsed.success)\n throw new AwiError(\n 'Invalid configuration: ' +\n parsed.error.issues\n .map((i) => i.path.join('.') + ': ' + i.code)\n .join('; '),\n );\n return parsed.data;\n}\n","import { createHash } from 'node:crypto';\nimport {\n validateValue,\n validateIgnorePaths,\n AwiError,\n} from '../security/index.js';\nimport type { Operation } from './models.js';\ninterface IgnoreNode {\n ignored: boolean;\n children: Map<string, IgnoreNode>;\n}\nconst ignoredPathCache = new WeakMap<\n readonly string[],\n { snapshot: string[]; root: IgnoreNode | undefined }\n>();\nfunction compileIgnorePaths(paths: readonly string[]): IgnoreNode | undefined {\n if (\n !Array.isArray(paths) ||\n Object.getPrototypeOf(paths) !== Array.prototype ||\n paths.length > 100\n )\n throw new AwiError('Invalid fingerprint ignore paths');\n const values: string[] = [];\n if (Reflect.ownKeys(paths).length !== paths.length + 1)\n throw new AwiError('Invalid fingerprint ignore paths');\n for (let index = 0; index < paths.length; index++) {\n const descriptor = Object.getOwnPropertyDescriptor(paths, String(index));\n if (\n !descriptor ||\n descriptor.get ||\n descriptor.set ||\n typeof descriptor.value !== 'string'\n )\n throw new AwiError('Invalid fingerprint ignore paths');\n values.push(descriptor.value);\n }\n const cached = ignoredPathCache.get(paths);\n if (\n cached &&\n cached.snapshot.length === values.length &&\n values.every((value, index) => value === cached.snapshot[index])\n )\n return cached.root;\n validateIgnorePaths(values);\n const root: IgnoreNode | undefined = values.length\n ? { ignored: false, children: new Map() }\n : undefined;\n for (const path of values) {\n let node = root!;\n for (const part of path.split('.')) {\n let child = node.children.get(part);\n if (!child) {\n child = { ignored: false, children: new Map() };\n node.children.set(part, child);\n }\n node = child;\n }\n node.ignored = true;\n }\n ignoredPathCache.set(paths, { snapshot: values, root });\n return root;\n}\nexport function canonicalize(\n value: unknown,\n ignorePaths: string[] = [],\n): string {\n validateValue(value);\n const root = compileIgnorePaths(ignorePaths);\n function encode(v: unknown, node: IgnoreNode | undefined): string {\n if (Array.isArray(v))\n return '[' + v.map((item) => encode(item, undefined)).join(',') + ']';\n if (v && typeof v === 'object')\n return (\n '{' +\n Object.keys(v)\n .sort()\n .filter((key) => !node?.children.get(key)?.ignored)\n .map(\n (key) =>\n JSON.stringify(key) +\n ':' +\n encode(\n (v as Record<string, unknown>)[key],\n node?.children.get(key),\n ),\n )\n .join(',') +\n '}'\n );\n return JSON.stringify(v);\n }\n return encode(value, root);\n}\nexport function hash(value: unknown): string {\n return createHash('sha256').update(canonicalize(value)).digest('hex');\n}\nexport function fingerprint(op: Operation, ignorePaths: string[] = []): string {\n validateValue(op, true);\n compileIgnorePaths(ignorePaths);\n const tool = op.toolName ?? op.name;\n if (\n typeof tool !== 'string' ||\n !['tool', 'agent', 'model', 'workflow', 'generic'].includes(op.type)\n )\n throw new AwiError('Invalid operation fingerprint identity');\n // Preserve the exact v1 byte contract without treating generated canonical JSON as an input string field.\n const digest = createHash('sha256').update('{\"arguments\":');\n if (op.arguments === undefined) digest.update('{\"present\":false}');\n else\n digest\n .update('{\"present\":true,\"value\":')\n .update(JSON.stringify(canonicalize(op.arguments, ignorePaths)))\n .update('}');\n return digest\n .update(',\"tool\":')\n .update(JSON.stringify(tool))\n .update(',\"type\":')\n .update(JSON.stringify(op.type))\n .update(',\"version\":\"awi-sha256-v1\"}')\n .digest('hex');\n}\n","import { timeNanoseconds } from './timestamps.js';\nimport type { Operation, Trace } from './models.js';\nimport { AwiError, LIMITS } from '../security/index.js';\nexport interface Normalized {\n trace: Trace;\n depth: number;\n warnings: string[];\n children: Map<string, Operation[]>;\n}\nexport function normalize(trace: Trace): Normalized {\n if (trace.operations.length > LIMITS.spans)\n throw new AwiError('Maximum span count exceeded');\n const ids = new Map<string, Operation>();\n const warnings: string[] = [];\n for (const op of trace.operations) {\n if (ids.has(op.id)) throw new AwiError('Duplicate operation identity');\n ids.set(op.id, op);\n if (\n op.startTime &&\n op.endTime &&\n timeNanoseconds(op.endTime) < timeNanoseconds(op.startTime)\n )\n throw new AwiError('End timestamp precedes start timestamp');\n }\n const depths = new Map<string, number>();\n let depth = 0;\n for (const op of trace.operations) {\n const path: Operation[] = [];\n const seen = new Set<string>();\n let current: Operation | undefined = op;\n while (current && !depths.has(current.id)) {\n if (seen.has(current.id)) throw new AwiError('Cyclic parent references');\n seen.add(current.id);\n path.push(current);\n const parent: Operation | undefined = current.parentId\n ? ids.get(current.parentId)\n : undefined;\n if (current.parentId && !parent)\n warnings.push(\n 'Missing parent reference; observed depth is a lower bound.',\n );\n current = parent;\n }\n let d = current ? depths.get(current.id)! : 0;\n for (const item of path.reverse()) {\n depths.set(item.id, ++d);\n depth = Math.max(depth, d);\n }\n }\n const children = new Map<string, Operation[]>();\n for (const op of trace.operations) {\n const key = op.parentId ?? '';\n const group = children.get(key) ?? [];\n group.push(op);\n children.set(key, group);\n }\n // Preserve recorded order; only fully timed, non-overlapping sibling operations establish sequence evidence.\n return { trace, depth, warnings: [...new Set(warnings)], children };\n}\nexport function sequentialRuns(ops: Operation[]): Operation[][] {\n if (\n ops.some(\n (o) =>\n !o.startTime ||\n !o.endTime ||\n timeNanoseconds(o.endTime) <= timeNanoseconds(o.startTime),\n )\n )\n return [];\n const timed = ops\n .map((op) => ({\n op,\n start: timeNanoseconds(op.startTime!),\n end: timeNanoseconds(op.endTime!),\n }))\n .sort((a, b) =>\n a.start < b.start\n ? -1\n : a.start > b.start\n ? 1\n : a.op.id < b.op.id\n ? -1\n : a.op.id > b.op.id\n ? 1\n : 0,\n );\n const runs: Operation[][] = [];\n let run: typeof timed = [];\n let overlapEnd: bigint | undefined;\n for (const item of timed) {\n if (overlapEnd !== undefined) {\n if (item.start < overlapEnd) {\n if (item.end > overlapEnd) overlapEnd = item.end;\n continue;\n }\n overlapEnd = undefined;\n }\n const previous = run.at(-1);\n if (previous && item.start < previous.end) {\n run.pop();\n if (run.length) runs.push(run.map((value) => value.op));\n run = [];\n overlapEnd = previous.end > item.end ? previous.end : item.end;\n continue;\n }\n run.push(item);\n }\n if (run.length) runs.push(run.map((value) => value.op));\n return runs;\n}\n","import { safeText } from '../security/index.js';\nimport type { Report } from './models.js';\nexport function humanReport(\n report: Report,\n options: { color?: boolean } = {},\n): string {\n const paint = (text: string, severity: string) =>\n options.color\n ? `\\u001b[${severity === 'high' ? 31 : 33}m${text}\\u001b[0m`\n : text;\n const lines = [\n 'Agent Workflow Inspector — Find loops, retries, and wasted work in AI agent traces.',\n ];\n for (const t of report.summaries)\n lines.push(\n `Trace ${safeText(t.traceId)}: ${t.operations} operations, ${t.toolCalls} tool calls, depth ${t.maxDepth}; duration ${t.durationMs === undefined ? 'unknown' : t.durationMs + ' ms'}; recorded leaf usage ${t.usage ? JSON.stringify(t.usage) : 'unknown'}`,\n );\n for (const f of report.findings)\n lines.push(\n `\\n${paint('[' + f.severity.toUpperCase() + ']', f.severity)} ${safeText(f.ruleId)} ${safeText(f.title)} (${safeText(f.confidence)} evidence)`,\n ` Trace: ${safeText(f.traceId)}; operations: ${f.operationIds.map(safeText).join(', ') || 'trace-wide'}`,\n ` ${safeText(f.explanation)}`,\n ` Evidence: ${safeText(JSON.stringify(f.evidence))}`,\n ` Remediation: ${safeText(f.remediation)}`,\n );\n for (const warning of report.warnings)\n lines.push('Warning: ' + safeText(warning));\n if (report.content)\n lines.push(\n 'Content (opt-in, key-based redaction): ' +\n safeText(JSON.stringify(report.content)),\n );\n lines.push(\n `\\n${report.findings.length} findings; analysis ${report.complete ? 'complete' : 'INCOMPLETE'}.`,\n );\n return lines.join('\\n') + '\\n';\n}\n\nexport function jsonReport(report: Report): string {\n return (\n JSON.stringify(report, null, 2).replace(\n /[\\u007f-\\u009f\\p{Cf}\\p{Zl}\\p{Zp}]/gu,\n (value) =>\n value\n .split('')\n .map((c) => '\\\\u' + c.charCodeAt(0).toString(16).padStart(4, '0'))\n .join(''),\n ) + '\\n'\n );\n}\n","import { z } from 'zod';\nconst usage = z.strictObject({\n inputTokens: z\n .number()\n .int()\n .nonnegative()\n .max(Number.MAX_SAFE_INTEGER)\n .optional(),\n outputTokens: z\n .number()\n .int()\n .nonnegative()\n .max(Number.MAX_SAFE_INTEGER)\n .optional(),\n totalTokens: z\n .number()\n .int()\n .nonnegative()\n .max(Number.MAX_SAFE_INTEGER)\n .optional(),\n});\nconst traceId = z.string().regex(/^trace-[1-9][0-9]*$/);\nconst operationId = z.string().regex(/^op-[1-9][0-9]*$/);\nexport const reportSchema = z.strictObject({\n version: z.literal(2),\n fingerprintVersion: z.literal('awi-sha256-v1'),\n complete: z.boolean(),\n summaries: z.array(\n z.strictObject({\n traceId,\n operations: z.number().int().nonnegative(),\n toolCalls: z.number().int().nonnegative(),\n maxDepth: z.number().int().nonnegative(),\n durationMs: z.number().nonnegative().optional(),\n usage: usage.optional(),\n }),\n ),\n findings: z.array(\n z.strictObject({\n ruleId: z.enum([\n 'AWI001',\n 'AWI002',\n 'AWI003',\n 'AWI004',\n 'AWI005',\n 'AWI006',\n 'AWI007',\n ]),\n severity: z.enum(['low', 'medium', 'high']),\n confidence: z.enum(['high', 'moderate']),\n title: z.string(),\n description: z.string(),\n explanation: z.string(),\n remediation: z.string(),\n traceId,\n operationIds: z.array(operationId),\n evidence: z.looseObject({\n references: z.array(\n z.strictObject({\n operationId,\n source: z\n .strictObject({\n format: z.enum(['awi', 'otel']),\n index: z\n .number()\n .int()\n .nonnegative()\n .max(Number.MAX_SAFE_INTEGER),\n })\n .optional(),\n }),\n ),\n }),\n }),\n ),\n warnings: z.array(z.string()),\n content: z\n .array(\n z.strictObject({\n traceId,\n recordedTraceId: z.string(),\n operations: z.array(z.unknown()),\n }),\n )\n .optional(),\n});\n"],"mappings":"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","names":["z","traceId","usage","key","z","z","z","traceId","usage","total","policy","index","z"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
Adapters validate canonical JSON and OTLP. Core normalization validates identity/graph structure and derives observed depth. Fingerprinting implements call identity. Analysis runs bounded rules and associates recorded leaf resources. Reporting renders safe terminal text. Config owns strict non-executable settings; security owns parsing, structural limits, sanitization and opt-in redaction. CLI alone accesses files and process streams. src/index.ts is the ESM library entry.
|
|
4
|
+
|
|
5
|
+
The supplied brief was truncated in its redaction section. The present requirements were implemented; no unseen requirements are claimed.
|
|
6
|
+
|
|
7
|
+
## Dependencies and support
|
|
8
|
+
|
|
9
|
+
Commander handles help/option validation and Zod validates configuration and trace/report schemas. Native Node APIs provide crypto, files and JSON. There are no HTTP clients or framework SDKs. TypeScript 5.9 stays within typescript-eslint's peer range. ESLint 10, Vitest 5, Prettier 3 and tsup 9 are pinned or constrained and locked. Their engines determine the supported Node floor. pnpm-workspace.yaml allows only esbuild's required install script.
|
|
10
|
+
|
|
11
|
+
Supported Node lines: 22.18+ on 22.x, 24.11+ on 24.x, and 26.x. CI is configured for Windows/macOS/Linux and Node 22/24/26. Future majors require CI evidence before release compatibility claims. Builds target Node 22. CommonJS/browser builds are outside V1.
|
|
12
|
+
|
|
13
|
+
## Algorithms
|
|
14
|
+
|
|
15
|
+
SHA-256 fingerprints sort JSON keys. Ignored fields use bounded compiled path maps instead of serializing ancestor paths per key. Rules group by trace and parent. Only fully timed, positive-duration, non-overlapping siblings form sequences. Untimed/zero-duration siblings disable sequence scanning for the group. Every member of an overlap cluster is excluded; known model/generic spans are projected out of tool sequences; calls without arguments or recorded identity interrupt them. Neither parent relationships nor timestamps establish causality.
|
|
16
|
+
|
|
17
|
+
Repetition uses disjoint 100-call windows. Cycles are at most 16 calls long (default 6), with O(n × maximum cycle length squared) bounded scanning. Depth uses iterative memoized traversal and cycle detection. JSON recursion is bounded at depth 64. Findings, resource IDs and warnings sort deterministically; CLI sorts files. Nanosecond arithmetic preserves concurrency evidence. Reports omit clocks, absolute paths, raw errors and hashes.
|
|
18
|
+
|
|
19
|
+
## Release checks
|
|
20
|
+
|
|
21
|
+
Run `pnpm check`, `pnpm format:check`, `pnpm schemas`, `pnpm audit`, and `pnpm smoke:package`. Regenerate schemas when contracts change. The smoke check packs the current version, installs the archive in a clean OS temporary consumer outside the repository, and checks tarball permissions and contents, shipped examples, CLI options, ESM exports, and strict consumer TypeScript declarations. No release credentials are needed locally. CI runs checks only.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 940 380" width="100%" height="100%">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" stop-color="#0d1117"/>
|
|
5
|
+
<stop offset="100%" stop-color="#161b22"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="cardGrad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
8
|
+
<stop offset="0%" stop-color="#1f2937"/>
|
|
9
|
+
<stop offset="100%" stop-color="#111827"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
<linearGradient id="coreGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
12
|
+
<stop offset="0%" stop-color="#1c2d42"/>
|
|
13
|
+
<stop offset="100%" stop-color="#131e2e"/>
|
|
14
|
+
</linearGradient>
|
|
15
|
+
<linearGradient id="accentBlue" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
16
|
+
<stop offset="0%" stop-color="#38bdf8"/>
|
|
17
|
+
<stop offset="100%" stop-color="#818cf8"/>
|
|
18
|
+
</linearGradient>
|
|
19
|
+
<linearGradient id="accentGreen" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
20
|
+
<stop offset="0%" stop-color="#34d399"/>
|
|
21
|
+
<stop offset="100%" stop-color="#10b981"/>
|
|
22
|
+
</linearGradient>
|
|
23
|
+
<linearGradient id="accentAmber" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
24
|
+
<stop offset="0%" stop-color="#fbbf24"/>
|
|
25
|
+
<stop offset="100%" stop-color="#f59e0b"/>
|
|
26
|
+
</linearGradient>
|
|
27
|
+
<filter id="cardShadow" x="-5%" y="-5%" width="110%" height="110%">
|
|
28
|
+
<feDropShadow dx="0" dy="6" stdDeviation="10" flood-color="#000000" flood-opacity="0.4"/>
|
|
29
|
+
</filter>
|
|
30
|
+
</defs>
|
|
31
|
+
|
|
32
|
+
<style>
|
|
33
|
+
.font-sans { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; }
|
|
34
|
+
.font-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
|
|
35
|
+
</style>
|
|
36
|
+
|
|
37
|
+
<!-- Background Canvas -->
|
|
38
|
+
<rect width="940" height="380" rx="14" fill="url(#bgGrad)" stroke="#30363d" stroke-width="1"/>
|
|
39
|
+
|
|
40
|
+
<!-- Section 1: Ingestion & Formats -->
|
|
41
|
+
<g transform="translate(30, 40)" filter="url(#cardShadow)">
|
|
42
|
+
<rect width="250" height="300" rx="10" fill="url(#cardGrad1)" stroke="#374151" stroke-width="1.5"/>
|
|
43
|
+
<rect x="0" y="0" width="250" height="42" rx="10" fill="#1f2937"/>
|
|
44
|
+
<rect x="0" y="32" width="250" height="10" fill="#1f2937"/>
|
|
45
|
+
<line x1="0" y1="42" x2="250" y2="42" stroke="#374151" stroke-width="1"/>
|
|
46
|
+
<text x="125" y="27" text-anchor="middle" class="font-sans" font-size="14" font-weight="700" fill="#93c5fd">1. TRACE INGESTION</text>
|
|
47
|
+
|
|
48
|
+
<!-- Source Items -->
|
|
49
|
+
<g transform="translate(16, 60)">
|
|
50
|
+
<!-- AI Agents Box -->
|
|
51
|
+
<rect width="218" height="56" rx="6" fill="#111827" stroke="#374151" stroke-width="1"/>
|
|
52
|
+
<text x="14" y="25" class="font-sans" font-size="12" font-weight="600" fill="#e5e7eb">Agent Frameworks</text>
|
|
53
|
+
<text x="14" y="43" class="font-mono" font-size="11" fill="#9ca3af">LangChain, CrewAI, AutoGen, SDKs</text>
|
|
54
|
+
|
|
55
|
+
<!-- Trace Format Box -->
|
|
56
|
+
<rect y="68" width="218" height="74" rx="6" fill="#111827" stroke="#374151" stroke-width="1"/>
|
|
57
|
+
<text x="14" y="90" class="font-sans" font-size="12" font-weight="600" fill="#38bdf8">Supported Trace Formats</text>
|
|
58
|
+
<text x="14" y="110" class="font-mono" font-size="11" fill="#cbd5e1">• Canonical AWI JSON (v1)</text>
|
|
59
|
+
<text x="14" y="128" class="font-mono" font-size="11" fill="#cbd5e1">• OpenTelemetry OTLP JSON</text>
|
|
60
|
+
|
|
61
|
+
<!-- Privacy Callout -->
|
|
62
|
+
<rect y="154" width="218" height="60" rx="6" fill="#1e1e2d" stroke="#6366f1" stroke-width="1"/>
|
|
63
|
+
<text x="14" y="176" class="font-sans" font-size="11" font-weight="700" fill="#a5b4fc">🔒 Privacy By Default</text>
|
|
64
|
+
<text x="14" y="196" class="font-sans" font-size="10.5" fill="#94a3b8">Payloads & raw arguments redacted.</text>
|
|
65
|
+
</g>
|
|
66
|
+
</g>
|
|
67
|
+
|
|
68
|
+
<!-- Flow Arrow 1 -> 2 -->
|
|
69
|
+
<path d="M 288 190 L 322 190" stroke="#60a5fa" stroke-width="2.5" stroke-dasharray="4 3"/>
|
|
70
|
+
<polygon points="328,190 320,186 320,194" fill="#60a5fa"/>
|
|
71
|
+
|
|
72
|
+
<!-- Section 2: Core Inspection Engine -->
|
|
73
|
+
<g transform="translate(336, 30)" filter="url(#cardShadow)">
|
|
74
|
+
<rect width="290" height="320" rx="10" fill="url(#coreGrad)" stroke="#38bdf8" stroke-width="1.8"/>
|
|
75
|
+
<rect x="0" y="0" width="290" height="44" rx="10" fill="#0f2136"/>
|
|
76
|
+
<rect x="0" y="34" width="290" height="10" fill="#0f2136"/>
|
|
77
|
+
<line x1="0" y1="44" x2="290" y2="44" stroke="#1e3a5f" stroke-width="1"/>
|
|
78
|
+
<text x="145" y="28" text-anchor="middle" class="font-sans" font-size="14" font-weight="700" fill="#38bdf8">2. LOCAL-FIRST LINTER</text>
|
|
79
|
+
|
|
80
|
+
<!-- Sub-boxes for Rules -->
|
|
81
|
+
<g transform="translate(16, 56)">
|
|
82
|
+
<text x="6" y="14" class="font-sans" font-size="11" font-weight="700" fill="#94a3b8">DETERMINISTIC HEURISTICS (NO LLM)</text>
|
|
83
|
+
|
|
84
|
+
<rect y="24" width="258" height="34" rx="5" fill="#0b1726" stroke="#1e3a5f"/>
|
|
85
|
+
<text x="12" y="45" class="font-mono" font-size="11" font-weight="600" fill="#f87171">AWI001 & AWI002</text>
|
|
86
|
+
<text x="130" y="45" class="font-sans" font-size="11" fill="#94a3b8">Duplicate / Failing Calls</text>
|
|
87
|
+
|
|
88
|
+
<rect y="64" width="258" height="34" rx="5" fill="#0b1726" stroke="#1e3a5f"/>
|
|
89
|
+
<text x="12" y="85" class="font-mono" font-size="11" font-weight="600" fill="#fbbf24">AWI003</text>
|
|
90
|
+
<text x="78" y="85" class="font-sans" font-size="11" fill="#94a3b8">Execution Cycles (A-B-C-A)</text>
|
|
91
|
+
|
|
92
|
+
<rect y="104" width="258" height="34" rx="5" fill="#0b1726" stroke="#1e3a5f"/>
|
|
93
|
+
<text x="12" y="125" class="font-mono" font-size="11" font-weight="600" fill="#f87171">AWI004</text>
|
|
94
|
+
<text x="78" y="125" class="font-sans" font-size="11" fill="#94a3b8">Rapid Retry Storms</text>
|
|
95
|
+
|
|
96
|
+
<rect y="144" width="258" height="34" rx="5" fill="#0b1726" stroke="#1e3a5f"/>
|
|
97
|
+
<text x="12" y="165" class="font-mono" font-size="11" font-weight="600" fill="#fbbf24">AWI005</text>
|
|
98
|
+
<text x="78" y="165" class="font-sans" font-size="11" fill="#94a3b8">Runaway Depth & Ops</text>
|
|
99
|
+
|
|
100
|
+
<rect y="184" width="258" height="34" rx="5" fill="#0b1726" stroke="#1e3a5f"/>
|
|
101
|
+
<text x="12" y="205" class="font-mono" font-size="11" font-weight="600" fill="#34d399">AWI006</text>
|
|
102
|
+
<text x="78" y="205" class="font-sans" font-size="11" fill="#94a3b8">Associated Token & Cost Waste</text>
|
|
103
|
+
|
|
104
|
+
<rect y="226" width="258" height="24" rx="4" fill="#032541"/>
|
|
105
|
+
<text x="129" y="242" text-anchor="middle" class="font-sans" font-size="10.5" font-weight="600" fill="#38bdf8">⚡ 100% Offline • Zero Network Calls</text>
|
|
106
|
+
</g>
|
|
107
|
+
</g>
|
|
108
|
+
|
|
109
|
+
<!-- Flow Arrow 2 -> 3 -->
|
|
110
|
+
<path d="M 634 190 L 668 190" stroke="#60a5fa" stroke-width="2.5" stroke-dasharray="4 3"/>
|
|
111
|
+
<polygon points="674,190 666,186 666,194" fill="#60a5fa"/>
|
|
112
|
+
|
|
113
|
+
<!-- Section 3: Actionable Outputs -->
|
|
114
|
+
<g transform="translate(682, 40)" filter="url(#cardShadow)">
|
|
115
|
+
<rect width="230" height="300" rx="10" fill="url(#cardGrad1)" stroke="#374151" stroke-width="1.5"/>
|
|
116
|
+
<rect x="0" y="0" width="230" height="42" rx="10" fill="#1f2937"/>
|
|
117
|
+
<rect x="0" y="32" width="230" height="10" fill="#1f2937"/>
|
|
118
|
+
<line x1="0" y1="42" x2="230" y2="42" stroke="#374151" stroke-width="1"/>
|
|
119
|
+
<text x="115" y="27" text-anchor="middle" class="font-sans" font-size="14" font-weight="700" fill="#34d399">3. OUTPUTS & CI</text>
|
|
120
|
+
|
|
121
|
+
<g transform="translate(14, 56)">
|
|
122
|
+
<!-- Terminal Output -->
|
|
123
|
+
<rect width="202" height="64" rx="6" fill="#111827" stroke="#374151" stroke-width="1"/>
|
|
124
|
+
<text x="12" y="24" class="font-sans" font-size="12" font-weight="700" fill="#f3f4f6">🖥️ Human Terminal</text>
|
|
125
|
+
<text x="12" y="44" class="font-sans" font-size="10.5" fill="#9ca3af">Formatted findings, severity, evidence & operations list.</text>
|
|
126
|
+
|
|
127
|
+
<!-- JSON Report -->
|
|
128
|
+
<rect y="74" width="202" height="64" rx="6" fill="#111827" stroke="#374151" stroke-width="1"/>
|
|
129
|
+
<text x="12" y="98" class="font-sans" font-size="12" font-weight="700" fill="#f3f4f6">📄 JSON Report File</text>
|
|
130
|
+
<text x="12" y="118" class="font-sans" font-size="10.5" fill="#9ca3af">Schema-validated JSON for test suites & automation.</text>
|
|
131
|
+
|
|
132
|
+
<!-- CI Pipeline Gating -->
|
|
133
|
+
<rect y="148" width="202" height="74" rx="6" fill="#111827" stroke="#10b981" stroke-width="1"/>
|
|
134
|
+
<text x="12" y="172" class="font-sans" font-size="12" font-weight="700" fill="#34d399">🚦 CI/CD Gatekeeper</text>
|
|
135
|
+
<text x="12" y="192" class="font-mono" font-size="10.5" fill="#e5e7eb">Exit 0: Below threshold</text>
|
|
136
|
+
<text x="12" y="208" class="font-mono" font-size="10.5" fill="#fca5a5">Exit 2: Threshold failed</text>
|
|
137
|
+
</g>
|
|
138
|
+
</g>
|
|
139
|
+
</svg>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 280" width="100%" height="100%">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bannerBg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" stop-color="#090d13"/>
|
|
5
|
+
<stop offset="50%" stop-color="#0d1117"/>
|
|
6
|
+
<stop offset="100%" stop-color="#161b22"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<linearGradient id="textGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
9
|
+
<stop offset="0%" stop-color="#38bdf8"/>
|
|
10
|
+
<stop offset="50%" stop-color="#818cf8"/>
|
|
11
|
+
<stop offset="100%" stop-color="#c084fc"/>
|
|
12
|
+
</linearGradient>
|
|
13
|
+
<linearGradient id="shieldGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
14
|
+
<stop offset="0%" stop-color="#38bdf8"/>
|
|
15
|
+
<stop offset="100%" stop-color="#4f46e5"/>
|
|
16
|
+
</linearGradient>
|
|
17
|
+
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
|
18
|
+
<feGaussianBlur stdDeviation="6" result="blur" />
|
|
19
|
+
<feComposite in="SourceGraphic" in2="blur" operator="over" />
|
|
20
|
+
</filter>
|
|
21
|
+
</defs>
|
|
22
|
+
|
|
23
|
+
<style>
|
|
24
|
+
.font-sans { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
|
|
25
|
+
.font-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
|
|
26
|
+
</style>
|
|
27
|
+
|
|
28
|
+
<!-- Background -->
|
|
29
|
+
<rect width="1000" height="280" rx="16" fill="url(#bannerBg)" stroke="#30363d" stroke-width="1.5"/>
|
|
30
|
+
|
|
31
|
+
<!-- Subtle Grid Pattern in Background -->
|
|
32
|
+
<g opacity="0.08" stroke="#ffffff" stroke-width="1">
|
|
33
|
+
<line x1="50" y1="0" x2="50" y2="280"/>
|
|
34
|
+
<line x1="150" y1="0" x2="150" y2="280"/>
|
|
35
|
+
<line x1="250" y1="0" x2="250" y2="280"/>
|
|
36
|
+
<line x1="350" y1="0" x2="350" y2="280"/>
|
|
37
|
+
<line x1="450" y1="0" x2="450" y2="280"/>
|
|
38
|
+
<line x1="550" y1="0" x2="550" y2="280"/>
|
|
39
|
+
<line x1="650" y1="0" x2="650" y2="280"/>
|
|
40
|
+
<line x1="750" y1="0" x2="750" y2="280"/>
|
|
41
|
+
<line x1="850" y1="0" x2="850" y2="280"/>
|
|
42
|
+
<line x1="950" y1="0" x2="950" y2="280"/>
|
|
43
|
+
<line x1="0" y1="70" x2="1000" y2="70"/>
|
|
44
|
+
<line x1="0" y1="140" x2="1000" y2="140"/>
|
|
45
|
+
<line x1="0" y1="210" x2="1000" y2="210"/>
|
|
46
|
+
</g>
|
|
47
|
+
|
|
48
|
+
<!-- Left Icon / Badge -->
|
|
49
|
+
<g transform="translate(60, 65)">
|
|
50
|
+
<!-- Outer Glow & Shield Frame -->
|
|
51
|
+
<rect width="140" height="140" rx="28" fill="#131d2e" stroke="#1e3a5f" stroke-width="2"/>
|
|
52
|
+
<rect x="12" y="12" width="116" height="116" rx="20" fill="url(#shieldGrad)" opacity="0.15"/>
|
|
53
|
+
|
|
54
|
+
<!-- Inspector Graphic: Magnifying Glass + Trace Loop Node -->
|
|
55
|
+
<!-- Loop Nodes -->
|
|
56
|
+
<circle cx="50" cy="52" r="8" fill="#38bdf8"/>
|
|
57
|
+
<circle cx="90" cy="52" r="8" fill="#818cf8"/>
|
|
58
|
+
<circle cx="70" cy="88" r="8" fill="#f43f5e"/>
|
|
59
|
+
|
|
60
|
+
<!-- Connecting path -->
|
|
61
|
+
<path d="M 58 52 L 82 52" stroke="#38bdf8" stroke-width="2.5"/>
|
|
62
|
+
<path d="M 88 58 L 74 82" stroke="#818cf8" stroke-width="2.5"/>
|
|
63
|
+
<path d="M 66 82 L 52 58" stroke="#f43f5e" stroke-width="2.5" stroke-dasharray="3 2"/>
|
|
64
|
+
|
|
65
|
+
<!-- Warning badge on loop -->
|
|
66
|
+
<circle cx="70" cy="88" r="14" fill="none" stroke="#f43f5e" stroke-width="2" opacity="0.8"/>
|
|
67
|
+
<text x="70" y="122" text-anchor="middle" class="font-mono" font-size="11" font-weight="700" fill="#38bdf8">AWI v1.0</text>
|
|
68
|
+
</g>
|
|
69
|
+
|
|
70
|
+
<!-- Main Titles -->
|
|
71
|
+
<g transform="translate(235, 78)">
|
|
72
|
+
<text x="0" y="32" class="font-sans" font-size="34" font-weight="800" fill="url(#textGrad)" letter-spacing="-0.5">Agent Workflow Inspector</text>
|
|
73
|
+
|
|
74
|
+
<text x="0" y="66" class="font-sans" font-size="17" font-weight="500" fill="#e6edf3">
|
|
75
|
+
Local-first, deterministic diagnostics & linter for AI agent execution traces
|
|
76
|
+
</text>
|
|
77
|
+
|
|
78
|
+
<text x="0" y="94" class="font-sans" font-size="13.5" fill="#8b949e">
|
|
79
|
+
Detect suspicious retry storms, loops, cycles, and token waste • Zero LLM • Zero telemetry • Offline & CI-ready
|
|
80
|
+
</text>
|
|
81
|
+
|
|
82
|
+
<!-- Badges Row Inside Banner -->
|
|
83
|
+
<g transform="translate(0, 114)">
|
|
84
|
+
<rect width="112" height="24" rx="12" fill="#1f2937" stroke="#374151"/>
|
|
85
|
+
<circle cx="12" cy="12" r="4" fill="#38bdf8"/>
|
|
86
|
+
<text x="22" y="16" class="font-sans" font-size="11" font-weight="600" fill="#f3f4f6">100% Local</text>
|
|
87
|
+
|
|
88
|
+
<rect x="122" width="138" height="24" rx="12" fill="#1f2937" stroke="#374151"/>
|
|
89
|
+
<circle cx="134" cy="12" r="4" fill="#34d399"/>
|
|
90
|
+
<text x="144" y="16" class="font-sans" font-size="11" font-weight="600" fill="#f3f4f6">Deterministic</text>
|
|
91
|
+
|
|
92
|
+
<rect x="270" width="150" height="24" rx="12" fill="#1f2937" stroke="#374151"/>
|
|
93
|
+
<circle cx="282" cy="12" r="4" fill="#fbbf24"/>
|
|
94
|
+
<text x="292" y="16" class="font-sans" font-size="11" font-weight="600" fill="#f3f4f6">OTLP & AWI JSON</text>
|
|
95
|
+
|
|
96
|
+
<rect x="430" width="128" height="24" rx="12" fill="#1f2937" stroke="#374151"/>
|
|
97
|
+
<circle cx="442" cy="12" r="4" fill="#a855f7"/>
|
|
98
|
+
<text x="452" y="16" class="font-sans" font-size="11" font-weight="600" fill="#f3f4f6">CLI & TS API</text>
|
|
99
|
+
|
|
100
|
+
<rect x="568" width="118" height="24" rx="12" fill="#1f2937" stroke="#374151"/>
|
|
101
|
+
<circle cx="580" cy="12" r="4" fill="#f43f5e"/>
|
|
102
|
+
<text x="590" y="16" class="font-sans" font-size="11" font-weight="600" fill="#f3f4f6">CI Gatekeeper</text>
|
|
103
|
+
</g>
|
|
104
|
+
</g>
|
|
105
|
+
</svg>
|