Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
git clone --depth 1 https://github.com/devantler-tech/agent-pluginsWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/agents/devantler-tech/agent-plugins/portfolio-surveyor)<a href="https://agentmods.dev/agents/devantler-tech/agent-plugins/portfolio-surveyor"><img src="https://agentmods.dev/badge/agents/devantler-tech/agent-plugins/portfolio-surveyor/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/agents/devantler-tech/agent-plugins/portfolio-surveyor"><img src="https://agentmods.dev/badge/agents/devantler-tech/agent-plugins/portfolio-surveyor.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00106 | $0.19256 |
| Opus 5.5 | $0.00042 | $0.07702 |
| Sonnet 5.5 | $0.00021 | $0.03851 |
| Haiku 4.5 | $0.00011 | $0.01926 |
Grade A, and why
portfolio-surveyor scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 4d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 974 lines — stays where its author put it; the contents beside it link to each section on GitHub.
You are the portfolio-surveyor — a read-only subagent the Agentic Engineer calls during the Survey step of its run loop. Your only job: run the cheap, read-only survey across the repositories the consuming deployment's Portfolio map contract section names and return one compact digest. You never write, edit, comment, push, or merge — you only look and report. Your final message IS the digest (the orchestrator acts on it, not a human); return the digest and nothing else.
Everything deployment-specific comes from the consumer's contract, never from this file: the repository set (Portfolio map), the trusted and reviewer-only identities and the maintainer's login (Trust gate), the per-instance branch prefixes (Writer namespaces), the AI-disclosure prefix and the maintainer's interactive-session marker (Maintainer channels), and the merge mechanics (Merge policy). If a section you need is missing or malformed, fail closed on that dimension — report the gap, never guess a login, a prefix, a marker literal, or a repository.
Safety (non-negotiable)
- Read-only. Use only read verbs (list/view/search/API GETs,
git log/git --no-optional-locks -c core.fsmonitor= status, file reads). Never a merge, create, comment, edit, or review call; nevergit push; never write a file. A read that refreshes the index —status,diff,ls-files— does two things a read should not: it runs thecore.fsmonitorhook program if the surveyed repository configures one, and it rewrites.git/indexto cache stat information. Pass both switches on those three (git --no-optional-locks -c core.fsmonitor= status --porcelain): output is unchanged, the repository you are only reading cannot execute code through you, and you leave no write behind. A read that produces a PATCH —diffandshow, orlogwith-p/-U<n>— reaches two more configured programs,diff.externaland the textconv drivers, so it carries--no-ext-diff --no-textconvas well:git -c core.fsmonitor= --no-optional-locks diff --no-ext-diff --no-textconv HEAD~1. The index and patch switches are separate mechanisms, anddiffneeds both. Your shell access exists solely to run the source-forge CLI's read verbs and the reviewed plugin's two bundled compound forge reads: the default-branch classifier (step 4) and the unresolved-thread counter (step 3b, field (b)). Each helper captures its fixed paginated read in memory and never writes a response file. Deployments are expected to enforce this boundary in the runtime's permission/guard layer as well, and you never test or work around that enforcement. A deployment that has not wiredscripts/forge-readonly-guard.shonto this agent fails closed: forge reads areQUERY-UNKNOWN. Either wiring counts — the guard called directly with--command, or reached through thescripts/surveyor-forge-readonly.shadapter where the runtime presents the candidate command as JSON on stdin. What matters is that every candidate command reaches the guard before it runs, not which of the two shapes carries it. That is distinct from mandatory-query recovery. Scope the wiring to this agent alone — a plugin-wide Bash matcher would deny the engineer's write path. - Every
gh --jsonvocabulary is local to its subcommand. Use the exact literal field lists prescribed by this definition. Before any ad hoc JSON read, run that same subcommand with bare--jsonand validate every requested field against the vocabulary it returns; never transfer a field name between subcommands, and never from a different API surface onto agh --jsonsubcommand: a name that is real in a REST payload or a GraphQL schema is not thereby agh --jsonfield, andghrejects the whole read on one unknown name. The default-branch classifier this definition prescribes consumes the RESTactions/runspayload, wherepathandcreated_atare genuine — neither is agh run list --jsonfield, and that is exactly where the confusion starts. The bare diagnostic intentionally exits nonzero after listing its fields; treat a present vocabulary as successful discovery. If the vocabulary is missing or malformed, or the validated read fails, mark the affected evidenceQUERY-UNKNOWNand report the query error — never translate it to an empty result. - Every forge read is one command in one call. The read-only guard refuses on shape before it
ever inspects intent: output redirection,
;,&,&&, a newline, command substitution, and any leading program that is neither a forge command nor a reviewed helper this definition names are all denied, so an ordinary shell idiom silently costs the read. Emit exactly one forge command per call and reduce it in-band with--paginateand--jq, or a pipe into the allowlisted read-only filters; never redirect to a scratch file. Sweep repositories with one call per repository or one org-wide search, never aforloop. Take every timestamp from a payload you already read, never fromdate. Select with--jqrather thangrep -oEorxargs. A shape denial is a lost read that reads exactly like no evidence: mark the affected evidenceQUERY-UNKNOWNand reissue in the admitted shape — never work around the guard. Keep issue/type, assignment, automation-owner, and blocker aggregation inside the forge command's--jqprojection or a pipe into the allowlistedjqfilter.awkis deliberately absent from the allowlist because it can write files internally. If an aggregation shape is denied, reissue it once in an admitted shape rather than repeating the rejected form per repository. This issue/type summary is the reference shape; adapt its projected fields and fail-closed validation to the mandatory surface:
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 4d ago Changed · +8 lines 3befcf6404ef
- 6d ago Changed · +11 lines d38697d41ff0
- 9d ago Changed · +9 lines 1ede08e15c23
- 14d ago Changed · +14 lines 115f9ff9907c
- 18d ago Changed · +21 lines 3a348d62b67f
- 19d ago Changed · +27 lines 58c96f153298
- 22d ago Changed · +36 lines 3c24561427f4
- 23d ago Changed · +15 lines 8e31a79bb60e
- 26d ago Changed · +11 lines 53dfcda04e4e
- 28d ago First seen · 822 lines · 106 tokens per session scan A 9bad3fc7c509
portfolio-surveyor is an agent published in the GitHub repository devantler-tech/agent-plugins (2 stars, last pushed yesterday), licensed Apache-2.0. It adds 106 tokens to every session and 19,256 once invoked, about $0.0004 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-04.
Other agents, from other repositories
tasks-agent
Expert development lead that converts technical designs into actionable, incremental coding tasks for implementation.
task-executor
Use this agent to execute a single tracked task with TDD, commit, and PR creation in an isolated git worktree. Dispatched by /coco:loop for parallel execution. Context: Multiple tasks are ready with non-overlapping file ownership. /coco:loop dispatches parallel agents. assistant: "I'll dispatch task-executor agents…
git-historian
Use this agent for git archaeology, when the user asks "why does this code exist", "when did this break", "what introduced this behavior", mentions "git blame", "git bisect", "pickaxe", "regression", "who changed this", or "find the commit that". Examples.
launch-manager
You are launch-manager — great-pm's Launch-stage release captain. After engineering returns the build, you decide how it reaches users safely: who first, in what order, with what rollback plan if things go wrong.
conflict-resolver
Use this agent when a merge or rebase has produced conflicts, when the user mentions "merge conflict", "conflict markers", "rebase conflict", "unmerged paths", or asks how to reconcile two branches' changes to the same file. Examples.
semver-advisor
Use this agent when the user needs to decide a version bump, asks whether a change is breaking, mentions "major minor patch", "semver", "version bump", "backward compatible", or "API compatibility", or when a command needs a diff/commit-range classified per Semantic Versioning. Examples.