Add persistent Subject behavior context

This commit is contained in:
2026-10-05 16:27:23 +09:00
parent cc97987482
commit 8891236db3
28 changed files with 1999 additions and 190 deletions
@@ -66,7 +66,14 @@ ${"detail-wide-code-".repeat(18)}
<script>alert("not rendered")</script>`;
const subjects = [
subject(representativeSubjectId, "Release coordination", "active", 42),
subject(
representativeSubjectId,
"Release coordination",
"active",
42,
"Prefer explicit evidence over assumptions.\nAsk before irreversible actions, and state uncertainty plainly.",
3,
),
subject(emptySubjectId, "Empty ready subject", "active", 0),
subject(staleSubjectId, "Stale surface subject", "active", 19),
subject(failedSubjectId, "Failed surface subject", "active", 8),
@@ -75,10 +82,19 @@ const subjects = [
];
const pagedSubject = subject(pagedSubjectId, "Subject on the next page", "active", 1);
function subject(id: string, role: string, state: "active" | "retired", storeRevision: number) {
function subject(
id: string,
role: string,
state: "active" | "retired",
storeRevision: number,
behaviorMd = "",
behaviorRevision = 0,
) {
return {
id,
role,
behavior_md: behaviorMd,
behavior_revision: behaviorRevision,
state,
store_revision: storeRevision,
created_at: "2026-01-01T00:00:00Z",
@@ -403,7 +419,10 @@ Deno.serve({ hostname: "127.0.0.1", port }, async (request) => {
const subjectsPath = `/api/w/${workspaceId}/subjektiv/subjects`;
if (url.pathname === subjectsPath) {
if (request.method === "POST") {
const payload = await request.json().catch(() => null) as { role?: unknown } | null;
const payload = await request.json().catch(() => null) as {
role?: unknown;
behavior_md?: unknown;
} | null;
subjectCreateRequests.push(payload);
if (!payload || typeof payload.role !== "string" || payload.role.trim().length === 0) {
return json({ error: "Bad Request", message: "subject role must not be empty" }, 400);
@@ -411,9 +430,12 @@ Deno.serve({ hostname: "127.0.0.1", port }, async (request) => {
if (payload.role === "Permission denied") {
return json({ error: "Forbidden", message: "workspace permission denied" }, 403);
}
if (typeof payload.behavior_md !== "string") {
return json({ error: "Bad Request", message: "subject behavior must be a string" }, 400);
}
createdSubjectCount += 1;
const id = `created-subject-${String(createdSubjectCount).padStart(4, "0")}`;
const created = subject(id, payload.role, "active", 0);
const created = subject(id, payload.role, "active", 0, payload.behavior_md);
createdSubjectIds.add(id);
subjects.unshift(created);
return json(created, 201);
@@ -442,6 +464,27 @@ Deno.serve({ hostname: "127.0.0.1", port }, async (request) => {
const foundSubject = subjects.find((item) => item.id === subjectId);
if (!foundSubject) return json({}, 404);
if (parts.length === 2 && parts[1] === "behavior" && request.method === "PATCH") {
const payload = await request.json().catch(() => null) as {
expected_behavior_revision?: unknown;
behavior_md?: unknown;
} | null;
if (
!payload ||
typeof payload.expected_behavior_revision !== "number" ||
typeof payload.behavior_md !== "string"
) {
return json({ error: "Bad Request", message: "invalid behavior update" }, 400);
}
if (payload.expected_behavior_revision !== foundSubject.behavior_revision) {
return json({ error: "Conflict", message: "subject behavior revision conflict" }, 409);
}
foundSubject.behavior_md = payload.behavior_md;
foundSubject.behavior_revision += 1;
foundSubject.updated_at = "2026-01-03T04:05:06Z";
return json(foundSubject);
}
if (request.method !== "GET") return new Response("method not allowed", { status: 405 });
if (parts.length === 1) return json(foundSubject);
if (parts.length === 2 && parts[1] === "surface") return json(surfaceFor(subjectId));
if (parts.length === 2 && parts[1] === "memories") {