Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ new version heading in the same commit.

## [Unreleased]

## [0.281.3] — 2026-07-31
### Fixed
- **Opaque identifiers are no longer "things the fleet works on".** The digit rule that admits `v3`/`php8`
also admitted hex handles — after the topic-map rebuild, live instawp surfaced `f90fc16d7fb9a19` in the
guidance line. A long hex/base36 run (or a `tsk_…`-style prefixed id) is a handle, not a name.
- **The approval-friction signal now needs a sample, not just a rate.** v0.280.0 replaced a raw-count gate
with a ≥20% rejection rate; on live instawp that fired off **3 decisions** (0 approved, 3 rejected =
100%) — directionally true for the window but far too thin to tell an owner their policy is
miscalibrated, or to tell every agent to expect rejection. Both the guidance line and the
`policy.review` recommendation now also require at least 8 human approval decisions in the window.

## [0.281.2] — 2026-07-31
### Fixed
- **A fixed topic extractor now actually reaches workspaces that have already been running.** `topics` is a
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agent-os",
"version": "0.281.2",
"version": "0.281.3",
"description": "A generic, governed operating system for running autonomous agents safely across brands. Ships with a local web console.",
"license": "MIT",
"type": "commonjs",
Expand Down
10 changes: 9 additions & 1 deletion src/edge/dreaming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,10 @@ function properNouns(episodes: EpisodeRow[]): Set<string> {
* and the guidance line only prints at all when ≥2 topics survive.
*/
function isEntity(token: string, proper: Set<string>): boolean {
// An opaque IDENTIFIER is never a topic. The digit rule below exists for `v3`/`php8`, but it also let
// hex ids through — live instawp surfaced `f90fc16d7fb9a19` as something "the fleet frequently works
// on". A long hex/base36 run with no vowel structure is a handle, not a name.
if (/^[0-9a-f]{8,}$/i.test(token) || /^[a-z]{2,4}_[0-9a-f]{6,}$/i.test(token)) return false;
// A FILENAME qualifies on its base name, never its extension — otherwise the dot rule (meant for
// hostnames and versions) admits every path an agent mentions, including format placeholders like
// `yyyy-mm-dd.md`. `.com`/`.io` are not code extensions, so real hostnames still pass below.
Expand Down Expand Up @@ -474,9 +478,13 @@ function recentTally(s: DreamState): { sessions: number; success: number; approv
* it self-corrects on the next pass, which records the denominator.
*/
const REJECTION_RATE = 0.2;
/** A rate also needs a SAMPLE. Live instawp fired the recommendation off 3 decisions (0 approved,
* 3 rejected = 100%) — directionally true for that window, but far too thin to tell an owner their
* policy is miscalibrated. Below this many human decisions the signal stays quiet. */
const MIN_APPROVAL_DECISIONS = 8;
function rejectionRate(t: { approved: number; rejected: number }): number {
const n = t.approved + t.rejected;
return n ? t.rejected / n : 0;
return n >= MIN_APPROVAL_DECISIONS ? t.rejected / n : 0;
}

// Cadence is OFF (everyHours 0) → learned guidance goes stale after this long unrefreshed. When a cadence
Expand Down
Loading