Skip to content

[walk test] whoami --short - #71

Open
sagnik11 wants to merge 17 commits into
mainfrom
autter-walk-test/cli
Open

sagnik11 wants to merge 17 commits into
mainfrom
autter-walk-test/cli

Conversation

@sagnik11

@sagnik11 sagnik11 commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

This is a test PR to exercise Autter's product walk. It will not be merged.

It adds autter whoami --short (-s), which prints one line, <email> (<org>) <state>, for scripts and shell prompts. It keeps the full report's exit code: 1 when not logged in and no API key is set. Unknown arguments are still a usage error.

Unit tests in src/commands/whoami.rs cover the formatter, the exit rule and API-key masking.

What the walk should exercise: the CLI walk, which builds the binary and runs it, including the concurrency personas.

Note: this was written without a local Rust toolchain, so CI and the walk's build are the compile check.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


View code changes stack in Autter

Summary

Summary generated by Autter.

Why this change

autter whoami has no compact output mode for scripts and quick checks, and it silently accepts arbitrary arguments. This change adds a --short mode and tightens argument handling.

What changes for users

Users can run autter whoami --short (or -s) for condensed output. Unrecognised arguments now produce an error instead of being ignored, and whoami gains masked API key display.

Implementation and review notes

  • Argument parsing in handle_whoami detects --short/-s and filters them out before checking for unknown arguments; the --help/-h/help short-circuit still runs first and exits 0.
  • Any remaining unknown argument triggers an Error: message on stderr. Review whether this should exit non-zero, since that determines script behaviour.
  • The new mask_api_key helper (around lines 151-227 in the new file) is the main addition; check that it never prints a full key in either short or full output.
  • Short and full output both draw on collect_auth_status and format_unix_timestamp from crate::auth, so no new auth logic is introduced.
  • No persistent state, config, or database changes are involved.

Changes

  • Adds a --short / -s flag to autter whoami (src/commands/whoami.rs) that produces condensed output.
  • Argument handling now collects unrecognised arguments and reports them as an error on stderr. Scripts that previously passed extra, ignored arguments will now see this error.
  • Adds a mask_api_key helper so API keys are displayed in masked form rather than in full.
  • --help, -h and help still print usage and exit 0.
  • Reuses collect_auth_status and format_unix_timestamp from crate::auth; no auth logic changes.

Acceptance Criteria

  • autter whoami --short and autter whoami -s print condensed auth status and exit 0 when signed in.
  • autter whoami --help, -h and help print usage and exit 0.
  • An unrecognised argument prints an Error: message to stderr.
  • API keys never appear unmasked in either short or full output.
  • cargo check --locked --all-targets passes.

Test Plan

  • Run task dev to install the local debug build.
  • Run autter whoami and confirm full output is unchanged apart from key masking.
  • Run autter whoami --short and autter whoami -s and confirm both produce the condensed output.
  • Run autter whoami --help, autter whoami -h and autter whoami help and confirm usage text with exit code 0.
  • Run autter whoami --bogus and confirm the error on stderr.
  • Run autter whoami while signed out and confirm the output is still sensible.
  • Run task test and confirm it passes.
  • Run task lint and task fmt and confirm no issues remain.

Rollback Plan

  • Revert the commit that modifies src/commands/whoami.rs; this restores the previous argument handling and output.
  • No schema, config, or stored-data changes are involved, so no data cleanup is needed.
  • Rebuild with task build and confirm autter whoami behaves as before.

Related Issues

No linked issue was identified from the branch name, commit messages, or diff context.

Written for commit 46159e9. Summary will update on new commits.

autter whoami --short (-s) prints `<email> (<org>) <state>` and keeps the full
report's exit rule (fails when not logged in and no API key). Unit tests for
the formatter, the exit rule and API-key masking. Test PR for Autter's
product walk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@autter-dev

autter-dev Bot commented Oct 12, 2026

Copy link
Copy Markdown
⚠️ 2 unconfirmed finding(s) — flagged by a detector but not proven by Autter's verification pass

Inline comments are reserved for findings that survived verification. These are plausible but could not be confirmed from the available context, so they are listed here as FYIs instead — review the ones that look real to you.

  • 🟡 Missing linked tracker issue (risk 20/100) — src/commands/whoami.rs:14 — The PR title "[walk test] whoami --short" contains no tracker reference, so the title half of the claim holds. The PR body is not in the provided evidence, so I cannot confirm the body also lacks one. This is a process/policy concern rather than a code defect, and no repository rule requires linked issues.
  • 🟡 Broken invariant (risk 36/100) — src/commands/whoami.rs:161 — state_label interpolates AuthState::Error verbatim, so a newline in the error would violate the one-line contract. However, the provided excerpts do not show whether collect_auth_status can return an error containing a newline or sanitizes it upstream, so reachability of the counterexample is unproven.

@autter-dev

autter-dev Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

⚠️ Couldn't fully check this: a test suite this PR doesn't touch was already failing

