personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add `sol remote rename` and host-mismatch warning on ingest

Rename updates the remote metadata name, which changes the stream
name for future uploads. Existing segments stay under the old stream.

The ingest endpoint now logs a warning when a remote's reported host
differs from its registered name, making hostname renames visible
in the logs before they cause stream splits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+57
+10
apps/remote/routes.py
··· 331 331 if platform and "platform" not in meta: 332 332 meta["platform"] = platform 333 333 334 + # Warn if client hostname differs from registered remote name 335 + effective_host = meta.get("host", host) 336 + remote_name = remote.get("name", "") 337 + if effective_host and effective_host != remote_name: 338 + logger.warning( 339 + f"Remote '{remote_name}' ({key[:8]}) connecting from host " 340 + f"'{effective_host}' — hostname differs from registered name. " 341 + f"Use `sol remote rename` to update if the host was renamed." 342 + ) 343 + 334 344 if not segment: 335 345 return jsonify({"error": "Missing segment"}), 400 336 346 if not day:
+47
observe/remote_cli.py
··· 209 209 return 0 210 210 211 211 212 + def cmd_rename(args: argparse.Namespace) -> int: 213 + """Rename a remote observer (affects future stream names).""" 214 + identifier = args.identifier 215 + new_name = args.new_name 216 + 217 + remote = _find_remote(identifier) 218 + if not remote: 219 + print(f"Error: remote '{identifier}' not found", file=sys.stderr) 220 + return 1 221 + 222 + # Check new name isn't taken 223 + existing = find_remote_by_name(new_name) 224 + if existing and existing.get("key") != remote.get("key"): 225 + print(f"Error: remote '{new_name}' already exists", file=sys.stderr) 226 + return 1 227 + 228 + old_name = remote.get("name", "") 229 + if old_name == new_name: 230 + print(f"Remote is already named '{new_name}'.", file=sys.stderr) 231 + return 1 232 + 233 + key_prefix = remote.get("key", "")[:8] 234 + remote["name"] = new_name 235 + 236 + if not save_remote(remote): 237 + print("Error: failed to save remote", file=sys.stderr) 238 + return 1 239 + 240 + log_app_action( 241 + app="remote", 242 + facet=None, 243 + action="observer_rename", 244 + params={"old_name": old_name, "new_name": new_name, "key_prefix": key_prefix}, 245 + ) 246 + 247 + print(f"Renamed remote '{old_name}' -> '{new_name}' ({key_prefix})") 248 + print(f" Future segments will use stream: {new_name}") 249 + print(f" Existing segments remain under stream: {old_name}") 250 + return 0 251 + 252 + 212 253 def cmd_status(args: argparse.Namespace) -> int: 213 254 """Show remote status details.""" 214 255 if args.identifier: ··· 320 361 # list 321 362 sub.add_parser("list", help="List all registered remotes") 322 363 364 + # rename 365 + p_rename = sub.add_parser("rename", help="Rename a remote (affects future streams)") 366 + p_rename.add_argument("identifier", help="Remote name or key prefix") 367 + p_rename.add_argument("new_name", help="New name for the remote") 368 + 323 369 # revoke 324 370 p_revoke = sub.add_parser("revoke", help="Revoke a remote registration") 325 371 p_revoke.add_argument("identifier", help="Remote name or key prefix") ··· 349 395 handlers = { 350 396 "create": cmd_create, 351 397 "list": cmd_list, 398 + "rename": cmd_rename, 352 399 "revoke": cmd_revoke, 353 400 "status": cmd_status, 354 401 }