# Trace/File-History Empty-Result Diagnostics ## AC-1: Human mode shows searched paths on empty results When `lore trace ` returns 0 chains in human mode, the output includes the resolved path(s) that were searched. If renames were followed, show the full rename chain. ## AC-2: Human mode shows actionable reason on empty results When 0 chains are found, the hint message distinguishes between: - "No MR file changes synced yet" (mr_file_changes table is empty for this project) -> suggest `lore sync` - "File paths not found in MR file changes" (sync has run but this file has no matches) -> suggest checking the path or that the file may predate the sync window ## AC-3: Robot mode includes diagnostics object on empty results When `total_chains == 0` in robot JSON output, add a `"diagnostics"` key to `"meta"` containing: - `paths_searched: [...]` (already present as `resolved_paths` in data -- no duplication needed) - `hints: [string]` -- same actionable reasons as AC-2 but machine-readable ## AC-4: Info-level logging at each pipeline stage Add `tracing::info!` calls visible with `-v`: - After rename resolution: number of paths found - After MR query: number of MRs found - After issue/discussion enrichment: counts per MR ## AC-5: Apply same pattern to `lore file-history` All of the above (AC-1 through AC-4) also apply to `lore file-history` empty results. --- # Secure Token Resolution for Cron ## AC-6: Config file supports optional stored token `config.json` accepts an optional `"token"` field in the `gitlab` section. Existing configs without this field continue to load without error. ## AC-7: Token resolution chain — env var wins, config file falls back When resolving the GitLab token, the CLI checks in order: (1) environment variable named by `tokenEnvVar`, (2) `token` field in config file. The first non-empty value wins. If neither is set, the existing `TOKEN_NOT_SET` error is returned. ## AC-8: `lore token set` stores token securely A new `lore token set` subcommand: - Accepts token via `--token` flag, stdin pipe, or interactive prompt (masked input) - Validates the token against the GitLab API before storing - Writes the token into the existing `config.json` without disturbing other fields - Sets file permissions to `0600` (owner read/write only) on the config file after writing - Works in both human and robot mode ## AC-9: `lore token show` reveals stored token A new `lore token show` subcommand: - Shows the token source (env var or config file) and a masked version by default - `--unmask` flag reveals the full token value - Works in both human and robot mode ## AC-10: All token lookups use centralized resolver The 5 call sites that currently do `std::env::var(&config.gitlab.token_env_var)` are replaced with a single `config.gitlab.resolve_token()` method. No inline env var lookups remain for the GitLab token. ## AC-11: `lore cron install` warns when no stored token After installing the cron entry, if `resolve_token()` would fail without an env var (i.e., no token in config file), print a warning directing the user to run `lore token set`. ## AC-12: `TOKEN_NOT_SET` error suggests `lore token set` The error suggestion and `actions` array for `TOKEN_NOT_SET` include `lore token set` as the primary recommended fix, with env var export as the secondary option. ## AC-13: `lore doctor` reports token source The doctor command's GitLab check shows where the token was found: "from config file" or "from GITLAB_TOKEN env var", helping users diagnose cron issues.