@pellux/goodvibes-agent 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +28 -1
  3. package/dist/package/main.js +36631 -28780
  4. package/dist/package/{web-tree-sitter-jbz042ba.wasm → web-tree-sitter-e011xaqr.wasm} +0 -0
  5. package/docs/README.md +1 -1
  6. package/docs/connected-host.md +1 -1
  7. package/docs/getting-started.md +1 -1
  8. package/docs/release-and-publishing.md +5 -1
  9. package/docs/tools-and-commands.md +1 -0
  10. package/package.json +3 -3
  11. package/release/live-verification/live-verification.json +11 -11
  12. package/release/live-verification/live-verification.md +12 -12
  13. package/src/agent/email/email-service.ts +1 -1
  14. package/src/agent/email/imap-client.ts +4 -4
  15. package/src/agent/email/smtp-client.ts +5 -5
  16. package/src/cli/config-overrides.ts +29 -14
  17. package/src/cli/entrypoint.ts +12 -4
  18. package/src/cli/launch-auto-update.ts +218 -0
  19. package/src/cli/relay-command.ts +4 -4
  20. package/src/cli/service-posture.ts +2 -2
  21. package/src/cli/tui-startup.ts +31 -0
  22. package/src/cli/workspaces-command.ts +5 -1
  23. package/src/cli-flags.ts +1 -1
  24. package/src/config/index.ts +1 -1
  25. package/src/config/update-settings.ts +45 -0
  26. package/src/config/workspace-registration.ts +214 -15
  27. package/src/input/commands/runtime-services.ts +0 -5
  28. package/src/input/commands/update-runtime.ts +313 -0
  29. package/src/input/commands.ts +2 -0
  30. package/src/input/feed-context-factory.ts +2 -2
  31. package/src/input/handler-feed.ts +8 -8
  32. package/src/input/handler.ts +1 -1
  33. package/src/input/mcp-workspace.ts +5 -1
  34. package/src/input/panel-paste-flood-guard.ts +1 -1
  35. package/src/input/settings-modal-types.ts +11 -5
  36. package/src/input/settings-modal.ts +56 -61
  37. package/src/main.ts +19 -20
  38. package/src/renderer/activity-sidebar.ts +53 -4
  39. package/src/renderer/settings-modal-helpers.ts +2 -0
  40. package/src/renderer/settings-modal.ts +37 -25
  41. package/src/runtime/bootstrap-core.ts +16 -5
  42. package/src/runtime/bootstrap-external-services.ts +107 -11
  43. package/src/runtime/bootstrap-hook-bridge.ts +2 -2
  44. package/src/runtime/bootstrap-shell.ts +4 -4
  45. package/src/runtime/bootstrap.ts +34 -12
  46. package/src/runtime/connected-host-autostart.ts +269 -0
  47. package/src/runtime/daemon-receipts.ts +66 -0
  48. package/src/runtime/diagnostics/panels/index.ts +0 -2
  49. package/src/runtime/feature-enablement.ts +176 -0
  50. package/src/runtime/index.ts +12 -29
  51. package/src/runtime/memory-spine-adoption.ts +18 -0
  52. package/src/runtime/onboarding/apply.ts +50 -37
  53. package/src/runtime/onboarding/types.ts +2 -2
  54. package/src/runtime/onboarding/verify.ts +22 -4
  55. package/src/runtime/release-artifacts.ts +113 -0
  56. package/src/runtime/services.ts +228 -19
  57. package/src/runtime/session-spine-rest-transport.ts +84 -4
  58. package/src/runtime/ui-services.ts +1 -1
  59. package/src/runtime/update-check.ts +64 -0
  60. package/src/shell/ui-openers.ts +8 -0
  61. package/src/tools/agent-harness-metadata.ts +8 -0
  62. package/src/tools/agent-harness-setup-connected-host.ts +1 -1
  63. package/src/tools/agent-harness-setup-posture.ts +1 -1
  64. package/src/version.ts +1 -1
  65. package/src/runtime/diagnostics/panels/ops.ts +0 -156
  66. package/src/runtime/surface-feature-flags.ts +0 -100
package/docs/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # GoodVibes Agent Docs
2
2
 
3
- These are the package-facing docs for the GoodVibes Agent `1.9.x` release line.
3
+ These are the package-facing docs for the GoodVibes Agent `1.10.x` release line.
4
4
 
5
5
  ## Current Docs
6
6
 
@@ -75,7 +75,7 @@ The model can inspect the public operator method catalog with `host action:"meth
75
75
 
76
76
  The model can inspect service posture with `host action:"services"`. That report exposes endpoint binding, network-facing posture, issues, and redacted-log diagnostics used by status, doctor, and support bundles. Use `includeParameters:true` when reachability probes and redacted log tail are needed. To inspect one endpoint, use `host action:"service"` with `endpointId`, `target`, or `query`; valid endpoint ids are `controlPlane`, `httpListener`, and `web`. The connected browser cockpit/PWA is the visible UI surface `connected-browser-cockpit`; `computer action:"browser"` inspects readiness and `computer action:"open_browser" confirm:true explicitUserRequest:"..."` opens the configured URL through the existing confirmed surface route. `ui_surface surfaceId:"connected-browser-cockpit"` remains available for detailed compatibility inspection and reports Agent workspace category coverage, mobile/PWA control routes, the Agent onboarding marker, and browser/PWA first-run evidence. Certified SDK/daemon browser/PWA category-route records can make the cockpit `browser-native-ready` only when every Agent workspace category has schema/version/publication/publisher/provenance/freshness-cursor/receipt metadata, exact inspect/open routes, and mobile/touch evidence. Certified browser/PWA first-run records add manifest, service-worker, install, and offline evidence with redacted URLs and summaries. Start/setup readiness can also satisfy the setup checklist from saved durable artifacts or live SDK/daemon setup read models when the connected host publishes them, and reports the gap when no receipt exists. Service lifecycle and listener changes must use setup or confirmed daemon operator methods.
77
77
 
78
- For setup or host repair asks, start with `setup action:"repair"`. It is read-only and chooses the next safe route for the current setup blocker or a named target: connected-host status, a `services.status` receipt, confirmed token repair, user-run bootstrap commands, or no lifecycle action when the host is already reachable. It does not start, install, restart, write tokens, import settings, or open UI by itself.
78
+ For setup or host repair asks, start with `setup action:"repair"`. It is read-only and chooses the next safe route for the current setup blocker or a named target: connected-host status, a `services.status` receipt, confirmed token repair, user-run bootstrap commands, or no lifecycle action when the host is already reachable. It does not start, install, restart, write tokens, import settings, or open UI by itself. Separately from these routes, at boot the Agent starts a host that is installed on this machine but stopped: one start through the platform service manager, a bounded wait for it to answer, and an honest receipt. A running host is never restarted, a held port is left alone, and a host that is not installed keeps this guidance.
79
79
 
80
80
  The model can inspect live connected-host readiness with `host action:"status"`. That report uses the same status probe as the CLI: it checks the connected-host status route, verifies host compatibility, checks isolated Agent Knowledge when token and compatibility posture allow it, reports endpoint bindings and token posture without printing token values, returns actionable findings, and includes a compact `modelRoute` for follow-up diagnostics. `includeParameters:true` adds route family and capability detail. Lower-level `connected_host_status` and `daemon_status` remain compatibility routes.
81
81
 
@@ -189,7 +189,7 @@ Host diagnostics:
189
189
 
190
190
  Model-visible diagnostics prefer `host action:"status|capabilities|capability|services|service|methods|method"`. Lower-level `service_posture`, `service_endpoint`, `connected_host`, `connected_host_status`, `connected_host_capability`, `daemon`, and `daemon_status` harness modes remain available for compatibility and detailed inspection. `agent_operator_method` can run read-only routes directly and write/admin routes only with `confirm:true` plus `explicitUserRequest`.
191
191
 
192
- When no connected host is reachable, inspect `setup action:"item" setupItemId:"connected-host-readiness"` for the offline bootstrap plan. It returns user-run commands to verify Bun, install and trust the owning GoodVibes host package, verify host entrypoints, start the GoodVibes service, and reconnect Agent. Agent does not run those host install/start commands implicitly. When the host auth token is missing or malformed on the local machine, use `setup action:"token" setupItemId:"connected-host-auth" confirm:true explicitUserRequest:"..."`; it uses the GoodVibes SDK pairing helper to create or repair `~/.goodvibes/daemon/operator-tokens.json`, preserves valid existing tokens, leaves environment tokens untouched, and returns only path/fingerprint metadata.
192
+ When no connected host is reachable, inspect `setup action:"item" setupItemId:"connected-host-readiness"` for the offline bootstrap plan. It returns user-run commands to verify Bun, install and trust the owning GoodVibes host package, verify host entrypoints, start the GoodVibes service, and reconnect Agent. Agent does not run those host install/start commands implicitly. One bounded exception happens at boot: when the host is already installed on this machine but its service is stopped, Agent starts it once through the platform service manager, waits briefly for it to answer, and reports what it did. When the host auth token is missing or malformed on the local machine, use `setup action:"token" setupItemId:"connected-host-auth" confirm:true explicitUserRequest:"..."`; it uses the GoodVibes SDK pairing helper to create or repair `~/.goodvibes/daemon/operator-tokens.json`, preserves valid existing tokens, leaves environment tokens untouched, and returns only path/fingerprint metadata.
193
193
 
194
194
  ## Current Product Notes
195
195
 
@@ -62,7 +62,11 @@ The GitHub release workflow publishes to npm only when the repository variable `
62
62
 
63
63
  Branch CI is the only workflow that runs the full test suite and release gates. It runs `bun run test` once for the release SHA, along with typecheck, architecture, performance, build, publish, packed install, and verification ledger checks. The release workflow must not run tests or duplicate those gates; shared release metadata verification rejects duplicated release-workflow gates and requires the workflow to verify that branch CI and its test job passed for the exact checked-out SHA before package packing, GitHub Release creation, and optional npm publish. It also requires the release workflow to preserve tag/package version matching, single-tarball packing, changelog excerpt extraction, and GitHub Release tarball attachment markers.
64
64
 
