Stood Flows treats every finding as a candidate for an issue — something the team has to act on, comment on, close, or come back to. Every panel supports issue creation through a right-click menu on a row or cell, and every issue carries an anchor that pins it to the exact thing it's about.
There are two backends. They share the same UI; you don't usually need to think about which one you're using.
When the folder is linked to a GitHub repo, all issue operations go through the gh CLI:
Listing — gh issue list
Creating — gh issue create
Editing, commenting, closing, reopening — the corresponding gh issue ... commands
The repo link lives in graph.json as githubOwner + githubRepo. Set it from the Issues tab if the auto-detection (gh repo view) didn't pick it up.
You'll need the gh CLI installed and authenticated (gh auth login). The CLI status (green / red / browse) is in Global Settings, same place as sf.
GitHub issues are real GitHub issues — labels, milestones, assignees all work. They show up in your repo's normal Issues tab. The integration is one-way write: Stood Flows creates and edits issues; you can also act on them on GitHub directly and Stood Flows will pick up changes on next fetch.
When no GitHub repo is linked, Stood Flows stores issues in a local CSV file:
workspaces/<alias>/graphs/<slug>/issues.csv
Same operations — create, edit, comment, close, reopen — all done locally. The CSV has a stable header so it's safe to open in a spreadsheet, but the app expects to be the only writer (concurrent edits will trip up).
This is the offline-by-default mode. Use it when:
The org's audit work is private and you don't want a GitHub repo for it.
You're early in the analysis and don't yet know who'll own which finding.
You want issues to disappear when the graph is archived (a CSV in the workspace doesn't sync to a remote system).
The Issues tab UI is identical in both modes.
An anchor is a tiny block of metadata embedded in the issue body. It looks like:
<!-- stood-anchor:graph=acme-prod-q3,rt=01234000000xyz,col=score,obj=Opportunity,name=New Business -->The five fields are:
graph — the graph slug. So an issue created in acme-prod-q3 knows it belongs to acme-prod-q3 even after you've created acme-prod-q4.
rt — the record-type ID it relates to (where applicable).
col — the column (or analysis dimension) the issue was created from.
obj — the object type (Lead, Opportunity, Apex class name, profile name, etc.).
name — a human label (RT developer name, profile label, app name).
Anchors are HTML comments — they're invisible in the rendered issue body on GitHub and ignored when reading the CSV file in a spreadsheet. But Stood Flows reads them and uses them to:
Filter — the Issues tab shows a count next to each KPI/DML/IO/Apex node that has open issues anchored to it.
Navigate — clicking View on an issue jumps to the right tab, expands the right tree node, applies the right filter, and highlights the row.
Survive refreshes — record-type IDs and column names stay stable across versions, so an issue anchored to Opportunity.NewBusiness.complexity last quarter is still findable after a refresh that adds new RTs.
You don't write the anchor yourself. Every "Create issue" entry point in the app constructs one for you and pre-fills the body with a sensible title and a description that includes the metric value at creation time.
Three entry points:
Right-click any KPI cell → "Create issue". Anchor records the (object, RT, column) for that cell.
Right-click a row in DML / Licensing / I/O / Apex → "Create issue". Anchor records the drill path.
Issues tab → New issue (with the form). Used for issues that aren't tied to a specific cell.
The pre-filled body is usually enough — review, tag with labels if needed, save.
Every issue row in the Issues tab has a View button. Clicking it:
Reads the anchor from the body.
Switches to the appropriate panel (KPI, DML, IO, Apex, or Licensing based on col and obj).
Walks the panel state to the anchored target — expanding tree nodes, applying filters, scrolling.
Briefly highlights the destination row so you can spot it.
This is the muscle behind "every finding is verifiable". You don't lose the link between a comment from three months ago and the data that caused it.
Run a fresh Refresh + analyses.
For each high-complexity, low-volume row in the KPI table: right-click → "Create issue" with label retire-candidate.
For each integration in the DML integration bucket you don't recognise: right-click → "Create issue" with label unknown-integration.
For each callout destination with errors >20%: right-click → "Create issue" with label broken-callout.
Hand the resulting Issues tab to the team — every row is grounded in a specific number on a specific version of the data.
After a release:
Refresh.
Open the Issues tab and walk down. For each open issue, click View and confirm the metric has improved (or moved as expected).
Close issues that are resolved; comment on issues that have moved differently than expected.
The anchors mean the metric is always one click away — no copying URLs, no remembering which RT was which.
If you start CSV-only and later add a GitHub repo: the existing issues.csv stays where it is. The Issues tab quietly switches to GitHub-backed once githubOwner is set in graph.json. There is no automatic CSV → GitHub migration; you can copy rows over manually if you want them preserved in GitHub.
The reverse — removing the GitHub link — leaves the GitHub issues where they are and switches new issues to CSV. Past issues are still readable via the GitHub website; you just won't see them in the panel any more unless you re-link the repo.