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
10 changes: 10 additions & 0 deletions .changeset/biome-lint-cleanup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@wasmagent/aep": patch
"@wasmagent/compliance": patch
"@wasmagent/core": patch
"@wasmagent/mcp-posture": patch
"@wasmagent/react": patch
---

Internal: apply Biome import-ordering and formatting fixes to source files.
No public API, type, or runtime behavior change.
45 changes: 30 additions & 15 deletions packages/aep/src/evidenceCompressor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createHash } from "node:crypto";
import { canonicalBytes } from "./canonical.js";
import type { AEPRecord, ActionEvidence } from "./types.js";
import type { ActionEvidence, AEPRecord } from "./types.js";

/**
* evidenceCompressor.ts — auditable summaries and cryptographic fingerprints
Expand Down Expand Up @@ -215,12 +215,15 @@ export class EvidenceCompressor {
const lastRecord = records[records.length - 1]!;

// --- tool stats ---
const toolMap = new Map<string, {
total_calls: number;
state_changing_calls: number;
side_effect_distribution: Record<string, number>;
outcome_distribution: Record<string, number>;
}>();
const toolMap = new Map<
string,
{
total_calls: number;
state_changing_calls: number;
side_effect_distribution: Record<string, number>;
outcome_distribution: Record<string, number>;
}
>();

let totalActions = 0;
let startedAtMs = firstRecord.created_at_ms;
Expand Down Expand Up @@ -273,10 +276,18 @@ export class EvidenceCompressor {
// aggregate capability decisions
for (const dec of record.capability_decisions) {
switch (dec.decision) {
case "allow": decAllow++; break;
case "deny": decDeny++; break;
case "ask_user": decAsk++; break;
case "dry_run": decDry++; break;
case "allow":
decAllow++;
break;
case "deny":
decDeny++;
break;
case "ask_user":
decAsk++;
break;
case "dry_run":
decDry++;
break;
}
}

Expand Down Expand Up @@ -320,11 +331,15 @@ export class EvidenceCompressor {
};

const budgetTotals: CompressedBudgetTotals = {};
if (tokensSpent !== undefined) (budgetTotals as Record<string, number>).tokens_spent = tokensSpent;
if (toolCallsSpent !== undefined) (budgetTotals as Record<string, number>).tool_calls_spent = toolCallsSpent;
if (tokensSpent !== undefined)
(budgetTotals as Record<string, number>).tokens_spent = tokensSpent;
if (toolCallsSpent !== undefined)
(budgetTotals as Record<string, number>).tool_calls_spent = toolCallsSpent;
if (riskSpent !== undefined) (budgetTotals as Record<string, number>).risk_spent = riskSpent;
if (retriesSpent !== undefined) (budgetTotals as Record<string, number>).retries_spent = retriesSpent;
if (humanApprovalsSpent !== undefined) (budgetTotals as Record<string, number>).human_approvals_spent = humanApprovalsSpent;
if (retriesSpent !== undefined)
(budgetTotals as Record<string, number>).retries_spent = retriesSpent;
if (humanApprovalsSpent !== undefined)
(budgetTotals as Record<string, number>).human_approvals_spent = humanApprovalsSpent;

const summary: CompressedChainSummary = {
chainFingerprint,
Expand Down
30 changes: 24 additions & 6 deletions packages/aep/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ import { createLocalSignerFromSeed } from "./signer.js";
import { LocalTimestamper } from "./timestamperLocal.js";
import type { AEPRecord, SideEffectClass } from "./types.js";
import { AEPRecordSchema } from "./types.js";
import { isStateChangingTool, STATE_CHANGING_PATTERNS, registerStatefulVerbs, clearStatefulVerbs } from "./utils.js";
import {
clearStatefulVerbs,
isStateChangingTool,
registerStatefulVerbs,
STATE_CHANGING_PATTERNS,
} from "./utils.js";
import { verifyAEPChain, verifyAEPRecord } from "./verify.js";

// Deterministic seed for tests (32 bytes as hex)
Expand Down Expand Up @@ -540,7 +545,6 @@ describe("isStateChangingTool (#23)", () => {
});
});


describe("registerStatefulVerbs (#304)", () => {
afterEach(() => {
clearStatefulVerbs();
Expand Down Expand Up @@ -5263,8 +5267,12 @@ describe("EvidenceCompressor (#272)", () => {
const r2 = emitter2.build(1_700_000_000_001);

const summary = compressor.compress([r1, r2], { nowMs: 0 });
expect(EvidenceCompressor.verifyChainFingerprint([r1, r2], summary.chainFingerprint)).toBe(true);
expect(EvidenceCompressor.verifyChainFingerprint([r2, r1], summary.chainFingerprint)).toBe(false);
expect(EvidenceCompressor.verifyChainFingerprint([r1, r2], summary.chainFingerprint)).toBe(
true
);
expect(EvidenceCompressor.verifyChainFingerprint([r2, r1], summary.chainFingerprint)).toBe(
false
);
});

it("verifyChainFingerprint returns false for empty records", () => {
Expand Down Expand Up @@ -5296,8 +5304,18 @@ describe("EvidenceCompressor (#272)", () => {
const compressor = new EvidenceCompressor();
const signer = createLocalSignerFromSeed(TEST_SEED, TEST_KEY_ID);
const emitter = new AEPEmitter({ run_id: "run-h1", signer });
emitter.addCapabilityDecision({ capability: "fs:write", subject: "a", resource: "/", decision: "allow" });
emitter.addCapabilityDecision({ capability: "fs:read", subject: "a", resource: "/", decision: "deny" });
emitter.addCapabilityDecision({
capability: "fs:write",
subject: "a",
resource: "/",
decision: "allow",
});
emitter.addCapabilityDecision({
capability: "fs:read",
subject: "a",
resource: "/",
decision: "deny",
});
const r = emitter.build(1_700_000_000_000);
const summary = compressor.compress([r], { nowMs: 0 });
expect(summary.decisionStats.total).toBe(2);
Expand Down
3 changes: 1 addition & 2 deletions packages/aep/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from "./canonical.js";
export * from "./dsse.js";
export * from "./emitter.js";
export * from "./evidenceCompressor.js";
export * from "./evidenceMirror.js";
export * from "./evidenceMonitor.js";
export * from "./evidencePublisher.js";
Expand All @@ -16,5 +17,3 @@ export * from "./timestamperLocal.js";
export * from "./types.js";
export * from "./utils.js";
export * from "./verify.js";

export * from "./evidenceCompressor.js";
4 changes: 1 addition & 3 deletions packages/aep/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ export function isStateChangingTool(tool: ToolDescriptor): boolean {
if (STATE_CHANGING_PATTERNS.some((p) => p.test(text))) return true;
if (customStatefulVerbs.size > 0) {
for (const verb of customStatefulVerbs) {
const pattern = new RegExp(
`(?:^|[\\s_-])${escapeRegex(verb)}(?:$|[\\s_-])`
);
const pattern = new RegExp(`(?:^|[\\s_-])${escapeRegex(verb)}(?:$|[\\s_-])`);
if (pattern.test(text)) return true;
}
}
Expand Down
9 changes: 4 additions & 5 deletions packages/compliance/src/verifier/ComplianceVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,8 @@
* `TaskSpec.priority_hierarchy` + `ConstraintIR.priority`.
*/