65
- Shared release metadata verification requires the package build scripts to keep exact TypeScript and Bun compile commands for the Agent entrypoint and platform binary names. It also requires `scripts/build.ts` to keep the prebuild/compatibility patch, multi-target matrix, sqlite-vec native addon externalization/copy policy, same-platform hard failure, cross-target warning, and build summary/failure exit behavior.
65
+ Shared release metadata verification requires the package build scripts to keep exact TypeScript and Bun compile commands for the Agent entrypoint and platform binary names. It also requires `scripts/build.ts` to keep the prebuild/compatibility patch, multi-target matrix, sqlite-vec native addon externalization/copy policy, same-platform hard failure, cross-target registry fetch of the target-platform addon, and build summary/failure exit behavior. On a cross-target build the runner does not have the target platform's optional sqlite-vec package installed, so `scripts/build.ts` fetches that platform's addon from the npm registry (pinned to the resolved `sqlite-vec` version) and copies it into `dist/lib/sqlite-vec-<os>-<arch>/`; a failed fetch or a missing addon in the fetched package is a hard build failure, never a silent skip.
66
+
67
+ ### sqlite-vec native addon release assets
68
+
69
+ A compiled Agent binary loads the sqlite-vec native addon from `<binary-dir>/lib/sqlite-vec-<os>-<arch>/vec0.<suffix>` (`vec0.so` on Linux, `vec0.dylib` on macOS). Bun cannot embed a native addon inside the compiled binary, so the release lane ships the addon as a separate per-platform asset. Each build matrix leg contributes its target's addon tree, and the GitHub Release job packages one archive per platform — `sqlite-vec-<os>-<arch>.tar.gz` — whose interior layout is exactly `lib/sqlite-vec-<os>-<arch>/vec0.<suffix>`, so it extracts in place next to the binary with no renaming. All four archives are checksummed in `SHA256SUMS.txt` alongside the binaries under the missing-entry-fatal convention: a directly-downloaded binary can restore the semantic vector index by co-locating the matching addon (see the README "Standalone binary and the semantic vector index" section). On macOS the system SQLite that `bun:sqlite` links refuses to load extensions, so the darwin archives ship for parity but the vector index stays unavailable there and memory search degrades to literal matching; this is a platform capability limit, not a packaging defect.
66
70
 
67
71
  Shared release metadata verification requires branch CI to run the compiled binary smoke after `bun run build`, and `scripts/post-build-smoke.ts` must keep the default `dist/goodvibes-agent` binary path, optional `--binary` override, isolated temp cwd, `--version` launch, sqlite-vec/`$bunfs` module-resolution leak guards, Agent version-prefix assertion, failure diagnostics, and cleanup.
68
72
 
@@ -332,6 +332,7 @@ Routine promotion is an explicit scheduling route. Local routines stay local unt
332
332
  | `/tts` | Submit a normal prompt and play the assistant response through live TTS. |
333
333
  | `/undo` | Undo the last conversation turn. |
334
334
  | `/unpin` | Unpin a model from the favorites list. |
335
+ | `/update` | Check for a newer release; for binary installs, verify and apply it or roll back to the kept previous version. |
335
336
  | `/vibe` | Inspect, create, show, or import VIBE.md personality files. |
336
337
  | `/voice` | Review voice posture and portable voice metadata. |
337
338
  | `/welcome` | Open or print the Agent setup guide. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "private": false,
5
5
  "description": "GoodVibes personal operator assistant TUI with a proactive Agent product brain, isolated Agent Knowledge, local profiles, routines, skills, personas, and explicit build delegation.",
6
6
  "type": "module",
@@ -93,8 +93,8 @@
93
93
  },
94
94
  "dependencies": {},
95
95
  "devDependencies": {
96
- "@pellux/goodvibes-sdk": "1.7.1",
97
- "@pellux/goodvibes-terminal-shell": "1.7.1",
96
+ "@pellux/goodvibes-sdk": "1.8.0",
97
+ "@pellux/goodvibes-terminal-shell": "1.8.0",
98
98
  "sql.js": "^1.14.1",
99
99
  "sqlite-vec": "^0.1.9",
100
100
  "zustand": "^5.0.12",
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-07-09T06:39:25.714Z",
2
+ "generatedAt": "2026-07-13T23:20:59.518Z",
3
3
  "homeDir": "[goodvibes-home]",
4
4
  "binaryPath": "[agent-binary]",
5
5
  "connectedHostBaseUrl": "http://127.0.0.1:3421",
@@ -9,8 +9,8 @@
9
9
  "id": "verification-ledger",
10
10
  "title": "Verification inventory ledger",
11
11
  "status": "pass",
12
- "summary": "99.5% local verification signal across 839 inventory items.",
13
- "detail": "82.8% local behavior verified; 110 item(s) require external outcomes."
12
+ "summary": "99.6% local verification signal across 978 inventory items.",
13
+ "detail": "73.7% local behavior verified; 223 item(s) require external outcomes."
14
14
  },
15
15
  {
16
16
  "id": "compiled-cli-present",
@@ -23,7 +23,7 @@
23
23
  "title": "Agent CLI version command",
24
24
  "status": "pass",
25
25
  "summary": "Agent CLI version returned successfully.",
26
- "detail": "goodvibes-agent 1.6.4"
26
+ "detail": "goodvibes-agent 1.9.1"
27
27
  },
28
28
  {
29
29
  "id": "cli-status-json",
@@ -37,14 +37,14 @@
37
37
  "title": "Agent CLI compatibility JSON command",
38
38
  "status": "pass",
39
39
  "summary": "Agent CLI compatibility returned parseable JSON.",
40
- "detail": "{\n \"ok\": true,\n \"packageVersion\": \"1.6.4\",\n \"connectedHost\": {\n \"baseUrl\": \"http://127.0.0.1:3421\",\n \"status\": 200,\n \"reachable\": true,\n \"compatible\": true\n },\n \"auth\": {\n \"tokenPresent\": true,\n \"tokenPath\": \"env:GOODVIBES_CONNECTED_HOST_TOKEN\"\n },\n \"agentKnowledge\": {\n \"route\": \"/api/goodvibes-agent/knowledge/status\",\n \"ready\": true,\n \"kind\": \"ok\"\n }\n}"
40
+ "detail": "{\n \"ok\": true,\n \"packageVersion\": \"1.9.1\",\n \"connectedHost\": {\n \"baseUrl\": \"http://127.0.0.1:3421\",\n \"status\": 200,\n \"reachable\": true,\n \"compatible\": true\n },\n \"auth\": {\n \"tokenPresent\": true,\n \"tokenPath\": \"env:GOODVIBES_CONNECTED_HOST_TOKEN\"\n },\n \"agentKnowledge\": {\n \"route\": \"/api/goodvibes-agent/knowledge/status\",\n \"ready\": true,\n \"kind\": \"ok\"\n }\n}"
41
41
  },