Nothing Autter could check blocks merging, but some checks didn't run. See “Autter couldn't check everything” below.

  • 🔄 Re-run review

What we checked

✅ Code review: No problems found. 2 minor suggestions.
⚠️ Build and tests: Couldn't run everything: a test suite this PR doesn't touch was already failing.
✅ Installed and used the package like a user: No problems found. 6 of 6 simulated users reached their goals.

⚙️ Autter couldn't check everything

These are problems with Autter's setup, not with your code.

  • Couldn't run the autter tests. The provided cargo test output does not show any failing test or error; it only lists passing autter tests and is truncated.
    👉 Nothing to do for this PR. That suite fails without your change too.

Plus 2 minor suggestions (style, conventions, hardening) in the sections below. They don't block merging.


🧭 Installed and used the package like a user: no problems

Autter tried this change and found no problems.

Revision: 46159e97e894

This change is a package or command-line tool, so Autter installed it the way a user receives it into a clean project and used it, rather than only running the repo's own tests.

Database for .: built from Autter's parse of your schema files at this commit (the repo has no migrate command), 21 tables; seeded 64 rows in 21 tables.

Simulated users: 6 simulated command-line users. Each one has a different habit: follows the docs, mistypes, double-clicks, and so on.

Goal With this PR Result
User checks what the whoami command offers and sees usage text 3/3 Pass
User runs whoami outside a git repository and gets a clear 3/3 Pass

Package walk of autter: autter-test-git-shim looks like the project's own tooling (a test helper, shim or fixture that the README doesn't mention), so the walk didn't run it.

Known autter journeys: 4 replayed with no model decisions; 4 still work.

Saved 2 new autter journeys from this PR's goals, to replay on later PRs that touch the same files.

Steps Autter took (4)
  1. check “autter: packages with cargo package” — completed
  2. check “autter: a clean consumer crate builds against the packaged crate” — completed
  3. check “autter: the binaries build from the packaged crate” — completed
  4. check “autter: autter --help runs” — completed

Live view: streamed through the Autter API relay from us-west-2.

Trying the change like a user doesn't block merging.

🧪 Test run: couldn't run everything

Autter checked 46159e97.

Tests couldn't run: a test suite this PR doesn't touch was already failing.

  • ⚠️ Functional: couldn't run: a test suite this PR doesn't touch was already failing
  • ⚠️ Regression: couldn't run: the affected tests couldn't start

Autter couldn't run your tests because…

  • A test suite this PR doesn't touch was already failing (functional).
    👉 Nothing to do for this PR. That suite fails without your change too.

This is about Autter's setup, not your code.

Full test report

This PR changes 1 source file. It ran the project's test command for the workspace this PR touched, because those suites are the fastest check that the change did not break existing behavior. It wrote 1 temporary test for changed files that had no matching test, so the new behavior is still checked. It also executed 1 check from the PR's test plan.

Targeted agent checks: Autter ran targeted checks against the files this PR changed — it executed uncovered test-plan items and, where a changed file had no matching test, wrote a temporary test to verify the new behavior.

Execution summary: 2 checks executed · 1 passed · 1 failed.

Why suites failed

  • autter — cargo test: the failing test names no file this PR changes, so it most probably fails on the base branch too.
    First error: test api::types::tests::test_cas_upload_result_with_error ... ok

Project test commands

Scope Command Result
autter cargo test ❌ failed · 76s

Autter targeted verification

1 test executed · 1 passed.

Code-level simulations

Revision 46159e97e894 · 421.8s · up to 2 scenarios in parallel

  • Short output and -s alias for a signed-in identity — execution incomplete (code_diff, code_diff, spec)
    Source: src/commands/whoami.rs — let org_slug = auth.orgs.first().and_then(|org| org.org_slug.as_deref());
    Source: src/commands/whoami.rs — println!("{}", short_identity(&auth.state, auth.email.as_deref(), org_slug));
    Source: PR description — It adds autter whoami --short (-s), which prints one line, <email> (<org>) <state>, for scripts and shell prompts.
    Ran: python3 '.autter/scratch/whoami_short_harness.py'
    Indexed blast radius: 0 direct / 0 transitive dependents (indexed 2026-08-31T13:52:36.822Z).
    Could not complete: Simulation did not emit exactly one completed assertion report. File "/tmp/autter-wt-sim-1f7c6a83bdb1e009e995-OsWZxu/tree/.autter/scratch/whoami_short_harness.py", line 197
  • Help precedence and unknown-argument failures — execution incomplete (code_diff, code_diff, spec)
    Source: src/commands/whoami.rs — .any(|arg| arg == "--help" || arg == "-h" || arg == "help")
    Source: src/commands/whoami.rs — std::process::exit(crate::commands::EXIT_USAGE_ERROR);
    Source: PR description — Unknown arguments are still a usage error.
    Ran: node '.autter/scratch/whoami-help-precedence.mjs'
    Indexed blast radius: 0 direct / 0 transitive dependents (indexed 2026-08-31T13:52:36.822Z).
    Could not complete: The check stopped on an internal error.
  • Short output preserves non-logged-in auth state labels — execution incomplete (code_diff, code_diff, code_diff, spec)
    Source: src/commands/whoami.rs — AuthState::SyncBlocked => "cloud sync blocked".to_string(),
    Source: src/commands/whoami.rs — AuthState::RefreshExpired => "credentials expired".to_string(),
    Source: src/commands/whoami.rs — if identity_failed(&auth.state, has_api_key) {
    Source: PR description — It keeps the full report's exit code: 1 when not logged in and no API key is set.
    Ran: python3 '.autter/scratch/whoami_short_auth_labels.py'
    Indexed blast radius: 0 direct / 0 transitive dependents (indexed 2026-08-31T13:52:36.822Z).
    Could not complete: Simulation did not emit exactly one completed assertion report. simulation infrastructure error: startup command failed (128): git
  • API-key masking in the full report and no key leakage in short output — execution incomplete (code_diff, code_diff, spec)
    Source: src/commands/whoami.rs — let masked = mask_api_key(api_key);
    Source: src/commands/whoami.rs — let has_api_key = ApiContext::new(None).api_key.is_some();
    Source: PR description — Unit tests in src/commands/whoami.rs cover the formatter, the exit rule and API-key masking.
    Ran: node '.autter/scratch/whoami-api-key.mjs'
    Indexed blast radius: 0 direct / 0 transitive dependents (indexed 2026-08-31T13:52:36.822Z).
    Could not complete: Simulation did not emit exactly one completed assertion report. Harness infrastructure error: Creating isolated worktree failed
  • Concurrent CLI personas remain isolated — execution incomplete (code_diff, code_diff, spec)
    Source: src/commands/whoami.rs — let auth = collect_auth_status();
    Source: src/commands/whoami.rs — let has_api_key = ApiContext::new(None).api_key.is_some();
    Source: PR description — What the walk should exercise: the CLI walk, which builds the binary and runs it, including the concurrency personas.
    Ran: node '.autter/scratch/whoami-concurrency.mjs'
    Indexed blast radius: 0 direct / 0 transitive dependents (indexed 2026-08-31T13:52:36.822Z).
    Could not complete: Simulation did not emit exactly one completed assertion report. (node:39122) [DEP0174] DeprecationWarning: Calling promisify on a function that returns a Promise is likely a mistake.
  • Full report remains multi-line and preserves signed-out exit behavior — execution incomplete (code_diff, code_diff, spec)
    Source: src/commands/whoami.rs — if short {
    Source: src/commands/whoami.rs — println!("API Base URL: {}", api_base_url);
    Source: PR description — Run autter whoami and confirm full output is unchanged apart from key masking.
    Ran: python3 '.autter/scratch/whoami_multiline.py'
    Indexed blast radius: 0 direct / 0 transitive dependents (indexed 2026-08-31T13:52:36.822Z).
    Could not complete: Simulation did not emit exactly one completed assertion report. Traceback (most recent call last):
    Source unavailable: Production traffic data was not available for this run.
    Coverage limitation: No production patterns or runtime IDs were supplied, so no production-derived scenario is included.
    Coverage limitation: The changed behavior is local CLI argument parsing and auth-status formatting; these scenarios require no disposable Postgres database.

Declared tests: 4 test file(s) found — 0 ran, 4 not observed in suite output, 0 did not run.

"Not observed" means a test command ran but never named the file in its output. A runner that stops at the first failure, shards its files, or prints only a summary produces this. Autter cannot confirm these tests ran, so it does not count them as passed. The autter command failed here, so the files after the failure most probably never started.

⚠️ Test cases that did not run
  • ❔ agent-support/vscode/src/test/extension.test.ts (1 case) — its suite (autter) failed before it reported this file
  • ❔ agent-support/vscode/src/test/semver.test.ts (5 cases) — its suite (autter) failed before it reported this file
  • ❔ agent-support/vscode/src/test/vscode-hooks.test.ts (2 cases) — its suite (autter) failed before it reported this file
  • ❔ npm/install.test.js (3 cases) — its suite (autter) failed before it reported this file

Tests for this change

Autter wrote 1 temporary test for changed files that had none (1 passed, 0 failed).

Change coverage (is each changed file's behavior verified by a test?)

Changed file Related test Result
src/commands/whoami.rs src/commands/whoami.rs ✅ no declared test — temporary test passed
🤖 Coverage-check evidence

src/commands/whoami.rs

Temporary tests are written under .autter/scratch/ for verification only — they are never committed to the repository.

Test plan (from the PR description)

  • ⬜ Run task dev to install the local debug build. — needs manual verification
  • ⬜ Run autter whoami and confirm full output is unchanged apart from key masking. — needs manual verification
  • ⬜ Run autter whoami --short and autter whoami -s and confirm both produce the condensed output. — needs manual verification
  • ⬜ Run autter whoami --help, autter whoami -h and autter whoami help and confirm usage text with exit code 0. — needs manual verification
  • ⬜ Run autter whoami --bogus and confirm the error on stderr. — needs manual verification
  • ⬜ Run autter whoami while signed out and confirm the output is still sensible. — needs manual verification
  • ❌ Run task test and confirm it passes. — cargo test failed
  • ⬜ Run task lint and task fmt and confirm no issues remain. — needs manual verification

⬜ items could not be verified automatically and still need a manual check.

🚦 Pre-merge checks: 1 worth a look, 164 passed
Check Status Explanation
Missing linked tracker issue ⚠️ Worth a look 1 potential issue(s) detected (max risk 50/100): src/commands/whoami.rs:14.
✅ 164 passed

Too many files changed · Too many lines changed · Too many unrelated chapters · Generated files hiding real changes · Missing PR context · Mixed concerns (refactor + behavior change) · Migration + app logic + UI combined in one PR · Sensitive data in logs · Log injection · Missing audit logging · Removed observability · Rate limiting not detected · Rate limiting removed · Batch size limit not detected · Pagination not detected · Merge-blocking marker left in the change · Known-defect marker shipped in code · Untracked TODO without an issue reference · Test disabled or left pending · Redundant alias / duplicate import · Redundant type construct · Unnecessary type assertion · Module smell · Dead export (no callers) · Code duplication / DRY violation · Silent exception swallowing · Unhandled promise rejection · Circuit breaker not detected · Stack trace leakage · Multi-write without detected transaction · Possible TOCTOU in critical path · Idempotency key not detected · Possible non-atomic read-modify-write · Optimistic locking not detected · Prompt injection risk · LLM output used in a dangerous sink · Sensitive data in prompt or system-prompt leakage · Over-privileged LLM tool / excessive agency · Missing validation on an LLM-driven decision · Unbounded LLM usage (denial-of-wallet) · Table exposed without row-level security · Over-broad row-level security policy · Code path that bypasses row-level security · Privileged database credential reachable from the client · Privileged query without row-level scoping · Row-level security enabled with no policy · Template-default gradient styling · Interchangeable AI marketing copy · Placeholder content shipped to users · Emoji standing in for an icon system · Call-to-action that goes nowhere · Templated page composition · Color outside the brand palette · Hardcoded style bypassing design tokens · Typography outside the brand type system · One-off UI instead of the shared component · Copy that does not match brand voice · Screen does not match the rest of the product · PII in logs · PII or internals leaked in error response · PII stored without application-level encryption · User data stored without retention controls · PII sent to external / cross-border destination · Lockfile resolution / integrity tampered · Dependency runs install-time lifecycle script · Possible dependency-confusion attack · Lockfile resolves a dependency the manifest does not declare · Checked-in build artefact modified without source change · Dockerfile build-step is insecure · External artefact pulled in without integrity pinning · Changed export, importer not updated · Missing CODEOWNERS reviewer approval · Missing security-team review on sensitive path · Source changes without matching tests · Migration missing rollback / down step · Frontend importing database client directly · Route handler bypassing service layer · Backend service importing UI module · Cross-context internals import · Workspace package rule violation · Inconsistent logging pattern · Inconsistent error handling · Endpoint missing input validation · Multi-write without transaction wrapper · New feature shipped without feature flag · Module placed in the wrong workspace package · Hallucinated import (package not installed) · Nonexistent package (not found in registry) · Call to function that does not exist · Generic placeholder identifier in production logic · Repetitive boilerplate (duplicated block) · Overbroad try/catch swallowing all exceptions · TODO / FIXME on critical path · Comment contradicts or fabricates code behaviour · Abstraction defined but never used · Code style differs from rest of codebase · Established pattern ignored · Unhandled edge case (null / empty / zero / boundary) · Insecure training-data / doc-example pattern · Dead code (defined but never referenced) · Deprecated API call · API pattern from wrong library version · API endpoint removed · HTTP method changed (GET ↔ POST etc.) · New required field added to request · Field removed from response schema · Response field type changed · HTTP status code changed · Auth requirement added / removed / changed · Error response shape changed · Pagination behaviour changed · Outbound webhook payload schema changed · GraphQL field removed without deprecation · GraphQL enum value removed · Connected repositories · Vendor API consumer · SQL injection · Cross-site scripting (XSS) · Path traversal · Command injection · Insecure deserialization · Weak cryptography · Hardcoded secret · Insecure randomness for security material · Unsafe file upload · Missing input validation · Unsafe CORS configuration · Unsafe / open redirect · Missing CSRF protection · Unsafe cookie / session settings · Sensitive data exposure · Invisible Unicode / Trojan Source characters · API key in source · Access token in source · Private key in source · Database connection URL with embedded credentials · Cloud credential in source · Webhook signing secret in source · OAuth client secret in source · JWT signing secret in source · Hardcoded password · Auth middleware removed from route · Route protection changed (protected → public) · Permission / RBAC check removed · Required role weakened · Admin-only route exposed to lower privilege · Token validation skipped in middleware chain · JWT verification weakened or changed · Session expiration / TTL changed · Password reset flow changed · OAuth callback / redirect handling changed · Webhook endpoint missing signature verification · Public route touches private/PII data · Code correctness issue · Runtime error risk · Resource leak risk · Data integrity risk · Maintainability issue · Co-change coupling · Scanner suppressions added · Scanner settings changed · Complexity Guard · Release Notes Curator · Intent vs. implementation

☑️ Task list (1)
  • Exit non-zero for unknown whoami arguments (src/commands/whoami.rs) - Make handle_whoami return or exit with a failure status when unrecognized arguments are supplied, and verify autter whoami --bogus exits non-zero.

Generated from PR diff, blast radius, and context.

Issues found

No unresolved code findings remain for this revision — 3 finding(s) dismissed as likely false positives by verification. Dismissed findings stay listed with their verdicts in the Autter review dashboard.

3 additional non-blocking finding(s) are available in the Autter review.

🤖 Release Notes Curator

Release impact: minor. This adds a new user-facing capability, autter whoami --short (with -s alias), for a one-line identity summary. Nothing existing breaks: unknown arguments still error as before.

Changelog entry:

  • Added autter whoami --short (or -s) for a one-line summary of who you are signed in as, your organization, and your login state. It is handy in scripts and shell prompts. The command exits non-zero when you are logged out and no API key is configured.

Custom agent · runs after review · configured in Autter

📄 What this PR changes

Users can run autter whoami --short (or -s) for condensed output. Unrecognised arguments now produce an error instead of being ignored, and whoami gains masked API key display.

  • Argument parsing in handle_whoami detects --short/-s and filters them out before checking for unknown arguments; the --help/-h/help short-circuit still runs first and exits 0.
  • Any remaining unknown argument triggers an Error: message on stderr. Review whether this should exit non-zero, since that determines script behaviour.
  • The new mask_api_key helper (around lines 151-227 in the new file) is the main addition; check that it never prints a full key in either short or full output.
  • Short and full output both draw on collect_auth_status and format_unix_timestamp from crate::auth, so no new auth logic is introduced.
  • No persistent state, config, or database changes are involved.
📖 What these words mean
  • Must fix: Blocks merging. Autter is confident this is a real problem in this PR.
  • Should fix: Doesn't block merging, but is likely a real problem worth fixing.
  • Minor: Style, conventions or hardening ideas. Fine to skip.
  • Simulated users: Autter runs your app, package or CLI the way people would, each with a different habit (follows the docs, mistypes a command, …).
  • Already broken before this PR: The same failure happens on the code before this PR, so this PR didn't cause it.
  • We couldn't tell: Some runs failed, but not clearly enough to blame this PR.
  • Doesn't block merging: Shown for your information; the merge check ignores it.

View this PR in Autter · Checked commit 46159e9 · Tick Re-run review to check this commit again

@autter-dev

autter-dev Bot commented Oct 12, 2026

Copy link
Copy Markdown

Cargo.toml:1 · build_failure

🟡 [deterministic] Build failed: autter — Risk: 40/100

cargo build could not verify the autter build in . — this is not evidence that this PR breaks it.

What happened: The build failed because your Rust compiler version (1.85.0) is older than what several dependencies require, such as ratatui and time which need 1.86.0 or 1.88.0.

How to fix: Upgrade your Rust toolchain to at least version 1.88.0 using rustup, or downgrade the conflicting dependencies to versions compatible with rustc 1.85.0 using cargo update.

Build output
error: rustc 1.85.0 is not supported by the following packages:
  ratatui@0.30.0 requires rustc 1.86.0
  ratatui-core@0.1.0 requires rustc 1.86.0
  ratatui-crossterm@0.1.0 requires rustc 1.86.0
  ratatui-widgets@0.3.0 requires rustc 1.86.0
  time@0.3.47 requires rustc 1.88.0
  time-core@0.1.8 requires rustc 1.88.0
  zip@8.6.0 requires rustc 1.88
Either upgrade rustc or select compatible dependency versions with
`cargo update <name>@<current-ver> --precise <compatible-ver>`
where `<compatible-ver>` is the latest version supporting rustc 1.85.0
🛠 AI fix prompt (copy & paste into your coding agent)
The autter build (`cargo build` in `.`) fails. The build failed because your Rust compiler version (1.85.0) is older than what several dependencies require, such as ratatui and time which need 1.86.0 or 1.88.0. Fix: Upgrade your Rust toolchain to at least version 1.88.0 using rustup, or downgrade the conflicting dependencies to versions compatible with rustc 1.85.0 using cargo update.

Flagged by Autter security & observability checks.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autter blocked this PR: test; build. See the findings below and the full PR review for details.

@autter-dev

autter-dev Bot commented Oct 12, 2026

Copy link
Copy Markdown

Autter review completed — merge blocked

Autter completed its review and found at least one confirmed merge-blocking finding.

Autter blocked this PR: test; build. See the findings below and the full PR review for details.

How to fix: Resolve the blocking finding (or have a maintainer dismiss it), then push a new commit.

Other findings explain the additional warnings, but they did not independently block this PR.

The merge gate remains blocked until the confirmed finding is resolved.

Retry

Retrying reruns the review on the same commit. If the commit is unchanged, the same finding and block may be reproduced.

  • Click Retry review on the autter/review-gate check below, or
  • Comment @autter review on this PR

Autter will post a new comment when the retry starts.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autter approved #71 with notes: the merge gate is clear, and 3 non-blocking finding(s) remain as review detail. (Also detected: 3 finding(s) dismissed as likely false positives by verification.)

@autter-dev autter-dev Bot added the enhancement New feature or request label Oct 12, 2026

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autter approved #71 with notes: the merge gate is clear, and 3 non-blocking finding(s) remain as review detail. (Also detected: 3 finding(s) dismissed as likely false positives by verification.)

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autter approved #71 with notes: the merge gate is clear, and 3 non-blocking finding(s) remain as review detail. (Also detected: 3 finding(s) dismissed as likely false positives by verification.)

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autter approved #71 with notes: the merge gate is clear, and 3 non-blocking finding(s) remain as review detail. (Also detected: 3 finding(s) dismissed as likely false positives by verification.)

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autter approved #71 with notes: the merge gate is clear, and 3 non-blocking finding(s) remain as review detail. (Also detected: 3 finding(s) dismissed as likely false positives by verification.)

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autter approved #71 with notes: the merge gate is clear, and 3 non-blocking finding(s) remain as review detail. (Also detected: 3 finding(s) dismissed as likely false positives by verification.)

@autter-dev

autter-dev Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

🧪 Tests Autter wrote for this change

Autter wrote 5 test files for the changed code that had no test, ran them on the base commit and on this PR, and kept 3: 3 files passed.

The tests

tests/whoami_autter.rs — 5 cases, ✅ passes · covers what this PR adds

Runs with cargo test --quiet --test whoami_autter.

// Integration tests for `autter whoami --short`.
//
// `short_identity` is private to `src/commands/whoami.rs`, so these tests
// exercise it through the built `autter` binary, the only public surface.
// Each test runs with an isolated HOME so no real credentials are read.

use std::fs;
use std::path::PathBuf;
use std::process::{Command, Output};

const BIN: &str = env!("CARGO_BIN_EXE_autter");

/// Temporary HOME that is removed when the guard drops.
struct IsolatedHome {
    path: PathBuf,
}

impl IsolatedHome {
    fn new(tag: &str) -> Self {
        let path = std::env::temp_dir().join(format!(
            "autter-whoami-short-{}-{}",
            std::process::id(),
            tag
        ));
        let _ = fs::remove_dir_all(&path);
        fs::create_dir_all(path.join(".config")).expect("create isolated home");
        IsolatedHome { path }
    }
}

impl Drop for IsolatedHome {
    fn drop(&mut self) {
        let _ = fs::remove_dir_all(&self.path);
    }
}

fn run_whoami(home: &IsolatedHome, args: &[&str]) -> Output {
    let mut command = Command::new(BIN);
    command.arg("whoami").args(args);
    command.env("HOME", &home.path);
    command.env("USERPROFILE", &home.path);
    command.env("XDG_CONFIG_HOME", home.path.join(".config"));
    command.env_remove("AUTTER_API_KEY");
    command
        .output()
        .expect("failed to run autter whoami")
}

fn stdout_lines(output: &Output) -> Vec<String> {
    String::from_utf8_lossy(&output.stdout)
        .lines()
        .map(|line| line.to_string())
        .collect()
}

#[test]
fn new_whoami_short_prints_one_line_and_fails_when_logged_out() {
    let home = IsolatedHome::new("long");
    let output = run_whoami(&home, &["--short"]);

    assert_eq!(output.status.code(), Some(1));
    let lines = stdout_lines(&output);
    assert_eq!(lines.len(), 1, "short mode must print exactly one line: {:?}", lines);
    assert_eq!(lines[0], "logged out");
}

#[test]
fn new_whoami_short_alias_dash_s_matches_long_flag() {
    let home = IsolatedHome::new("alias");
    let long = run_whoami(&home, &["--short"]);
    let alias = run_whoami(&home, &["-s"]);

    assert_eq!(alias.status.code(), long.status.code());
    assert_eq!(stdout_lines(&alias), stdout_lines(&long));
    assert_eq!(stdout_lines(&alias), vec!["logged out".to_string()]);
}

#[test]
fn new_whoami_short_prints_no_full_report_fields() {
    let home = IsolatedHome::new("nofull");
    let output = run_whoami(&home, &["--short"]);

    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(!stdout.contains("API Base URL:"), "stdout was: {}", stdout);
    assert!(!stdout.contains("Credential backend:"), "stdout was: {}", stdout);
    assert!(!stdout.contains("Organizations:"), "stdout was: {}", stdout);
}

#[test]
fn new_whoami_unknown_argument_is_a_usage_error_on_stderr() {
    let home = IsolatedHome::new("unknown");
    let output = run_whoami(&home, &["--bogus"]);

    let code = output.status.code();
    assert!(code.is_some(), "process must exit with a code");
    assert_ne!(code, Some(0), "unknown argument must not succeed");
    assert_ne!(code, Some(1), "unknown argument is a usage error, not an auth failure");

    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(
        stderr.contains("unknown whoami argument(s): --bogus"),
        "stderr was: {}",
        stderr
    );
}

#[test]
fn new_whoami_help_wins_over_short_and_exits_zero() {
    let home = IsolatedHome::new("help");
    let output = run_whoami(&home, &["--short", "--help"]);

    assert_eq!(output.status.code(), Some(0));
    assert!(stdout_lines(&output).is_empty(), "help goes to stderr, not stdout");
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("autter whoami --short"), "stderr was: {}", stderr);
}
tests/whoami_autter2.rs — 2 cases, ✅ passes · covers what this PR adds

Runs with cargo test --quiet --test whoami_autter2.

#[macro_use]
#[path = "integration/repos/mod.rs"]
mod repos;

use repos::test_repo::{TestRepo, get_binary_path};
use std::process::{Command, Output};

// `state_label` is private to `src/commands/whoami.rs`, so this integration
// test reaches it through the built binary, the only public surface that
// calls it. The run uses an isolated HOME with no stored session, so the
// auth state is "logged out". The test also assumes no API key env var is
// set in the environment, and it clears the common ones below.

fn run_whoami(repo: &TestRepo, args: &[&str]) -> Output {
    let home = repo.test_home_path();
    let mut command = Command::new(get_binary_path());
    command.args(["whoami"]).args(args);
    command.env("HOME", &home);
    command.env("XDG_CONFIG_HOME", home.join(".config"));
    command.env("AUTTER_DAEMON_HOME", repo.daemon_home_path());
    command.env_remove("AUTTER_API_KEY");
    command.env_remove("AUTTER_DAEMON_CONTROL_SOCKET");
    command.env_remove("AUTTER_DAEMON_TRACE_SOCKET");
    command.output().expect("failed to run autter whoami")
}

#[test]
fn new_whoami_short_reports_logged_out_state_and_exits_1() {
    let repo = TestRepo::new();
    let output = run_whoami(&repo, &["--short"]);

    assert_eq!(
        output.status.code(),
        Some(1),
        "logged-out session without an API key should exit 1; stderr: {}",
        String::from_utf8_lossy(&output.stderr)
    );

    let stdout = String::from_utf8_lossy(&output.stdout);
    let lines: Vec<&str> = stdout.lines().collect();
    assert_eq!(lines.len(), 1, "short output should be a single line: {:?}", stdout);
    assert_eq!(lines[0], "logged out");
}

#[test]
fn new_whoami_short_flag_alias_matches_long_flag() {
    let repo = TestRepo::new();
    let long = run_whoami(&repo, &["--short"]);
    let alias = run_whoami(&repo, &["-s"]);

    assert_eq!(alias.status.code(), long.status.code());
    assert_eq!(
        String::from_utf8_lossy(&alias.stdout),
        String::from_utf8_lossy(&long.stdout)
    );
}
tests/whoami_autter3.rs — 6 cases, ✅ passes · covers what this PR adds

Runs with cargo test --quiet --test whoami_autter3.

//! Integration tests for `autter whoami --short`.
//!
//! `identity_failed` is private to `src/commands/whoami.rs`, so an integration
//! test cannot call it directly. These tests run the built `autter` binary in
//! an isolated HOME and check the exit-code rule it implements: `--short`
//! exits 1 when the session is not logged in and no API key is set, and 0
//! when an API key is set. The binary's credential backend may read the real
//! OS keychain on some platforms, so these tests assume a machine with no
//! stored autter login.

use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};

const API_KEY: &str = "sk-test-0123456789abcdef";

struct ScratchHome(PathBuf);

impl ScratchHome {
    fn new(name: &str) -> Self {
        let dir = std::env::temp_dir().join(format!(
            "autter-whoami-short-{}-{}",
            name,
            std::process::id()
        ));
        let _ = fs::remove_dir_all(&dir);
        fs::create_dir_all(&dir).expect("failed to create scratch home");
        ScratchHome(dir)
    }

    fn path(&self) -> &Path {
        &self.0
    }
}

impl Drop for ScratchHome {
    fn drop(&mut self) {
        let _ = fs::remove_dir_all(&self.0);
    }
}

fn run_whoami(home: &Path, args: &[&str], api_key: Option<&str>) -> Output {
    let mut cmd = Command::new(env!("CARGO_BIN_EXE_autter"));
    cmd.arg("whoami")
        .args(args)
        .env("HOME", home)
        .env("USERPROFILE", home)
        .env("XDG_CONFIG_HOME", home.join(".config"))
        .env("AUTTER_DAEMON_HOME", home)
        .env_remove("AUTTER_API_KEY");
    if let Some(key) = api_key {
        cmd.env("AUTTER_API_KEY", key);
    }
    cmd.output().expect("failed to run autter binary")
}

fn stdout_lines(output: &Output) -> Vec<String> {
    String::from_utf8_lossy(&output.stdout)
        .lines()
        .map(|line| line.to_string())
        .collect()
}

#[test]
fn new_short_logged_out_without_api_key_exits_1_with_one_line() {
    let home = ScratchHome::new("logged-out");
    let output = run_whoami(home.path(), &["--short"], None);

    assert_eq!(output.status.code(), Some(1));
    assert_eq!(stdout_lines(&output), vec!["logged out".to_string()]);
}

#[test]
fn new_short_flag_dash_s_matches_long_flag() {
    let home = ScratchHome::new("dash-s");
    let long = run_whoami(home.path(), &["--short"], None);
    let short = run_whoami(home.path(), &["-s"], None);

    assert_eq!(short.status.code(), long.status.code());
    assert_eq!(stdout_lines(&short), stdout_lines(&long));
}

#[test]
fn new_short_with_api_key_exits_0() {
    let home = ScratchHome::new("api-key");
    let output = run_whoami(home.path(), &["--short"], Some(API_KEY));

    assert_eq!(output.status.code(), Some(0));
}

#[test]
fn new_short_output_never_contains_the_full_api_key() {
    let home = ScratchHome::new("no-leak");
    let output = run_whoami(home.path(), &["--short"], Some(API_KEY));

    let stdout = String::from_utf8_lossy(&output.stdout);
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(!stdout.contains(API_KEY));
    assert!(!stderr.contains(API_KEY));
}

#[test]
fn new_short_with_unknown_argument_is_a_usage_error() {
    let home = ScratchHome::new("unknown-arg");
    let output = run_whoami(home.path(), &["--short", "--bogus"], None);

    assert_ne!(output.status.code(), Some(0));
    assert_ne!(output.status.code(), Some(1));
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("unknown whoami argument(s): --bogus"));
}

