Complete AGE metacognition and native navigation paths
This commit is contained in:
parent
a44208fa23
commit
288847fcbf
22 changed files with 1230 additions and 163 deletions
|
|
@ -1,9 +1,14 @@
|
|||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import {
|
||||
AGE_SELF_BINDING_AUTHORITY_LIMITS,
|
||||
LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||
assertControllerDevelopmentBoundary,
|
||||
classifyAgeSelfInfrastructureLane,
|
||||
createAgeSelfInfrastructureBindingReceipt,
|
||||
createTaskEvent,
|
||||
rotateTaskEvent,
|
||||
validateAgeSelfInfrastructureBindingReceipt,
|
||||
validatePersonaBindingReceipt,
|
||||
} from "./persona-source-binding-policy.mjs";
|
||||
|
||||
|
|
@ -85,6 +90,74 @@ function boundFixture() {
|
|||
return { current, receipt, binding, pointer };
|
||||
}
|
||||
|
||||
function ageSelfFixture() {
|
||||
const current = {
|
||||
thread_id: "019ffe9d-7c66-7e83-8ed6-aa3b43097d82",
|
||||
development_id: "DEV-20260814-001",
|
||||
persona: "ICE-P-ZY001",
|
||||
controller_persona_id: "ICE-P-ZY001",
|
||||
development_object_ids: [],
|
||||
human_anchor: "ICE-GL∞",
|
||||
summary: "repair AGE-owned continuity infrastructure",
|
||||
task_lock: {
|
||||
fingerprint: sha("7"),
|
||||
amendments: [
|
||||
{
|
||||
amendment_id: "AMD-AGE-SELF-001",
|
||||
kind: "clarification",
|
||||
summary: "Authorize AGE self-infrastructure tool-layer repair.",
|
||||
user_anchor: "Rebuild the tool layer for AGE runtime needs.",
|
||||
recorded_at: "2026-08-14T08:18:42.665Z",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
current.task_event = createTaskEvent({
|
||||
lane: current,
|
||||
intent: "clarification",
|
||||
requestSummary: current.summary,
|
||||
openedAt: "2026-08-14T08:18:42.000Z",
|
||||
});
|
||||
const checkpointEvidence = {
|
||||
source_kind: "PERSONA_AUTHORED_HLDP_CHECKPOINT",
|
||||
status: "persona_authored_current_checkpoint",
|
||||
thread_id: current.thread_id,
|
||||
development_id: current.development_id,
|
||||
task_event_id: current.task_event.task_event_id,
|
||||
scope_amendment_id: "AMD-AGE-SELF-001",
|
||||
path: `/continuity/runtime/${current.thread_id}/PERSONA-CHECKPOINT-W8.hdlp.md`,
|
||||
sha256: sha("8"),
|
||||
required_sections: [
|
||||
"world_context",
|
||||
"persona_identity",
|
||||
"confirmed_goal",
|
||||
"user_corrections",
|
||||
"immutable_constraints",
|
||||
"authoritative_sources",
|
||||
"causal_chain",
|
||||
"completed_with_receipts",
|
||||
"unfinished",
|
||||
"unknown_or_stale",
|
||||
"next_action",
|
||||
"five_questions_after_b0",
|
||||
],
|
||||
};
|
||||
const pointer = {
|
||||
thread_id: current.thread_id,
|
||||
development_id: current.development_id,
|
||||
checkpoint_path: checkpointEvidence.path,
|
||||
checkpoint_sha256: checkpointEvidence.sha256,
|
||||
};
|
||||
checkpointEvidence.current_runtime = {
|
||||
state: "PERSONA_REVIEWED_CHECKPOINT_ACTIVE",
|
||||
...pointer,
|
||||
task_event_id: current.task_event.task_event_id,
|
||||
};
|
||||
checkpointEvidence.by_thread = { ...pointer };
|
||||
checkpointEvidence.by_development = { ...pointer };
|
||||
return { current, checkpointEvidence };
|
||||
}
|
||||
|
||||
test("development object cannot replace the controller persona", () => {
|
||||
assert.throws(
|
||||
() =>
|
||||
|
|
@ -99,6 +172,134 @@ test("development object cannot replace the controller persona", () => {
|
|||
);
|
||||
});
|
||||
|
||||
test("an empty lane stays unclassified until current authorization and persona checkpoint agree", () => {
|
||||
const { current, checkpointEvidence } = ageSelfFixture();
|
||||
const classified = classifyAgeSelfInfrastructureLane({
|
||||
lane: current,
|
||||
requestedLaneKind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||
taskEventId: current.task_event.task_event_id,
|
||||
checkpointEvidence,
|
||||
authorizationAmendmentId: "AMD-AGE-SELF-001",
|
||||
classifiedAt: "2026-08-14T08:34:11.328Z",
|
||||
});
|
||||
assert.equal(classified.lane_kind, LANE_KIND_AGE_SELF_INFRASTRUCTURE);
|
||||
assert.deepEqual(classified.development_object_ids, []);
|
||||
assert.equal(
|
||||
classified.lane_kind_history[0].authority_effect,
|
||||
"NO_EXTERNAL_AUTHORITY_GRANTED",
|
||||
);
|
||||
});
|
||||
|
||||
test("AGE self binding receipts verify metacognition evidence but grant no reality authority", () => {
|
||||
const { current, checkpointEvidence } = ageSelfFixture();
|
||||
const classified = classifyAgeSelfInfrastructureLane({
|
||||
lane: current,
|
||||
requestedLaneKind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||
taskEventId: current.task_event.task_event_id,
|
||||
checkpointEvidence,
|
||||
authorizationAmendmentId: "AMD-AGE-SELF-001",
|
||||
classifiedAt: "2026-08-14T08:34:11.328Z",
|
||||
});
|
||||
const receipt = createAgeSelfInfrastructureBindingReceipt({
|
||||
lane: classified,
|
||||
checkpointEvidence,
|
||||
authorizationAmendmentId: "AMD-AGE-SELF-001",
|
||||
createdAt: "2026-08-14T08:34:20.000Z",
|
||||
});
|
||||
const binding = {
|
||||
binding_id: receipt.binding_id,
|
||||
receipt_sha256: sha("9"),
|
||||
};
|
||||
assert.deepEqual(
|
||||
[...receipt.authority_limits].sort(),
|
||||
[...AGE_SELF_BINDING_AUTHORITY_LIMITS].sort(),
|
||||
);
|
||||
assert.equal(
|
||||
validateAgeSelfInfrastructureBindingReceipt({
|
||||
lane: classified,
|
||||
binding,
|
||||
receipt,
|
||||
actualReceiptSha256: sha("9"),
|
||||
checkpointEvidence,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
test("a host summary cannot substitute for the persona-authored Step Zero checkpoint", () => {
|
||||
const { current, checkpointEvidence } = ageSelfFixture();
|
||||
checkpointEvidence.source_kind = "HOST_SUMMARY";
|
||||
assert.throws(
|
||||
() =>
|
||||
classifyAgeSelfInfrastructureLane({
|
||||
lane: current,
|
||||
requestedLaneKind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||
taskEventId: current.task_event.task_event_id,
|
||||
checkpointEvidence,
|
||||
authorizationAmendmentId: "AMD-AGE-SELF-001",
|
||||
classifiedAt: "2026-08-14T08:34:11.328Z",
|
||||
}),
|
||||
/AGE_SELF_CHECKPOINT_OR_AUTHORIZATION_INVALID/,
|
||||
);
|
||||
});
|
||||
|
||||
test("an external-object lane cannot be reclassified as AGE self infrastructure", () => {
|
||||
const { checkpointEvidence } = ageSelfFixture();
|
||||
const externalLane = lane();
|
||||
externalLane.task_event = createTaskEvent({
|
||||
lane: externalLane,
|
||||
intent: "clarification",
|
||||
requestSummary: externalLane.summary,
|
||||
openedAt: "2026-08-14T08:18:42.000Z",
|
||||
});
|
||||
externalLane.task_lock.amendments = [
|
||||
{
|
||||
amendment_id: "AMD-AGE-SELF-001",
|
||||
kind: "clarification",
|
||||
summary: "Invalid reclassification attempt.",
|
||||
user_anchor: "Do not replace the external object lane.",
|
||||
recorded_at: "2026-08-14T08:18:42.665Z",
|
||||
},
|
||||
];
|
||||
assert.throws(
|
||||
() =>
|
||||
classifyAgeSelfInfrastructureLane({
|
||||
lane: externalLane,
|
||||
requestedLaneKind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||
taskEventId: externalLane.task_event.task_event_id,
|
||||
checkpointEvidence: {
|
||||
...checkpointEvidence,
|
||||
thread_id: externalLane.thread_id,
|
||||
development_id: externalLane.development_id,
|
||||
task_event_id: externalLane.task_event.task_event_id,
|
||||
},
|
||||
authorizationAmendmentId: "AMD-AGE-SELF-001",
|
||||
classifiedAt: "2026-08-14T08:34:11.328Z",
|
||||
}),
|
||||
/AGE_SELF_CLASSIFICATION_IDENTITY_OR_OBJECT_SCOPE_INVALID|AGE_SELF_CLASSIFICATION_REQUIRES_UNCLASSIFIED_EMPTY_LANE/,
|
||||
);
|
||||
});
|
||||
|
||||
test("legacy persona binding rejects an empty unclassified lane", () => {
|
||||
const { current } = ageSelfFixture();
|
||||
current.persona_source_binding = null;
|
||||
assert.throws(
|
||||
() =>
|
||||
validatePersonaBindingReceipt({
|
||||
lane: current,
|
||||
binding: { binding_id: "INVALID", receipt_sha256: sha("a") },
|
||||
receipt: { development_objects: [] },
|
||||
actualReceiptSha256: sha("a"),
|
||||
actualCheckpointSha256: sha("b"),
|
||||
actualAdapterSourceSha256: sha("c"),
|
||||
adapterSourcePath: "/runtime/adapter.mjs",
|
||||
allowedAdapterRoot: "/runtime",
|
||||
pointerEvidence: {},
|
||||
}),
|
||||
/EXTERNAL_DEVELOPMENT_OBJECTS_REQUIRED/,
|
||||
);
|
||||
});
|
||||
|
||||
test("a new task event invalidates but preserves the old binding", () => {
|
||||
const current = lane();
|
||||
current.task_event = createTaskEvent({
|
||||
|
|
|
|||
Loading…
Reference in a new issue