42
42
  {
43
43
  "id": "cli-agent-knowledge-status",
44
44
  "title": "Agent Knowledge CLI status command",
45
45
  "status": "pass",
46
46
  "summary": "Agent Knowledge status returned parseable JSON.",
47
- "detail": "{\n \"ok\": true,\n \"kind\": \"agentKnowledge.status\",\n \"route\": \"/api/goodvibes-agent/knowledge/status\",\n \"data\": {\n \"ready\": true,\n \"storagePath\": \"[goodvibes-home]/tui/knowledge-agent.sqlite\",\n \"sourceCount\": 0,\n \"nodeCount\": 0,\n \"edgeCount\": 0,\n \"issueCount\": 0,\n \"extractionCount\": 0,\n \"jobRunCount\": 561,\n \"refinementTaskCount\": 0,\n \"usageCount\": 0,\n \"candidateCount\": 0,\n \"reportCount\": 26,\n \"scheduleCount\": 3,\n \"note\": \"Structured knowledge uses SQL-backed sources, nodes, edges, issues, extractions, and job runs. Markdown is an optional projection, not the source of truth.\"\n }\n}"
47
+ "detail": "{\n \"ok\": true,\n \"kind\": \"agentKnowledge.status\",\n \"route\": \"/api/goodvibes-agent/knowledge/status\",\n \"data\": {\n \"ready\": true,\n \"storagePath\": \"[goodvibes-home]/tui/knowledge-agent.sqlite\",\n \"sourceCount\": 0,\n \"nodeCount\": 0,\n \"edgeCount\": 0,\n \"issueCount\": 0,\n \"extractionCount\": 0,\n \"jobRunCount\": 655,\n \"refinementTaskCount\": 0,\n \"usageCount\": 0,\n \"candidateCount\": 0,\n \"reportCount\": 31,\n \"scheduleCount\": 3,\n \"note\": \"Structured knowledge uses SQL-backed sources, nodes, edges, issues, extractions, and job runs. Markdown is an optional projection, not the source of truth.\"\n }\n}"
48
48
  },
49
49
  {
50
50
  "id": "cli-providers",
@@ -65,7 +65,7 @@
65
65
  "title": "Authenticated connected-host /status",
66
66
  "status": "pass",
67
67
  "summary": "/status returned 200 with parseable JSON.",
68
- "detail": "{\"status\":\"running\",\"version\":\"1.5.0\"}"
68
+ "detail": "{\"status\":\"running\",\"version\":\"1.7.1\"}"
69
69
  },
70
70
  {
71
71
  "id": "connected-host-health",
@@ -78,15 +78,15 @@
78
78
  "id": "openai-compatible-models",
79
79
  "title": "OpenAI-compatible /v1/models route",
80
80
  "status": "pass",
81
- "summary": "/v1/models returned 214 model(s).",
82
- "detail": "/v1/models returned 214 model(s); model identifiers omitted from release artifact."
81
+ "summary": "/v1/models returned 307 model(s).",
82
+ "detail": "/v1/models returned 307 model(s); model identifiers omitted from release artifact."
83
83
  },
84
84
  {
85
85
  "id": "agent-knowledge-status",
86
86
  "title": "Agent Knowledge isolated /status",
87
87
  "status": "pass",
88
88
  "summary": "Agent Knowledge status route returned parseable isolated JSON.",
89
- "detail": "{\"ready\":true,\"storagePath\":\"[goodvibes-home]/tui/knowledge-agent.sqlite\",\"sourceCount\":0,\"nodeCount\":0,\"edgeCount\":0,\"issueCount\":0,\"extractionCount\":0,\"jobRunCount\":561,\"refinementTaskCount\":0,\"usageCount\":0,\"candidateCount\":0,\"reportCount\":26,\"scheduleCount\":3,\"note\":\"Structured knowledge uses SQL-backed sources, nodes, edges, issues, extractions, and job runs. Markdown is an optional projection, not the source of truth.\"}"
89
+ "detail": "{\"ready\":true,\"storagePath\":\"[goodvibes-home]/tui/knowledge-agent.sqlite\",\"sourceCount\":0,\"nodeCount\":0,\"edgeCount\":0,\"issueCount\":0,\"extractionCount\":0,\"jobRunCount\":655,\"refinementTaskCount\":0,\"usageCount\":0,\"candidateCount\":0,\"reportCount\":31,\"scheduleCount\":3,\"note\":\"Structured knowledge uses SQL-backed sources, nodes, edges, issues, extractions, and job runs. Markdown is an optional projection, not the source of truth.\"}"
90
90
  },
91
91
  {
92
92
  "id": "agent-knowledge-ask-isolated",
@@ -128,7 +128,7 @@
128
128
  "title": "Agent Knowledge isolated map",
129
129
  "status": "pass",
130
130
  "summary": "Agent Knowledge isolated map stayed on the isolated Agent route.",
131
- "detail": "{\"ok\":true,\"title\":\"Knowledge Map\",\"generatedAt\":1783579165713,\"width\":1280,\"height\":920,\"nodeCount\":0,\"edgeCount\":0,\"totalNodeCount\":0,\"totalEdgeCount\":0,\"facets\":{\"recordKinds\":[],\"nodeKinds\":[],\"sourceTypes\":[],\"sourceStatuses\":[],\"nodeStatuses\":[],\"issueCodes\":[],\"issueStatuses\":[],\"issueSeverities\":[],\"edgeRelations\":[],\"tags\":[]},\"nodes\":[],\"edges\":[],\"svg\":\"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"1280\\\" height=\\\"920\\\" viewBox=\\\"0 0 1280 920\\\" role=\\\"img\\\" aria-label=\\\"Knowledge Map\\\">\\n<defs>\\n <radialGradient id=\\\"knowledgeMapBg\\\" cx=\\\"50%\\\" cy=\\\"46%\\\" r=\\\"70%\\\">\\n <stop offset=\\\"0%\\\" stop-color=\\\"#f7f4ec\\\" />\\n <stop offset=\\\"60%\\\" stop-color=\\\"#e9eef0\\\" />\\n <stop offset=\\\"100%\\\" stop-color=\\\"#dde6df\\\" />\\n </radialGradient>\\n <filter id=\\\"softShadow\\\" x=\\\"-20%\\\" y=\\\"-20%\\\" width=\\\"140%\\\" height=\\\"140%\\\">\\n <feDropShadow dx=\\\"0\\\" dy=\\\"6\\... [truncated]"
131
+ "detail": "{\"ok\":true,\"title\":\"Knowledge Map\",\"generatedAt\":1783984859516,\"width\":1280,\"height\":920,\"nodeCount\":0,\"edgeCount\":0,\"totalNodeCount\":0,\"totalEdgeCount\":0,\"facets\":{\"recordKinds\":[],\"nodeKinds\":[],\"sourceTypes\":[],\"sourceStatuses\":[],\"nodeStatuses\":[],\"issueCodes\":[],\"issueStatuses\":[],\"issueSeverities\":[],\"edgeRelations\":[],\"tags\":[]},\"nodes\":[],\"edges\":[],\"svg\":\"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"1280\\\" height=\\\"920\\\" viewBox=\\\"0 0 1280 920\\\" role=\\\"img\\\" aria-label=\\\"Knowledge Map\\\">\\n<defs>\\n <radialGradient id=\\\"knowledgeMapBg\\\" cx=\\\"50%\\\" cy=\\\"46%\\\" r=\\\"70%\\\">\\n <stop offset=\\\"0%\\\" stop-color=\\\"#f7f4ec\\\" />\\n <stop offset=\\\"60%\\\" stop-color=\\\"#e9eef0\\\" />\\n <stop offset=\\\"100%\\\" stop-color=\\\"#dde6df\\\" />\\n </radialGradient>\\n <filter id=\\\"softShadow\\\" x=\\\"-20%\\\" y=\\\"-20%\\\" width=\\\"140%\\\" height=\\\"140%\\\">\\n <feDropShadow dx=\\\"0\\\" dy=\\\"6\\... [truncated]"
132
132
  },
