@ouro.bot/cli 0.1.0-alpha.689 → 0.1.0-alpha.690
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/changelog.json
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.690",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Clear stale context-loss Sentinel-authored Flight Recorder blockers once later health checks recover, so transient sense failures cannot leave Arc stuck on an obsolete recovery ask."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.689",
|
|
6
12
|
"changes": [
|
|
@@ -609,8 +609,6 @@ function anchorFromResume(kind, resume) {
|
|
|
609
609
|
};
|
|
610
610
|
}
|
|
611
611
|
function readFlightRecorderEventsByIds(agentRoot, eventIds) {
|
|
612
|
-
if (eventIds.length === 0)
|
|
613
|
-
return [];
|
|
614
612
|
const wanted = new Set(eventIds);
|
|
615
613
|
const eventsRoot = path.join(agentRoot, "arc", "flight-recorder", "events");
|
|
616
614
|
if (!fs.existsSync(eventsRoot))
|
|
@@ -634,16 +632,24 @@ function isSentinelAuthoredBlockerEvent(event) {
|
|
|
634
632
|
&& (event.meta?.source === "context-loss-sentinel"
|
|
635
633
|
|| Boolean(event.producedRefs?.some((ref) => ref.kind === "arc" && ref.locator.startsWith(relativeSentinelRoot()))));
|
|
636
634
|
}
|
|
637
|
-
function
|
|
635
|
+
function hasOnlySentinelAuthoredBlockers(agentRoot, resume) {
|
|
638
636
|
if (resume.blockedBecause.length === 0)
|
|
639
637
|
return false;
|
|
640
|
-
|
|
641
|
-
|
|
638
|
+
if (resume.lastSafeCheckpoint.sourceEventIds.length === 0)
|
|
639
|
+
return false;
|
|
640
|
+
const events = readFlightRecorderEventsByIds(agentRoot, resume.lastSafeCheckpoint.sourceEventIds);
|
|
641
|
+
const foundEventIds = new Set(events.map((event) => event.id));
|
|
642
|
+
if (resume.lastSafeCheckpoint.sourceEventIds.some((eventId) => !foundEventIds.has(eventId)))
|
|
643
|
+
return false;
|
|
644
|
+
const blockerEvents = events.filter((event) => (event.blockedBecause?.length ?? 0) > 0);
|
|
645
|
+
if (blockerEvents.length === 0)
|
|
646
|
+
return false;
|
|
647
|
+
return blockerEvents.every(isSentinelAuthoredBlockerEvent);
|
|
642
648
|
}
|
|
643
649
|
function selectGauntletResume(agentRoot) {
|
|
644
650
|
const resume = (0, flight_recorder_1.readFlightRecorderResume)(agentRoot);
|
|
645
651
|
const latestReady = readLatestReady(agentRoot);
|
|
646
|
-
if (
|
|
652
|
+
if (hasOnlySentinelAuthoredBlockers(agentRoot, resume) && latestReady) {
|
|
647
653
|
return { resume: latestReady.resumeSnapshot, anchorKind: "latest-ready" };
|
|
648
654
|
}
|
|
649
655
|
return { resume, anchorKind: "flight-recorder" };
|
|
@@ -743,6 +749,8 @@ function blockedSignalSummaries(receipt) {
|
|
|
743
749
|
function recordBlockedReceiptEvent(agentRoot, receipt) {
|
|
744
750
|
if (receipt.verdict !== "blocked")
|
|
745
751
|
return;
|
|
752
|
+
if (receipt.signals.some((signal) => signal.kind === "gauntlet" && signal.verdictImpact === "blocked"))
|
|
753
|
+
return;
|
|
746
754
|
(0, flight_recorder_1.recordFlightRecorderEvent)(agentRoot, {
|
|
747
755
|
id: `fr-${receipt.id}`,
|
|
748
756
|
kind: "blocker_detected",
|
|
@@ -760,6 +768,30 @@ function recordBlockedReceiptEvent(agentRoot, receipt) {
|
|
|
760
768
|
},
|
|
761
769
|
});
|
|
762
770
|
}
|
|
771
|
+
function recordRecoveredReceiptEvent(agentRoot, receipt) {
|
|
772
|
+
if (receipt.verdict === "blocked")
|
|
773
|
+
return;
|
|
774
|
+
const resume = (0, flight_recorder_1.readFlightRecorderResume)(agentRoot);
|
|
775
|
+
if (!hasOnlySentinelAuthoredBlockers(agentRoot, resume))
|
|
776
|
+
return;
|
|
777
|
+
(0, flight_recorder_1.recordFlightRecorderEvent)(agentRoot, {
|
|
778
|
+
id: `fr-${receipt.id}-recovered`,
|
|
779
|
+
kind: "agent_note",
|
|
780
|
+
recordedAt: receipt.generatedAt,
|
|
781
|
+
summary: "context-loss Sentinel cleared its prior recovery blocker",
|
|
782
|
+
blockedBecause: [],
|
|
783
|
+
producedRefs: [{
|
|
784
|
+
kind: "arc",
|
|
785
|
+
locator: receipt.receiptLocator,
|
|
786
|
+
}],
|
|
787
|
+
meta: {
|
|
788
|
+
source: "context-loss-sentinel",
|
|
789
|
+
receiptId: receipt.id,
|
|
790
|
+
trigger: receipt.trigger,
|
|
791
|
+
resolution: "blocked-signals-recovered",
|
|
792
|
+
},
|
|
793
|
+
});
|
|
794
|
+
}
|
|
763
795
|
async function persistReceipt(agentRoot, receipt, lockTimeoutMs) {
|
|
764
796
|
const paths = contextLossSentinelPaths(agentRoot);
|
|
765
797
|
return withFileLock(paths.lock, lockTimeoutMs, async () => {
|
|
@@ -782,6 +814,7 @@ async function persistReceipt(agentRoot, receipt, lockTimeoutMs) {
|
|
|
782
814
|
writeWatermark(agentRoot, watermark);
|
|
783
815
|
setReceiptFileMtime(paths.latest, receipt);
|
|
784
816
|
recordBlockedReceiptEvent(agentRoot, receipt);
|
|
817
|
+
recordRecoveredReceiptEvent(agentRoot, receipt);
|
|
785
818
|
}
|
|
786
819
|
else if (existingLatest && nextReady === receipt) {
|
|
787
820
|
const updatedLatest = syncLatestReadyState(existingLatest, nextReady);
|