tests/contract/agent-ergonomics.ts
Rama main · réplica de lectura del repositorio original.
import assert from "node:assert/strict";
import { CASES } from "./cases";
function expectError(res: { status: number; body: any }, status: number, code: string) {
assert.equal(res.status, status, JSON.stringify(res.body));
assert.equal(res.body.error.code, code);
}
CASES.push({
name: "agent ergonomics explain fences, fill one project, and reassign private principals",
async run(fx) {
const owner = await fx.provision({ scopes: ["*"], principalId: "agent_owner" });
const shared = await fx.call("POST", "/v1/projects/resolve", {
key: owner.key,
body: { reference: "owner/shared", create: true, default_visibility: "organization" },
});
assert.equal(shared.status, 201, JSON.stringify(shared.body));
const profile = await fx.call("POST", "/v1/projects/resolve", {
key: owner.key,
body: { reference: "owner/profile-agent", create: true },
});
assert.equal(profile.status, 201, JSON.stringify(profile.body));
const sharedId = shared.body.data.project_id as string;
const profileId = profile.body.data.project_id as string;
const many = await fx.call("POST", "/v1/keys", {
key: owner.key,
body: {
label: "two projects",
principal_id: "agent_many",
max_trust: "asserted",
scopes: ["observations:write", "claims:write", "context:compile", "mcp:call", "projects:resolve"],
write_subjects: ["team:shared", "team:profile:agent_a"],
write_projects: [sharedId, profileId],
},
});
assert.equal(many.status, 201, JSON.stringify(many.body));
const manyKey = many.body.data.api_key as string;
const missingProject = await fx.call("POST", "/v1/observations", {
key: manyKey,
body: {
subject_id: "team:profile:agent_a",
kind: "user_statement",
content: "A fenced write must name its project.",
source: { type: "chat", ref: "note-1" },
visibility: "organization",
},
});
expectError(missingProject, 403, "FORBIDDEN");
assert.equal(missingProject.body.meta.reason, "project_fence");
assert.equal(missingProject.body.meta.failed, "project_id");
assert.equal(missingProject.body.meta.got, null);
assert.deepEqual(missingProject.body.meta.allowed_projects, [profileId, sharedId].sort());
assert.match(missingProject.body.error.message, /project_id is required/);
const wrongSubject = await fx.call("POST", "/v1/observations", {
key: manyKey,
body: {
subject_id: "team:profile:agent_b",
project_id: sharedId,
kind: "user_statement",
content: "A fenced write must name an allowed subject.",
source: { type: "chat", ref: "note-2" },
visibility: "organization",
},
});
expectError(wrongSubject, 403, "FORBIDDEN");
assert.equal(wrongSubject.body.meta.failed, "subject_id");
assert.equal(wrongSubject.body.meta.reason, "subject_fence");
const trust = await fx.call("POST", "/v1/observations", {
key: manyKey,
body: {
subject_id: "team:shared",
project_id: sharedId,
kind: "user_statement",
content: "Verified trust is above this key.",
source: { type: "chat", ref: "note-3" },
trust: "verified",
visibility: "organization",
},
});
expectError(trust, 403, "FORBIDDEN");
assert.equal(trust.body.meta.reason, "trust_ceiling");
assert.deepEqual(trust.body.meta.allowed_trust, ["unverified", "asserted"]);
const missing = await fx.call("POST", "/v1/context/compile", { key: manyKey, body: {} });
expectError(missing, 400, "VALIDATION_ERROR");
const missingFields = (missing.body.meta.fields as Array<{ field: string }>).map((field) => field.field);
assert.deepEqual(missingFields, ["subject_id", "task", "max_tokens"]);
const aliased = await fx.call("POST", "/v1/context/compile", {
key: manyKey,
body: { subject: "team:shared", query: "shared notes", max_tokens: 800 },
});
assert.equal(aliased.status, 200, JSON.stringify(aliased.body));
assert.deepEqual(aliased.body.meta.deprecated_fields, ["subject", "query"]);
assert.match(aliased.body.data.scope.hint, /not project-scoped/);
assert.match(aliased.body.data.scope.hint, new RegExp(sharedId));
assert.equal(aliased.body.meta.degraded.reason.length > 0, true);
assert.match(aliased.body.meta.consistent_as_of, /^\d{4}-/);
assert.equal(aliased.body.meta.read_your_writes, "sql_fts");
const one = await fx.call("POST", "/v1/keys", {
key: owner.key,
body: {
label: "one project",
principal_id: "agent_a",
max_trust: "asserted",
scopes: ["observations:write", "claims:write", "context:compile", "mcp:call", "projects:resolve"],
write_subjects: ["team:profile:agent_a"],
write_projects: [profileId],
},
});
assert.equal(one.status, 201, JSON.stringify(one.body));
const oneKey = one.body.data.api_key as string;
const remembered = await fx.call("POST", "/v1/observations", {
key: oneKey,
body: {
subject_id: "team:profile:agent_a",
kind: "user_statement",
content: "One fenced project is filled in.",
source: { type: "chat", ref: "note-4" },
visibility: "organization",
consolidate: true,
tz: "Asia/Bangkok",
},
});
assert.equal(remembered.status, 201, JSON.stringify(remembered.body));
assert.equal(remembered.body.data.project_id, profileId);
assert.equal(remembered.body.data.project_id_source, "key_fence");
assert.match(remembered.body.data.ingested_at_local, /\+07:00$/);
assert.match(remembered.body.data.ingested_at, /Z$/);
const compiled = await fx.call("POST", "/v1/context/compile", {
key: oneKey,
body: {
subject_id: "team:profile:agent_a",
task: "filled project",
max_tokens: 800,
tz: "Asia/Bangkok",
},
});
assert.equal(compiled.status, 200, JSON.stringify(compiled.body));
assert.equal(compiled.body.data.scope.project_id, profileId);
assert.equal(compiled.body.data.scope.project_id_source, "key_fence");
assert.equal(compiled.body.data.scope.project_mode, "project");
assert.match(compiled.body.data.scope.as_of_local, /\+07:00$/);
assert.equal(compiled.body.data.budget.unconsolidated_observations, 0);
const tight = await fx.call("POST", "/v1/context/compile", {
key: oneKey,
body: { subject_id: "team:profile:agent_a", task: "filled project", max_tokens: 128 },
});
assert.equal(tight.status, 200, JSON.stringify(tight.body));
if (tight.body.data.items.length === 0 && tight.body.data.budget.budget_exhausted === true)
assert.match(tight.body.data.budget.hint, /increase max_tokens/);
const pending = await fx.call("POST", "/v1/observations", {
key: oneKey,
body: {
subject_id: "team:profile:agent_a",
kind: "user_statement",
content: "This note still needs a claim.",
source: { type: "chat", ref: "note-5" },
visibility: "organization",
},
});
assert.equal(pending.status, 201, JSON.stringify(pending.body));
const empty = await fx.call("POST", "/v1/context/compile", {
key: oneKey,
body: { subject_id: "team:profile:agent_a", task: "pending note", max_tokens: 800 },
});
assert.equal(empty.status, 200, JSON.stringify(empty.body));
assert.equal(empty.body.data.budget.unconsolidated_observations, 1);
assert.deepEqual(empty.body.data.budget.unconsolidated_observation_ids, [pending.body.data.observation_id]);
assert.match(empty.body.data.budget.hint, /titen_consolidate/);
const archival = await fx.call("POST", "/v1/observations", {
key: oneKey,
body: {
subject_id: "team:profile:agent_a",
kind: "imported_source",
content: "An archival note dated before standard time.",
source: { type: "test", ref: "archive:1900" },
visibility: "organization",
occurred_at: "1900-01-01T00:00:00Z",
tz: "Asia/Jakarta",
},
});
assert.equal(archival.status, 201, JSON.stringify(archival.body));
assert.equal(archival.body.data.occurred_at_local, "1900-01-01T07:07:00.000+07:07");
assert.equal(Date.parse(archival.body.data.occurred_at_local), Date.parse("1900-01-01T00:00:00Z"));
const subjectLookup = await fx.call("POST", "/v1/projects/resolve", {
key: oneKey,
body: { reference: "team:profile:agent_a" },
});
assert.equal(subjectLookup.status, 200, JSON.stringify(subjectLookup.body));
assert.equal(subjectLookup.body.data.matched, "subject");
assert.deepEqual(subjectLookup.body.data.projects, [{
project_id: profileId,
reference: "owner/profile-agent",
default_visibility: "private",
}]);
const suggestion = await fx.call("POST", "/v1/projects/resolve", {
key: oneKey,
body: { reference: "owner/profile-agen" },
});
expectError(suggestion, 404, "NOT_FOUND");
assert.deepEqual(suggestion.body.meta.suggestions, [{
project_id: profileId,
reference: "owner/profile-agent",
default_visibility: "private",
}]);
const who = await fx.call("GET", "/v1/principal", { key: oneKey });
assert.equal(who.status, 200, JSON.stringify(who.body));
assert.equal(who.body.data.principal_id, "agent_a");
assert.deepEqual(who.body.data.allowed_trust, ["unverified", "asserted"]);
assert.equal(JSON.stringify(who.body).includes(oneKey), false);
assert.equal(who.body.data.projects[0].reference, "owner/profile-agent");
const mcpWho = await fx.call("POST", "/mcp", {
key: oneKey,
body: { jsonrpc: "2.0", id: 1, method: "tools/call", params: { name: "titen_whoami", arguments: {} } },
});
assert.equal(mcpWho.status, 200, JSON.stringify(mcpWho.body));
const whoText = mcpWho.body.result.content[0].text as string;
assert.equal(whoText.includes(oneKey), false);
assert.match(whoText, /agent_a/);
assert.equal(mcpWho.body.result.isError, undefined);
const writer = await fx.provision({
orgId: owner.orgId,
principalId: "agent_old",
scopes: ["observations:write", "context:compile"],
});
const kept = await fx.call("POST", "/v1/observations", {
key: writer.key,
body: {
subject_id: "team:shared",
kind: "decision",
content: "Private note that should follow the principal.",
source: { type: "chat", ref: "note-6" },
visibility: "private",
},
});
assert.equal(kept.status, 201, JSON.stringify(kept.body));
const reader = await fx.provision({
orgId: owner.orgId,
principalId: "agent_next",
scopes: ["observations:write", "context:compile", "claims:write"],
});
const before = await fx.call("POST", "/v1/context/compile", {
key: reader.key,
body: { subject_id: "team:shared", task: "private note", max_tokens: 800 },
});
assert.equal(before.body.data.budget.unconsolidated_observations, 0);
const preview = await fx.call("POST", "/v1/principals/reassign", {
key: owner.key,
body: { from: "agent_old", to: "agent_next", dry_run: true },
});
assert.equal(preview.status, 200, JSON.stringify(preview.body));
assert.equal(preview.body.data.dry_run, true);
assert.equal(preview.body.data.observations, 1);
const stillOld = await fx.query<{ actor_id: string }>(
"SELECT actor_id FROM observations WHERE id = ?",
[kept.body.data.observation_id],
);
assert.equal(stillOld[0]?.actor_id, "agent_old");
const moved = await fx.call("POST", "/v1/principals/reassign", {
key: owner.key,
body: { from: "agent_old", to: "agent_next" },
});
assert.equal(moved.status, 200, JSON.stringify(moved.body));
assert.equal(moved.body.data.observations, 1);
const after = await fx.call("POST", "/v1/context/compile", {
key: reader.key,
body: { subject_id: "team:shared", task: "private note", max_tokens: 800 },
});
assert.equal(after.body.data.budget.unconsolidated_observations, 1);
assert.deepEqual(after.body.data.budget.unconsolidated_observation_ids, [kept.body.data.observation_id]);
const outsider = await fx.provision();
expectError(await fx.call("POST", "/v1/principals/reassign", {
key: outsider.key,
body: { from: "agent_old", to: "agent_next" },
}), 403, "FORBIDDEN");
const ready = await fx.call("GET", "/readyz");
assert.equal(ready.status, 200, JSON.stringify(ready.body));
assert.equal(typeof ready.body.data.version, "string");
assert.equal(ready.body.data.schema_version, ready.body.data.schema.applied);
},
});