import {
DeterministicVerifier,
VerificationPipeline,
} from "@wasmagent/core";
import type { Criterion, WorkspaceReader } from "@wasmagent/core";
import { DeterministicVerifier, VerificationPipeline } from "@wasmagent/core";
import type { ConstraintIR, TaskSpec } from "../ir/ConstraintIR.js";
import {
type ConstraintViolation,
Expand Down Expand Up @@ -204,7 +201,9 @@ export class ComplianceVerifier {
const pipeline = new VerificationPipeline({ ws, verifiers: [new DeterministicVerifier()] });
const verifier = new ComplianceVerifier({
pipeline,
...(opts.evidenceSpanHooks !== undefined ? { evidenceSpanHooks: opts.evidenceSpanHooks } : {}),
...(opts.evidenceSpanHooks !== undefined
? { evidenceSpanHooks: opts.evidenceSpanHooks }
: {}),
});
return verifier.verify(spec, ...(opts.stage !== undefined ? [{ stage: opts.stage }] : []));
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,12 @@ export {
hybridRetriever,
InMemoryStructuredKv,
InMemoryVectorStore,
injectHistoryIntoAssembler,
KvBackendVectorStore,
LazyObservationHandle,
MapKvBackend,
MemoryBlockSet,
MessageAssembler,
injectHistoryIntoAssembler,
makeRetrievalTool,
ObservationalMemory,
StructuredMemory,
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/memory/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { Bm25Indexer, tokenize as bm25Tokenize } from "./Bm25Indexer.js";
export { FileStructuredKv } from "./fileKv.js";
export type { HybridRetrieverOpts } from "./HybridRetriever.js";
export { HybridRetriever, hybridRetriever } from "./HybridRetriever.js";
export { injectHistoryIntoAssembler } from "./injectHistory.js";
export { LazyObservationHandle } from "./LazyObservationHandle.js";
export type { MemoryBlock } from "./MemoryBlocks.js";
export { coreMemoryTools, MemoryBlockSet } from "./MemoryBlocks.js";
Expand Down Expand Up @@ -37,5 +38,3 @@ export {
InMemoryStructuredKv,
StructuredMemory,
} from "./StructuredMemory.js";

export { injectHistoryIntoAssembler } from "./injectHistory.js";
4 changes: 2 additions & 2 deletions packages/core/src/memory/injectHistory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
*/

import { describe, expect, test } from "bun:test";
import { MessageAssembler } from "./MessageAssembler.js";
import { injectHistoryIntoAssembler } from "./injectHistory.js";
import type { ModelMessage } from "../models/types.js";
import { injectHistoryIntoAssembler } from "./injectHistory.js";
import { MessageAssembler } from "./MessageAssembler.js";

function makeAssembler(): MessageAssembler {
return new MessageAssembler({
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/memory/injectHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
* ```
*/

import type { MessageAssembler } from "./MessageAssembler.js";
import type { ModelMessage } from "../models/types.js";
import type { MessageAssembler } from "./MessageAssembler.js";

/**
* Inject an array of prior `ModelMessage` turns into `assembler` so that
Expand Down
Loading
Loading