@lqc123qwe/car-runtime 1.23.0 → 1.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/SHA256SUMS CHANGED
@@ -1 +1 @@
1
- 6e62dc16fe612b7bb524a8233c60428b1a6f76685dd9d9da75dc7749eadd0cf0 car-runtime-1.23.0.tgz
1
+ 92e00b2804c1640dbe983cfcc24a6b0be749c793b9d9e7a1157540f9385a71da car-runtime-1.24.1.tgz
Binary file
@@ -0,0 +1 @@
1
+ {"base64Signature":"MEUCIQC+uDDRKFQb4EChJmMlCxeuqDmsediUV8fDWqe29WR+qgIgK8mPs9jQgPNncC4X3Nz8paWdO/WvZydKvhUW+VpPBJA=","cert":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUc1ekNDQm0yZ0F3SUJBZ0lVUXk1b3NudTJvVTNRZXQzOWpkRTVYeERqL293d0NnWUlLb1pJemowRUF3TXcKTnpFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUjR3SEFZRFZRUURFeFZ6YVdkemRHOXlaUzFwYm5SbApjbTFsWkdsaGRHVXdIaGNOTWpZeE1URTFNVEEwTWpBNFdoY05Nall4TVRFMU1UQTFNakE0V2pBQU1Ga3dFd1lICktvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUV5MVBRN0txVkY3azk2U0FGb3JoTEdhZE1EWFNKTEVYeU5oSS8KQ2NLT0RnT21nNHoxcmtGQnVTcWd6SlYwMDBFWVdXcnhPSTNHNHQzSE93M08vbGlWVnFPQ0JZd3dnZ1dJTUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREF6QWZCZ05WSFNNRUdEQVdnQlRmCjArblBWaVFSbHZtbzJPa29WYUxHTGhoa1B6QmlCZ05WSFJFQkFmOEVXREJXaGxSb2RIUndjem92TDJkcGRHaDEKWWk1amIyMHZiSEZqTmpJMEwyTmhjaTF5ZFc1MGFXMWxMeTVuYVhSb2RXSXZkMjl5YTJac2IzZHpMM0psYkdWaApjMlV1ZVcxc1FISmxabk12ZEdGbmN5OHhMakkwTGpFd09RWUtLd1lCQkFHRHZ6QUJBUVFyYUhSMGNITTZMeTkwCmIydGxiaTVoWTNScGIyNXpMbWRwZEdoMVluVnpaWEpqYjI1MFpXNTBMbU52YlRBVkJnb3JCZ0VFQVlPL01BRUMKQkFkeVpXeGxZWE5sTURZR0Npc0dBUVFCZzc4d0FRTUVLRGcwWWpBd016bGlOVEpqTUdKaE1qTXhNamRrWXpKagpZelUyTVRka00yVTJZMlZrTVRobVpqWXdGUVlLS3dZQkJBR0R2ekFCQkFRSGNtVnNaV0Z6WlRBZ0Jnb3JCZ0VFCkFZTy9NQUVGQkJKc2NXTTJNalF2WTJGeUxYSjFiblJwYldVd0hnWUtLd1lCQkFHRHZ6QUJCZ1FRY21WbWN5OTAKWVdkekx6RXVNalF1TVRBN0Jnb3JCZ0VFQVlPL01BRUlCQzBNSzJoMGRIQnpPaTh2ZEc5clpXNHVZV04wYVc5dQpjeTVuYVhSb2RXSjFjMlZ5WTI5dWRHVnVkQzVqYjIwd1pBWUtLd1lCQkFHRHZ6QUJDUVJXREZSb2RIUndjem92CkwyZHBkR2gxWWk1amIyMHZiSEZqTmpJMEwyTmhjaTF5ZFc1MGFXMWxMeTVuYVhSb2RXSXZkMjl5YTJac2IzZHoKTDNKbGJHVmhjMlV1ZVcxc1FISmxabk12ZEdGbmN5OHhMakkwTGpFd09BWUtLd1lCQkFHRHZ6QUJDZ1FxRENnNApOR0l3TURNNVlqVXlZekJpWVRJek1USTNaR015WTJNMU5qRTNaRE5sTm1ObFpERTRabVkyTUIwR0Npc0dBUVFCCmc3OHdBUXNFRHd3TloybDBhSFZpTFdodmMzUmxaREExQmdvckJnRUVBWU8vTUFFTUJDY01KV2gwZEhCek9pOHYKWjJsMGFIVmlMbU52YlM5c2NXTTJNalF2WTJGeUxYSjFiblJwYldVd09BWUtLd1lCQkFHRHZ6QUJEUVFxRENnNApOR0l3TURNNVlqVXlZekJpWVRJek1USTNaR015WTJNMU5qRTNaRE5sTm1ObFpERTRabVkyTUNBR0Npc0dBUVFCCmc3OHdBUTRFRWd3UWNtVm1jeTkwWVdkekx6RXVNalF1TVRBYUJnb3JCZ0VFQVlPL01BRVBCQXdNQ2pFek5qRXgKT1RJM01UUXdLUVlLS3dZQkJBR0R2ekFCRUFRYkRCbG9kSFJ3Y3pvdkwyZHBkR2gxWWk1amIyMHZiSEZqTmpJMApNQmdHQ2lzR0FRUUJnNzh3QVJFRUNnd0lOamt5TXpRMU5qUXdaQVlLS3dZQkJBR0R2ekFCRWdSV0RGUm9kSFJ3CmN6b3ZMMmRwZEdoMVlpNWpiMjB2YkhGak5qSTBMMk5oY2kxeWRXNTBhVzFsTHk1bmFYUm9kV0l2ZDI5eWEyWnMKYjNkekwzSmxiR1ZoYzJVdWVXMXNRSEpsWm5NdmRHRm5jeTh4TGpJMExqRXdPQVlLS3dZQkJBR0R2ekFCRXdRcQpEQ2c0TkdJd01ETTVZalV5WXpCaVlUSXpNVEkzWkdNeVkyTTFOakUzWkRObE5tTmxaREU0Wm1ZMk1CY0dDaXNHCkFRUUJnNzh3QVJRRUNRd0hjbVZzWldGelpUQlpCZ29yQmdFRUFZTy9NQUVWQkVzTVNXaDBkSEJ6T2k4dloybDAKYUhWaUxtTnZiUzlzY1dNMk1qUXZZMkZ5TFhKMWJuUnBiV1V2WVdOMGFXOXVjeTl5ZFc1ekx6UXpOekExTXpNMQpOVFkxTDJGMGRHVnRjSFJ6THpFd0ZnWUtLd1lCQkFHRHZ6QUJGZ1FJREFad2RXSnNhV013VUFZS0t3WUJCQUdECnZ6QUJHQVJDREVCeVpYQnZPbXh4WXpZeU5FQTJPVEl6TkRVMk5DOWpZWEl0Y25WdWRHbHRaVUF4TXpZeE1Ua3kKTnpFME9uSmxaanB5WldaekwzUmhaM012TVM0eU5DNHhNSUdLQmdvckJnRUVBZFo1QWdRQ0JId0VlZ0I0QUhZQQozVDB3YXNiSEVUSmpHUjRjbVdjM0FxSktYcmplUEszL2g0cHlnQzhwN280QUFBR2gzc3pXaHdBQUJBTUFSekJGCkFpRUEyRjFIRTB5cm9TUkZXNHdPeHhrVWdiMzhLc0FEcEhXN2tJQlJ3dHVoSWUwQ0lCa1lJemRzUUxuQ1drVEkKbndQNzR3VnRuWHNTWGp2ZTlETWRWMEg5YU5RWU1Bb0dDQ3FHU000OUJBTURBMmdBTUdVQ01RQ3did2RGR0Rqdgp3WCtJcnhlRDU3WWNqSkM4VURMOEU5QXpqamF1WncxNm5URW5wanhCM0s1bXliWkJMTkt1WCt3Q01GMytqMTU0CjhWZit4c09uTWJNZ2NDYVY3WnZSaVFNYVRJVkxYSjBpeStEa1VESTBDR1hzUm56SkFUVko3ZXJRYkE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==","rekorBundle":{"SignedEntryTimestamp":"MEQCICOlSFCfujGiqQsKzB470RfZN7UZYSBMENfk2I2iPMPnAiBaqwU91Q8gX6j/ei7/ejtleJDEC02moIX64FTnG0vkbw==","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI5MmUwMGIyODA0YzE2NDBkYmU5ODNjZmNjMjRhNmIwYmU3NDljNzkzYjlkOWU3YTExNTc1NDBmOTM4NWE3MWRhIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUMrdUREUktGUWI0RUNoSm1NbEN4ZXVxRG1zZWRpVVY4ZkRXcWUyOVdSK3FnSWdLOG1QczlqUWdQTm5jQzRYM056OHBhV2RPL1d2WnlkS3ZoVVcrVnBQQkpBPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVYzFla05EUW0weVowRjNTVUpCWjBsVlVYazFiM051ZFRKdlZUTlJaWFF6T1dwa1JUVlllRVJxTDI5M2QwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFplRTFVUlRGTlZFRXdUV3BCTkZkb1kwNU5hbGw0VFZSRk1VMVVRVEZOYWtFMFYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVY1TVZCUk4wdHhWa1kzYXprMlUwRkdiM0pvVEVkaFpFMUVXRk5LVEVWWWVVNW9TUzhLUTJOTFQwUm5UMjFuTkhveGNtdEdRblZUY1dkNlNsWXdNREJGV1ZkWGNuaFBTVE5ITkhRelNFOTNNMDh2YkdsV1ZuRlBRMEpaZDNkbloxZEpUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXWkNaMDVXU0ZOTlJVZEVRVmRuUWxSbUNqQXJibEJXYVZGU2JIWnRiekpQYTI5V1lVeEhUR2hvYTFCNlFtbENaMDVXU0ZKRlFrRm1PRVZYUkVKWGFHeFNiMlJJVW5kamVtOTJUREprY0dSSGFERUtXV2sxYW1JeU1IWmlTRVpxVG1wSk1Fd3lUbWhqYVRGNVpGYzFNR0ZYTVd4TWVUVnVZVmhTYjJSWFNYWmtNamw1WVRKYWMySXpaSHBNTTBwc1lrZFdhQXBqTWxWMVpWY3hjMUZJU214YWJrMTJaRWRHYm1ONU9IaE1ha2t3VEdwRmQwOVJXVXRMZDFsQ1FrRkhSSFo2UVVKQlVWRnlZVWhTTUdOSVRUWk1lVGt3Q21JeWRHeGlhVFZvV1ROU2NHSXlOWHBNYldSd1pFZG9NVmx1Vm5wYVdFcHFZakkxTUZwWE5UQk1iVTUyWWxSQlZrSm5iM0pDWjBWRlFWbFBMMDFCUlVNS1FrRmtlVnBYZUd4WldFNXNUVVJaUjBOcGMwZEJVVkZDWnpjNGQwRlJUVVZMUkdjd1dXcEJkMDE2YkdsT1ZFcHFUVWRLYUUxcVRYaE5hbVJyV1hwS2FncFplbFV5VFZSa2EwMHlWVEpaTWxaclRWUm9iVnBxV1hkR1VWbExTM2RaUWtKQlIwUjJla0ZDUWtGUlNHTnRWbk5hVjBaNldsUkJaMEpuYjNKQ1owVkZDa0ZaVHk5TlFVVkdRa0pLYzJOWFRUSk5hbEYyV1RKR2VVeFlTakZpYmxKd1lsZFZkMGhuV1V0TGQxbENRa0ZIUkhaNlFVSkNaMUZSWTIxV2JXTjVPVEFLV1Zka2VreDZSWFZOYWxGMVRWUkJOMEpuYjNKQ1owVkZRVmxQTDAxQlJVbENRekJOU3pKb01HUklRbnBQYVRoMlpFYzVjbHBYTkhWWlYwNHdZVmM1ZFFwamVUVnVZVmhTYjJSWFNqRmpNbFo1V1RJNWRXUkhWblZrUXpWcVlqSXdkMXBCV1V0TGQxbENRa0ZIUkhaNlFVSkRVVkpYUkVaU2IyUklVbmRqZW05MkNrd3laSEJrUjJneFdXazFhbUl5TUhaaVNFWnFUbXBKTUV3eVRtaGphVEY1WkZjMU1HRlhNV3hNZVRWdVlWaFNiMlJYU1haa01qbDVZVEphYzJJelpIb0tURE5LYkdKSFZtaGpNbFYxWlZjeGMxRklTbXhhYmsxMlpFZEdibU41T0hoTWFra3dUR3BGZDA5QldVdExkMWxDUWtGSFJIWjZRVUpEWjFGeFJFTm5OQXBPUjBsM1RVUk5OVmxxVlhsWmVrSnBXVlJKZWsxVVNUTmFSMDE1V1RKTk1VNXFSVE5hUkU1c1RtMU9iRnBFUlRSYWJWa3lUVUl3UjBOcGMwZEJVVkZDQ21jM09IZEJVWE5GUkhkM1Rsb3liREJoU0ZacFRGZG9kbU16VW14YVJFRXhRbWR2Y2tKblJVVkJXVTh2VFVGRlRVSkRZMDFLVjJnd1pFaENlazlwT0hZS1dqSnNNR0ZJVm1sTWJVNTJZbE01YzJOWFRUSk5hbEYyV1RKR2VVeFlTakZpYmxKd1lsZFZkMDlCV1V0TGQxbENRa0ZIUkhaNlFVSkVVVkZ4UkVObk5BcE9SMGwzVFVSTk5WbHFWWGxaZWtKcFdWUkplazFVU1ROYVIwMTVXVEpOTVU1cVJUTmFSRTVzVG0xT2JGcEVSVFJhYlZreVRVTkJSME5wYzBkQlVWRkNDbWMzT0hkQlVUUkZSV2QzVVdOdFZtMWplVGt3V1Zka2VreDZSWFZOYWxGMVRWUkJZVUpuYjNKQ1owVkZRVmxQTDAxQlJWQkNRWGROUTJwRmVrNXFSWGdLVDFSSk0wMVVVWGRMVVZsTFMzZFpRa0pCUjBSMmVrRkNSVUZSWWtSQ2JHOWtTRkozWTNwdmRrd3laSEJrUjJneFdXazFhbUl5TUhaaVNFWnFUbXBKTUFwTlFtZEhRMmx6UjBGUlVVSm5OemgzUVZKRlJVTm5kMGxPYW10NVRYcFJNVTVxVVhkYVFWbExTM2RaUWtKQlIwUjJla0ZDUldkU1YwUkdVbTlrU0ZKM0NtTjZiM1pNTW1Sd1pFZG9NVmxwTldwaU1qQjJZa2hHYWs1cVNUQk1NazVvWTJreGVXUlhOVEJoVnpGc1RIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTUtZak5rZWt3elNteGlSMVpvWXpKVmRXVlhNWE5SU0Vwc1dtNU5kbVJIUm01amVUaDRUR3BKTUV4cVJYZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JYZFJjUXBFUTJjMFRrZEpkMDFFVFRWWmFsVjVXWHBDYVZsVVNYcE5WRWt6V2tkTmVWa3lUVEZPYWtVeldrUk9iRTV0VG14YVJFVTBXbTFaTWsxQ1kwZERhWE5IQ2tGUlVVSm5OemgzUVZKUlJVTlJkMGhqYlZaeldsZEdlbHBVUWxwQ1oyOXlRbWRGUlVGWlR5OU5RVVZXUWtWelRWTlhhREJrU0VKNlQyazRkbG95YkRBS1lVaFdhVXh0VG5aaVV6bHpZMWROTWsxcVVYWlpNa1o1VEZoS01XSnVVbkJpVjFWMldWZE9NR0ZYT1hWamVUbDVaRmMxZWt4NlVYcE9la0V4VFhwTk1RcE9WRmt4VERKR01HUkhWblJqU0ZKNlRIcEZkMFpuV1V0TGQxbENRa0ZIUkhaNlFVSkdaMUZKUkVGYWQyUlhTbk5oVjAxM1ZVRlpTMHQzV1VKQ1FVZEVDblo2UVVKSFFWSkRSRVZDZVZwWVFuWlBiWGg0V1hwWmVVNUZRVEpQVkVsNlRrUlZNazVET1dwWldFbDBZMjVXZFdSSGJIUmFWVUY0VFhwWmVFMVVhM2tLVG5wRk1FOXVTbXhhYW5CNVdsZGFla3d6VW1oYU0wMTJUVk0wZVU1RE5IaE5TVWRMUW1kdmNrSm5SVVZCWkZvMVFXZFJRMEpJZDBWbFowSTBRVWhaUVFvelZEQjNZWE5pU0VWVVNtcEhValJqYlZkak0wRnhTa3RZY21wbFVFc3pMMmcwY0hsblF6aHdOMjgwUVVGQlIyZ3pjM3BYYUhkQlFVSkJUVUZTZWtKR0NrRnBSVUV5UmpGSVJUQjVjbTlUVWtaWE5IZFBlSGhyVldkaU16aExjMEZFY0VoWE4ydEpRbEozZEhWb1NXVXdRMGxDYTFsSmVtUnpVVXh1UTFkclZFa0tibmRRTnpSM1ZuUnVXSE5UV0dwMlpUbEVUV1JXTUVnNVlVNVJXVTFCYjBkRFEzRkhVMDAwT1VKQlRVUkJNbWRCVFVkVlEwMVJRM2RpZDJSR1IwUnFkZ3AzV0N0SmNuaGxSRFUzV1dOcVNrTTRWVVJNT0VVNVFYcHFhbUYxV25jeE5tNVVSVzV3YW5oQ00wczFiWGxpV2tKTVRrdDFXQ3QzUTAxR015dHFNVFUwQ2poV1ppdDRjMDl1VFdKTloyTkRZVlkzV25aU2FWRk5ZVlJKVmt4WVNqQnBlU3RFYTFWRVNUQkRSMWh6VW01NlNrRlVWa28zWlhKUllrRTlQUW90TFMwdExVVk9SQ0JEUlZKVVNVWkpRMEZVUlMwdExTMHRDZz09In19fX0=","integratedTime":1794739329,"logIndex":3900403779,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}}
@@ -1,3 +1,4 @@
1
+ import { appendSettlement } from './settlement.js';
1
2
  /** 扫描日志中未闭合的 turn(有 turnStart 语义的用户事件但没有 turnEnd)与未配对 toolCall */
2
3
  export function recoverInterrupted(log) {
3
4
  const report = { turnsClosed: 0, pairedCalls: 0 };
@@ -31,7 +32,10 @@ export function recoverInterrupted(log) {
31
32
  report.pairedCalls++;
32
33
  }
33
34
  // 未闭合 turn → 补记 turnEnd=interrupted(不可与 aborted 混用)
35
+ // 1.24-W2(D-W2-2):补记前先落 settlement——部分链对账 = hasUnknownOutcomes 主战场
36
+ // (上方成对补记的 recovered:true 合成结果在结算里按「结果不明」显式记账,不丢信号)
34
37
  for (const turnId of openTurns) {
38
+ appendSettlement(log, turnId, { reason: 'interrupted', recovered: true });
35
39
  log.append('runtime', 'turnEnd', turnId, null, { reason: 'interrupted', recovered: true });
36
40
  report.turnsClosed++;
37
41
  }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 1.24-W2 · 回合结算回执(settlement receipt)
3
+ *
4
+ * 口径(《Qwen-Code 对照分析》§2.3/§5 / 借鉴四篇裁决记录 Q-W2 / 迭代规划 D-W2-1~6):
5
+ * - 「结算必留回执」:任何 turn 无论成败都有一张结构化凭据——观测 / 恢复 / 审计消费同一张
6
+ * - 落链形态 = kind:'system' + payload.type:'settlement'(EventKind 零新增;payload.type 扩展
7
+ * 沿 routing 'decide' / memory 'write|edit|delete|rollback' 先例);一 turn 一张,llm 面与
8
+ * tool 节合并(D-W2-1)
9
+ * - 产出点仅两处:runTurn closeTurn(turnEnd 之前——turnEnd 保持终止标记语义)与
10
+ * recoverInterrupted 补记(部分链对账);authz 台账 turnEnd 与 facade sessionStop 不经
11
+ * closeTurn、不触发(D-W2-2 登记)
12
+ * - 事实源 = 链(非运行时状态):两本账按链上 toolCall/toolResult payload.id 对账;
13
+ * permissionDenialCount = toolResult error:'authorization-denied' 且 granted===false;
14
+ * hasUnknownOutcomes = 无配对 toolResult 或配对结果 recovered:true(副作用状态未知显式记账);
15
+ * bounded = aborted-before-dispatch 补记形态在链(取消落在派发边界,未打断在途执行)
16
+ * - 字段 CAR 化:outcome 由 reason 映射(complete|interrupted|failed);failureKind = 1.23
17
+ * meta.kind 诚实缺键;assistantSeq 代 Qwen assistantMessageUuid;Qwen nextMaxOutputTokens
18
+ * 在 CAR 无对应机制 → 诚实缺键不预埋(D-W2-3 偏差登记)
19
+ * - turnEnd meta 零变化:settlement 是独立事件非 meta 尾键(D-W2-4,s78-16 字节兼容锚不动);
20
+ * stopRequested 经 closeTurn hints 传递不落 meta
21
+ * - kill-switch:CAR_SETTLEMENT=off 跳过 append(K1 env 逐 turn 求值先例);缺省开(D-W2-5)
22
+ * - 链量纪律(R-W2):定长小 payload——账本数组 cap 64 + truncated 标记;内容类信息不进链
23
+ */
24
+ import type { SessionLog } from '../session/log.ts';
25
+ export type SettlementOutcome = 'complete' | 'interrupted' | 'failed';
26
+ /** 账本数组上限(超出截断 + ledgerTruncated 标记——防病态长 turn 链量失控) */
27
+ export declare const SETTLEMENT_LEDGER_CAP = 64;
28
+ export interface SettlementHints {
29
+ /** terminate 型收口(工具主动 stop 语义,stop.ts closeTurn hints——不落 turnEnd meta) */
30
+ stopRequested?: boolean;
31
+ }
32
+ /** TurnEndReason → settlement outcome 映射(completed/max-tokens=complete;aborted/interrupted=interrupted;error/blocked=failed) */
33
+ export declare function outcomeFromReason(reason: string): SettlementOutcome;
34
+ /**
35
+ * 结算回执落链(closeTurn / recover 共用单点)。meta = 同 turn turnEnd 将携带的 meta
36
+ * (reason/kind 等事实同源);usage/hints 缺省时从链自证(requestSent 由 usage 事件或
37
+ * assistant 在场推导)。
38
+ */
39
+ export declare function appendSettlement(log: SessionLog, turnId: string, meta: Record<string, unknown>, hints?: SettlementHints): void;
@@ -0,0 +1,76 @@
1
+ /** 账本数组上限(超出截断 + ledgerTruncated 标记——防病态长 turn 链量失控) */
2
+ export const SETTLEMENT_LEDGER_CAP = 64;
3
+ /** TurnEndReason → settlement outcome 映射(completed/max-tokens=complete;aborted/interrupted=interrupted;error/blocked=failed) */
4
+ export function outcomeFromReason(reason) {
5
+ if (reason === 'completed' || reason === 'max-tokens')
6
+ return 'complete';
7
+ if (reason === 'aborted' || reason === 'interrupted')
8
+ return 'interrupted';
9
+ return 'failed';
10
+ }
11
+ /**
12
+ * 结算回执落链(closeTurn / recover 共用单点)。meta = 同 turn turnEnd 将携带的 meta
13
+ * (reason/kind 等事实同源);usage/hints 缺省时从链自证(requestSent 由 usage 事件或
14
+ * assistant 在场推导)。
15
+ */
16
+ export function appendSettlement(log, turnId, meta, hints) {
17
+ if (process.env.CAR_SETTLEMENT === 'off')
18
+ return;
19
+ const reason = typeof meta.reason === 'string' ? meta.reason : 'error';
20
+ const kind = typeof meta.kind === 'string' ? meta.kind : undefined;
21
+ // 单次链扫描:两本账 + 拒绝计数 + unknown/bounded 事实 + requestSent 事实 + assistantSeq
22
+ const declared = [];
23
+ const resultById = new Map();
24
+ let denialCount = 0;
25
+ let bounded = false;
26
+ let usageRequests = 0;
27
+ let assistantSeq;
28
+ for (const e of log.events) {
29
+ if (e.turnId !== turnId)
30
+ continue;
31
+ const p = (e.payload ?? {});
32
+ if (e.kind === 'toolCall') {
33
+ if (typeof p.id === 'string')
34
+ declared.push(p.id);
35
+ }
36
+ else if (e.kind === 'toolResult') {
37
+ if (typeof p.id === 'string') {
38
+ resultById.set(p.id, p); // 1.6-S1 last-wins 同款口径
39
+ if (p.error === 'authorization-denied' && p.granted === false)
40
+ denialCount++;
41
+ if (p.error === 'aborted-before-dispatch')
42
+ bounded = true;
43
+ }
44
+ }
45
+ else if (e.kind === 'usage') {
46
+ usageRequests++;
47
+ }
48
+ else if (e.kind === 'assistant') {
49
+ assistantSeq = e.seq;
50
+ }
51
+ }
52
+ const dispatched = [...resultById.keys()];
53
+ const unknownIds = declared.filter((id) => {
54
+ const res = resultById.get(id);
55
+ return !res || res.recovered === true;
56
+ });
57
+ const cap = (arr) => (arr.length > SETTLEMENT_LEDGER_CAP ? arr.slice(0, SETTLEMENT_LEDGER_CAP) : arr);
58
+ const ledgerTruncated = declared.length > SETTLEMENT_LEDGER_CAP || dispatched.length > SETTLEMENT_LEDGER_CAP;
59
+ log.append('runtime', 'system', turnId, {
60
+ type: 'settlement',
61
+ outcome: outcomeFromReason(reason),
62
+ ...(kind ? { failureKind: kind } : {}),
63
+ requestSent: usageRequests > 0 || assistantSeq !== undefined,
64
+ ...(assistantSeq !== undefined ? { assistantSeq } : {}),
65
+ declaredToolUseIds: cap(declared),
66
+ dispatchedToolUseIds: cap(dispatched),
67
+ ...(ledgerTruncated ? { ledgerTruncated: true } : {}),
68
+ tool: {
69
+ permissionDenialCount: denialCount,
70
+ hasUnknownOutcomes: unknownIds.length > 0,
71
+ ...(unknownIds.length ? { unknownToolUseIds: cap(unknownIds) } : {}),
72
+ stopRequested: hints?.stopRequested === true,
73
+ bounded,
74
+ },
75
+ });
76
+ }
package/dist/loop/stop.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { CarM8Error } from '../runtime-core/errors.js';
2
+ import { appendSettlement } from './settlement.js';
2
3
  /**
3
4
  * 1.23-W1(D-W1-6):取消时机标注(W-0 审计 F-W0-3——aborted 三路径链上不区分)——
4
5
  * 'before-request' = 请求未发出(runTurn 循环头 / chatStep 零 chunk 流结束检查);
@@ -55,13 +56,16 @@ export async function runTurn(opts) {
55
56
  let steps = 0;
56
57
  // 1.11-S2(D-33):turnEnd 落链单点包装——聚合本 turn usage 事件(无 usage 不带键,
57
58
  // 缺省=未采集向后兼容);reason 保持 meta 首键,usage 恒为加法尾键
58
- const closeTurn = (meta) => {
59
+ // 1.24-W2(D-W2-2):turnEnd 之前先落 settlement 结算回执(turnEnd 保持终止标记语义;
60
+ // hints 仅 terminate 收口传递 stopRequested——不落 turnEnd meta,D-W2-4)
61
+ const closeTurn = (meta, hints) => {
59
62
  const usage = turnUsageFrom(log, turnId);
60
63
  // 1.18.2-K8(R-K7-2):计量缺失 fail-visible——商汤网关实测 20% 概率 message_delta
61
64
  // 不带 usage(流正常回复但计量整条缺席)→ 缺失口径纪律不落半条事实(turnUsageFrom
62
65
  // undefined),缺失本身在此显式标注:本 turn 存在 assistant 事件(模型有可见输出 ⇒
63
66
  // 必有请求)而无 usage 聚合时带 usageMissing: true(加法尾键,与 usage 同语义位)
64
67
  const hasAssistant = log.events.some((e) => e.kind === 'assistant' && e.turnId === turnId);
68
+ appendSettlement(log, turnId, meta, hints);
65
69
  return log.append('runtime', 'turnEnd', turnId, null, {
66
70
  ...meta,
67
71
  ...(usage ? { usage } : hasAssistant ? { usageMissing: true } : {}),
@@ -237,7 +241,8 @@ export async function runTurn(opts) {
237
241
  const agg = preset.aggregate ?? {};
238
242
  const abortedNow = (agg.terminate ?? 'all') === 'any' ? batch.terminateVotes > 0 : batch.terminateAll;
239
243
  if (abortedNow) { // terminate 收口:默认 AND(整批),可配置 any
240
- const seq = closeTurn({ reason: 'aborted' }).seq;
244
+ // 1.24-W2:工具主动 stop 语义 → settlement stopRequested=true(hints 不落 meta,D-W2-4)
245
+ const seq = closeTurn({ reason: 'aborted' }, { stopRequested: true }).seq;
241
246
  trail.push({ seq, reason: 'aborted' });
242
247
  return { reason: 'aborted', steps, endReasonTrail: trail };
243
248
  }
@@ -1,4 +1,4 @@
1
- {"stage":"archive","detail":"git archive HEAD → car-runtime-1.23.0.tgz(450442 bytes,树哈希锚定)","ts":1794727381948}
2
- {"stage":"sha256sums","detail":"SHA256SUMS 6e62dc16fe612b7b…(裸字节复核通过)","ts":1794727381950}
3
- {"stage":"sbom","detail":"55 个组件(运行时依赖 0 项)","ts":1794727381957}
4
- {"stage":"cosign-keyless","detail":"signed car-runtime-1.23.0.tgz (keyless OIDC + Rekor)","ts":1794727387719}
1
+ {"stage":"archive","detail":"git archive HEAD → car-runtime-1.24.1.tgz(457235 bytes,树哈希锚定)","ts":1794739327661}
2
+ {"stage":"sha256sums","detail":"SHA256SUMS 92e00b2804c1640d…(裸字节复核通过)","ts":1794739327662}
3
+ {"stage":"sbom","detail":"56 个组件(运行时依赖 0 项)","ts":1794739327668}
4
+ {"stage":"cosign-keyless","detail":"signed car-runtime-1.24.1.tgz (keyless OIDC + Rekor)","ts":1794739330230}
package/dist/sbom.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "bomFormat": "CAR-SBOM",
3
3
  "specVersion": "0.1",
4
- "version": "1.23.0",
4
+ "version": "1.24.1",
5
5
  "components": [
6
6
  {
7
7
  "type": "file",
@@ -101,12 +101,17 @@
101
101
  {
102
102
  "type": "file",
103
103
  "path": "src/loop/recover.ts",
104
- "sha256": "095d68827ae129f80f84cf485d7d2c41549dec99574311b8fe0f65fae9498ec5"
104
+ "sha256": "28f3ee3c244380b91ea5f037bb7920c55c2979ea5e818f77827ab2c473e1578a"
105
+ },
106
+ {
107
+ "type": "file",
108
+ "path": "src/loop/settlement.ts",
109
+ "sha256": "07b9da93f216f5bee4dc7e034e7e194e9a209449599e71371255c7cd388f4c3a"
105
110
  },
106
111
  {
107
112
  "type": "file",
108
113
  "path": "src/loop/stop.ts",
109
- "sha256": "a39751b233cbf42073af08fd9a6ba29f29a47700cd025fa79a3d5418e1116a60"
114
+ "sha256": "7e185d31c4c65ee4ba1d43135a609572e677a70f93110c183e34d593d8aaf0a6"
110
115
  },
111
116
  {
112
117
  "type": "file",
@@ -251,7 +256,7 @@
251
256
  {
252
257
  "type": "file",
253
258
  "path": "src/session/log.ts",
254
- "sha256": "e87fdaaeecb3ad71924664bd565369b8bfb7347500cd2d97c51c22c5c68ab8be"
259
+ "sha256": "7f6bcd67921db47f77537372eab3efb007c115c01110be77ce99bd9dd2f91a45"
255
260
  },
256
261
  {
257
262
  "type": "file",
@@ -271,7 +276,7 @@
271
276
  {
272
277
  "type": "file",
273
278
  "path": "package.json",
274
- "sha256": "593002604fb264718099c16d5a3d04b82d1a1073b7c8f8160fc7835f4a695e50"
279
+ "sha256": "440e90670135d3a84c3fd9c97595a6761dbcbfc7fb8b8a39c5b087df0d05c346"
275
280
  },
276
281
  {
277
282
  "type": "file",
@@ -132,6 +132,11 @@ export class SessionLog {
132
132
  let pendingThinkingTurn = null;
133
133
  let pendingBlocks = [];
134
134
  for (const e of projected) {
135
+ // 1.24-W2(D-W2-1):settlement 回执不投影(model_visible=0 同 usage 纪律——结算凭据是
136
+ // 审计面事实非模型上下文;system kind 语义位但 payload.type 判别排除,先于 thinking
137
+ // 隔断检查,杜绝任何投影面影响;无 settlement 链投影逐字节不变)
138
+ if (e.kind === 'system' && e.payload?.type === 'settlement')
139
+ continue;
135
140
  if (pendingBlocks.length && (e.turnId !== pendingThinkingTurn || e.kind === 'user' || e.kind === 'system'))
136
141
  pendingBlocks = [];
137
142
  if (e.kind === 'thinking') {
@@ -146,8 +151,18 @@ export class SessionLog {
146
151
  }
147
152
  continue; // thinking 不单独成消息(无独立回传语义)
148
153
  }
149
- if (e.kind === 'system')
154
+ if (e.kind === 'system') {
155
+ // 1.24.1(F4 / 桌面 B-2 演练 2026-11-15 实锤):对象形态 system = 宿主审计叙事
156
+ //(browser/*、bash/*、session/* 等 payload.type 载体)——不投影(model_visible=0 与
157
+ // settlement 同纪律)。对象叙事落在 assistant(toolCall) 与 toolResult 之间会破坏
158
+ // tool 消息相邻性——openai 严格网关 400("insufficient tool messages following",
159
+ // tokenhub deepseek 槽演练实锤);anthropic 宽容网关则表现为叙事脏上下文。
160
+ // payload 字符串 = system prompt(1.4-S2)/ persona 注入(T-MP)——设计内模型可见,保持投影。
161
+ // 隔断语义不变(对象 system 仍隔断跨叙事 thinking 附加——上一行口径)。
162
+ if (typeof e.payload !== 'string')
163
+ continue;
150
164
  out.push({ role: 'system', content: e.payload });
165
+ }
151
166
  else if (e.kind === 'user')
152
167
  out.push({ role: 'user', content: e.payload });
153
168
  else if (e.kind === 'assistant')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lqc123qwe/car-runtime",
3
- "version": "1.23.0",
3
+ "version": "1.24.1",
4
4
  "description": "Composable Agent Runtime (CAR) - microkernel plugin system with sandboxed PTC, append-only hashed session log, and MCP host bridge",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -7,6 +7,7 @@
7
7
  * - 副作用审计:补记事件带 recovered=true 标记(副作用是否落地由恢复层显式声明为未知)
8
8
  */
9
9
  import type { SessionLog, SessionEvent } from '../session/log.ts'
10
+ import { appendSettlement } from './settlement.ts'
10
11
 
11
12
  export interface RecoveryReport {
12
13
  /** 补记 interrupted 的 turn 数 */
@@ -39,7 +40,10 @@ export function recoverInterrupted(log: SessionLog): RecoveryReport {
39
40
  report.pairedCalls++
40
41
  }
41
42
  // 未闭合 turn → 补记 turnEnd=interrupted(不可与 aborted 混用)
43
+ // 1.24-W2(D-W2-2):补记前先落 settlement——部分链对账 = hasUnknownOutcomes 主战场
44
+ // (上方成对补记的 recovered:true 合成结果在结算里按「结果不明」显式记账,不丢信号)
42
45
  for (const turnId of openTurns) {
46
+ appendSettlement(log, turnId, { reason: 'interrupted', recovered: true })
43
47
  log.append('runtime', 'turnEnd', turnId, null, { reason: 'interrupted', recovered: true })
44
48
  report.turnsClosed++
45
49
  }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * 1.24-W2 · 回合结算回执(settlement receipt)
3
+ *
4
+ * 口径(《Qwen-Code 对照分析》§2.3/§5 / 借鉴四篇裁决记录 Q-W2 / 迭代规划 D-W2-1~6):
5
+ * - 「结算必留回执」:任何 turn 无论成败都有一张结构化凭据——观测 / 恢复 / 审计消费同一张
6
+ * - 落链形态 = kind:'system' + payload.type:'settlement'(EventKind 零新增;payload.type 扩展
7
+ * 沿 routing 'decide' / memory 'write|edit|delete|rollback' 先例);一 turn 一张,llm 面与
8
+ * tool 节合并(D-W2-1)
9
+ * - 产出点仅两处:runTurn closeTurn(turnEnd 之前——turnEnd 保持终止标记语义)与
10
+ * recoverInterrupted 补记(部分链对账);authz 台账 turnEnd 与 facade sessionStop 不经
11
+ * closeTurn、不触发(D-W2-2 登记)
12
+ * - 事实源 = 链(非运行时状态):两本账按链上 toolCall/toolResult payload.id 对账;
13
+ * permissionDenialCount = toolResult error:'authorization-denied' 且 granted===false;
14
+ * hasUnknownOutcomes = 无配对 toolResult 或配对结果 recovered:true(副作用状态未知显式记账);
15
+ * bounded = aborted-before-dispatch 补记形态在链(取消落在派发边界,未打断在途执行)
16
+ * - 字段 CAR 化:outcome 由 reason 映射(complete|interrupted|failed);failureKind = 1.23
17
+ * meta.kind 诚实缺键;assistantSeq 代 Qwen assistantMessageUuid;Qwen nextMaxOutputTokens
18
+ * 在 CAR 无对应机制 → 诚实缺键不预埋(D-W2-3 偏差登记)
19
+ * - turnEnd meta 零变化:settlement 是独立事件非 meta 尾键(D-W2-4,s78-16 字节兼容锚不动);
20
+ * stopRequested 经 closeTurn hints 传递不落 meta
21
+ * - kill-switch:CAR_SETTLEMENT=off 跳过 append(K1 env 逐 turn 求值先例);缺省开(D-W2-5)
22
+ * - 链量纪律(R-W2):定长小 payload——账本数组 cap 64 + truncated 标记;内容类信息不进链
23
+ */
24
+ import type { SessionLog } from '../session/log.ts'
25
+
26
+ export type SettlementOutcome = 'complete' | 'interrupted' | 'failed'
27
+
28
+ /** 账本数组上限(超出截断 + ledgerTruncated 标记——防病态长 turn 链量失控) */
29
+ export const SETTLEMENT_LEDGER_CAP = 64
30
+
31
+ export interface SettlementHints {
32
+ /** terminate 型收口(工具主动 stop 语义,stop.ts closeTurn hints——不落 turnEnd meta) */
33
+ stopRequested?: boolean
34
+ }
35
+
36
+ /** TurnEndReason → settlement outcome 映射(completed/max-tokens=complete;aborted/interrupted=interrupted;error/blocked=failed) */
37
+ export function outcomeFromReason(reason: string): SettlementOutcome {
38
+ if (reason === 'completed' || reason === 'max-tokens') return 'complete'
39
+ if (reason === 'aborted' || reason === 'interrupted') return 'interrupted'
40
+ return 'failed'
41
+ }
42
+
43
+ /**
44
+ * 结算回执落链(closeTurn / recover 共用单点)。meta = 同 turn turnEnd 将携带的 meta
45
+ * (reason/kind 等事实同源);usage/hints 缺省时从链自证(requestSent 由 usage 事件或
46
+ * assistant 在场推导)。
47
+ */
48
+ export function appendSettlement(
49
+ log: SessionLog,
50
+ turnId: string,
51
+ meta: Record<string, unknown>,
52
+ hints?: SettlementHints,
53
+ ): void {
54
+ if (process.env.CAR_SETTLEMENT === 'off') return
55
+ const reason = typeof meta.reason === 'string' ? meta.reason : 'error'
56
+ const kind = typeof meta.kind === 'string' ? meta.kind : undefined
57
+
58
+ // 单次链扫描:两本账 + 拒绝计数 + unknown/bounded 事实 + requestSent 事实 + assistantSeq
59
+ const declared: string[] = []
60
+ const resultById = new Map<string, Record<string, unknown>>()
61
+ let denialCount = 0
62
+ let bounded = false
63
+ let usageRequests = 0
64
+ let assistantSeq: number | undefined
65
+ for (const e of log.events) {
66
+ if (e.turnId !== turnId) continue
67
+ const p = (e.payload ?? {}) as Record<string, unknown>
68
+ if (e.kind === 'toolCall') {
69
+ if (typeof p.id === 'string') declared.push(p.id)
70
+ } else if (e.kind === 'toolResult') {
71
+ if (typeof p.id === 'string') {
72
+ resultById.set(p.id, p) // 1.6-S1 last-wins 同款口径
73
+ if (p.error === 'authorization-denied' && p.granted === false) denialCount++
74
+ if (p.error === 'aborted-before-dispatch') bounded = true
75
+ }
76
+ } else if (e.kind === 'usage') {
77
+ usageRequests++
78
+ } else if (e.kind === 'assistant') {
79
+ assistantSeq = e.seq
80
+ }
81
+ }
82
+ const dispatched = [...resultById.keys()]
83
+ const unknownIds = declared.filter((id) => {
84
+ const res = resultById.get(id)
85
+ return !res || res.recovered === true
86
+ })
87
+ const cap = (arr: string[]) => (arr.length > SETTLEMENT_LEDGER_CAP ? arr.slice(0, SETTLEMENT_LEDGER_CAP) : arr)
88
+ const ledgerTruncated = declared.length > SETTLEMENT_LEDGER_CAP || dispatched.length > SETTLEMENT_LEDGER_CAP
89
+
90
+ log.append('runtime', 'system', turnId, {
91
+ type: 'settlement',
92
+ outcome: outcomeFromReason(reason),
93
+ ...(kind ? { failureKind: kind } : {}),
94
+ requestSent: usageRequests > 0 || assistantSeq !== undefined,
95
+ ...(assistantSeq !== undefined ? { assistantSeq } : {}),
96
+ declaredToolUseIds: cap(declared),
97
+ dispatchedToolUseIds: cap(dispatched),
98
+ ...(ledgerTruncated ? { ledgerTruncated: true } : {}),
99
+ tool: {
100
+ permissionDenialCount: denialCount,
101
+ hasUnknownOutcomes: unknownIds.length > 0,
102
+ ...(unknownIds.length ? { unknownToolUseIds: cap(unknownIds) } : {}),
103
+ stopRequested: hints?.stopRequested === true,
104
+ bounded,
105
+ },
106
+ })
107
+ }
package/src/loop/stop.ts CHANGED
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import type { SessionLog } from '../session/log.ts'
18
18
  import { CarM8Error } from '../runtime-core/errors.ts'
19
+ import { appendSettlement } from './settlement.ts'
19
20
 
20
21
  export type StepOutcome = 'completed' | 'max-tokens' | 'null'
21
22
  export type TurnEndReason = 'completed' | 'max-tokens' | 'aborted' | 'error' | 'blocked' | 'interrupted'
@@ -129,13 +130,16 @@ export async function runTurn(opts: {
129
130
 
130
131
  // 1.11-S2(D-33):turnEnd 落链单点包装——聚合本 turn usage 事件(无 usage 不带键,
131
132
  // 缺省=未采集向后兼容);reason 保持 meta 首键,usage 恒为加法尾键
132
- const closeTurn = (meta: Record<string, unknown>) => {
133
+ // 1.24-W2(D-W2-2):turnEnd 之前先落 settlement 结算回执(turnEnd 保持终止标记语义;
134
+ // hints 仅 terminate 收口传递 stopRequested——不落 turnEnd meta,D-W2-4)
135
+ const closeTurn = (meta: Record<string, unknown>, hints?: { stopRequested?: boolean }) => {
133
136
  const usage = turnUsageFrom(log, turnId)
134
137
  // 1.18.2-K8(R-K7-2):计量缺失 fail-visible——商汤网关实测 20% 概率 message_delta
135
138
  // 不带 usage(流正常回复但计量整条缺席)→ 缺失口径纪律不落半条事实(turnUsageFrom
136
139
  // undefined),缺失本身在此显式标注:本 turn 存在 assistant 事件(模型有可见输出 ⇒
137
140
  // 必有请求)而无 usage 聚合时带 usageMissing: true(加法尾键,与 usage 同语义位)
138
141
  const hasAssistant = log.events.some((e) => e.kind === 'assistant' && e.turnId === turnId)
142
+ appendSettlement(log, turnId, meta, hints)
139
143
  return log.append('runtime', 'turnEnd', turnId, null, {
140
144
  ...meta,
141
145
  ...(usage ? { usage } : hasAssistant ? { usageMissing: true } : {}),
@@ -301,7 +305,8 @@ export async function runTurn(opts: {
301
305
  const agg = preset.aggregate ?? {}
302
306
  const abortedNow = (agg.terminate ?? 'all') === 'any' ? batch.terminateVotes > 0 : batch.terminateAll
303
307
  if (abortedNow) { // terminate 收口:默认 AND(整批),可配置 any
304
- const seq = closeTurn({ reason: 'aborted' }).seq
308
+ // 1.24-W2:工具主动 stop 语义 → settlement stopRequested=true(hints 不落 meta,D-W2-4)
309
+ const seq = closeTurn({ reason: 'aborted' }, { stopRequested: true }).seq
305
310
  trail.push({ seq, reason: 'aborted' })
306
311
  return { reason: 'aborted', steps, endReasonTrail: trail }
307
312
  }
@@ -11,7 +11,7 @@ import { createHash } from 'node:crypto'
11
11
  import { readFileSync } from 'node:fs'
12
12
  import { decodeLogBuffer, splitJsonlLines } from './format.ts'
13
13
 
14
- export type EventKind = 'user' | 'assistant' | 'toolCall' | 'toolResult' | 'turnEnd' | 'goalUpdate' | 'hostRaw' | 'fork' | 'system' | 'usage' | 'compact' | 'routing' | 'memory' | 'thinking' // M3-S11 加法扩展:多宿主归一化降级通道(pattern 未命中留痕,零静默);M5-DEC4 加法扩展:跨宿主 fork 标记事件;1.4-S2 加法扩展:system prompt 落链(§3.5.5:新模型可见输入 = 新事件类型);1.11-S2 加法扩展:usage 计量事实(D-33,actor='runtime'、model_visible=0 不进模型消息流,deriveMessages 不投影);六值 TurnEndReason 不变;1.14-S2 加法扩展(K-MP-2 / D-40):历史压缩事件(actor='runtime',append-only 只追加——payload={summary, compactedUpTo, ...},投影按 compactedUpTo 前缀折叠为摘要,原事件链不改写);1.14-S4 加法扩展(K-POOL-1 / D-42):模型池路由决策(actor='runtime',payload.type='decide',selected/reason/retries/attempts——禁静默换模型;model_visible=0 不进模型消息流,deriveMessages 不投影——同 usage 纪律);1.15-S1 加法扩展(K-MEM-1 / D-46):白盒记忆操作事件(actor='user' 宿主代理用户操作,turnId='memory' 会话级标识同 'compaction' 先例,payload.type='write'|'edit'|'delete'|'rollback'——审计链同源差异化面,链即版本库〔rollback 恢复数据源=链上 payload.before/after 全文〕;model_visible=0 不进模型消息流——记忆注入走宿主装配层 system ctx 行,deriveMessages 不投影);1.21 加法扩展(R-TOKENHUB-1 / D-T2):thinking 事件(actor='model',payload=thinking 原文禁改写,meta={signature?, redacted?, secretsRedacted?}——先于 assistant/toolCall 落链;投影 = 同 turn 首个 toolCall 消息附加回传(工具环 reasoning_content 契约,Anthropic thinking+tool_use 规范同款);standalone/隔断/跨 turn 不投影;无 thinking 事件链投影逐字节不变;1.22 加法扩展(1.22 迭代规划 D-B1):多块语义——一块一事件(多块链每事件 meta.blockIndex=块序,单块链 meta 与 1.21 逐字节同形),投影单块 = 1.21 三元组、多块 = blocks 数组(D-B2,消费方 toAnthropic 双形态展开));
14
+ export type EventKind = 'user' | 'assistant' | 'toolCall' | 'toolResult' | 'turnEnd' | 'goalUpdate' | 'hostRaw' | 'fork' | 'system' | 'usage' | 'compact' | 'routing' | 'memory' | 'thinking' // M3-S11 加法扩展:多宿主归一化降级通道(pattern 未命中留痕,零静默);M5-DEC4 加法扩展:跨宿主 fork 标记事件;1.4-S2 加法扩展:system prompt 落链(§3.5.5:新模型可见输入 = 新事件类型);1.11-S2 加法扩展:usage 计量事实(D-33,actor='runtime'、model_visible=0 不进模型消息流,deriveMessages 不投影);六值 TurnEndReason 不变;1.14-S2 加法扩展(K-MP-2 / D-40):历史压缩事件(actor='runtime',append-only 只追加——payload={summary, compactedUpTo, ...},投影按 compactedUpTo 前缀折叠为摘要,原事件链不改写);1.14-S4 加法扩展(K-POOL-1 / D-42):模型池路由决策(actor='runtime',payload.type='decide',selected/reason/retries/attempts——禁静默换模型;model_visible=0 不进模型消息流,deriveMessages 不投影——同 usage 纪律);1.15-S1 加法扩展(K-MEM-1 / D-46):白盒记忆操作事件(actor='user' 宿主代理用户操作,turnId='memory' 会话级标识同 'compaction' 先例,payload.type='write'|'edit'|'delete'|'rollback'——审计链同源差异化面,链即版本库〔rollback 恢复数据源=链上 payload.before/after 全文〕;model_visible=0 不进模型消息流——记忆注入走宿主装配层 system ctx 行,deriveMessages 不投影);1.21 加法扩展(R-TOKENHUB-1 / D-T2):thinking 事件(actor='model',payload=thinking 原文禁改写,meta={signature?, redacted?, secretsRedacted?}——先于 assistant/toolCall 落链;投影 = 同 turn 首个 toolCall 消息附加回传(工具环 reasoning_content 契约,Anthropic thinking+tool_use 规范同款);standalone/隔断/跨 turn 不投影;无 thinking 事件链投影逐字节不变;1.22 加法扩展(1.22 迭代规划 D-B1):多块语义——一块一事件(多块链每事件 meta.blockIndex=块序,单块链 meta 与 1.21 逐字节同形),投影单块 = 1.21 三元组、多块 = blocks 数组(D-B2,消费方 toAnthropic 双形态展开);1.24-W2 加法扩展(Q-W2 / D-W2-1):system kind payload.type='settlement' 回合结算回执(actor='runtime',一 turn 一张——closeTurn〔turnEnd 之前〕与 recoverInterrupted 补记两产出点,字段见 loop/settlement.ts,CAR_SETTLEMENT=off 可关;model_visible=0 白名单不投影同 usage 纪律));
15
15
  export type Actor = 'user' | 'model' | 'plugin' | 'runtime'
16
16
  export interface SessionEvent {
17
17
  seq: number
@@ -156,6 +156,10 @@ export class SessionLog {
156
156
  let pendingThinkingTurn: string | null = null
157
157
  let pendingBlocks: Array<{ text: string; signature?: string; redacted?: boolean }> = []
158
158
  for (const e of projected) {
159
+ // 1.24-W2(D-W2-1):settlement 回执不投影(model_visible=0 同 usage 纪律——结算凭据是
160
+ // 审计面事实非模型上下文;system kind 语义位但 payload.type 判别排除,先于 thinking
161
+ // 隔断检查,杜绝任何投影面影响;无 settlement 链投影逐字节不变)
162
+ if (e.kind === 'system' && (e.payload as { type?: unknown } | null)?.type === 'settlement') continue
159
163
  if (pendingBlocks.length && (e.turnId !== pendingThinkingTurn || e.kind === 'user' || e.kind === 'system')) pendingBlocks = []
160
164
  if (e.kind === 'thinking') {
161
165
  const p = typeof e.payload === 'string' ? e.payload : ''
@@ -169,7 +173,17 @@ export class SessionLog {
169
173
  }
170
174
  continue // thinking 不单独成消息(无独立回传语义)
171
175
  }
172
- if (e.kind === 'system') out.push({ role: 'system', content: e.payload })
176
+ if (e.kind === 'system') {
177
+ // 1.24.1(F4 / 桌面 B-2 演练 2026-11-15 实锤):对象形态 system = 宿主审计叙事
178
+ //(browser/*、bash/*、session/* 等 payload.type 载体)——不投影(model_visible=0 与
179
+ // settlement 同纪律)。对象叙事落在 assistant(toolCall) 与 toolResult 之间会破坏
180
+ // tool 消息相邻性——openai 严格网关 400("insufficient tool messages following",
181
+ // tokenhub deepseek 槽演练实锤);anthropic 宽容网关则表现为叙事脏上下文。
182
+ // payload 字符串 = system prompt(1.4-S2)/ persona 注入(T-MP)——设计内模型可见,保持投影。
183
+ // 隔断语义不变(对象 system 仍隔断跨叙事 thinking 附加——上一行口径)。
184
+ if (typeof e.payload !== 'string') continue
185
+ out.push({ role: 'system', content: e.payload })
186
+ }
173
187
  else if (e.kind === 'user') out.push({ role: 'user', content: e.payload })
174
188
  else if (e.kind === 'assistant') out.push({ role: 'assistant', content: e.payload })
175
189
  else if (e.kind === 'toolCall') {
Binary file
@@ -1 +0,0 @@
1
- {"base64Signature":"MEYCIQDW2ZdCjKblGFqrvmJOVOwajIkbcz3Y5rSVCO/xoU0CgwIhALOUpcq1yOaJXrvFJPepFRLaUqz1gAcNINk5Ix81rKrv","cert":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUc2VENDQm02Z0F3SUJBZ0lVVUhrY0dRTEVYcnFOWFdNSzN0TnQxaE01R3ljd0NnWUlLb1pJemowRUF3TXcKTnpFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUjR3SEFZRFZRUURFeFZ6YVdkemRHOXlaUzFwYm5SbApjbTFsWkdsaGRHVXdIaGNOTWpZeE1URTFNRGN5TXpBeVdoY05Nall4TVRFMU1EY3pNekF5V2pBQU1Ga3dFd1lICktvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVIWU1COWxHSExQelVFd291cFB1S2s5OExENnpsZzlyUURaY3oKR2g2YzhZY0N0a0VUVnZnN0g2eU5UL3VudjA3VG0raEdSVVNoUHBkVTFxekNCT1A3NWFPQ0JZMHdnZ1dKTUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREF6QWZCZ05WSFNNRUdEQVdnQlRmCjArblBWaVFSbHZtbzJPa29WYUxHTGhoa1B6QmlCZ05WSFJFQkFmOEVXREJXaGxSb2RIUndjem92TDJkcGRHaDEKWWk1amIyMHZiSEZqTmpJMEwyTmhjaTF5ZFc1MGFXMWxMeTVuYVhSb2RXSXZkMjl5YTJac2IzZHpMM0psYkdWaApjMlV1ZVcxc1FISmxabk12ZEdGbmN5OHhMakl6TGpBd09RWUtLd1lCQkFHRHZ6QUJBUVFyYUhSMGNITTZMeTkwCmIydGxiaTVoWTNScGIyNXpMbWRwZEdoMVluVnpaWEpqYjI1MFpXNTBMbU52YlRBVkJnb3JCZ0VFQVlPL01BRUMKQkFkeVpXeGxZWE5sTURZR0Npc0dBUVFCZzc4d0FRTUVLRFUwTURWa1lqbGlaR0U0TURaak0yTXpaV1ZrWVRVMwpOV014WldJMFlXVTBPREE0WWpWaE16SXdGUVlLS3dZQkJBR0R2ekFCQkFRSGNtVnNaV0Z6WlRBZ0Jnb3JCZ0VFCkFZTy9NQUVGQkJKc2NXTTJNalF2WTJGeUxYSjFiblJwYldVd0hnWUtLd1lCQkFHRHZ6QUJCZ1FRY21WbWN5OTAKWVdkekx6RXVNak11TURBN0Jnb3JCZ0VFQVlPL01BRUlCQzBNSzJoMGRIQnpPaTh2ZEc5clpXNHVZV04wYVc5dQpjeTVuYVhSb2RXSjFjMlZ5WTI5dWRHVnVkQzVqYjIwd1pBWUtLd1lCQkFHRHZ6QUJDUVJXREZSb2RIUndjem92CkwyZHBkR2gxWWk1amIyMHZiSEZqTmpJMEwyTmhjaTF5ZFc1MGFXMWxMeTVuYVhSb2RXSXZkMjl5YTJac2IzZHoKTDNKbGJHVmhjMlV1ZVcxc1FISmxabk12ZEdGbmN5OHhMakl6TGpBd09BWUtLd1lCQkFHRHZ6QUJDZ1FxRENnMQpOREExWkdJNVltUmhPREEyWXpOak0yVmxaR0UxTnpWak1XVmlOR0ZsTkRnd09HSTFZVE15TUIwR0Npc0dBUVFCCmc3OHdBUXNFRHd3TloybDBhSFZpTFdodmMzUmxaREExQmdvckJnRUVBWU8vTUFFTUJDY01KV2gwZEhCek9pOHYKWjJsMGFIVmlMbU52YlM5c2NXTTJNalF2WTJGeUxYSjFiblJwYldVd09BWUtLd1lCQkFHRHZ6QUJEUVFxRENnMQpOREExWkdJNVltUmhPREEyWXpOak0yVmxaR0UxTnpWak1XVmlOR0ZsTkRnd09HSTFZVE15TUNBR0Npc0dBUVFCCmc3OHdBUTRFRWd3UWNtVm1jeTkwWVdkekx6RXVNak11TURBYUJnb3JCZ0VFQVlPL01BRVBCQXdNQ2pFek5qRXgKT1RJM01UUXdLUVlLS3dZQkJBR0R2ekFCRUFRYkRCbG9kSFJ3Y3pvdkwyZHBkR2gxWWk1amIyMHZiSEZqTmpJMApNQmdHQ2lzR0FRUUJnNzh3QVJFRUNnd0lOamt5TXpRMU5qUXdaQVlLS3dZQkJBR0R2ekFCRWdSV0RGUm9kSFJ3CmN6b3ZMMmRwZEdoMVlpNWpiMjB2YkhGak5qSTBMMk5oY2kxeWRXNTBhVzFsTHk1bmFYUm9kV0l2ZDI5eWEyWnMKYjNkekwzSmxiR1ZoYzJVdWVXMXNRSEpsWm5NdmRHRm5jeTh4TGpJekxqQXdPQVlLS3dZQkJBR0R2ekFCRXdRcQpEQ2cxTkRBMVpHSTVZbVJoT0RBMll6TmpNMlZsWkdFMU56VmpNV1ZpTkdGbE5EZ3dPR0kxWVRNeU1CY0dDaXNHCkFRUUJnNzh3QVJRRUNRd0hjbVZzWldGelpUQlpCZ29yQmdFRUFZTy9NQUVWQkVzTVNXaDBkSEJ6T2k4dloybDAKYUhWaUxtTnZiUzlzY1dNMk1qUXZZMkZ5TFhKMWJuUnBiV1V2WVdOMGFXOXVjeTl5ZFc1ekx6UXpOamc1TmpnNApNekV3TDJGMGRHVnRjSFJ6THpFd0ZnWUtLd1lCQkFHRHZ6QUJGZ1FJREFad2RXSnNhV013VUFZS0t3WUJCQUdECnZ6QUJHQVJDREVCeVpYQnZPbXh4WXpZeU5FQTJPVEl6TkRVMk5DOWpZWEl0Y25WdWRHbHRaVUF4TXpZeE1Ua3kKTnpFME9uSmxaanB5WldaekwzUmhaM012TVM0eU15NHdNSUdMQmdvckJnRUVBZFo1QWdRQ0JIMEVld0I1QUhjQQozVDB3YXNiSEVUSmpHUjRjbVdjM0FxSktYcmplUEszL2g0cHlnQzhwN280QUFBR2gzaGFQbmdBQUJBTUFTREJHCkFpRUF2Wkp2ZFdYdHZXc2VxOWR5MGRjWU43L0F3Q1BJZ0dRV3FMME1oTWZZb0xnQ0lRRDdYTk1sVnZ4VGE2ZUQKZVZ3ZEczcGhjZWh4NVhrTTZqVTdyRkY4VmpTdyt6QUtCZ2dxaGtqT1BRUURBd05wQURCbUFqRUFnaUptNlBGQwprWjV5bHNDaW42a0pFQkFHVjZyRW1QV0xxQW5yak5seDRUVnRZSnBHMm5UQThJNFBRRkFrV0ROdUFqRUF6dlJqCmg3dEhTNVQzYWlBVXZvVmlMZmZnSlgzMk52dk5RdFJCWndZQlBya3F2RW40OU0weFBoa0VqQWZ5TVdiQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==","rekorBundle":{"SignedEntryTimestamp":"MEQCIDFX1LK6tAMq5Zen3TbpVZE22INBCyh2O1gxEqUxIE8MAiA6L4cok518P7smZs+PnaPqiaXNB3zTFGx8g3v3hJW4/g==","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI2ZTYyZGMxNmZlNjEyYjdiYjUyNGE4MjMzYzYwNDI4YjFhNmY3NjY4NWRkOWQ5ZGE3NWRjNzc0OWVhZGQwY2YwIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUURXMlpkQ2pLYmxHRnFydm1KT1ZPd2FqSWtiY3ozWTVyU1ZDTy94b1UwQ2d3SWhBTE9VcGNxMXlPYUpYcnZGSlBlcEZSTGFVcXoxZ0FjTklOazVJeDgxcktydiIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVYzJWRU5EUW0wMlowRjNTVUpCWjBsVlZVaHJZMGRSVEVWWWNuRk9XRmROU3pOMFRuUXhhRTAxUjNsamQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFplRTFVUlRGTlJHTjVUWHBCZVZkb1kwNU5hbGw0VFZSRk1VMUVZM3BOZWtGNVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZJV1UxQ09XeEhTRXhRZWxWRmQyOTFjRkIxUzJzNU9FeEVObnBzWnpseVVVUmFZM29LUjJnMll6aFpZME4wYTBWVVZuWm5OMGcyZVU1VUwzVnVkakEzVkcwcmFFZFNWVk5vVUhCa1ZURnhla05DVDFBM05XRlBRMEpaTUhkbloxZEtUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXWkNaMDVXU0ZOTlJVZEVRVmRuUWxSbUNqQXJibEJXYVZGU2JIWnRiekpQYTI5V1lVeEhUR2hvYTFCNlFtbENaMDVXU0ZKRlFrRm1PRVZYUkVKWGFHeFNiMlJJVW5kamVtOTJUREprY0dSSGFERUtXV2sxYW1JeU1IWmlTRVpxVG1wSk1Fd3lUbWhqYVRGNVpGYzFNR0ZYTVd4TWVUVnVZVmhTYjJSWFNYWmtNamw1WVRKYWMySXpaSHBNTTBwc1lrZFdhQXBqTWxWMVpWY3hjMUZJU214YWJrMTJaRWRHYm1ONU9IaE1ha2w2VEdwQmQwOVJXVXRMZDFsQ1FrRkhSSFo2UVVKQlVWRnlZVWhTTUdOSVRUWk1lVGt3Q21JeWRHeGlhVFZvV1ROU2NHSXlOWHBNYldSd1pFZG9NVmx1Vm5wYVdFcHFZakkxTUZwWE5UQk1iVTUyWWxSQlZrSm5iM0pDWjBWRlFWbFBMMDFCUlVNS1FrRmtlVnBYZUd4WldFNXNUVVJaUjBOcGMwZEJVVkZDWnpjNGQwRlJUVVZMUkZVd1RVUldhMWxxYkdsYVIwVTBUVVJhYWsweVRYcGFWMVpyV1ZSVk13cE9WMDE0V2xkSk1GbFhWVEJQUkVFMFdXcFdhRTE2U1hkR1VWbExTM2RaUWtKQlIwUjJla0ZDUWtGUlNHTnRWbk5hVjBaNldsUkJaMEpuYjNKQ1owVkZDa0ZaVHk5TlFVVkdRa0pLYzJOWFRUSk5hbEYyV1RKR2VVeFlTakZpYmxKd1lsZFZkMGhuV1V0TGQxbENRa0ZIUkhaNlFVSkNaMUZSWTIxV2JXTjVPVEFLV1Zka2VreDZSWFZOYWsxMVRVUkJOMEpuYjNKQ1owVkZRVmxQTDAxQlJVbENRekJOU3pKb01HUklRbnBQYVRoMlpFYzVjbHBYTkhWWlYwNHdZVmM1ZFFwamVUVnVZVmhTYjJSWFNqRmpNbFo1V1RJNWRXUkhWblZrUXpWcVlqSXdkMXBCV1V0TGQxbENRa0ZIUkhaNlFVSkRVVkpYUkVaU2IyUklVbmRqZW05MkNrd3laSEJrUjJneFdXazFhbUl5TUhaaVNFWnFUbXBKTUV3eVRtaGphVEY1WkZjMU1HRlhNV3hNZVRWdVlWaFNiMlJYU1haa01qbDVZVEphYzJJelpIb0tURE5LYkdKSFZtaGpNbFYxWlZjeGMxRklTbXhhYmsxMlpFZEdibU41T0hoTWFrbDZUR3BCZDA5QldVdExkMWxDUWtGSFJIWjZRVUpEWjFGeFJFTm5NUXBPUkVFeFdrZEpOVmx0VW1oUFJFRXlXWHBPYWsweVZteGFSMFV4VG5wV2FrMVhWbWxPUjBac1RrUm5kMDlIU1RGWlZFMTVUVUl3UjBOcGMwZEJVVkZDQ21jM09IZEJVWE5GUkhkM1Rsb3liREJoU0ZacFRGZG9kbU16VW14YVJFRXhRbWR2Y2tKblJVVkJXVTh2VFVGRlRVSkRZMDFLVjJnd1pFaENlazlwT0hZS1dqSnNNR0ZJVm1sTWJVNTJZbE01YzJOWFRUSk5hbEYyV1RKR2VVeFlTakZpYmxKd1lsZFZkMDlCV1V0TGQxbENRa0ZIUkhaNlFVSkVVVkZ4UkVObk1RcE9SRUV4V2tkSk5WbHRVbWhQUkVFeVdYcE9hazB5Vm14YVIwVXhUbnBXYWsxWFZtbE9SMFpzVGtSbmQwOUhTVEZaVkUxNVRVTkJSME5wYzBkQlVWRkNDbWMzT0hkQlVUUkZSV2QzVVdOdFZtMWplVGt3V1Zka2VreDZSWFZOYWsxMVRVUkJZVUpuYjNKQ1owVkZRVmxQTDAxQlJWQkNRWGROUTJwRmVrNXFSWGdLVDFSSk0wMVVVWGRMVVZsTFMzZFpRa0pCUjBSMmVrRkNSVUZSWWtSQ2JHOWtTRkozWTNwdmRrd3laSEJrUjJneFdXazFhbUl5TUhaaVNFWnFUbXBKTUFwTlFtZEhRMmx6UjBGUlVVSm5OemgzUVZKRlJVTm5kMGxPYW10NVRYcFJNVTVxVVhkYVFWbExTM2RaUWtKQlIwUjJla0ZDUldkU1YwUkdVbTlrU0ZKM0NtTjZiM1pNTW1Sd1pFZG9NVmxwTldwaU1qQjJZa2hHYWs1cVNUQk1NazVvWTJreGVXUlhOVEJoVnpGc1RIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTUtZak5rZWt3elNteGlSMVpvWXpKVmRXVlhNWE5SU0Vwc1dtNU5kbVJIUm01amVUaDRUR3BKZWt4cVFYZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JYZFJjUXBFUTJjeFRrUkJNVnBIU1RWWmJWSm9UMFJCTWxsNlRtcE5NbFpzV2tkRk1VNTZWbXBOVjFacFRrZEdiRTVFWjNkUFIwa3hXVlJOZVUxQ1kwZERhWE5IQ2tGUlVVSm5OemgzUVZKUlJVTlJkMGhqYlZaeldsZEdlbHBVUWxwQ1oyOXlRbWRGUlVGWlR5OU5RVVZXUWtWelRWTlhhREJrU0VKNlQyazRkbG95YkRBS1lVaFdhVXh0VG5aaVV6bHpZMWROTWsxcVVYWlpNa1o1VEZoS01XSnVVbkJpVjFWMldWZE9NR0ZYT1hWamVUbDVaRmMxZWt4NlVYcE9hbWMxVG1wbk5BcE5la1YzVERKR01HUkhWblJqU0ZKNlRIcEZkMFpuV1V0TGQxbENRa0ZIUkhaNlFVSkdaMUZKUkVGYWQyUlhTbk5oVjAxM1ZVRlpTMHQzV1VKQ1FVZEVDblo2UVVKSFFWSkRSRVZDZVZwWVFuWlBiWGg0V1hwWmVVNUZRVEpQVkVsNlRrUlZNazVET1dwWldFbDBZMjVXZFdSSGJIUmFWVUY0VFhwWmVFMVVhM2tLVG5wRk1FOXVTbXhhYW5CNVdsZGFla3d6VW1oYU0wMTJUVk0wZVUxNU5IZE5TVWRNUW1kdmNrSm5SVVZCWkZvMVFXZFJRMEpJTUVWbGQwSTFRVWhqUVFvelZEQjNZWE5pU0VWVVNtcEhValJqYlZkak0wRnhTa3RZY21wbFVFc3pMMmcwY0hsblF6aHdOMjgwUVVGQlIyZ3phR0ZRYm1kQlFVSkJUVUZUUkVKSENrRnBSVUYyV2twMlpGZFlkSFpYYzJWeE9XUjVNR1JqV1U0M0wwRjNRMUJKWjBkUlYzRk1NRTFvVFdaWmIweG5RMGxSUkRkWVRrMXNWblo0VkdFMlpVUUtaVlozWkVjemNHaGpaV2g0TlZoclRUWnFWVGR5UmtZNFZtcFRkeXQ2UVV0Q1oyZHhhR3RxVDFCUlVVUkJkMDV3UVVSQ2JVRnFSVUZuYVVwdE5sQkdRd3ByV2pWNWJITkRhVzQyYTBwRlFrRkhWalp5UlcxUVYweHhRVzV5YWs1c2VEUlVWblJaU25CSE1tNVVRVGhKTkZCUlJrRnJWMFJPZFVGcVJVRjZkbEpxQ21nM2RFaFROVlF6WVdsQlZYWnZWbWxNWm1ablNsZ3pNazUyZGs1UmRGSkNXbmRaUWxCeWEzRjJSVzQwT1Uwd2VGQm9hMFZxUVdaNVRWZGlRd290TFMwdExVVk9SQ0JEUlZKVVNVWkpRMEZVUlMwdExTMHRDZz09In19fX0=","integratedTime":1794727383,"logIndex":3896882215,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}}