133
133
  {
134
134
  "id": "agent-knowledge-connectors-isolated",
@@ -1,6 +1,6 @@
1
1
  # GoodVibes Agent Live Verification
2
2
 
3
- Generated: 2026-07-09T06:39:25.714Z
3
+ Generated: 2026-07-13T23:20:59.518Z
4
4
  Home: `[goodvibes-home]`
5
5
  Binary: `[agent-binary]`
6
6
  Connected host: `http://127.0.0.1:3421`
@@ -14,7 +14,7 @@ Connected host: `http://127.0.0.1:3421`
14
14
 
15
15
  | Check | Status | Summary |
16
16
  |---|---|---|
17
- | Verification inventory ledger | pass | 99.5% local verification signal across 839 inventory items. |
17
+ | Verification inventory ledger | pass | 99.6% local verification signal across 978 inventory items. |
18
18
  | Compiled GoodVibes Agent CLI binary | pass | Found [agent-binary]. |
19
19
  | Agent CLI version command | pass | Agent CLI version returned successfully. |
20
20
  | Agent CLI status JSON command | pass | Agent CLI status returned parseable JSON. |
@@ -24,7 +24,7 @@ Connected host: `http://127.0.0.1:3421`
24
24
  | CLI doctor command | pass | Doctor completed; 1 operator-configuration risk advisory(ies) noted (intentional trust posture, not a release defect). |
25
25
  | Authenticated connected-host /status | pass | /status returned 200 with parseable JSON. |
26
26
  | Authenticated connected-host /api/health | pass | Health overall=healthy. |
27
- | OpenAI-compatible /v1/models route | pass | /v1/models returned 214 model(s). |
27
+ | OpenAI-compatible /v1/models route | pass | /v1/models returned 307 model(s). |
28
28
  | Agent Knowledge isolated /status | pass | Agent Knowledge status route returned parseable isolated JSON. |
29
29
  | Agent Knowledge isolated ask | pass | Agent Knowledge ask stayed on the isolated Agent route. |
30
30
  | Agent Knowledge isolated search | pass | Agent Knowledge search stayed on the isolated Agent route. |
@@ -39,13 +39,13 @@ Connected host: `http://127.0.0.1:3421`
39
39
  ### Verification inventory ledger
40
40
 
41
41
  ```text
42
- 82.8% local behavior verified; 110 item(s) require external outcomes.
42
+ 73.7% local behavior verified; 223 item(s) require external outcomes.
43
43
  ```
44
44
 
45
45
  ### Agent CLI version command
46
46
 
47
47
  ```text
48
- goodvibes-agent 1.6.4
48
+ goodvibes-agent 1.9.1
49
49
  ```
50
50
 
51
51
  ### Agent CLI status JSON command
@@ -59,7 +59,7 @@ Status JSON command completed; provider/model identifiers omitted from release a
59
59
  ```text
60
60
  {
61
61
  "ok": true,
62
- "packageVersion": "1.6.4",
62
+ "packageVersion": "1.9.1",
63
63
  "connectedHost": {
64
64
  "baseUrl": "http://127.0.0.1:3421",
65
65
  "status": 200,
@@ -93,11 +93,11 @@ Status JSON command completed; provider/model identifiers omitted from release a
93
93
  "edgeCount": 0,
94
94
  "issueCount": 0,
95
95
  "extractionCount": 0,
96
- "jobRunCount": 561,
96
+ "jobRunCount": 655,
97
97
  "refinementTaskCount": 0,
98
98
  "usageCount": 0,
99
99
  "candidateCount": 0,
100
- "reportCount": 26,
100
+ "reportCount": 31,
101
101
  "scheduleCount": 3,
102
102
  "note": "Structured knowledge uses SQL-backed sources, nodes, edges, issues, extractions, and job runs. Markdown is an optional projection, not the source of truth."
103
103
  }
@@ -119,7 +119,7 @@ Doctor command completed without findings; provider/model identifiers and creden
119
119
  ### Authenticated connected-host /status
120
120
 
121
121
  ```text
122
- {"status":"running","version":"1.5.0"}
122
+ {"status":"running","version":"1.7.1"}
123
123
  ```
124
124
 
125
125
  ### Authenticated connected-host /api/health
@@ -131,13 +131,13 @@ Doctor command completed without findings; provider/model identifiers and creden
131
131
  ### OpenAI-compatible /v1/models route
132
132
 
133
133
  ```text
134
- /v1/models returned 214 model(s); model identifiers omitted from release artifact.
134
+ /v1/models returned 307 model(s); model identifiers omitted from release artifact.
135
135
  ```
136
136
 
137
137
  ### Agent Knowledge isolated /status
138
138
 
139
139
  ```text
140
- {"ready":true,"storagePath":"[goodvibes-home]/tui/knowledge-agent.sqlite","sourceCount":0,"nodeCount":0,"edgeCount":0,"issueCount":0,"extractionCount":0,"jobRunCount":561,"refinementTaskCount":0,"usageCount":0,"candidateCount":0,"reportCount":26,"scheduleCount":3,"note":"Structured knowledge uses SQL-backed sources, nodes, edges, issues, extractions, and job runs. Markdown is an optional projection, not the source of truth."}
140
+ {"ready":true,"storagePath":"[goodvibes-home]/tui/knowledge-agent.sqlite","sourceCount":0,"nodeCount":0,"edgeCount":0,"issueCount":0,"extractionCount":0,"jobRunCount":655,"refinementTaskCount":0,"usageCount":0,"candidateCount":0,"reportCount":31,"scheduleCount":3,"note":"Structured knowledge uses SQL-backed sources, nodes, edges, issues, extractions, and job runs. Markdown is an optional projection, not the source of truth."}
141
141
  ```
142
142
 
143
143
  ### Agent Knowledge isolated ask
@@ -173,7 +173,7 @@ Doctor command completed without findings; provider/model identifiers and creden
173
173
  ### Agent Knowledge isolated map
174
174
 
175
175
  ```text
176
- {"ok":true,"title":"Knowledge Map","generatedAt":1783579165713,"width":1280,"height":920,"nodeCount":0,"edgeCount":0,"totalNodeCount":0,"totalEdgeCount":0,"facets":{"recordKinds":[],"nodeKinds":[],"sourceTypes":[],"sourceStatuses":[],"nodeStatuses":[],"issueCodes":[],"issueStatuses":[],"issueSeverities":[],"edgeRelations":[],"tags":[]},"nodes":[],"edges":[],"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1280\" height=\"920\" viewBox=\"0 0 1280 920\" role=\"img\" aria-label=\"Knowledge Map\">\n<defs>\n <radialGradient id=\"knowledgeMapBg\" cx=\"50%\" cy=\"46%\" r=\"70%\">\n <stop offset=\"0%\" stop-color=\"#f7f4ec\" />\n <stop offset=\"60%\" stop-color=\"#e9eef0\" />\n <stop offset=\"100%\" stop-color=\"#dde6df\" />\n </radialGradient>\n <filter id=\"softShadow\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\">\n <feDropShadow dx=\"0\" dy=\"6\... [truncated]
176
+ {"ok":true,"title":"Knowledge Map","generatedAt":1783984859516,"width":1280,"height":920,"nodeCount":0,"edgeCount":0,"totalNodeCount":0,"totalEdgeCount":0,"facets":{"recordKinds":[],"nodeKinds":[],"sourceTypes":[],"sourceStatuses":[],"nodeStatuses":[],"issueCodes":[],"issueStatuses":[],"issueSeverities":[],"edgeRelations":[],"tags":[]},"nodes":[],"edges":[],"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1280\" height=\"920\" viewBox=\"0 0 1280 920\" role=\"img\" aria-label=\"Knowledge Map\">\n<defs>\n <radialGradient id=\"knowledgeMapBg\" cx=\"50%\" cy=\"46%\" r=\"70%\">\n <stop offset=\"0%\" stop-color=\"#f7f4ec\" />\n <stop offset=\"60%\" stop-color=\"#e9eef0\" />\n <stop offset=\"100%\" stop-color=\"#dde6df\" />\n </radialGradient>\n <filter id=\"softShadow\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\">\n <feDropShadow dx=\"0\" dy=\"6\... [truncated]
177
177
  ```
178
178
 
179
179
  ### Agent Knowledge isolated connectors list
@@ -363,7 +363,7 @@ export class EmailService {
363
363
  password,
364
364
  });
365
365
 
366
- // SEC-1: validate at the service boundary so injection is blocked regardless of
366
+ // Validate at the service boundary so injection is blocked regardless of
367
367
  // which client implementation is used.
368
368
  validateSmtpAddress(config.fromAddress, 'from');
369
369
  validateSmtpAddress(opts.to, 'to');
@@ -80,7 +80,7 @@ function buildXOAuth2Token(username: string, bearerToken: string): string {
80
80
  * Owns a single shared read cursor; callers must not interleave awaits.
81
81
  */
82
82
  // ---------------------------------------------------------------------------
83
- // IMAP credential quoting (SEC-2: LOGIN injection prevention)
83
+ // IMAP credential quoting: LOGIN injection prevention
84
84
  // ---------------------------------------------------------------------------
85
85
 
86
86
  /**
@@ -248,7 +248,7 @@ class ImapSession {
248
248
  const literalMatch = /\{(\d+)\}$/.exec(line);
249
249
  if (literalMatch) {
250
250
  const requested = parseInt(literalMatch[1] ?? '0', 10);
251
- // SEC-3: cap server-supplied literal size to prevent memory DoS
251
+ // Cap server-supplied literal size to prevent memory exhaustion
252
252
  if (requested > this.literalCap) {
253
253
  cleanup();
254
254
  reject(new Error(
@@ -538,7 +538,7 @@ export class ImapClient {
538
538
 
539
539
  private session(): ImapSession {
540
540
  const maxBodyBytes = this.options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
541
- // SEC-3: cap literal size at the larger of 1 MB or 4× the configured body preview limit
541
+ // Cap literal size at the larger of 1 MB or 4× the configured body preview limit
542
542
  const literalCap = Math.max(1_048_576, 4 * maxBodyBytes);
543
543
  return new ImapSession(
544
544
  this.options.socket,
@@ -554,7 +554,7 @@ export class ImapClient {
554
554
  const token = buildXOAuth2Token(username, password.slice(7));
555
555
  await session.command(`AUTHENTICATE XOAUTH2 ${token}`);
556
556
  } else {
557
- // LOGIN — credentials are quoted per RFC 3501 to prevent injection (SEC-2).
557
+ // LOGIN — credentials are quoted per RFC 3501 to prevent injection.
558
558
  // Credentials are not logged anywhere in this module.
559
559
  const quotedUser = imapQuoteCredential(username, 'username');
560
560
  const quotedPass = imapQuoteCredential(password, 'password');
@@ -53,15 +53,15 @@ const DEFAULT_TIMEOUT_MS = 15_000;
53
53
  const CRLF = '\r\n';
54
54
 
55
55
  // ---------------------------------------------------------------------------
56
- // Input validation (SEC-1: SMTP header/command injection prevention)
56
+ // Input validation: SMTP header/command injection prevention
57
57
  // ---------------------------------------------------------------------------
58
58
 
59
- /** Control-character pattern: CR, LF, and other C0/C1 control characters. */
59
+ /** Control-character pattern: CR, LF, and the other C0 and C1 control characters. */
60
60
  const CONTROL_CHAR_RE = /[\x00-\x1f\x7f-\x9f]/;
61
61
 
62
62
  /**
63
63
  * Validate a single SMTP envelope address (MAIL FROM / RCPT TO value).
64
- * Rejects: control characters (\r, \n, any C0/C1), spaces, angle brackets,
64
+ * Rejects: control characters (\r, \n, any C0 or C1), spaces, angle brackets,
65
65
  * comma-separated lists. Only a single bare address is accepted.
66
66
  *
67
67
  * @throws Error with a plain-language message on invalid input.
@@ -274,7 +274,7 @@ export class SmtpClient {
274
274
  // AUTH
275
275
  await this.authenticate(session, capabilities, username, password);
276
276
 
277
- // Validate envelope fields before writing to the protocol stream (SEC-1)
277
+ // Validate envelope fields before writing to the protocol stream (injection prevention)
278
278
  validateSmtpAddress(opts.from, 'from');
279
279
  validateSmtpAddress(opts.to, 'to');
280
280
  validateSmtpSubject(opts.subject);
@@ -427,7 +427,7 @@ export function createSmtpStartTlsSocket(
427
427
  return;
428
428
  }
429
429
 
430
- // SEC-4: assert no pipelined data arrived after the 220 STARTTLS reply.
430
+ // STARTTLS guard: assert no pipelined data arrived after the 220 reply.
431
431
  // Any bytes beyond the \n of the 220 line indicate a hostile server
432
432
  // injecting data before TLS negotiation begins.
433
433
  const newlineIdx = stBuffer.indexOf('\n');
@@ -1,5 +1,6 @@
1
- import type { ConfigKey, ConfigManager, ConfigSetting, PersistedFlagState } from '../config/index.ts';
1
+ import type { ConfigKey, ConfigManager, ConfigSetting } from '../config/index.ts';
2
2
  import { CONFIG_SCHEMA, ConfigError } from '../config/index.ts';
3
+ import { resolveFeatureEnablementWrite } from '../runtime/feature-enablement.ts';
3
4
  import type { GoodVibesCliCommand, GoodVibesCliFlags } from './types.ts';
4
5
  import { RUNTIME_ENDPOINT_CONFIG_KEYS, hostModeForHostname } from './endpoints.ts';
5
6
  import type { RuntimeEndpointId } from './endpoints.ts';
@@ -150,24 +151,38 @@ export function applyRuntimeUrlOverride(
150
151
  }
151
152
  }
152
153
 
153
- export function applyRuntimeFeatureFlagOverrides(
154
+ /**
155
+ * Apply --enable-feature/--disable-feature as RUNTIME-ONLY writes to the
156
+ * feature's domain settings key (the dissolved feature model has no separate
157
+ * enablement namespace). Nothing is persisted: the write lands on the
158
+ * in-memory config just like --config overrides, and the settings-derived
159
+ * gate seeding in bootstrap picks it up. Returns honest per-feature errors
160
+ * (unknown ids, always-available features) instead of silently accepting
161
+ * anything, matching applyRuntimeConfigOverrides' contract.
162
+ */
163
+ export function applyRuntimeFeatureOverrides(
154
164
  configManager: ConfigManager,
155
165
  options: {
156
166
  readonly enableFeatures: readonly string[];
157
167
  readonly disableFeatures: readonly string[];
158
168
  },
159
- ): void {
160
- if (options.enableFeatures.length === 0 && options.disableFeatures.length === 0) return;
161
- const flags = { ...configManager.getCategory('featureFlags') };
162
- for (const feature of options.enableFeatures) {
163
- flags[feature] = 'enabled' satisfies PersistedFlagState;
164
- }
165
- for (const feature of options.disableFeatures) {
166
- flags[feature] = 'disabled' satisfies PersistedFlagState;
167
- }
168
- // Write the entire featureFlags category at once to preserve the exact shape getCategory expects.
169
- // mutableConfig() validates the 'config' field exists and throws loudly if the SDK renames it.
170
- mutableConfig(configManager).featureFlags = flags;
169
+ ): readonly string[] {
170
+ const errors: string[] = [];
171
+ const requests = [
172
+ ...options.enableFeatures.map((featureId) => ({ featureId, desired: 'enabled' as const, flag: '--enable-feature' })),
173
+ ...options.disableFeatures.map((featureId) => ({ featureId, desired: 'disabled' as const, flag: '--disable-feature' })),
174
+ ];
175
+ for (const request of requests) {
176
+ try {
177
+ const write = resolveFeatureEnablementWrite(request.featureId, request.desired);
178
+ setRuntimeOnlyConfigValue(configManager, write.key, write.value);
179
+ } catch (error) {
180
+ errors.push(error instanceof Error
181
+ ? `Invalid ${request.flag} ${request.featureId}. ${error.message}`
182
+ : `Invalid ${request.flag} ${request.featureId}`);
183
+ }
184
+ }
185
+ return errors;
171
186
  }
172
187
 
173
188
  export function applyRuntimeEndpointFlagOverrides(
@@ -10,7 +10,7 @@ import {
10
10
  applyRuntimeCommandEndpointFlagOverrides,
11
11
  applyRuntimeConfigOverrides,
12
12
  applyRuntimeConfigValue,
13
- applyRuntimeFeatureFlagOverrides,
13
+ applyRuntimeFeatureOverrides,
14
14
  applyRuntimeUrlOverride,
15
15
  buildCliStatusSnapshot,
16
16
  handleGoodVibesCliCommand,
@@ -27,7 +27,7 @@ import { inspectCliExternalRuntime } from './external-runtime.ts';
27
27
  import { inspectConnectedHostMetrics } from './connected-host-metrics.ts';
28
28
  import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
29
29
  import { readCheckpointRegistrationSetting } from '../config/checkpoint-settings.ts';
30
- import { migrateLegacyWorkspaceRegistryIfNeeded, resolveWorkspaceRegistrationSync } from '../config/workspace-registration.ts';
30
+ import { backfillCheckpointEligibilityIfNeeded, migrateLegacyWorkspaceRegistryIfNeeded, resolveCheckpointEligibilitySync } from '../config/workspace-registration.ts';
31
31
  import { resolveAgentRuntimeProfileHome, resolveSelectedAgentRuntimeProfileHome } from '../agent/runtime-profile.ts';
32
32
 
33
33
  type ShellEntrypointOwnership = {
@@ -147,10 +147,14 @@ export async function prepareShellCliRuntime(
147
147
  console.error(overrideErrors.join('\n'));
148
148
  process.exit(2);
149
149
  }
150
- applyRuntimeFeatureFlagOverrides(configManager, {
150
+ const featureOverrideErrors = applyRuntimeFeatureOverrides(configManager, {
151
151
  enableFeatures: cli.flags.enableFeatures,
152
152
  disableFeatures: cli.flags.disableFeatures,
153
153
  });
154
+ if (featureOverrideErrors.length > 0) {
155
+ console.error(featureOverrideErrors.join('\n'));
156
+ process.exit(2);
157
+ }
154
158
 
155
159
  if (cli.flags.provider !== undefined || cli.flags.model !== undefined) {
156
160
  const currentModel = configManager.get('provider.model');
@@ -207,8 +211,12 @@ export async function prepareShellCliRuntime(
207
211
  if (registrationMigration) {
208
212
  logger.info('Migrated the local workspace registry into the shared registration store', { ...registrationMigration });
209
213
  }
214
+ backfillCheckpointEligibilityIfNeeded(shellPaths);
210
215
  const checkpoints = {
211
- workspaceRegistered: resolveWorkspaceRegistrationSync(shellPaths, bootstrapWorkingDir).status === 'covered',
216
+ // Honest to the checkpoint boundary: a workspace is "registered" for
217
+ // checkpoints only when it is checkpoint-ELIGIBLE (an explicit owner
218
+ // opt-in), not merely present in the shared store as a TUI self-record.
219
+ workspaceRegistered: resolveCheckpointEligibilitySync(shellPaths, bootstrapWorkingDir).status === 'covered',
212
220
  unregisteredWorkspaceMode: readCheckpointRegistrationSetting(configManager),
213
221
  };
214
222
  const statusOptions = {