Harden AGE self-infrastructure lifecycle
This commit is contained in:
parent
288847fcbf
commit
f1bd2f031e
3 changed files with 167 additions and 3 deletions
|
|
@ -31,6 +31,8 @@
|
||||||
HLDP、runtime CURRENT 和 thread/development 双 CURRENT;
|
HLDP、runtime CURRENT 和 thread/development 双 CURRENT;
|
||||||
- 工具只验证、保存、执行和出回执,不产生人格判断,不接收宿主摘要作为元认知;
|
- 工具只验证、保存、执行和出回执,不产生人格判断,不接收宿主摘要作为元认知;
|
||||||
- 自有基础设施绑定固定声明不含仓库、服务器、部署权限,也不能推断任何外部开发对象。
|
- 自有基础设施绑定固定声明不含仓库、服务器、部署权限,也不能推断任何外部开发对象。
|
||||||
|
- 同一任务事件发生真实新压缩窗口时,只接受不同警报且窗口号递增的新检查点;旧绑定随即失效,
|
||||||
|
新回执绑定新检查点指纹。同一窗口内任意换证据失败关闭;新任务事件同样必须刷新分类与绑定。
|
||||||
|
|
||||||
机器回执合同见 `age-self-infrastructure-persona-binding.schema.json`。这条路只拆开“人格主体”
|
机器回执合同见 `age-self-infrastructure-persona-binding.schema.json`。这条路只拆开“人格主体”
|
||||||
与“外部开发对象”两条轴,不是通用绕过门;每个现实资源仍要另取精确租约并独立回读。
|
与“外部开发对象”两条轴,不是通用绕过门;每个现实资源仍要另取精确租约并独立回读。
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,9 @@ function validateAgeSelfCheckpointEvidence({
|
||||||
checkpointEvidence?.development_id !== lane.development_id ||
|
checkpointEvidence?.development_id !== lane.development_id ||
|
||||||
checkpointEvidence?.task_event_id !== lane.task_event?.task_event_id ||
|
checkpointEvidence?.task_event_id !== lane.task_event?.task_event_id ||
|
||||||
checkpointEvidence?.scope_amendment_id !== authorizationAmendmentId ||
|
checkpointEvidence?.scope_amendment_id !== authorizationAmendmentId ||
|
||||||
|
!/^GUARD-[a-f0-9]{16}$/u.test(checkpointEvidence?.source_alert_id ?? "") ||
|
||||||
|
!Number.isInteger(checkpointEvidence?.source_window_number) ||
|
||||||
|
checkpointEvidence.source_window_number < 1 ||
|
||||||
!checkpointEvidence?.path ||
|
!checkpointEvidence?.path ||
|
||||||
!isSha256(checkpointEvidence?.sha256) ||
|
!isSha256(checkpointEvidence?.sha256) ||
|
||||||
JSON.stringify(sections) !==
|
JSON.stringify(sections) !==
|
||||||
|
|
@ -164,31 +167,67 @@ export function classifyAgeSelfInfrastructureLane({
|
||||||
) {
|
) {
|
||||||
fail("AGE_SELF_CLASSIFICATION_IDENTITY_OR_OBJECT_SCOPE_INVALID");
|
fail("AGE_SELF_CLASSIFICATION_IDENTITY_OR_OBJECT_SCOPE_INVALID");
|
||||||
}
|
}
|
||||||
if (laneKind(lane) !== LANE_KIND_UNCLASSIFIED) {
|
const currentLaneKind = laneKind(lane);
|
||||||
fail("AGE_SELF_CLASSIFICATION_REQUIRES_UNCLASSIFIED_EMPTY_LANE");
|
if (
|
||||||
|
currentLaneKind !== LANE_KIND_UNCLASSIFIED &&
|
||||||
|
currentLaneKind !== LANE_KIND_AGE_SELF_INFRASTRUCTURE
|
||||||
|
) {
|
||||||
|
fail("AGE_SELF_CLASSIFICATION_CANNOT_REPLACE_EXTERNAL_OBJECT_LANE");
|
||||||
}
|
}
|
||||||
validateAgeSelfCheckpointEvidence({
|
validateAgeSelfCheckpointEvidence({
|
||||||
lane,
|
lane,
|
||||||
checkpointEvidence,
|
checkpointEvidence,
|
||||||
authorizationAmendmentId,
|
authorizationAmendmentId,
|
||||||
});
|
});
|
||||||
|
const existing = [...(lane.lane_kind_history ?? [])].reverse().find(
|
||||||
|
(entry) => entry.next_lane_kind === LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||||
|
);
|
||||||
|
if (currentLaneKind === LANE_KIND_AGE_SELF_INFRASTRUCTURE && existing) {
|
||||||
|
const sameEvidence =
|
||||||
|
existing.task_event_id === lane.task_event.task_event_id &&
|
||||||
|
existing.checkpoint_path === checkpointEvidence.path &&
|
||||||
|
existing.checkpoint_sha256 === checkpointEvidence.sha256 &&
|
||||||
|
existing.authorization_amendment_id === authorizationAmendmentId;
|
||||||
|
if (sameEvidence) return lane;
|
||||||
|
if (
|
||||||
|
existing.task_event_id === lane.task_event.task_event_id &&
|
||||||
|
(existing.source_alert_id === checkpointEvidence.source_alert_id ||
|
||||||
|
!Number.isInteger(existing.source_window_number) ||
|
||||||
|
checkpointEvidence.source_window_number <= existing.source_window_number)
|
||||||
|
) {
|
||||||
|
fail("AGE_SELF_CLASSIFICATION_ALREADY_EXISTS_WITH_DIFFERENT_EVIDENCE");
|
||||||
|
}
|
||||||
|
}
|
||||||
const classification = {
|
const classification = {
|
||||||
previous_lane_kind: LANE_KIND_UNCLASSIFIED,
|
previous_lane_kind: currentLaneKind,
|
||||||
next_lane_kind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
next_lane_kind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||||
task_event_id: lane.task_event.task_event_id,
|
task_event_id: lane.task_event.task_event_id,
|
||||||
task_fingerprint: lane.task_lock.fingerprint,
|
task_fingerprint: lane.task_lock.fingerprint,
|
||||||
checkpoint_path: checkpointEvidence.path,
|
checkpoint_path: checkpointEvidence.path,
|
||||||
checkpoint_sha256: checkpointEvidence.sha256,
|
checkpoint_sha256: checkpointEvidence.sha256,
|
||||||
|
source_alert_id: checkpointEvidence.source_alert_id,
|
||||||
|
source_window_number: checkpointEvidence.source_window_number,
|
||||||
authorization_amendment_id: authorizationAmendmentId,
|
authorization_amendment_id: authorizationAmendmentId,
|
||||||
classified_at: classifiedAt,
|
classified_at: classifiedAt,
|
||||||
classification_basis:
|
classification_basis:
|
||||||
"CURRENT_PERSONA_AUTHORED_CHECKPOINT_AND_EXPLICIT_HUMAN_SCOPE_AMENDMENT",
|
"CURRENT_PERSONA_AUTHORED_CHECKPOINT_AND_EXPLICIT_HUMAN_SCOPE_AMENDMENT",
|
||||||
authority_effect: "NO_EXTERNAL_AUTHORITY_GRANTED",
|
authority_effect: "NO_EXTERNAL_AUTHORITY_GRANTED",
|
||||||
};
|
};
|
||||||
|
const bindingHistory = [...(lane.persona_source_binding_history ?? [])];
|
||||||
|
if (lane.persona_source_binding) {
|
||||||
|
bindingHistory.push({
|
||||||
|
...lane.persona_source_binding,
|
||||||
|
state: "STALE_SUPERSEDED_BY_NEW_PERSONA_CHECKPOINT",
|
||||||
|
invalidated_at: classifiedAt,
|
||||||
|
invalidated_by_checkpoint_sha256: checkpointEvidence.sha256,
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...lane,
|
...lane,
|
||||||
lane_kind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
lane_kind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||||
lane_kind_history: [...(lane.lane_kind_history ?? []), classification],
|
lane_kind_history: [...(lane.lane_kind_history ?? []), classification],
|
||||||
|
persona_source_binding: null,
|
||||||
|
persona_source_binding_history: bindingHistory,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,8 @@ function ageSelfFixture() {
|
||||||
development_id: current.development_id,
|
development_id: current.development_id,
|
||||||
task_event_id: current.task_event.task_event_id,
|
task_event_id: current.task_event.task_event_id,
|
||||||
scope_amendment_id: "AMD-AGE-SELF-001",
|
scope_amendment_id: "AMD-AGE-SELF-001",
|
||||||
|
source_alert_id: "GUARD-1111111111111111",
|
||||||
|
source_window_number: 8,
|
||||||
path: `/continuity/runtime/${current.thread_id}/PERSONA-CHECKPOINT-W8.hdlp.md`,
|
path: `/continuity/runtime/${current.thread_id}/PERSONA-CHECKPOINT-W8.hdlp.md`,
|
||||||
sha256: sha("8"),
|
sha256: sha("8"),
|
||||||
required_sections: [
|
required_sections: [
|
||||||
|
|
@ -226,6 +228,127 @@ test("AGE self binding receipts verify metacognition evidence but grant no reali
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("a real later compaction window refreshes classification and invalidates the prior binding", () => {
|
||||||
|
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",
|
||||||
|
});
|
||||||
|
classified.persona_source_binding = { binding_id: "AGE-BINDING-W8" };
|
||||||
|
const nextEvidence = {
|
||||||
|
...checkpointEvidence,
|
||||||
|
source_alert_id: "GUARD-2222222222222222",
|
||||||
|
source_window_number: 9,
|
||||||
|
path: checkpointEvidence.path.replace("W8", "W9"),
|
||||||
|
sha256: sha("9"),
|
||||||
|
};
|
||||||
|
const pointer = {
|
||||||
|
thread_id: current.thread_id,
|
||||||
|
development_id: current.development_id,
|
||||||
|
checkpoint_path: nextEvidence.path,
|
||||||
|
checkpoint_sha256: nextEvidence.sha256,
|
||||||
|
};
|
||||||
|
nextEvidence.current_runtime = {
|
||||||
|
state: "PERSONA_REVIEWED_CHECKPOINT_ACTIVE",
|
||||||
|
...pointer,
|
||||||
|
task_event_id: current.task_event.task_event_id,
|
||||||
|
};
|
||||||
|
nextEvidence.by_thread = { ...pointer };
|
||||||
|
nextEvidence.by_development = { ...pointer };
|
||||||
|
const refreshed = classifyAgeSelfInfrastructureLane({
|
||||||
|
lane: classified,
|
||||||
|
requestedLaneKind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||||
|
taskEventId: current.task_event.task_event_id,
|
||||||
|
checkpointEvidence: nextEvidence,
|
||||||
|
authorizationAmendmentId: "AMD-AGE-SELF-001",
|
||||||
|
classifiedAt: "2026-08-14T08:58:36.614Z",
|
||||||
|
});
|
||||||
|
assert.equal(refreshed.lane_kind_history.length, 2);
|
||||||
|
assert.equal(refreshed.lane_kind_history[1].previous_lane_kind, LANE_KIND_AGE_SELF_INFRASTRUCTURE);
|
||||||
|
assert.equal(refreshed.persona_source_binding, null);
|
||||||
|
assert.equal(
|
||||||
|
refreshed.persona_source_binding_history[0].state,
|
||||||
|
"STALE_SUPERSEDED_BY_NEW_PERSONA_CHECKPOINT",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a new task event requires a new classification and binding evidence", () => {
|
||||||
|
const { current, checkpointEvidence } = ageSelfFixture();
|
||||||
|
let 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 oldReceipt = createAgeSelfInfrastructureBindingReceipt({
|
||||||
|
lane: classified,
|
||||||
|
checkpointEvidence,
|
||||||
|
authorizationAmendmentId: "AMD-AGE-SELF-001",
|
||||||
|
createdAt: "2026-08-14T08:34:20.000Z",
|
||||||
|
});
|
||||||
|
classified.persona_source_binding = { binding_id: oldReceipt.binding_id };
|
||||||
|
const rotated = rotateTaskEvent({
|
||||||
|
lane: classified,
|
||||||
|
intent: "correction",
|
||||||
|
requestSummary: "continue with corrected scope",
|
||||||
|
openedAt: "2026-08-14T09:00:00.000Z",
|
||||||
|
});
|
||||||
|
rotated.task_lock.amendments.push({
|
||||||
|
amendment_id: "AMD-AGE-SELF-002",
|
||||||
|
kind: "correction",
|
||||||
|
summary: "Authorize the refreshed AGE self-infrastructure event.",
|
||||||
|
user_anchor: "Continue this self-infrastructure repair with the correction.",
|
||||||
|
recorded_at: "2026-08-14T09:00:01.000Z",
|
||||||
|
});
|
||||||
|
const nextEvidence = {
|
||||||
|
...checkpointEvidence,
|
||||||
|
task_event_id: rotated.task_event.task_event_id,
|
||||||
|
scope_amendment_id: "AMD-AGE-SELF-002",
|
||||||
|
source_alert_id: "GUARD-3333333333333333",
|
||||||
|
source_window_number: 10,
|
||||||
|
path: checkpointEvidence.path.replace("W8", "W10"),
|
||||||
|
sha256: sha("a"),
|
||||||
|
};
|
||||||
|
const pointer = {
|
||||||
|
thread_id: rotated.thread_id,
|
||||||
|
development_id: rotated.development_id,
|
||||||
|
checkpoint_path: nextEvidence.path,
|
||||||
|
checkpoint_sha256: nextEvidence.sha256,
|
||||||
|
};
|
||||||
|
nextEvidence.current_runtime = {
|
||||||
|
state: "PERSONA_REVIEWED_CHECKPOINT_ACTIVE",
|
||||||
|
...pointer,
|
||||||
|
task_event_id: rotated.task_event.task_event_id,
|
||||||
|
};
|
||||||
|
nextEvidence.by_thread = { ...pointer };
|
||||||
|
nextEvidence.by_development = { ...pointer };
|
||||||
|
const refreshed = classifyAgeSelfInfrastructureLane({
|
||||||
|
lane: rotated,
|
||||||
|
requestedLaneKind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
|
||||||
|
taskEventId: rotated.task_event.task_event_id,
|
||||||
|
checkpointEvidence: nextEvidence,
|
||||||
|
authorizationAmendmentId: "AMD-AGE-SELF-002",
|
||||||
|
classifiedAt: "2026-08-14T09:00:02.000Z",
|
||||||
|
});
|
||||||
|
assert.equal(refreshed.lane_kind_history.length, 2);
|
||||||
|
assert.equal(refreshed.lane_kind_history[1].task_event_id, rotated.task_event.task_event_id);
|
||||||
|
assert.equal(
|
||||||
|
createAgeSelfInfrastructureBindingReceipt({
|
||||||
|
lane: refreshed,
|
||||||
|
checkpointEvidence: nextEvidence,
|
||||||
|
authorizationAmendmentId: "AMD-AGE-SELF-002",
|
||||||
|
createdAt: "2026-08-14T09:00:03.000Z",
|
||||||
|
}).task_event_id,
|
||||||
|
rotated.task_event.task_event_id,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("a host summary cannot substitute for the persona-authored Step Zero checkpoint", () => {
|
test("a host summary cannot substitute for the persona-authored Step Zero checkpoint", () => {
|
||||||
const { current, checkpointEvidence } = ageSelfFixture();
|
const { current, checkpointEvidence } = ageSelfFixture();
|
||||||
checkpointEvidence.source_kind = "HOST_SUMMARY";
|
checkpointEvidence.source_kind = "HOST_SUMMARY";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue