Harden AGE self-infrastructure lifecycle

This commit is contained in:
冰朔 2026-08-14 17:03:46 +08:00
commit f1bd2f031e
3 changed files with 167 additions and 3 deletions

View file

@ -107,6 +107,9 @@ function validateAgeSelfCheckpointEvidence({
checkpointEvidence?.development_id !== lane.development_id ||
checkpointEvidence?.task_event_id !== lane.task_event?.task_event_id ||
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 ||
!isSha256(checkpointEvidence?.sha256) ||
JSON.stringify(sections) !==
@ -164,31 +167,67 @@ export function classifyAgeSelfInfrastructureLane({
) {
fail("AGE_SELF_CLASSIFICATION_IDENTITY_OR_OBJECT_SCOPE_INVALID");
}
if (laneKind(lane) !== LANE_KIND_UNCLASSIFIED) {
fail("AGE_SELF_CLASSIFICATION_REQUIRES_UNCLASSIFIED_EMPTY_LANE");
const currentLaneKind = laneKind(lane);
if (
currentLaneKind !== LANE_KIND_UNCLASSIFIED &&
currentLaneKind !== LANE_KIND_AGE_SELF_INFRASTRUCTURE
) {
fail("AGE_SELF_CLASSIFICATION_CANNOT_REPLACE_EXTERNAL_OBJECT_LANE");
}
validateAgeSelfCheckpointEvidence({
lane,
checkpointEvidence,
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 = {
previous_lane_kind: LANE_KIND_UNCLASSIFIED,
previous_lane_kind: currentLaneKind,
next_lane_kind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
task_event_id: lane.task_event.task_event_id,
task_fingerprint: lane.task_lock.fingerprint,
checkpoint_path: checkpointEvidence.path,
checkpoint_sha256: checkpointEvidence.sha256,
source_alert_id: checkpointEvidence.source_alert_id,
source_window_number: checkpointEvidence.source_window_number,
authorization_amendment_id: authorizationAmendmentId,
classified_at: classifiedAt,
classification_basis:
"CURRENT_PERSONA_AUTHORED_CHECKPOINT_AND_EXPLICIT_HUMAN_SCOPE_AMENDMENT",
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 {
...lane,
lane_kind: LANE_KIND_AGE_SELF_INFRASTRUCTURE,
lane_kind_history: [...(lane.lane_kind_history ?? []), classification],
persona_source_binding: null,
persona_source_binding_history: bindingHistory,
};
}