[{"data":1,"prerenderedAt":1288},["ShallowReactive",2],{"docs-navigation":3,"docs\u002Fdocs\u002Freference\u002Fsecurity":194,"docs\u002Fdocs\u002Freference\u002Fsecurity-surround":1283},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,13,35,129,149,154],{"title":10,"path":6,"stem":11,"icon":12},"Overview","docs\u002Findex","i-lucide-house",{"title":14,"icon":15,"path":16,"stem":17,"children":18,"page":34},"Quickstart","i-lucide-rocket","\u002Fdocs\u002Fquickstart","docs\u002F1.quickstart",[19,24,29],{"title":20,"path":21,"stem":22,"icon":23},"Local","\u002Fdocs\u002Fquickstart\u002Flocal","docs\u002F1.quickstart\u002F1.local","i-lucide-laptop",{"title":25,"path":26,"stem":27,"icon":28},"Self-hosted","\u002Fdocs\u002Fquickstart\u002Fself-hosted","docs\u002F1.quickstart\u002F2.self-hosted","i-lucide-server",{"title":30,"path":31,"stem":32,"icon":33},"Cloud","\u002Fdocs\u002Fquickstart\u002Fcloud","docs\u002F1.quickstart\u002F3.cloud","i-lucide-cloud",false,{"title":36,"path":37,"stem":38,"children":39,"icon":41},"Harnesses","\u002Fdocs\u002Fharnesses","docs\u002F2.harnesses\u002Findex",[40,42,47,51,55,59,63,67,71,76,80,84,89,93,97,101,105,109,113,117,121,125],{"title":36,"path":37,"stem":38,"icon":41},"i-lucide-plug",{"title":43,"path":44,"stem":45,"icon":46},"Claude Code","\u002Fdocs\u002Fharnesses\u002Fclaude-code","docs\u002F2.harnesses\u002F1.claude-code","i-lucide-terminal",{"title":48,"path":49,"stem":50,"icon":46},"Devin","\u002Fdocs\u002Fharnesses\u002Fdevin","docs\u002F2.harnesses\u002F10.devin",{"title":52,"path":53,"stem":54,"icon":46},"Kiro","\u002Fdocs\u002Fharnesses\u002Fkiro","docs\u002F2.harnesses\u002F11.kiro",{"title":56,"path":57,"stem":58,"icon":46},"Cline","\u002Fdocs\u002Fharnesses\u002Fcline","docs\u002F2.harnesses\u002F12.cline",{"title":60,"path":61,"stem":62,"icon":46},"Amp","\u002Fdocs\u002Fharnesses\u002Famp","docs\u002F2.harnesses\u002F13.amp",{"title":64,"path":65,"stem":66,"icon":46},"VS Code","\u002Fdocs\u002Fharnesses\u002Fvscode","docs\u002F2.harnesses\u002F14.vscode",{"title":68,"path":69,"stem":70,"icon":46},"Gemini CLI","\u002Fdocs\u002Fharnesses\u002Fgemini-cli","docs\u002F2.harnesses\u002F15.gemini-cli",{"title":72,"path":73,"stem":74,"icon":75},"OpenClaw","\u002Fdocs\u002Fharnesses\u002Fopenclaw","docs\u002F2.harnesses\u002F16.openclaw","i-lucide-puzzle",{"title":77,"path":78,"stem":79,"icon":75},"Hermes Agent","\u002Fdocs\u002Fharnesses\u002Fhermes","docs\u002F2.harnesses\u002F17.hermes",{"title":81,"path":82,"stem":83,"icon":75},"NanoClaw","\u002Fdocs\u002Fharnesses\u002Fnanoclaw","docs\u002F2.harnesses\u002F18.nanoclaw",{"title":85,"path":86,"stem":87,"icon":88},"skills.sh (`npx skills`)","\u002Fdocs\u002Fharnesses\u002Fskills-sh","docs\u002F2.harnesses\u002F19.skills-sh","i-lucide-store",{"title":90,"path":91,"stem":92,"icon":46},"Codex CLI","\u002Fdocs\u002Fharnesses\u002Fcodex","docs\u002F2.harnesses\u002F2.codex",{"title":94,"path":95,"stem":96,"icon":88},"Claude Code plugin marketplace","\u002Fdocs\u002Fharnesses\u002Fclaude-code-marketplace","docs\u002F2.harnesses\u002F20.claude-code-marketplace",{"title":98,"path":99,"stem":100,"icon":88},"Codex plugin marketplace","\u002Fdocs\u002Fharnesses\u002Fcodex-marketplace","docs\u002F2.harnesses\u002F21.codex-marketplace",{"title":102,"path":103,"stem":104,"icon":46},"Cursor","\u002Fdocs\u002Fharnesses\u002Fcursor","docs\u002F2.harnesses\u002F3.cursor",{"title":106,"path":107,"stem":108,"icon":46},"OpenCode V1","\u002Fdocs\u002Fharnesses\u002Fopencode-v1","docs\u002F2.harnesses\u002F4.opencode-v1",{"title":110,"path":111,"stem":112,"icon":46},"OpenCode 2","\u002Fdocs\u002Fharnesses\u002Fopencode-v2","docs\u002F2.harnesses\u002F5.opencode-v2",{"title":114,"path":115,"stem":116,"icon":46},"Oh My Pi (omp)","\u002Fdocs\u002Fharnesses\u002Fomp","docs\u002F2.harnesses\u002F6.omp",{"title":118,"path":119,"stem":120,"icon":46},"Pi","\u002Fdocs\u002Fharnesses\u002Fpi","docs\u002F2.harnesses\u002F7.pi",{"title":122,"path":123,"stem":124,"icon":46},"Copilot CLI","\u002Fdocs\u002Fharnesses\u002Fcopilot","docs\u002F2.harnesses\u002F8.copilot",{"title":126,"path":127,"stem":128,"icon":46},"Antigravity","\u002Fdocs\u002Fharnesses\u002Fantigravity","docs\u002F2.harnesses\u002F9.antigravity",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":34},"Concepts","i-lucide-lightbulb","\u002Fdocs\u002Fconcepts","docs\u002F3.concepts",[135,140,145],{"title":136,"path":137,"stem":138,"icon":139},"Reports","\u002Fdocs\u002Fconcepts\u002Freports","docs\u002F3.concepts\u002F1.reports","i-lucide-file-text",{"title":141,"path":142,"stem":143,"icon":144},"Triage","\u002Fdocs\u002Fconcepts\u002Ftriage","docs\u002F3.concepts\u002F2.triage","i-lucide-list-checks",{"title":146,"path":147,"stem":148,"icon":41},"Model and harness independence","\u002Fdocs\u002Fconcepts\u002Fmodel-and-harness-independence","docs\u002F3.concepts\u002F3.model-and-harness-independence",{"title":150,"path":151,"stem":152,"icon":153},"Security","\u002Fdocs\u002Fsecurity","docs\u002F4.security","i-lucide-shield-check",{"title":155,"path":156,"stem":157,"children":158,"icon":160},"Reference","\u002Fdocs\u002Freference","docs\u002F5.reference\u002Findex",[159,161,166,171,174,179,184,189],{"title":155,"path":156,"stem":157,"icon":160},"i-lucide-book-open",{"title":162,"path":163,"stem":164,"icon":165},"API","\u002Fdocs\u002Freference\u002Fapi","docs\u002F5.reference\u002F1.api","i-lucide-braces",{"title":167,"path":168,"stem":169,"icon":170},"Operations","\u002Fdocs\u002Freference\u002Foperate","docs\u002F5.reference\u002F2.operate","i-lucide-settings",{"title":150,"path":172,"stem":173,"icon":153},"\u002Fdocs\u002Freference\u002Fsecurity","docs\u002F5.reference\u002F3.security",{"title":175,"path":176,"stem":177,"icon":178},"Session logs","\u002Fdocs\u002Freference\u002Fsessions","docs\u002F5.reference\u002F4.sessions","i-lucide-history",{"title":180,"path":181,"stem":182,"icon":183},"Releases","\u002Fdocs\u002Freference\u002Freleases","docs\u002F5.reference\u002F5.releases","i-lucide-tags",{"title":185,"path":186,"stem":187,"icon":188},"Client installation","\u002Fdocs\u002Freference\u002Fagent-install","docs\u002F5.reference\u002F6.agent-install","i-lucide-download",{"title":190,"path":191,"stem":192,"icon":193},"Stack installation","\u002Fdocs\u002Freference\u002Fagent-install-stack","docs\u002F5.reference\u002F7.agent-install-stack","i-lucide-container",{"id":195,"title":150,"body":196,"description":1276,"extension":1277,"meta":1278,"navigation":1279,"path":172,"seo":1280,"stem":173,"verified":1281,"__hash__":1282},"docs\u002Fdocs\u002F5.reference\u002F3.security.md",{"type":197,"value":198,"toc":1267},"minimark",[199,209,214,393,396,403,519,529,553,568,571,578,817,828,877,943,973,977,987,1044,1081,1187,1208,1211,1230,1234,1260,1264],[200,201,202,203,208],"p",{},"By default AgentFeedback is one binary and one database owned by one OS user\non one machine, with nothing listening (",[204,205,207],"a",{"href":206},"#the-client-on-a-machine","The client on a machine",").\nThe optional server is a single-trust-domain service for one team's\nmachines: it is not multi-tenant and is not safe to expose directly to the\ninternet.",[210,211,213],"h2",{"id":212},"access-and-network","Access and network",[215,216,217,226,238,304,325,344],"ul",{},[218,219,220,221,225],"li",{},"One shared API key authorizes every write, every read and every processed\nmark. No per-user permissions, no revocation of a single client, no overlap\nwindow on rotation (procedure in ",[204,222,224],{"href":223},"\u002Fdocs\u002Freference\u002Foperate#key-rotation","operate.md",").",[218,227,228,229,233,234,237],{},"HTTP is plaintext. The compose stacks bind ",[230,231,232],"code",{},"127.0.0.1:8090",". Set\n",[230,235,236],{},"AGENTFEEDBACK_BIND_ADDRESS=0.0.0.0"," only inside a trusted private network or\nbehind a reverse proxy that terminates TLS and authenticates.",[218,239,240,243,244,247,248,251,252,243,255,258,259,247,262,265,266,269,270,273,274,277,278,247,281,284,285,288,289,292,293,296,297,300,301,303],{},[230,241,242],{},"\u002Fhealth",", ",[230,245,246],{},"\u002Fready"," and ",[230,249,250],{},"\u002Fmetrics"," need no key; keep them inside the\ndeployment boundary. ",[230,253,254],{},"\u002Fskill",[230,256,257],{},"\u002F.well-known\u002Fagentfeedback.json",",\n",[230,260,261],{},"\u002Fapi\u002Fv1\u002Fopenapi.json",[230,263,264],{},"\u002Fapi\u002Fv1\u002Fschemas"," need no key and carry no\ndata. ",[230,267,268],{},"\u002Fmcp"," takes the same key as ",[230,271,272],{},"\u002Fapi\u002Fv1\u002F*","; its DNS-rebinding\ncheck is off because the key stands in for it. Turning that check off\n(",[230,275,276],{},"DisableLocalhostProtection"," in the MCP SDK) is acceptable only on a\nhandler behind the API key; a keyless loopback listener keeps it, or\nvalidates ",[230,279,280],{},"Host",[230,282,283],{},"Origin"," itself as ",[230,286,287],{},"agentfeedback ui"," does. ",[230,290,291],{},"\u002Fmcp\u002F{project}"," is a\nconvenience, not an access boundary: ",[230,294,295],{},"get_submission"," and\n",[230,298,299],{},"mark_processed"," take ids and are not scoped by the preset. There is no rate limiting; the only server-side bounds\nare the body caps: 10 MiB for a create or a mark, 32 MiB for an import,\nand 10 MiB plus 64 KiB for the JSON-RPC message on ",[230,302,268],{},".",[218,305,306,307,310,311,314,315,318,319,247,321,324],{},"Keep ",[230,308,309],{},"infra\u002Fagentfeedback\u002F.env",", the remote ",[230,312,313],{},".env",", backups and every\nproducer's ",[230,316,317],{},"AGENT_FEEDBACK_API_KEY"," private. ",[230,320,313],{},[230,322,323],{},".private\u002F"," are\ngitignored; never force-add them.",[218,326,327,328,331,332,335,336,339,340,343],{},"A local-mode write (no ",[230,329,330],{},"url"," configured) goes to the data-directory\ndatabase in-process and never presents the server key: the key guards the\nnetwork, and the one OS user who can read the database file can already\nwrite it. Local mode is for that one user; sharing a machine's queue with\nothers means running ",[230,333,334],{},"serve"," with a key. The file inbox\n(",[230,337,338],{},"inbox\u002F"," in the data directory, ",[230,341,342],{},"0700",") follows the same rule: a file\nthere is filed by the next command, so only that user may write it; the\nclient never follows a symlink out of it and never reads a file over the\ncreate limit.",[218,345,346,348,349,352,353,356,357,359,360,247,363,366,367,369,370,373,374,377,378,380,381,384,385,388,389,392],{},[230,347,287],{}," serves read-only queue and local session-status pages on a\nloopback address only (",[230,350,351],{},"--addr"," refuses any other). It is its own handler, never the\nAPI or the MCP handler: no ",[230,354,355],{},"\u002Fapi\u002Fv1"," or ",[230,358,268],{}," route is reachable through\nit, and every method but ",[230,361,362],{},"GET",[230,364,365],{},"HEAD"," is refused. A request whose ",[230,368,280],{},"\nis not the bound address (or ",[230,371,372],{},"localhost"," on the same port) is refused, so a\nweb page that rebinds its own DNS name to ",[230,375,376],{},"127.0.0.1"," reads nothing; so is\na request with any foreign ",[230,379,283],{},", and no CORS header is ever sent. The\npath carries a random token made at each launch, so another local process\nor page that guesses the port still gets ",[230,382,383],{},"404",", and no refused request's\nresponse carries the token; the URL is printed once,\nand anyone who has it can read the queue and local session store paths,\nproblems, counts and saved selection until the process exits. Every\nresponse is ",[230,386,387],{},"Cache-Control: no-store"," with a Content Security Policy that\nallows no remote source, stored text is HTML-escaped, and the page loads\nno external asset. With ",[230,390,391],{},"--server"," the queue pages read that server with\nthe configured key, which stays in the process. The sessions page reads\nlocal status only, without server requests or digest content.",[210,394,207],{"id":395},"the-client-on-a-machine",[200,397,398,399,402],{},"The ",[230,400,401],{},"agentfeedback"," binary runs when a person, a harness hook or an agent\nstarts it, or as a bounded upload child of one of those commands:",[215,404,405,426,493],{},[218,406,407,408,412,413,247,416,419,420,247,422,425],{},"No self-update, no resident daemon, no scheduled task, no telemetry.\nThe ",[204,409,411],{"href":410},"\u002Fdocs\u002Freference\u002Fsessions#automatic-sweep","automatic session sweep"," can launch one\ndetached, short-lived upload child from an existing turn-end hook or CLI\ncommand, bounded by ",[230,414,415],{},"sessions.push_budget",[230,417,418],{},"sessions.push_batch",".\nIt is never resident or scheduled. Only ",[230,421,334],{},[230,423,424],{},"ui"," (loopback only)\nopen a listening socket, and both stay in the foreground.\nUpgrading is installing a new binary.",[218,427,428,429,431,432,435,436,439,440,443,444,447,448,451,452,455,456,459,460,463,464,466,467,470,471,473,474,477,478,481,482,485,486,489,490,492],{},"Network: the client talks to one host, the server ",[230,430,330],{}," it is configured\nwith, and in local mode to none. Explicit onboarding and ",[230,433,434],{},"login"," contact the\nnamed server for discovery and authentication. ",[230,437,438],{},"agentfeedback migrate","\nalso talks to the target named by ",[230,441,442],{},"--to"," (",[230,445,446],{},"cloud"," is\n",[230,449,450],{},"https:\u002F\u002Fapi.agentfeedback.dev",") for the duration of that command; its\n",[230,453,454],{},"--dry-run"," sends no record but still reads the target's metadata and\ntombstones. Standard ",[230,457,458],{},"HTTPS_PROXY"," variables apply; redirects are not\nfollowed. ",[230,461,462],{},"agentfeedback mcp"," in remote mode holds the key in memory for\nthe life of the process and sends it, in the same two headers, only to\nthe configured server's ",[230,465,268],{},"; no MCP entry ",[230,468,469],{},"install"," writes holds the\nkey or a reference to it (the Codex block names ",[230,472,317],{},"\nin ",[230,475,476],{},"env_vars",", so Codex passes the variable through, never its value). ",[230,479,480],{},"skills\u002Fagentfeedback\u002Fscripts\u002Finstall.sh"," downloads the release\nand its ",[230,483,484],{},"SHA256SUMS"," from GitHub Releases over HTTPS only, and runs\n",[230,487,488],{},"version"," on an ",[230,491,401],{}," it finds already installed to decide\nwhether to keep it. The triage\nskill's optional clustering helper is a separate boundary (below).",[218,494,495,496,499,500,502,503,506,507,510,511,514,515,518],{},"No process enumeration, no keychain or credential store, no clipboard, no\nshell history. Commands it runs: ",[230,497,498],{},"git"," (read-only, for the context),\nharness CLIs during ",[230,501,469],{}," (such as ",[230,504,505],{},"claude mcp add","),\n",[230,508,509],{},"agentfeedback version --json"," of the binary each hook names (",[230,512,513],{},"doctor","),\nand ",[230,516,517],{},"agentfeedback sessions push --due --json"," for the automatic sweep.",[200,520,521,522,524,525,528],{},"Server onboarding accepts exactly one of an existing key on stdin, email\ndevice login, agent self-enrolment, or an enrolment token on stdin. Only\ncapability-advertised POST routes are used for the hosted methods; OSS\nsupports paste only. The human types secrets or completes email confirmation,\nnot the agent. Keys and tokens never belong in argv, chat, shell tracing or\nlogs. Device codes and verification URLs are not printed. Agent enrolment's\nclaim URL is shown once with its deadline and reduced-attribution notice and\nmust not be logged. No browser session, redirects or dummy credentials are\nused. ",[230,523,434],{}," explicitly reauthenticates a configured machine through email;\nneither onboarding nor login silently replaces an existing destination.\nReturned keys use the existing atomic ",[230,526,527],{},"0600"," config writer. Hosted credentials\nare saved before harness prompts or wiring; a later setup refusal does not\ndiscard the key. An environment API key must be unset before hosted\nauthentication. Login refuses a different saved destination, including one\nchanged while email approval was pending.",[200,530,531,243,534,247,536,539,540,543,544,547,548,552],{},[230,532,533],{},"init",[230,535,513],{},[230,537,538],{},"sessions status"," also read\n",[230,541,542],{},"GET \u002Fapi\u002Fv1\u002Fsessions\u002Fpolicy"," with the configured key. This policy request\nreturns the org identifier, processing permission, notice version and upload\nbounds, with optional org name and retention; it sends no transcript.\nThe response is cached in ",[230,545,546],{},"capture_policy"," in the data-directory database\nin remote mode. Local mode makes no request. Discovery alone uploads nothing,\nand failures never grant permission. See\n",[204,549,551],{"href":550},"\u002Fdocs\u002Freference\u002Foperate#session-policy-settings","Session policy settings"," for cache and\nbackoff behavior.",[200,554,555,558,559,562,563,567],{},[230,556,557],{},"sessions push"," sends eligible Claude Code, Codex, OpenCode (V1 and 2) and\nCursor transcripts to that configured server when its organisation enables\nprocessing. Depending on the harness, these contain prompts, responses,\ntool calls and tool output. Collection rules,\nrepository upload vetoes and the policy's consent cutoff apply. Every scrub\nclass is applied before hashing and partitioning, with JSON strings decoded\nso escaping cannot hide credentials and multiline private keys redacted\nacross records. Logs contain scrub counts, never transcript text. Scrubbing\nis not a guarantee that all sensitive prose is recognised. Uploads can be\nmanual or triggered by the ",[204,560,561],{"href":410},"automatic sweep",",\nwhich requires matching cached consent (including recovery from transient policy\nerrors) and refreshes permission in the upload child. See ",[204,564,566],{"href":565},"\u002Fdocs\u002Freference\u002Fsessions#push","Push"," for timing, revision, size and retry rules. A dry-run\npreview stays in command output; it is not saved or sent to the upload\nroutes. Pending uploads retain only their initial scrubbed manifest metadata\nand partition size in SQLite, never transcript content or parts. Source\npermissions and snapshot stability are checked again before each request.",[200,569,570],{},"Cursor hooks store only the conversation id, home-contained absolute\ntranscript path, workspace roots and reported cwd in the existing owner-only\ncounters cache, subject to its seven-day pruning. Hooks never open the transcript.\nListing and export check collection policy and repository upload vetoes for\nevery recorded root and cwd before reading; missing or invalid workspace roots,\nsymlink paths and nonregular transcripts are refused.\nCursor capture is storage-only, not a semantic digest.",[200,572,573,574,577],{},"Where it reads and writes (",[230,575,576],{},"XDG_*"," unset or not absolute means the default\nunder the home directory, on every operating system):",[579,580,581,597],"table",{},[582,583,584],"thead",{},[585,586,587,591,594],"tr",{},[588,589,590],"th",{},"Location",[588,592,593],{},"Access",[588,595,596],{},"What",[598,599,600,642,687,723,741,752,768,786],"tbody",{},[585,601,602,608,616],{},[603,604,605],"td",{},[230,606,607],{},"${XDG_DATA_HOME:-~\u002F.local\u002Fshare}\u002Fagentfeedback\u002F",[603,609,610,611,613,614],{},"owned, ",[230,612,342],{},", files ",[230,615,527],{},[603,617,618,619,243,621,247,623,625,626,629,630,243,633,243,636,443,638,641],{},"the database (reports in local mode; session watermarks and policy cache in both modes; remote ",[230,620,533],{},[230,622,513],{},[230,624,538],{}," create it for policy discovery; when switching to a server, existing reports leave the machine only through ",[230,627,628],{},"migrate"," or init's copy after a yes), ",[230,631,632],{},"spool\u002F",[230,634,635],{},"rejected\u002F",[230,637,338],{},[204,639,224],{"href":640},"\u002Fdocs\u002Freference\u002Foperate#data-directory",")",[585,643,644,649,655],{},[603,645,646],{},[230,647,648],{},"${XDG_CACHE_HOME:-~\u002F.cache}\u002Fagentfeedback\u002F",[603,650,610,651,613,653],{},[230,652,342],{},[230,654,527],{},[603,656,657,660,661,664,665,668,669,672,673,676,677,243,680,247,683,686],{},[230,658,659],{},"log\u002Fclient.jsonl",", the hooks' per-session counters (",[230,662,663],{},"sessions\u002F",", deleted after 7 days) and last-run records (",[230,666,667],{},"hooks\u002F","), ",[230,670,671],{},"filed\u002F"," markers, ",[230,674,675],{},"digest\u002F"," output; ",[230,678,679],{},"push.lock",[230,681,682],{},"push.last-started",[230,684,685],{},"push.last-run.json"," coordinate and summarize automatic session sweeps without transcript content",[585,688,689,694,700],{},[603,690,691],{},[230,692,693],{},"${XDG_CONFIG_HOME:-~\u002F.config}\u002Fagentfeedback\u002F",[603,695,610,696,613,698],{},[230,697,342],{},[230,699,527],{},[603,701,702,705,706,709,710,443,713,243,716,719,720],{},[230,703,704],{},"config.toml",", the install manifest ",[230,707,708],{},"install.json",", and ",[230,711,712],{},"server\u002F",[230,714,715],{},"api-key",[230,717,718],{},"serve.env",") from ",[230,721,722],{},"serve --init",[585,724,725,735,738],{},[603,726,727,728,731,732],{},"the working tree's ",[230,729,730],{},".git"," metadata and ",[230,733,734],{},".agentfeedback.toml",[603,736,737],{},"read",[603,739,740],{},"the project context and the repository's narrowing rules",[585,742,743,746,749],{},[603,744,745],{},"harness session stores",[603,747,748],{},"read, never written",[603,750,751],{},"below",[585,753,754,757,766],{},[603,755,756],{},"harness skill, hook, MCP and global instruction files",[603,758,759,760,247,762,765],{},"written by ",[230,761,469],{},[230,763,764],{},"uninstall"," only",[603,767,751],{},[585,769,770,779,784],{},[603,771,772,773,356,776],{},"a repository's ",[230,774,775],{},"AGENTS.md",[230,777,778],{},"CLAUDE.md",[603,780,759,781,765],{},[230,782,783],{},"install --project",[603,785,751],{},[585,787,788,791,794],{},[603,789,790],{},"paths named on the command line",[603,792,793],{},"as the command says",[603,795,796,243,799,243,802,243,805,808,809,812,813,816],{},[230,797,798],{},"backup \u003Cdest.db>",[230,800,801],{},"import \u003Cfile>",[230,803,804],{},"digest --out",[230,806,807],{},"submit review \u003Crun_dir>"," (reads it, writes its ",[230,810,811],{},".submitted"," marker), ",[230,814,815],{},"server install"," (one service file)",[200,818,819,820,823,824,827],{},"Owner-only modes are not set or checked on Windows. ",[230,821,822],{},"agentfeedback doctor","\nreports a data-directory path other users can reach, with the ",[230,825,826],{},"chmod"," to\nrun.",[200,829,830,834,835,839,840,843,844,847,848,851,852,855,856,859,860,247,863,866,867,870,871,873,874,225],{},[831,832,833],"strong",{},"Session stores."," The harness session stores (",[204,836,838],{"href":837},"\u002Fdocs\u002Freference\u002Fsessions#harnesses","sessions.md"," lists\nthem) are read only by ",[230,841,842],{},"agentfeedback sessions",", the UI sessions page,\n",[230,845,846],{},"submit --context-from",", the stdio ",[230,849,850],{},"sessions_*"," tools and the stdio\n",[230,853,854],{},"submit_feedback","'s ",[230,857,858],{},"context_from"," (in remote mode too: the session is read\nhere, and only the body built from it is sent), on demand and never written;\nthe OpenCode (",[230,861,862],{},"opencode-v1",[230,864,865],{},"opencode-v2",")\ndatabase is opened read-only, without creating any file beside it. The ",[230,868,869],{},"[collect]","\nrules are applied per session before a log is opened, and a digest is\nbounded and scrubbed before it is shown. Only watermark and push-outcome\nmetadata and what you file are stored in the data-directory database;\ntranscripts are sent only by ",[230,872,557],{}," (manual or automatic), never spooled.\nA digest reaches the provider of the model that reads it\n(",[204,875,838],{"href":876},"\u002Fdocs\u002Freference\u002Fsessions#provider-boundary",[200,878,879,885,886,889,890,247,893,896,897,443,900,903,904,907,908,911,912,914,915,917,918,921,922,925,926,928,929,931,932,934,935,938,939,942],{},[831,880,881,882,884],{},"What ",[230,883,469],{}," writes."," The files of the harness table in\n",[204,887,224],{"href":888},"\u002Fdocs\u002Freference\u002Foperate#wire-the-harnesses",", and in CLI mode one section in each\nharness's global instruction file (its Rule column), between\n",[230,891,892],{},"\u003C!-- agentfeedback:begin ... -->",[230,894,895],{},"\u003C!-- agentfeedback:end -->","; unless\n",[230,898,899],{},"--with-triage=false",[230,901,902],{},"init --no-triage","), also the binary's copy of the\n",[230,905,906],{},"agentfeedback-triage"," skill in each skills directory, never over a skill\nor triage directory or link it did not write (it takes over only one that\nholds exactly the files it would write). It reads, never writes, Claude\nCode's ",[230,909,910],{},"plugins\u002Finstalled_plugins.json"," and Codex's ",[230,913,704],{}," to find an\n",[230,916,401],{}," plugin, which then provides the skill instead. Each\nfile is backed up before its first change (",[230,919,920],{},"\u003Cfile>.agentfeedback-backup",") and recorded in the install\nmanifest like the other files; the text between the markers belongs to\ninstall, which replaces it in place and removes it by its markers even\nwhen edited, and ",[230,923,924],{},"--check"," only reads. A repository's instruction file\n(",[230,927,775],{},", else an existing ",[230,930,778],{},") is written only by\n",[230,933,783],{},", after a confirmation that names the repository and\nthe file, or with ",[230,936,937],{},"--yes",". It gets the pointer text only, between the\nsame markers, is never committed by the tool (reviewing the commit is the\nconsent), is removed by its markers with ",[230,940,941],{},"install --project --uninstall","\n(the file is deleted only when nothing remains), is never followed through\na symbolic link (a linked file is refused), and is not recorded in the\nmanifest and not backed up.",[200,944,945,950,951,954,955,959,960,963,964,247,966,969,970,972],{},[831,946,881,947,884],{},[230,948,949],{},"config"," The settings menu and ",[230,952,953],{},"config set"," edit only the\nallowlisted ",[204,956,958],{"href":957},"\u002Fdocs\u002Freference\u002Foperate#machine-settings","machine settings",", using an atomic\n0600 replacement that retains unknown keys and credentials, not TOML comments.\nCLI config writers serialize the whole read\u002Fedit\u002Fwrite operation with a persistent\n",[230,961,962],{},"config.toml.lock"," file. Symlinked configs and ambiguous case variants of known\nkeys are refused. Destination updates through ",[230,965,533],{},[230,967,968],{},"doctor --init"," retain\nmachine settings, including collection restrictions.\nThe settings menu and ",[230,971,953],{}," never change the destination, API key, repository\nnarrowing or organisation policy. Read output masks the API key; policy display can contact the configured\nserver but sends no transcript. Menu harness actions use the same installer\nand ownership rules described above, for one explicitly selected harness.",[210,974,976],{"id":975},"what-gets-stored","What gets stored",[200,978,979,980,983,984,986],{},"What the client collects into ",[230,981,982],{},"context"," for a friction, all best-effort\n(",[230,985,454],{}," shows it before anything is sent):",[215,988,989,1011,1017,1024],{},[218,990,991,992,995,996,443,999,1001,1002,1004,1005,1007,1008,225],{},"Project: the working directory's folder name (",[230,993,994],{},"~"," for the home\ndirectory), and inside a Git repository ",[230,997,998],{},"repo_root",[230,1000,994],{},"-relative under\nthe home directory), the remote URL with credentials, query string and\nfragment stripped, branch, commit, dirty flag, upstream, tag and default\nbranch, read from ",[230,1003,730],{}," metadata (with ",[230,1006,498],{}," when it is on ",[230,1009,1010],{},"PATH",[218,1012,1013,1014,303],{},"Machine: OS, architecture, client version, and the short hostname as\n",[230,1015,1016],{},"machine",[218,1018,1019,1020,1023],{},"Harness and session: the harness, model, session id, agent, effort and\nprofile, from a fixed allow-list of environment variables looked up by\nname (for OpenCode 2, ",[230,1021,1022],{},"OPENCODE_SESSION_ID",", which also tells it from\nOpenCode V1).",[218,1025,1026,1027,243,1030,258,1033,243,1035,243,1038,243,1041,225],{},"The event time, and any non-code keys you pass (",[230,1028,1029],{},"app",[230,1031,1032],{},"workspace",[230,1034,330],{},[230,1036,1037],{},"channel",[230,1039,1040],{},"task_id",[230,1042,1043],{},"workflow",[200,1045,1046,1047,1050,1051,1054,1055,1057,1058,1061,1062,1065,1066,1068,1069,1071,1072,1074,1075,1077,1078,1080],{},"Opt-in only: the full working directory, which holds the home path and so\nthe username (",[230,1048,1049],{},"cwd = true"," under ",[230,1052,1053],{},"[context]"," in ",[230,1056,704],{},"), and for ",[230,1059,1060],{},"submit review"," the reviewer outputs and prompt\n(",[230,1063,1064],{},"--include-outputs","). Never collected: the username or home path (except through that opt-in), IP or MAC\naddresses, serial numbers, other processes, files other than ",[230,1067,730],{},"\nmetadata and ",[230,1070,734],{},", and environment variables not on the\nallow-list. The ",[230,1073,869],{}," table in ",[230,1076,704],{}," and a repository's\n",[230,1079,734],{}," can only narrow this. Even so, a remote, a branch or\na hostname can reveal private repository names and internal hosts, and\nreport prose holds whatever the agent wrote.",[200,1082,1083,1086,1087,447,1090,1093,1094,1097,1098,258,1101,243,1104,243,1107,1110,1111,1114,1115,247,1117,1120,1121,1124,1125,1128,1129,243,1132,243,1135,243,1138,258,1141,243,1144,243,1147,243,1150,258,1153,243,1156,243,1159,243,1162,243,1165,1168,1169,1172,1173,1168,1176,243,1179,1182,1183,1186],{},[230,1084,1085],{},"submit \u003Ckind> --scrub",", and any submission whose ",[230,1088,1089],{},"context.origin",[230,1091,1092],{},"session-scan",", replaces known secret formats in every string value of the\nbody (summary, payload, context, any other member) with\n",[230,1095,1096],{},"[REDACTED:\u003Cclass>]"," before checking or sending; member names are never\nchanged, and a non-empty string under a secret-named member (",[230,1099,1100],{},"password",[230,1102,1103],{},"token",[230,1105,1106],{},"api_key",[230,1108,1109],{},"client_secret"," and similar) is redacted whole. The\noutcome line carries one ",[230,1112,1113],{},"scrubbed"," warning per member changed.\n",[230,1116,807],{},[230,1118,1119],{},"submit review --sweep"," do not scrub, and spool\nentries queued before are sent as they were. The server does the same at\ningest with ",[230,1122,1123],{},"INGEST_SCRUB=on"," (default ",[230,1126,1127],{},"off","), before decoding, silently: the\nstored text carries the markers, the response has no warning, and the server\nlog records the counts per class, never the text. The classes, in the order\nthey apply: ",[230,1130,1131],{},"private_key",[230,1133,1134],{},"jwt",[230,1136,1137],{},"aws_access_key",[230,1139,1140],{},"gcp_api_key",[230,1142,1143],{},"github_token",[230,1145,1146],{},"gitlab_token",[230,1148,1149],{},"slack_token",[230,1151,1152],{},"stripe_key",[230,1154,1155],{},"anthropic_key",[230,1157,1158],{},"openai_key",[230,1160,1161],{},"bearer_token",[230,1163,1164],{},"url_credentials",[230,1166,1167],{},"env_line","\n(",[230,1170,1171],{},"NAME=value"," lines whose name has a segment ending in KEY, TOKEN, SECRET,\nPASSWORD, PASSWD, CREDENTIAL(S), AUTH or PRIVATE) and ",[230,1174,1175],{},"assignment",[230,1177,1178],{},"password=",[230,1180,1181],{},"token:"," and similar, and secret-named members). This is\ndefence in depth: it detects these formats and no others, not secrets in\nprose, and never member names. ",[230,1184,1185],{},"import"," does not scrub. Otherwise the server\nstores what it receives and redacts nothing.",[200,1188,1189,1190,1193,1194,1196,1197,1199,1200,1203,1204,1207],{},"The harness hooks (",[230,1191,1192],{},"agentfeedback hook",") read only the payload the harness\npasses on stdin, never the transcript or any other file it names, call no\nmodel and send nothing about the session. They keep counters per session in\nthe cache directory (",[230,1195,342],{}," directories, ",[230,1198,527],{}," files, no command text,\ndeleted after 7 days); the short note they may show quotes the failed\ncommand, cut to 80 bytes after the same secret-format replacement as\n",[230,1201,1202],{},"--scrub",". A note suggests a friction report and never blocks or redirects\na tool call or continues a stopped turn. Amp appends the note to the tool's\nerror text while preserving its status and output; other adapters deliver\nadditional context without replacing the original result. The client log\nkeeps a submission's ",[230,1205,1206],{},"context.session_id",", and no other context; a friction\nreport with one also leaves an empty marker\nnamed by a digest of the session id, so the hook can tell a session already\nfiled a report without reading the log.",[200,1209,1210],{},"Stored text is untrusted. A processor treats reports, suggested fixes and\nevent payloads as evidence to verify, never as instructions to execute. The\ntriage skill's checkout rule exists for this reason.",[200,1212,1213,1214,1217,1218,1221,1222,1225,1226,1229],{},"The triage skill's optional TypeSafe helper is a separate disclosure boundary,\nnot a server feature. It sends selected report prose to ",[230,1215,1216],{},"api.typesafe.ai"," only with explicit\nper-repository approval; a key alone never enables it. Reports can contain\nsecrets in prose, so inspect the local preview before sending. Advice cannot\nauthorize edits or processed marks. A batched request shares one state\namong up to 8 reports, all from approved repositories. ",[230,1219,1220],{},"scripts\u002Feval-cluster.py","\nis the same boundary for calibration: it sends nothing unless every labelled\nreport's exact remote is approved and ",[230,1223,1224],{},"--live"," is given. The\nclustering reference (",[230,1227,1228],{},"skills\u002Fagentfeedback-triage\u002Freference\u002Fclustering.md",")\ndefines the fields, consent rules and manual fallback.",[210,1231,1233],{"id":1232},"data-at-rest","Data at rest",[200,1235,1236,1237,1240,1241,1244,1245,1248,1249,1251,1252,1254,1255,1257,1258,225],{},"One SQLite file in a Docker volume, or in local mode\n",[230,1238,1239],{},"~\u002F.local\u002Fshare\u002Fagentfeedback\u002Fagentfeedback.db",", readable by anyone who can\nread the volume, the file or a backup. Encrypt and restrict backups; they hold everything\nagents ever reported. Retention is manual (see\n",[204,1242,224],{"href":1243},"\u002Fdocs\u002Freference\u002Foperate#retention","). Producers keep unsent payloads in the\nsame data directory, ",[230,1246,1247],{},"~\u002F.local\u002Fshare\u002Fagentfeedback\u002Fspool\u002F",", until delivered\nor aged out; the client creates that directory ",[230,1250,342],{}," and its files ",[230,1253,527],{},",\nand ",[230,1256,822],{}," reports a path other users can reach (see\n",[204,1259,224],{"href":640},[210,1261,1263],{"id":1262},"reporting-a-vulnerability","Reporting a vulnerability",[200,1265,1266],{},"Do not post keys, telemetry or exploit details in public issues. Contact the\nmaintainer privately first.",{"title":1268,"searchDepth":1269,"depth":1269,"links":1270},"",2,[1271,1272,1273,1274,1275],{"id":212,"depth":1269,"text":213},{"id":395,"depth":1269,"text":207},{"id":975,"depth":1269,"text":976},{"id":1232,"depth":1269,"text":1233},{"id":1262,"depth":1269,"text":1263},"By default AgentFeedback is one binary and one database owned by one OS user on one machine, with nothing listening (The client on a machine).","md",{},{"title":150,"icon":153},{"title":150,"description":1276},null,"oSwpKKJ4Zf_MMpdSm6WZteuTT9SjwifM7aFaQ4meryU",[1284,1286],{"title":167,"path":168,"stem":169,"description":1285,"icon":170,"children":-1},"Run AgentFeedback on one machine with no server, or run a server for several machines; wire the harnesses, back up, upgrade and migrate.",{"title":175,"path":176,"stem":177,"description":1287,"icon":178,"children":-1},"`agentfeedback sessions` reads the session logs a coding-agent harness keeps on disk, on demand and read-only, so an agent can turn what went wrong in a past…",1794388868197]