Skip to content

feat(inspect): compose the framework fingerprint into scan and the dashboard - #39

Merged
trionnemesis merged 1 commit into
mainfrom
claude/agentsec-issue-32-review-i8pphg
Aug 10, 2026
Merged

feat(inspect): compose the framework fingerprint into scan and the dashboard#39
trionnemesis merged 1 commit into
mainfrom
claude/agentsec-issue-32-review-i8pphg

Conversation

@trionnemesis

@trionnemesis trionnemesis commented Aug 10, 2026

Copy link
Copy Markdown
Owner

What changed

agentsec scan now says what the repository is before what is wrong with it, and the dashboard leads with the same answer. #37 landed the detector with nothing reading it; this is the DTO, CLI and page it was built for.

  AI agent      confirmed
                runtime agent code in this repository
                langgraph (python)  src/agent/graph.py
                coding-agent config: claude_code

  project       order-agent  surfaces 1  risks 1

Same classification through agentsec dashboard, the rendered page and agentsec://project/risks. Closes the first three of #32's acceptance conditions end to end.

Type

  • New scenario (Attack–Detection Contract)
  • Evidence collector
  • Executor
  • Evaluator / verdict logic
  • MCP gateway surface
  • Docs / ADR
  • Fix

Purple coverage

Question Answer
Which scenario(s) cover this change? None. This is inventory, not a contract — it routes attention toward scenarios and produces no verdict.
Does it change how a verdict is produced? No. Axes, precedence and evaluator untouched. tests/test_fingerprint.py::test_the_fingerprint_never_reaches_the_purple_plane asserts neither the framework name nor agent_presence appears anywhere in the purple plane, and that verdict_counts keeps its five-verdict vocabulary.
Does it widen what the MCP gateway can reach? No. No new tool, no new resource, no new parameter. Two existing read-only resources carry one additional key inside a plane they already served.

Why project.fingerprint and not a sixth plane

"Does this repository implement an agent" qualifies the identity the project plane already reports, and it is read on the same screen as the surface counts it explains — skills 3 · hooks 2 · mcp 2 means something different depending on whether there is a runtime agent underneath them. A sixth top-level key would also have implied a sixth kind of conclusion. It is not one: nothing here executes anything, not_detected is an absence of evidence, and #32 asked specifically that new planes stay frozen while the first screen gets finished.

The distinction is enforced at every hop

Runtime agents and coding-agent configuration are separate lists in the service, the publisher, the schema, the template and the terminal output, and are never concatenated. That is the one overclaim #32 named — a .mcp.json becoming a claimed runtime agent — and it is a single template change away unless each layer keeps them apart.

configuration_only is what AgentSec's own checkout reports.

The project plane is now projected rather than passed through

It used to be forwarded whole, which was defensible while everything in it was a short service-authored string. The fingerprint is derived from reading arbitrary repository files. The detector is built never to carry source text — evidence is a dependency name, an import path, a builder symbol, a relative path — but that guarantee should not live in only one place, so publish_project names its fields like every other publisher here. A stray key on the service dict, and a source field on a hypothetical future detector, are both asserted absent from published output.

Schema

PUBLISH_SCHEMA_VERSION 1.3.0 → 1.4.0. project.fingerprint is an optional key inside a plane that already existed; every shape a consumer was already reading is untouched. $defs/fingerprint closes additionalProperties and enumerates both status vocabularies.

Gap this exposed by being run

Recorded in docs/feature-matrix.md rather than fixed here: Settings.scenarios_dir is <workspace>/scenarios, so in a repository that is not a checkout of AgentSec the catalogue is empty and every risk resolves to not_verifiable. Correct, and newly misleading — it now sits under a screen that can say confirmed langgraph. Bundling the reviewed catalogue as package data is the fix; which catalogue version an installed CLI should trust is what makes it more than a one-liner.

Checks

  • make check — ruff, mypy and pytest green on 3.11, 3.12 and 3.13 in CI. 397 passed, 2 skipped locally (387 before, 10 new).
  • agentsec validate --strict passes on all 8 scenarios
  • agentsec run --target demo-agent-fixture --profile nightly still exits 1 with exactly AGT-TENANT-001 and AGT-MEMPOIS-001 blocking — asserted by the harness runs against its own fixtures CI job, and by tests/test_pipeline.py::test_exit_code_reflects_blocking_findings. Not runnable from this session's shell: this repository's guard hook refuses agentsec run from Bash, which is the hook working as intended.

If this touches the MCP surface

  • The capability exists on HarnessService first (_fingerprint, composed by _project_planes), so CLI and CI reach it too
  • No input schema changed — neither resource takes parameters
  • tests/test_mcp_contract.py passes; both resource descriptions updated to state what they now carry

Notes for the reviewer

Three worth challenging:

  1. project.fingerprint rather than a top-level plane. Argued above; the counter-argument is that a reader scanning top-level keys will not find it.
  2. unsupported on a classifier failure. _fingerprint catches AgentSecError and reports unsupported with a problem, never not_detected — "we could not look" must not become "there is nothing here". The invented problem kind is unreadable_root, which the schema accepts as free-form kind like the other problem lists do.
  3. The masthead pill uses warn styling for confirmed/likely. Finding an agent is not a warning, but the palette has no neutral-but-notable colour and skip grey read as "nothing here". Open to a better answer.

…shboard

`agentsec scan` now answers what the repository *is* before what is wrong with
it, and the dashboard leads with the same answer. The detector landed in #37
with nothing reading it; this is the DTO, CLI and page it was built for.

The classification lives at `project.fingerprint` rather than in a sixth plane.
"Does this repository implement an agent" qualifies the identity the `project`
plane already reports, and it is read on the same screen as the surface counts
it explains — a sixth top-level key would have implied a sixth kind of
conclusion, which this is not: nothing here executes anything.

Runtime agents and coding-agent configuration stay in separate lists at every
hop — service, publisher, schema, template, terminal. Merging them is the one
overclaim #32 named, and it is a template change away unless each layer keeps
them apart.

Reported before `agentsec init`, since whether there is an agent in a checkout
does not depend on whether anyone wrote a manifest.

The `project` plane is now projected field by field like every other published
document instead of being passed through whole. Its content is newly derived
from reading arbitrary repository files; "the producer promises no source text"
should not be a guarantee that lives in only one place.

- `PUBLISH_SCHEMA_VERSION` 1.3.0 → 1.4.0: an optional key inside an existing
  plane. No plane added, none merged, no published shape changed.
- 10 composition tests: framework and entrypoint named, configuration-only never
  published as a runtime agent, `not_detected` never rendering as a pass, the
  fingerprint absent from the purple plane, a stray service key refused by the
  projection, source text absent from published evidence, and `scan` leading
  with the classification in both the initialised and uninitialised cases.

397 passed, ruff and mypy clean. `docs/feature-matrix.md` records a gap this
made visible: outside a checkout of AgentSec the catalogue is empty, so every
risk resolves to `not_verifiable` under a screen that can now say `confirmed`.

Refs #32
@trionnemesis
trionnemesis marked this pull request as ready for review August 10, 2026 08:31
@trionnemesis
trionnemesis merged commit 1b2555c into main Aug 10, 2026
5 checks passed

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cce17fffac

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

told only "not initialised" learns nothing about whether it was worth
initialising.
"""
fingerprint = self._fingerprint()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid rescanning the checkout on every dashboard poll

When agentsec://dashboard/latest or agentsec://project/risks is polled, this unconditional call runs synchronously on every read. fingerprint_repository recursively enumerates and reads up to 2,000 source files of up to 512 KiB each, so a large monorepo can make every refresh reread and process roughly 1 GiB while delaying the resource response. Cache the fingerprint with suitable invalidation, or move the full scan out of the per-read path.

Useful? React with 👍 / 👎.

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