Skip to content

fix(free-time): give the chooser the companion's identity so free time is not always rest - #625

Merged
axAilotl merged 2 commits into
mainfrom
fix/free-time-chooser-identity
Oct 10, 2026
Merged

axAilotl merged 2 commits into
mainfrom
fix/free-time-chooser-identity

Conversation

@axAilotl

@axAilotl axAilotl commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Free time never ran. Live logs from all three companions over 28h show every free-time block ending at the chooser with restReason: companion_rested (plus one chooser_timeout) and turnsUsed: 0.

The free-time chooser is a tool-less background call that decides rest / wander / resume before the block starts. Its system prompt held only the companion's name: no persona, no interests, nothing about what they can do. It also carried a "never manufacture activity" rule, and the menu was just "rest" and "unstructured private time". A model with no identity always picked rest, and rest then silenced the lane for 180 minutes.

Changes

  • The chooser gets the companion's identity. A new required resolveIdentityPrompt port is wired to SubstrateAgent.getCurrentAuthoritativeSystemPrompt(), the same canonical identity/policy prompt reflection deliberation already uses. That prompt goes first, and the chooser rules follow under [Free-time choice].
  • The prompt no longer tilts toward rest. The "never manufacture activity" line is gone. Rest stays a valid choice "when it is honestly what you want". The wander option now says what free time can be used for: explore, write, read back through memory, keep the journal/wiki/notes, or reach out to a known companion.
  • No identity yet → defer_to_block. A companion with no default turn since start has no captured identity prompt. The chooser now skips its model call and lets the block run on the default private session. That turn goes through the ordinary full-persona agent loop, the companion can still end it with the silent reply, and it captures the identity prompt for later chooser calls. No silence is persisted. This covers a companion that has had zero turns since restart (one live companion right now).

Change-budget exception

This is a small, self-contained fix for a live behavior bug: free time is completely non-functional for every companion. Padding or delaying it to reach 800 lines would not help anyone.

Validation

  • vitest on free-time-chooser, free-time-chooser-wiring, free-time-lane, and free-time: 83 passed
  • eslint on the changed files, tsc --noEmit, verify:hardcoded-settings: pass
  • gate:pre-pr via pr:publish

After deploy

  • The chooser prompt is now persona-sized. The live chooserDeadlineMs is 8s and one timeout already happened with the tiny prompt. If restReason: chooser_timeout shows up, raise socialAutonomy.freeTimeChooser.chooserDeadlineMs in the live scheduler.json.
  • Proof this worked: free-time blocks with turnsUsed > 0, or the Free-time chooser deferred to the block log line.

Bead: psfn-framework-ggki4

🤖 Generated with Claude Code

axAilotl and others added 2 commits October 9, 2026 18:41
…e is not always rest

Every live free-time block on every companion ended at the chooser with
companion_rested and zero turns. The chooser's background call saw only the
companion's name, a near-empty menu, and a "never manufacture activity" rule,
so a model with no persona or interests always picked rest, which then
silenced the lane for the quiet period.

The chooser now receives the authoritative identity prompt (the same source
reflection deliberation uses) first, followed by its rules. The wander option
says what free time can be spent on, and the anti-activity line is gone while
rest stays valid. With no identity yet it rests as identity_unavailable without
persisting silence.

Bead: psfn-framework-ggki4

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… exists yet

A companion with no default turn since start has no captured identity prompt,
and resting in that case would keep the quietest companions out of free time
indefinitely. The chooser now returns defer_to_block: the block runs on the
default private session through the ordinary full-persona agent turn, where she
decides whether to do anything (silent still ends it), and that turn captures
the identity for later chooser calls.

Bead: psfn-framework-ggki4

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@axAilotl axAilotl added the change-budget:exception Maintainer-approved under-800 unbundleable blocker label Oct 9, 2026
@axAilotl
axAilotl marked this pull request as ready for review October 9, 2026 22:47
@github-actions github-actions Bot added size:S 51-200 counted changed lines system:scheduler Scheduling, heartbeat, or background work labels Oct 9, 2026
@axAilotl
axAilotl merged commit 352592c into main Oct 10, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change-budget:exception Maintainer-approved under-800 unbundleable blocker size:S 51-200 counted changed lines system:scheduler Scheduling, heartbeat, or background work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant