MAY 31 2026 / SUNDAY / 0 COMMITS

New AI projects on Hugging Face or GitHub, May 31 2026. The repo was quiet that Sunday, and that is the most useful thing about the date.

There is no dated list of projects to hand you for May 31. Both platforms rank discovery by a rolling trending score, not by calendar day. The only records that carry an exact date are releases and commits, and in the open-source macOS agent this series tracks, May 31 was empty: nothing pushed between Saturday evening and Monday night. So the record that defined the day is the release that was already live, v2.9.57, and the one change inside it worth reading.

M
Matthew Diakonov
8 min read

Direct answer, verified 2026-06-17

No platform publishes an official "May 31, 2026" list of new AI projects. Both Hugging Face and GitHub order discovery by a rolling trending score, not by calendar date. New work surfaces continuously across three live feeds:

The records that carry that exact date are tagged releases and commit logs. For the open-source macOS agent Fazm, May 31 was a Sunday with zero commits. The record that actually defined the day was the release already shipped: v2.9.57, dated 2026-05-30 in CHANGELOG.json, carrying a narrowly scoped fix for pop-out chats stuck on "Compacting..." forever. The rest of this page reads that fix.

The empty Sunday, in the log

The honest way to answer "what shipped on a date" is to ask the log, not a roundup. Here is the repository asked directly. The first query, scoped to May 31, returns nothing. The second widens the window to show the two commits that bracket the day: the v2.9.57 release on Saturday evening, and the next work on Monday night.

fazm - git log around 2026-05-31

A gap of more than two days separates the last commit before the weekend from the first after it. That gap is not a bug in the data; it is the data. A maintainer who pushed 74 commits on May 29 rested on May 31. Which means the project that was "new" on that Sunday was whatever shipped Saturday and stayed live through it.

The release that carried the day: v2.9.57

A release is not a calendar day. It is the accumulated decisions of the days before it, frozen at one timestamp. The weekend around May 31 had exactly one such timestamp on either side, so the bracket is easy to read.

When (Pacific)RecordWhat it was
Sat 05-30 17:50v2.9.57Pop-out chat "Compacting..." stall recovery and a new-chat handoff fix. The release live all of Sunday.
Sun 05-31(no commits)The quiet day. Nothing pushed; v2.9.57 was the current state.
Mon 06-01 19:56739e2b57Work resumes: fix a chat hang when Claude OAuth expires mid-query.

v2.9.57 shipped two fixes, both about pop-out chats, per the release notes in CHANGELOG.json. The second was cosmetic: a New Chat window sometimes opened already spinning after a stuck turn. The first was load-bearing, and it is the part worth slowing down on.

The stall: a session that says "Compacting..." forever

The bug has a specific signature, recorded in the source comment from an actual field case (fazm.log, 2026-05-30, session 0ea67ea0). A prior heavy turn unwound a live subagent mid-flight, leaving the session inert. After that, every resume of that session did the same thing: it emitted a status change to compacting and a "Compacting..." placeholder, then resolved with stopReason=end_turn in roughly zero milliseconds, with zero output tokens and zero assistant text. The model was never called. The pop-out window showed "Compacting..." and looped on it forever, with no way out.

This is the hard kind of bug to fix, because the easy fix is wrong. You cannot just retry any empty reply: a blanket version of that recovery existed in this codebase and was deleted on 2026-05-13 (commit fad9af4f) for being lossy and out of spec. Replaying prior context destroys live MCP, browser, and subagent state, and the Agent Client Protocol defines end_turn as a success. A model that genuinely chooses to say nothing must not be retried.

The fix: one signature, six conditions, no loop

The May 30 re-add (commit 3e4fb0cd, 80 lines in one file) brings the recovery back, but narrowed so tightly it can only fire on the poisoned-resume signature. It is a single if block where all six conditions must hold at once.

acp-bridge/src/index.ts
// acp-bridge/src/index.ts  -  commit 3e4fb0cd, shipped v2.9.57
// [COMPACTION-POISON-RECOVERY]: fire on ONE signature only,
// a resumed session that short-circuits without calling the model.
if (
  !isNewSession &&            // a fresh empty reply is a real empty answer
  _retryDepth < 1 &&          // one-shot: never loops
  promptResult.stopReason === "end_turn" &&
  fullText.length === 0 &&    // zero assistant text
  promptDurationMs < 50 &&    // never reached the model (no round trip)
  outputTokens === 0
) {
  // The "Compacting..." placeholder already streamed toward the UI.
  abortController.abort();          // silence the dead session
  unregisterSession(sessionKey);
  msg.resume = undefined;           // force a fresh session
  msg._priorStuckSessionId = stuckSessionId;
  return handleQuery(msg, _retryDepth + 1);  // replay prior context, stream a real answer
}

The timing check is the clever part. Any real turn, even one that returns empty, has to make a network round trip to the model, which costs tens to hundreds of milliseconds. A resume that resolves in under 50 milliseconds with end_turn and zero output never reached the model at all. So promptDurationMs < 50 is what separates "the session short-circuited" from "the model thought and said nothing," the exact line the deleted blanket version could not draw. And because retry depth is capped below one, the recovery is one-shot: if the fresh session also comes back empty, the app delivers that empty result honestly instead of looping on a different session.

Why the quiet day is the better answer

A trending feed for May 31 would have shown you a list of models and repositories that happened to be popular that Sunday. It could not have told you that the most interesting thing about the date was a release that shipped the night before, or that the one change inside it that mattered was a six-condition guard built to catch a single failure signature without re-introducing a bug that was deleted eighteen days earlier. That is the texture a calendar view erases and a commit log keeps.

The lesson generalizes past one repo. When you want to know what was "new" on a specific day, the date is the wrong unit. Releases are the unit, and a release is a window onto the week behind it. A quiet Sunday is not a gap in the story; it is the part of the story where the last release is doing its job in front of users, which is the only test that matters.

How to read any project's May 31 yourself

  1. Open the repo's CHANGELOG.json or CHANGELOG.md and read entries dated 2026-05-31. None means the day was a release gap, which is itself a finding.
  2. Run git log --since=2026-05-31 --until=2026-06-01 --no-merges to confirm what, if anything, was pushed.
  3. Take the release that was live across the day, find its load-bearing commit, and run git show <hash>. Read the diff and the comment the author left for future readers. That comment, not the trending rank, is where the real decision lives.

Chasing a stall that only happens on resume?

In twenty-five minutes we open the compaction-recovery commit, your session lifecycle, and the exact signature your turns short-circuit on, and decide whether your agent needs the same narrow guard.

Frequently asked questions

What new AI projects appeared on Hugging Face or GitHub on May 31, 2026?

Neither platform publishes a dated release list. Models, datasets, papers, and repositories surface continuously, ordered by a rolling trending score rather than by calendar date, so there is no canonical "things launched on May 31" page to read. The records that genuinely carry an exact date are tagged releases and commit logs. For the open-source macOS agent Fazm, which this running series tracks day by day, May 31 was a Sunday and the commit log is empty: nothing was pushed between the v2.9.57 release on May 30 at 17:50 Pacific and the next commit on June 1 at 19:56. So the record that actually defined May 31 is the release that was already live: v2.9.57, dated 2026-05-30 in CHANGELOG.json.

So nothing shipped on May 31, 2026? Is that normal?

For one repository on one Sunday, yes, and it is more normal than the roundups imply. A maintainer takes a weekend; a project that pushed 74 commits two days earlier rests. The useful thing is not that the day was empty, it is what "empty" tells you about how to read a date. The unit of a new AI project is rarely a single calendar day. It is a release, and a release is the accumulated decisions of the days before it, frozen and shipped at one timestamp. The release live on May 31 was v2.9.57, cut the previous evening, and it is a more honest answer to "what was new" than any trending snapshot of that Sunday.

What did v2.9.57 actually fix?

Two pop-out chat bugs, per CHANGELOG.json. First: pop-out chats getting stuck on "Compacting..." forever when a session short-circuits with an empty instant response. Second: pop-out New Chat sometimes opening already in a thinking or spinner state after a stuck turn, plus logging to trace the new-chat session handoff. The first one is the load-bearing change. It is an 80-line addition to acp-bridge/src/index.ts (commit 3e4fb0cd) that re-adds an empty-turn recovery, but scoped to exactly one failure signature so it cannot fire on a legitimate empty answer.

What is the 'poisoned resume compaction' stall?

It is a specific dead state observed in the field on 2026-05-30 (fazm.log, session 0ea67ea0). A prior heavy turn unwound a live subagent mid-flight, leaving the session inert. After that, every resume of that session emitted a status_change of "compacting" and a "Compacting..." placeholder chunk, then resolved with stopReason=end_turn in roughly 0 milliseconds, with zero output tokens and zero assistant text. The model was never actually called. The pop-out window showed "Compacting..." and looped on it forever with no way out. The recovery detects that exact short-circuit and forces a fresh session that replays the prior context and streams a real answer.

Why is the recovery guarded so narrowly instead of just retrying any empty reply?

Because a blanket version of this recovery already existed and was removed on 2026-05-13 (commit fad9af4f) for being lossy and out of spec. Replaying prior context destroys live MCP, browser, and subagent state, and the Agent Client Protocol defines end_turn as a success, so a model that legitimately chooses to say nothing must not be retried. The May 30 re-add fires only when all six conditions hold at once: the session is resumed (not new), retry depth is below one, stopReason is end_turn, the assistant text length is zero, the prompt resolved in under 50 milliseconds, and output tokens are zero. A real empty answer needs an API round trip over 50 milliseconds or emits output tokens, so it can never match. At 0 milliseconds and 0 output the session is already inert, so there is no live state left to destroy by replaying.

Why does sub-50-millisecond timing matter for the fix?

Timing is the signal that separates a short-circuit from a real model call. Any genuine turn, even one that returns empty, has to make a network round trip to the model, which takes tens to hundreds of milliseconds. A resume that resolves in under 50 milliseconds with end_turn and zero output never reached the model at all; the SDK returned success without running inference. The promptDurationMs < 50 check is what lets the recovery distinguish "the session short-circuited" from "the model thought and said nothing," which is the line the removed blanket version could not draw. The recovery is also one-shot: retry depth is capped below one, so if the fresh session also returns empty, the app delivers that empty result honestly instead of looping.

How can I read any project's real May 31 myself?

Three artifacts, in order. Open the project's CHANGELOG.json or CHANGELOG.md at the repo root and read entries dated 2026-05-31; if there are none, the day was a release gap. Run git log --since=2026-05-31 --until=2026-06-01 --no-merges to see the commits, or confirm there were none. Then take the release that was live across that day, the most recent tag before it, and run git show on its load-bearing commit to read the diff and the comment the author left. The trending page shows you what existed at the end of the day; the diff and the changelog show you what someone decided, and a quiet day shows you that the unit of "new" is the release, not the calendar.

Where are the files this page cites?

github.com/mediar-ai/fazm is the public repository. The compaction recovery is in acp-bridge/src/index.ts, marked with the comment tag [COMPACTION-POISON-RECOVERY]; the guard is the six-condition if block, and the test hook is a debug file constant named DEBUG_POISON_EMPTY_RESUME_FILE that simulates the 0-millisecond empty resume. Release notes are in CHANGELOG.json at the repo root, where v2.9.57 is dated 2026-05-30. The commit referenced throughout is 3e4fb0cd, "Add recovery for poisoned resume compaction stalls."

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.