#[test]
fn new_help_flag_exits_0_even_with_short() {
    let home = ScratchHome::new("help");
    let output = run_whoami(home.path(), &["--short", "--help"], None);

    assert_eq!(output.status.code(), Some(0));
}
2 tests Autter wrote but did not keep
  • tests/whoami_autter.rs — The test fails on the base commit too, so it does not describe behaviour the code ever had.
  • tests/whoami_autter4.rs — The test fails on the base commit and the PR does not say it means to change that behaviour.
  • Add these tests to the PR — commits 3 passing test files to autter-walk-test/cli (this PR's branch only, never the default branch). Needs write access.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autter approved #71 with notes: the merge gate is clear, and 3 non-blocking finding(s) remain as review detail. (Also detected: 3 finding(s) dismissed as likely false positives by verification.)

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't fully check this: a test suite this PR doesn't touch was already failing. Nothing Autter could check blocks merging. Details are in Autter's summary comment on this PR. Autter also set aside 3 finding(s) as likely false alarms.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't fully check this: a test suite this PR doesn't touch was already failing. Nothing Autter could check blocks merging. Details are in Autter's summary comment on this PR. Autter also set aside 3 finding(s) as likely false alarms.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't fully check this: a test suite this PR doesn't touch was already failing. Nothing Autter could check blocks merging. Details are in Autter's summary comment on this PR. Autter also set aside 3 finding(s) as likely false alarms.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't fully check this: a test suite this PR doesn't touch was already failing. Nothing Autter could check blocks merging. Details are in Autter's summary comment on this PR. Autter also set aside 3 finding(s) as likely false alarms.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't fully check this: a test suite this PR doesn't touch was already failing. Nothing Autter could check blocks merging. Details are in Autter's summary comment on this PR. Autter also set aside 3 finding(s) as likely false alarms.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't fully check this: a test suite this PR doesn't touch was already failing. Nothing Autter could check blocks merging. Details are in Autter's summary comment on this PR. Autter also set aside 3 finding(s) as likely false alarms.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't fully check this: a test suite this PR doesn't touch was already failing. Nothing Autter could check blocks merging. Details are in Autter's summary comment on this PR. Autter also set aside 3 finding(s) as likely false alarms.

@autter-dev autter-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't fully check this: a test suite this PR doesn't touch was already failing. Nothing Autter could check blocks merging. Details are in Autter's summary comment on this PR. Autter also set aside 3 finding(s) as likely false alarms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request release: minor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant