Skip to content

[APIE-1370][APIE-1606] New agentdetect package - #3472

Open
Noel Cothren (noeldevelops) wants to merge 15 commits into
mainfrom
APIE-1370-agentdetect-package
Open

[APIE-1370][APIE-1606] New agentdetect package#3472
Noel Cothren (noeldevelops) wants to merge 15 commits into
mainfrom
APIE-1370-agentdetect-package

Conversation

@noeldevelops

@noeldevelops Noel Cothren (noeldevelops) commented Aug 23, 2026

Copy link
Copy Markdown
Member

⭐ No user-facing changes yet. This PR does not "hook up" the package to any existing code; it will be done in a follow-up after updating the cc usage service.
Closes APIE-1606

Release Notes

Checklist

  • I have successfully built and used a custom CLI binary, without linter issues from this PR.
  • I have clearly specified in the What section below whether this PR applies to Confluent Cloud, Confluent Platform, or both.
  • I have verified this PR in Confluent Cloud pre-prod or production environment, if applicable.
  • I have verified this PR in Confluent Platform on-premises environment, if applicable.
  • I have attached manual CLI verification results or screenshots in the Test & Review section below.
  • I have added appropriate CLI integration or unit tests for any new or updated commands and functionality.
  • I confirm that this PR introduces no breaking changes or backward compatibility issues.
  • I have indicated the potential customer impact if something goes wrong in the Blast Radius section below.
  • I have put checkmarks below confirming that the feature associated with this PR is enabled in:
    • Confluent Cloud prod
    • Confluent Cloud stag
    • Confluent Platform
    • Check this box if the feature is enabled for certain organizations only

What

Problem: We would like to improve the usability of our CLI tool for human and AI Agent users. As a first step, we'd like to know more.

Solution: This package adds logic to collect AI agent signals from a list of known env vars & process names to send with our telemetry and indicate whether users are in Agentic environment. We're adding the data to existing usage telemetry sent on command invocation, so we will also learn more about the commands' usage & error rates as they relate to environment and agent use cases.

Key Technical Details

  • This ships a new pkg/agentdetect with no call sites; no existing behavior changes. Wiring into telemetry is coming in a follow-up PR after updating the shared usage-service schema.

Detection Logic Design

Initially I thought just checking env vars, or just inspecting the process tree for names like "claude" or "codex" could tell us definitively "this is an agent", but in field testing with a proof of concept I found many gaps in both those approaches depending on things like OS, install method, and IDE host environment.

The final logic steps through several layers of checks and will send all definite signals found. Downstream we will infer agent usage from the patterns gathered (see internal docs for more details on metrics design).

The package contains a buildable debug binary that can be used going forward to troubleshoot or add more surface to our fingerprint tables.

Privacy

  • All detection uses whitelisted strings to check for known agent and ide patterns, never collecting, logging, or saving user's raw input text.
  • To that end, introduces fpKey, a private string type returned only by the fingerprint resolvers, so raw process text can never be assigned into fields in future updates either.

Blast Radius

At this time there are no user-facing changes or code paths, so this PR has zero blast radius.
Once connected to the usage events, there are multiple guards (depth cap, wall-clock deadline, cycle guard, pid-reuse guard), each able to stop data collection if something goes wrong. A key part of the design was to insure a failure in this package does not cascade to the user's original task.

References

Internal Docs

1-Pager with Eng Design
Wiki with initial research notes and questions
Jira issue
Claude-generated diagram of the Detect logic

Test & Review

  • Lots of unit tests to confirm data we want is collected correctly, and that private data is not collected, logged, or saved as part of the information we're adding to events. For example, TestLiveResultSerializesNoRawObservations runs the actual gopsutil walk against the live process tree and asserts no raw process names leak into JSON.
  • Manual 'field testing' done and more in progress to confirm our assumptions and reading of various agent process trees and env vars. The package contains a buildable debug binary that can be used going forward to troubleshoot or add more surface to our fingerprint tables.

How to Field Test

  • Build the debug binary from the root directory
    go build -o agentdetect-debug ./cmd/agentdetect-debug

  • Run the debugger yourself from a terminal, or ask an agent to run it to see what it detects

# print the Result as JSON
./agentdetect-debug   
# also print the raw ancestor chain                                  
./agentdetect-debug --chain
# print chain + redacted argv
./agentdetect-debug --chain --cmdlines

You can copy the binary to another machine and run it under different OSes and agent CLIs there too, since it has no dependency on the CLI's other state.

Remove references to internal-only artifacts (friction logs, ticket IDs
like FF-9295, the signals-comparison memo, "proof of concept" framing,
LaunchDarkly, and capture dates) from comments and test descriptions, and
neutralize the agentdetect-poc fixture string. Purely comment/description
changes plus one non-asserted test fixture value; no behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The " helper" suffix is an Electron packaging convention, not an editor
one, so classifyEditorHelper previously tagged any Electron app's helper
(Slack, Discord, Hyper — itself a terminal) as kindIDEHost with an empty
vendor, polluting the IDEHost signal. Gate classification on the product
matching a known kindIDEHost row; unrecognized Electron apps now fall
through to kindUnknown.

Trades away recognizing an unseen VS Code fork purely from its helper
(theoretical, since its main basename would be unknown too) for not
misclassifying non-editor Electron apps. Splits the fork-generalization
test into known-editor and non-editor-Electron cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A helper-matched IDE host previously resolved to an empty key, so its
identity was dropped from the wire (optional("") is nil) even though the
editor was known — a VS Code chain whose nearest editor process is a
"code helper (plugin)" emitted ide_host: nil. Resolve the helper to its
editor's table key ("code helper (plugin)" -> "code"), the same way the
version-suffix rule resolves "python3.13" -> "python", so ide_host now
carries the editor while still only ever recording table vocabulary,
never the observed helper basename.

Applies to the Electron editors (code, cursor, windsurf); zed and
JetBrains have no helper subprocesses and were already keyed directly.
Also tightens surrounding comments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 23, 2026 12:12
@confluent-cla-assistant

Copy link
Copy Markdown

🎉 All Contributor License Agreements have been signed. Ready to merge.
Please push an empty commit if you would like to re-run the checks to verify CLA status for all contributors.

Copilot AI 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.

Pull request overview

Adds a new pkg/agentdetect Go package that detects “agentic” execution context (AI agents / IDE-hosted environments) via env var fingerprints and best-effort process ancestry inspection, with a privacy-preserving telemetry projection intended for later wiring into usage events.

Changes:

  • Introduces core detection logic (Detect), fingerprint tables (env/proc/cmdline), and a constrained wire-format projection (Attributes) designed to avoid leaking raw process/argv data.
  • Adds a gopsutil-backed ProcSource implementation plus extensive synthetic + live-process tests to validate detection behavior, bounds/guards, and privacy constraints.
  • Updates module dependencies to include github.com/shirou/gopsutil/v4 and related indirect deps; adds a gitignore entry for local manual-testing binaries.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/agentdetect/doc.go Package-level documentation for agent detection goals, signals, and privacy guarantees
pkg/agentdetect/proc.go Defines ProcInfo and ProcSource abstraction for process ancestry walking
pkg/agentdetect/proc_gopsutil.go Implements real process lookup via gopsutil with per-read timeout guards
pkg/agentdetect/detect.go Core detection logic: env/CI/TTY signals, bounded ancestry walk, redaction helpers
pkg/agentdetect/fingerprints.go Env/proc/cmdline fingerprint tables and name/path resolution rules
pkg/agentdetect/attributes.go Wire-format Attributes projection for attaching to usage events
pkg/agentdetect/scenarios_test.go Synthetic scenario fixtures used to validate documented failure modes
pkg/agentdetect/detect_test.go Comprehensive unit tests for detection behavior, guards, and privacy constraints
pkg/agentdetect/ide_surfaces_test.go Tests for IDE-host surface classification and in-editor agent attribution limits
pkg/agentdetect/attributes_test.go Tests that enforce wire-format constraints and schema discipline
pkg/agentdetect/proc_gopsutil_test.go Live-process tests ensuring gopsutil source works and doesn’t serialize raw observations
pkg/agentdetect/field_probe_test.go Opt-in manual probe test for capturing real-world process tree shapes
go.mod Adds github.com/shirou/gopsutil/v4 dependency
go.sum Updates sums for gopsutil and transitive dependencies
.gitignore Ignores locally built agentdetect manual-testing binaries

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/agentdetect/detect.go Outdated
Comment thread pkg/agentdetect/attributes.go Outdated
Comment thread pkg/agentdetect/field_probe_test.go Outdated
Comment thread pkg/agentdetect/doc.go Outdated
Code review of the agentdetect package found the privacy invariant (only
fixed-table keys, never raw process text, reach AncestorMatch/WrapperMatch)
was enforced only by discipline and a runtime test. Introduce fpKey, a
private string type returned only by the fingerprint resolvers, so a future
assignment of raw process data into one of these fields is a compile error.

Also close a gap where walk()'s own budget check is cooperative and never
runs while a single ProcSource.Info call is blocked — on darwin several
gopsutil calls ignore their context, so a slow syscall could stall past the
configured budget. boundedWalk now enforces a hard wall-clock ceiling above
that budget and gives up on the walk if it's exceeded.

Also clarifies the maxIdentityArgs doc comment and notes the follow-up-PR
export need on vendorForProcKey/vendorForArgvPattern.
childStart, the walk's pid-reuse baseline, was only ever set from a
descendant already walked, so depth 1 (StartPid) had no prior read to compare
against and went unchecked — a recycled pid one hop above the CLI could
fabricate an ancestor undetected. Add Options.SelfPid (defaulting to
os.Getpid()) to seed childStart with the CLI's own start time before the walk
begins; a lookup failure just disables the depth-1 check, same as any other
unreadable start time.
ChainShape doc claimed a completed walk always ends in 'n' or 'r', but
a walk that reaches PID 1 without an init/remote ancestor produces a
valid shape like "sit" — drop the false claim. Also fixes "Detect
method" (it's a function) and the field-probe test's file header,
which said it's outside the automated suite even though go test
discovers and skips it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@noeldevelops
Noel Cothren (noeldevelops) marked this pull request as ready for review August 23, 2026 13:28
@noeldevelops
Noel Cothren (noeldevelops) requested a review from a team as a code owner August 23, 2026 13:28
@sonarqube-confluent

Copy link
Copy Markdown

@noeldevelops Noel Cothren (noeldevelops) changed the title [APIE-1370] New agentdetect package [APIE-1370][APIE-1606] New agentdetect package Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants