|
|
|
|
@@ -506,7 +506,7 @@ they failed. Rows recorded before the change keep their old field set and still
|
|
|
|
|
| Metric | Dimensions added | Question it answers |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| `hermes.extension.install.count` | failure class, registry | Why skill, plugin and MCP installs fail, and which skills-hub source fails. `failure_class` is `none` on success, else a closed name for the failure exit that stopped the install. Skills: `ambiguous`, `auth_rejected`, `fetch_failed`, `invalid_bundle`, `invalid_name`, `not_found`, `rate_limited`, `scan_blocked`, `stale_index`. Plugins: `already_installed`, `clone_failed`, `deps_declined`, `deps_failed`, `git_missing`, `incompatible`, `invalid_source`, `manifest_invalid`, `non_interactive`, `removed_from_catalog`, `scan_blocked`. MCP servers: `auth_required`, `bootstrap_failed`, `clone_failed`, `config_invalid`, `config_rejected`, `connect_failed`, `git_missing`, `missing_credentials`, `server_start_failed`. Every kind may also read `exception`, `filesystem_error`, `network`, `other`, `permission`. A raised error without a named class is classified by its Python type only (`PermissionError` reads `permission`, connection and timeout errors `network`, other `OSError`s `filesystem_error`, anything else `exception`, its type name dropped). `registry` is set on skill rows only: the skills-hub adapter that resolved or served the skill, one of `browse-sh`, `clawhub`, `github`, `hermes-index`, `lobehub`, `official`, `skills-sh`, `url`, `well-known` (the adapter ids `tools/skills_hub_search.py::create_source_router` builds), `unresolved` when no adapter answered, `none` for built-in restores and every plugin/MCP row, `other` otherwise. A row whose `failure_class` is outside its kind's set, is `none` on a failure or set on a success, or that names a registry on a plugin/MCP row is invalid. Never the identifier, URL, error text or path; `name` keeps its existing catalog-or-`custom` rule. |
|
|
|
|
|
| `hermes.update.run` | failure class | Why `hermes update` fails, next to where (`failed_stage`). `none` unless the outcome is `failed`, `refused` or `partial`. Derived from the final update receipt only: `build_failed`, `deps_failed`, `exception`, `fleet_stale`, `fleet_unverified`, `git_failed`, `interrupted`, `lock_held`, `managed_install`, `os_error`, `disk_full`, `permission_denied`, `restart_failed`, `subprocess_failed`, else `other`; Desktop packaged self-updates report `unknown` (their RPC carries a stage, never a reason). An exception that ended the run is read by its type name alone, never its message (a `PermissionError` reads `permission_denied`, an `OSError` whose errno is ENOSPC reads `disk_full`); a failed Windows gateway resume after the update reads `restart_failed`. Every exit that stops a run before its apply stage mark records one closed token at the exit itself, and the run reads it (a few of these, `syntax_rollback`, `stash_restore_rejected`, `unexpected_branch`, `head_moved`, fire after git moved the tree and put it back or left it for the next launch to restore): `fetch_failed`, `git_timeout` (a network git call hit the updater's time limit), `channel_unresolved` (also an invalid channel name in config.yaml), `config_unreadable` (config.yaml cannot be read or parsed, so the channel is unknown), `gateway_pause_failed` (Windows: the gateways could not be paused safely before the venv moves), `git_in_progress` (a merge/rebase/... was already running), `git_index_locked`, `merge_conflict` (local commits on a custom branch), `checkout_move_failed`, `branch_missing`, `parked_branch_blocked`, `detached_head`, `unexpected_branch`, `head_moved` (a ref moved mid-update), `target_unresolved`, `target_syntax_error` (refused before the move), `syntax_rollback` (moved, failed the syntax check, rolled back), `commit_point_refused` (the commit point could not be armed; nothing moved), `venv_foreign_owner`, `local_changes_blocked` (local changes git could not stash, or a dirty tree the ZIP fallback will not overwrite), `stash_restore_rejected`, `not_git_checkout`, `old_version_handoff` (an older updater's hand-off could not finish), `branch_unsupported`, `download_failed`, `zip_failed`, `disk_full`, `lock_held`, `managed_install`. `aborted_before_apply` is now only the fallback for such an exit with no recorded token. The startup-syntax preflight reads the target's critical files from git's object store; when that read times out (a blobless install lazily fetches each blob) the preflight skips them like absent files and the post-move syntax check decides, so the run no longer fails as `subprocess_failed`. The update-lock refusal, the Git-operation refusal and the managed-install refusal fire before the run's receipt opens; they still write no receipt (the receipt store belongs to the update holding the lock) and record one row with that token, with `kind` `desktop` when the update marker names this run's Desktop hand-off (as its delegate or its hand-off partner), never merely because another update holds the marker. A git error that ended the checkout move reads `git_index_locked` only when git reports the index lock already exists; git refused permission to write it (or any file) reads `permission_denied`. A token is read only while the run has no apply mark, so a reason can never outlive the exit that recorded it. A run that committed and then was interrupted, or whose stashed local changes could not be re-applied, reads outcome `partial` (`interrupted` / `local_changes_parked`, `failed_stage` `apply` for the latter), never `failed`; owed follow-ups alone keep the run a `success` (contract C3). A run the pre-update interpreter finishes is parked with the token, the exit code, the stop reason's leading exception type (or one of Hermes' two fixed phrases) and the restart/user-action flags (never argv, paths or messages), so it classifies exactly as the same run finished in-process. A failed run whose every stage mark passed now reads `failed_stage` `verify` (the post-restart verification wrote `partial`) or `restart` (a skipped restart left the fleet owing one) instead of `other`; a `partial` run with a failed build or restart mark keeps that stage, and its verify stage row is failed only when the fleet has a stale or down row. |
|
|
|
|
|
| `hermes.update.run` | failure class | Why `hermes update` fails, next to where (`failed_stage`). `none` unless the outcome is `failed`, `refused` or `partial`. Derived from the final update receipt only: `build_failed`, `deps_failed`, `exception`, `fleet_stale`, `fleet_unverified`, `git_failed`, `interrupted`, `lock_held`, `managed_install`, `os_error`, `disk_full`, `permission_denied`, `restart_failed`, `subprocess_failed`, else `other`; Desktop packaged self-updates report `unknown` (their RPC carries a stage, never a reason). An exception that ended the run is read by its type name alone, never its message (a `PermissionError` reads `permission_denied`, an `OSError` whose errno is ENOSPC reads `disk_full`); a failed Windows gateway resume after the update reads `restart_failed`. Every exit that stops a run before its apply stage mark records one closed token at the exit itself, and the run reads it (a few of these, `syntax_rollback`, `stash_restore_rejected`, `unexpected_branch`, `head_moved`, fire after git moved the tree and put it back or left it for the next launch to restore): `fetch_failed`, `git_timeout` (a network git call hit the updater's time limit), `channel_unresolved` (also an invalid channel name in config.yaml), `gateway_pause_failed` (Windows: the gateways could not be paused safely before the venv moves), `git_in_progress` (a merge/rebase/... was already running), `git_index_locked`, `merge_conflict` (local commits on a custom branch), `checkout_move_failed`, `branch_missing`, `parked_branch_blocked`, `detached_head`, `unexpected_branch`, `head_moved` (a ref moved mid-update), `target_unresolved`, `target_syntax_error` (refused before the move), `syntax_rollback` (moved, failed the syntax check, rolled back), `commit_point_refused` (the commit point could not be armed; nothing moved), `venv_foreign_owner`, `local_changes_blocked` (local changes git could not stash, or a dirty tree the ZIP fallback will not overwrite), `stash_restore_rejected`, `not_git_checkout`, `old_version_handoff` (an older updater's hand-off could not finish), `branch_unsupported`, `download_failed`, `zip_failed`, `disk_full`, `lock_held`, `managed_install`. `aborted_before_apply` is now only the fallback for such an exit with no recorded token. The startup-syntax preflight reads the target's critical files from git's object store; when that read times out (a blobless install lazily fetches each blob) the preflight skips them like absent files and the post-move syntax check decides, so the run no longer fails as `subprocess_failed`. The update-lock refusal, the Git-operation refusal and the managed-install refusal fire before the run's receipt opens; they still write no receipt (the receipt store belongs to the update holding the lock) and record one row with that token, with `kind` `desktop` when the update marker names this run's Desktop hand-off (as its delegate or its hand-off partner), never merely because another update holds the marker. A git error that ended the checkout move reads `git_index_locked` only when git reports the index lock already exists; git refused permission to write it (or any file) reads `permission_denied`. A token is read only while the run has no apply mark, so a reason can never outlive the exit that recorded it. A run that committed and then was interrupted, or whose stashed local changes could not be re-applied, reads outcome `partial` (`interrupted` / `local_changes_parked`, `failed_stage` `apply` for the latter), never `failed`; owed follow-ups alone keep the run a `success` (contract C3). A run the pre-update interpreter finishes is parked with the token, the exit code, the stop reason's leading exception type (or one of Hermes' two fixed phrases) and the restart/user-action flags (never argv, paths or messages), so it classifies exactly as the same run finished in-process. A failed run whose every stage mark passed now reads `failed_stage` `verify` (the post-restart verification wrote `partial`) or `restart` (a skipped restart left the fleet owing one) instead of `other`; a `partial` run with a failed build or restart mark keeps that stage, and its verify stage row is failed only when the fleet has a stale or down row. |
|
|
|
|
|
<!-- ---- end iuf c1 ---- -->
|
|
|
|
|
<!-- ---- iuf c2 ---- -->
|
|
|
|
|
#### Fresh installs
|
|
|
|
|
|