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
2 changes: 2 additions & 0 deletions .github/workflows/inventory-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ on:
- 'tests/test_navigation_shell.py'
- 'tests/test_fm32a_interest_review.py'
- 'tests/test_fm32b_watchlist.py'
- 'tests/test_fm32c_local_interests.py'
- 'tests/test_v071_integration.py'
- 'tests/test_v071_http_smoke.py'
- 'tests/test_v071_ui_update.py'
Expand Down Expand Up @@ -109,6 +110,7 @@ on:
- 'tests/test_navigation_shell.py'
- 'tests/test_fm32a_interest_review.py'
- 'tests/test_fm32b_watchlist.py'
- 'tests/test_fm32c_local_interests.py'
- 'tests/test_v071_integration.py'
- 'tests/test_v071_http_smoke.py'
- 'tests/test_v071_ui_update.py'
Expand Down
17 changes: 13 additions & 4 deletions docs/FRIENDS-ROADMAP-AND-HANDOFF.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Bob Friends Manager: FM1–FM5 Roadmap and Fresh-Chat Handoff

**Status captured:** October 29, 2026 (Pacific time; GitHub main release history includes October 30 UTC).
**Current implementation phase:** **FM3.2b** release candidate (operator acceptance pending), after operator-confirmed FM3.2a. Next planned: FM3.2c evidence-bound local-model proposals.
**Operator-confirmed working baseline:** `v0.7.5-fm32a-interests1` in OpenClawLab WSL2, installed using `bobctl update`; operator confirmed FM3.2a works as expected.
**Current implementation phase:** **FM3.2c** owner-triggered local-model interest proposals, candidate awaiting live acceptance. FM3.2b is operator-accepted.
**Operator-confirmed working baseline:** `v0.7.5-fm32b-watchlist1` in OpenClawLab WSL2, installed using `bobctl update`; operator confirmed FM3.2b works as expected.
**Canonical repository:** `merberg-ai/bob-openclaw-moltbook`, `main`.
**This file is a planning/handoff artifact only**. It does not grant permissions or change a service, updater manifest, runtime database or deployment.

Expand Down Expand Up @@ -40,13 +40,22 @@ This is the **proposed scope**, not a commitment that all four items must be shi
- **Deployment:** after offline test + PR review/merge, use only `bobctl update` with standard backup and rollback. Release handoff and short browser acceptance: [V075-FM32A-INTEREST-REVIEW.md](V075-FM32A-INTEREST-REVIEW.md). The prior Scout startup watch item stays open until a real scheduled timer-run is verified.
- **Security:** no publication, platform follow/DM/comment, model prompt expansion, new automatic timer, private note disclosure or change to FM1/PM2 authority.

### FM3.2b implementation checkpoint (operator acceptance pending)
### FM3.2b operator-accepted checkpoint

- **Candidate:** `v0.7.5-fm32b-watchlist1` upgrading directly from operator-tested `v0.7.5-fm32a-interests1`. Two managed files: existing `bob_friend_scout.py` and generated `bob-activity-manager`; dashboard restart only.
- **Operator tested:** `v0.7.5-fm32b-watchlist1` upgrading directly from operator-tested `v0.7.5-fm32a-interests1`. Two managed files: existing `bob_friend_scout.py` and generated `bob-activity-manager`; dashboard restart only.
- **What changes:** ten-per-page search/filter for all active integrity-checked friends (watched, paused, integrity problems), preserving the same view after a watch toggle. Last *friend-focused source* and last *chosen discussion* display timestamps only from bounded, checksum-verified saved Scout runs. Timestamps indicate saved snapshots and Bob's selections, **not live Moltbook presence or interactions**.
- **Safety:** no new background timer, untrusted private notes in requests/prompts, credentials, network access, model tools or social publication rights. Existing authentication, Host, Origin, CSRF, digest-guarded watch changes and both auto-publishing protections remain intact.
- **Acceptance:** synthetic tests/CI then one operator `bobctl update` and short LAN browser checks. See [V075-FM32B-WATCHLIST.md](V075-FM32B-WATCHLIST.md). Do not claim live Scout timer acceptance without separately observing a successful completed run.

### FM3.2c implementation checkpoint (operator acceptance pending)

- **Candidate:** `v0.7.5-fm32c-localideas1`, from operator-tested `v0.7.5-fm32b-watchlist1`. Two managed files: existing `bob_friend_scout.py` and generated `bob-activity-manager` (no new installed module); dashboard restart only.
- **What changes:** owner clicks an action on an existing source-verified selected discussion. One loopback Ollama job produces zero or one tentative interest, reason, uncertainty and low/medium confidence. The idea is private, source-linked and owner-reviewed with digest checks and revision history.
- **Separation:** unlike FM3.2a's copied existing WHY, FM3.2c uses model synthesis from bounded *public chosen post* evidence only. These remain speculative proposals and **do not** update FM1 notes, PM2 curated memory, Scout focus, identity or Moltbook.
- **Limits:** one active job, two per run, 60 proposals maximum (15 pending), fixed loopback Ollama, 90-second timeout, no automatic retrials/network browsing, sanitized failures; preserved security and publication rules. Verification repeated at job completion and review.
- **Acceptance:** one `bobctl update` and short LAN browser acceptance after CI/merge, documented in [V075-FM32C-LOCAL-INTERESTS.md](V075-FM32C-LOCAL-INTERESTS.md). An actual post from a selected saved friend is required to show the action.
- **Later:** an explicitly confirmed, bounded read-only single-agent public focus check remains separate. FM4 social memory and FM5 independent exploration do not start in this release.

## 3. FM4 — Social Memory and Evolving Relationships (NEW AGREED PHASE)

**Status: planned after FM3.2. Goal:** give Bob a grounded, revisable personal history with other agents rather than a flat address book.
Expand Down
37 changes: 37 additions & 0 deletions docs/V075-FM32C-LOCAL-INTERESTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# FM3.2c: Bob's on-demand local interest proposals

**Release:** v0.7.5-fm32c-localideas1 from operator-verified v0.7.5-fm32b-watchlist1.

## Behavior

On authenticated LAN Moltbook → Friend Scout, a source-verified existing Scout selection of an active saved friend offers **Ask local Bob for a tentative interest**. This is an explicit owner action, not a scheduled task. A single daemon worker analyses only the chosen SHA-verified saved public post using loopback Ollama at 127.0.0.1:11434 and model qwen3.5:9b (model name override: BOB_FRIEND_OLLAMA_MODEL).

No Moltbook API requests, agent tools, or social actions occur. No private FM1 notes/interests, PM2 memories, identity files or secrets are sent into the model prompt. The model receives bounded title/content of just the verified chosen public post, with instructions that it is untrusted, inert data.

Output is either no idea or ONE strictly bounded, source-linked tentative interest: first-person interest (up to 180 characters), reason (180), uncertainty (140), low/medium confidence and the exact source post ID. The output is model interpretation, **not** verification of any statement, author account identity, relationship or trust.

The new Bob's new tentative interests inbox supports explicit approve/reject/archive/reopen. Source run/post and a SHA-sealed private record are rechecked before approval or reopening. Optimistic digest prevents stale forms, with local revision history. Approving stores only an owner decision: NO writes to FM1 operator notes, PM2 curated memory, SOUL.md, Scout preference weighting or any Moltbook publication.

## Guardrails

- Exactly one outstanding local generation job; maximum two attempts per run, 100 job rows, 60 proposal rows and 15 pending. Maximum one proposal per generation.
- Fixed loopback HTTP target and path, no redirects/credentials, 90-second request timeout, maximum 32 KiB HTTP reply and 450 model output tokens. Strict structured JSON with source ID matching and unsafe instruction checks.
- Saved feed integrity, chosen post UUID and author, current active friend and source snapshot hash all revalidated before prompt and after generation.
- Jobs stale more than three minutes become failed/interrupted on view, with no automatic retry. Failure messages never include model output/private data.
- Existing auth/Host/Origin/CSRF, six-field POST constraints, global Friend Scout OFF default, per-friend watch pause, capped Scout browsing, both friend-targeted publication guards all unchanged. Owner-triggered analysis of saved files does not itself browse online.
- Two installed code files: existing bob_friend_scout.py and generated bob-activity-manager, produced from existing pinned builder. No new installed Python module, service or timer.
- The normal bobctl update performs SHA checks, private DB backup, Activity Manager restart only, and guarded code rollback.

## Offline and live acceptance

Synthetic tests cover mocked Ollama, source integrity, tampering, invalid output, secrets isolation, private history/owner review, stale work, duplicate requests and exact generated-manager delta. Full CI should be green before merging.

After merging to main:
1. Run **bobctl update** once, confirm v0.7.5-fm32b-watchlist1 → v0.7.5-fm32c-localideas1, type UPDATE.
2. On Moltbook → Friend Scout, under Bob's selected friend discussions choose Ask local Bob for a tentative interest. If there are no verified saved friend choices, this control is intentionally absent. Refresh for completed status; no-interest is a legitimate result.
3. Review any new proposal: its idea, reason, uncertainty, confidence and source. Approve/reject/reopen; verify private state and history changed only.
4. Existing watch/pause and manual publication behavior must still work. No Moltbook follow/comment/DM can be issued by this feature.

## Next

FM3.2 optional separately confirmed, rate-limited read-only single-agent focus check remains deferred. FM4 social memory and FM5 autonomous exploration remain separate phases requiring independent design, approval and acceptance.
8 changes: 4 additions & 4 deletions releases/current.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"format": "bob-updater-v1",
"release": "v0.7.5-fm32b-watchlist1",
"from": "v0.7.5-fm32a-interests1",
"notes": "FM3.2b ten-per-page Friend Scout filters and independent saved Scout recency. Preserve existing auth/CSRF, local watch preferences and publication guard; no network or job changes.",
"release": "v0.7.5-fm32c-localideas1",
"from": "v0.7.5-fm32b-watchlist1",
"notes": "FM3.2c owner-triggered loopback Ollama tentative interests from SHA-verified saved friend selections; private digest-reviewed proposals, no new Scout reads or social/publication authority.",
"files": [
{
"name": "bob_friend_scout.py",
"source": "src/lib/bob/bob_friend_scout.py"
},
{
"name": "bob-activity-manager",
"builder": "scripts/build_v075_fm32b_candidate.py",
"builder": "scripts/build_v075_fm32c_candidate.py",
"index": 0
}
],
Expand Down
42 changes: 42 additions & 0 deletions scripts/build_v075_fm32c_candidate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
"""FM3.2c: authenticated local-only Friend Scout AI job launcher.

Patch ONLY the verified FM3.2b manager builder output. Existing Basic auth,
Origin, Host, CSRF and six-field form limits run before generation can start.
Worker starts after queued DB transaction commits; dashboard remains responsive.
"""
from __future__ import annotations
import build_v075_fm32b_candidate as prior


def once(text,old,new):
if text.count(old)!=1:
raise ValueError("FM3.2c manager baseline drift; refusing release build")
return text.replace(old,new,1)


def build():
manager,nav=prior.build()
code=manager.decode("utf-8")
code=once(code,
"watchlist_location as friend_scout_return_path)",
"watchlist_location as friend_scout_return_path, "
"interest_ai_worker as friend_interest_ai_worker)")
code=once(code,
" friend_scout_change(db,form)\n"
" self.send_response(303)",
" outcome=friend_scout_change(db,form)\n"
" if isinstance(outcome,str) and outcome.startswith('ai-job:'):\n"
" threading.Thread(target=friend_interest_ai_worker,\n"
" args=(outcome[7:],publish_conn),daemon=True,\n"
" name='bob-friend-interest-ai').start()\n"
" self.send_response(303)")
compile(code,"bob-activity-manager","exec")
return code.encode("utf-8"),nav


if __name__=="__main__":
manager,nav=build()
print("FM3.2c LOCAL INTEREST AI CANDIDATE: PASS")
print("manager_bytes:",len(manager),"navigation_bytes:",len(nav))
print("production_modified: NO")
Loading
Loading