[{"data":1,"prerenderedAt":7925},["ShallowReactive",2],{"docs-navigation":3,"docs\u002Fdocs\u002Freference\u002Foperate":194,"docs\u002Fdocs\u002Freference\u002Foperate-surround":7920},[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":196,"body":197,"description":7913,"extension":7914,"meta":7915,"navigation":7916,"path":168,"seo":7917,"stem":169,"verified":7918,"__hash__":7919},"docs\u002Fdocs\u002F5.reference\u002F2.operate.md","Operate AgentFeedback",{"type":198,"value":199,"toc":7875},"minimark",[200,204,275,279,319,327,370,373,380,522,536,653,667,678,691,694,733,786,844,849,865,958,962,968,1093,1142,1177,1180,1216,1300,1304,1349,1361,1398,1423,1426,1511,1525,1538,1542,1545,1751,1772,1815,1826,1844,1904,1907,1911,2007,2017,2032,2051,2061,2067,2245,2255,2326,2332,2429,2439,2668,2691,2694,2697,2703,2737,2794,2854,2974,3008,3011,3051,3081,3084,3101,3164,3234,3239,3398,3497,3546,3576,3591,3732,3784,3819,4627,5391,5394,5401,5519,5580,5587,5602,5651,5655,5658,5687,5705,5708,5731,5792,5816,5847,5852,5901,5923,5938,5941,5944,6161,6182,6186,6228,6286,6294,6297,6356,6374,6377,6381,6387,6419,6436,6456,6470,6498,6501,6627,6629,6632,6638,6725,6736,6755,6761,6832,6835,6853,6856,6873,6952,6958,7036,7098,7107,7173,7221,7224,7268,7275,7300,7310,7313,7341,7344,7359,7395,7408,7411,7461,7463,7469,7473,7575,7579,7588,7691,7701,7707,7719,7815,7850,7854,7871],[201,202,203],"p",{},"Run AgentFeedback on one machine with no server, or run a server for\nseveral machines; wire the harnesses, back up, upgrade and migrate. One\nbinary and one SQLite file; a server adds one API key. Every step is a\ncommand an agent can run.",[201,205,206,207,212,213,217,218,222,223,212,227,212,231,222,235,222,239,212,243,212,247,222,251,212,255,222,259,212,263,212,267,222,271],{},"Contents: ",[208,209,211],"a",{"href":210},"#local-mode-no-server","Local mode (no server)"," · ",[208,214,216],{"href":215},"#run-locally","Run locally"," (a server in Docker) · ",[208,219,221],{"href":220},"#bare-binary-no-docker","Bare binary (no Docker)"," ·\n",[208,224,226],{"href":225},"#canonical-issues","Canonical issues",[208,228,230],{"href":229},"#wire-the-harnesses","Wire the harnesses",[208,232,234],{"href":233},"#build-from-source","Build from source",[208,236,238],{"href":237},"#deploy-to-a-host","Deploy to a host",[208,240,242],{"href":241},"#authenticate-a-client","Authenticate a client",[208,244,246],{"href":245},"#configuration","Configuration",[208,248,250],{"href":249},"#backups","Backups",[208,252,254],{"href":253},"#restore-and-migration","Restore and migration",[208,256,258],{"href":257},"#upgrading-and-downgrading","Upgrading and downgrading",[208,260,262],{"href":261},"#key-rotation","Key rotation",[208,264,266],{"href":265},"#retention","Retention",[208,268,270],{"href":269},"#monitoring","Monitoring",[208,272,274],{"href":273},"#uninstall","Uninstall",[276,277,242],"h2",{"id":278},"authenticate-a-client",[201,280,281,282,286,287,290,291,294,295,298,299,302,303,306,307,310,311,314,315,318],{},"Keep authentication separate from harness wiring. Select exactly one key source:\n",[283,284,285],"code",{},"--key-from-stdin"," (paste an existing key), ",[283,288,289],{},"--login EMAIL"," (email device\nlogin), ",[283,292,293],{},"--agent"," (self-enrolment), or ",[283,296,297],{},"--enrol-token-from-stdin"," (an\nenrolment token). For each, use ",[283,300,301],{},"agentfeedback init --server URL"," with the\nselected flag and ",[283,304,305],{},"--harnesses none --yes --json",". ",[283,308,309],{},"cloud"," still means\n",[283,312,313],{},"https:\u002F\u002Fapi.agentfeedback.dev",". Then wire separately with\n",[283,316,317],{},"agentfeedback init --harnesses HARNESS --yes --json",".",[201,320,321,322,326],{},"The human types keys or tokens privately on stdin and completes email\nconfirmation themselves; never put secrets in argv, chat, logs or shell\ntraces. See ",[208,323,325],{"href":324},"\u002Fdocs\u002Freference\u002Fagent-install#step-22-authenticate-without-exposing-the-key","the hidden terminal prompt",".\nEmail, agent and token routes must be advertised by the server's capabilities;\nOSS supports paste only. If interactive discovery fails, the menu still offers\npaste; explicit hosted methods fail rather than guess. Unsupported methods exit 2. Device polling\nhonors the advertised interval; codes, keys and verification URLs are not\nprinted. Agent enrolment prints its claim URL once with its deadline and\nreduced-attribution notice; treat that URL as private and never log it.",[201,328,329,330,333,334,337,338,341,342,345,346,349,350,353,354,357,358,361,362,365,366,369],{},"Existing configuration is not automatically replaced. To explicitly refresh\na configured machine's key through email, run\n",[283,331,332],{},"agentfeedback login --email EMAIL --server cloud --json"," (or a server URL).\n",[283,335,336],{},"login"," also accepts an interactive email when ",[283,339,340],{},"--email"," is omitted.\nThe key is saved through the existing ",[283,343,344],{},"0600"," config writer, not a browser\nsession. ",[283,347,348],{},"doctor --init"," remains the paste-key configuration path;\n",[283,351,352],{},"doctor --init --url cloud --key-from-stdin"," saves the hosted service URL,\njust like ",[283,355,356],{},"install --server cloud"," and ",[283,359,360],{},"migrate --to cloud",".\nHosted credentials are saved before harness selection and wiring. If either\nlater step fails, fix that setup problem and rerun ",[283,363,364],{},"init"," without an\nauthentication flag; do not consume another enrolment token. Unset\n",[283,367,368],{},"AGENT_FEEDBACK_API_KEY"," before acquiring hosted credentials. A claim URL in\neither successful or failed output is private; do not paste it into agent chat\nor retain it in session transcripts.\nAuthentication does not change feature-target or session collection policy.",[276,371,216],{"id":372},"run-locally",[201,374,375,376,379],{},"A server on this machine, for trying the HTTP API or serving other machines;\nreporting from this machine alone needs none (",[208,377,378],{"href":210},"Local mode",").\nNeeds Docker with Compose. From the repository root:",[381,382,387],"pre",{"className":383,"code":384,"language":385,"meta":386,"style":386},"language-bash shiki shiki-themes github-light github-light github-dark","cd infra\u002Fagentfeedback\ntest -e .env || (umask 077 && printf 'API_KEY=%s\\n' \"$(openssl rand -hex 32)\" > .env)   # keeps an existing key\ndocker compose up -d --build --wait\ncurl --fail --silent --show-error --retry 60 --retry-all-errors --retry-delay 1 http:\u002F\u002F127.0.0.1:8090\u002Fready\n","bash","",[283,388,389,402,468,489],{"__ignoreMap":386},[390,391,394,398],"span",{"class":392,"line":393},"line",1,[390,395,397],{"class":396},"sBjJW","cd",[390,399,401],{"class":400},"sIIMD"," infra\u002Fagentfeedback\n",[390,403,405,408,411,414,418,422,425,428,431,434,437,440,444,447,450,453,456,459,461,464],{"class":392,"line":404},2,[390,406,407],{"class":396},"test",[390,409,410],{"class":396}," -e",[390,412,413],{"class":400}," .env",[390,415,417],{"class":416},"s8jYJ"," ||",[390,419,421],{"class":420},"sxrX7"," (",[390,423,424],{"class":396},"umask",[390,426,427],{"class":396}," 077",[390,429,430],{"class":420}," && ",[390,432,433],{"class":396},"printf",[390,435,436],{"class":400}," 'API_KEY=%s\\n'",[390,438,439],{"class":400}," \"$(",[390,441,443],{"class":442},"snPdu","openssl",[390,445,446],{"class":400}," rand ",[390,448,449],{"class":396},"-hex",[390,451,452],{"class":396}," 32",[390,454,455],{"class":400},")\"",[390,457,458],{"class":416}," >",[390,460,413],{"class":400},[390,462,463],{"class":420},")   ",[390,465,467],{"class":466},"sCsY4","# keeps an existing key\n",[390,469,471,474,477,480,483,486],{"class":392,"line":470},3,[390,472,473],{"class":442},"docker",[390,475,476],{"class":400}," compose",[390,478,479],{"class":400}," up",[390,481,482],{"class":396}," -d",[390,484,485],{"class":396}," --build",[390,487,488],{"class":396}," --wait\n",[390,490,492,495,498,501,504,507,510,513,516,519],{"class":392,"line":491},4,[390,493,494],{"class":442},"curl",[390,496,497],{"class":396}," --fail",[390,499,500],{"class":396}," --silent",[390,502,503],{"class":396}," --show-error",[390,505,506],{"class":396}," --retry",[390,508,509],{"class":396}," 60",[390,511,512],{"class":396}," --retry-all-errors",[390,514,515],{"class":396}," --retry-delay",[390,517,518],{"class":396}," 1",[390,520,521],{"class":400}," http:\u002F\u002F127.0.0.1:8090\u002Fready\n",[201,523,524,525,528,529,421,532,535],{},"The service listens on ",[283,526,527],{},"127.0.0.1:8090"," and stores its database in the named\nvolume ",[283,530,531],{},"agentfeedback-data",[283,533,534],{},"\u002Fdata\u002Fagentfeedback.db"," in the container). First request:",[381,537,539],{"className":383,"code":538,"language":385,"meta":386,"style":386},"export AGENT_FEEDBACK_URL=http:\u002F\u002F127.0.0.1:8090\nexport AGENT_FEEDBACK_API_KEY=$(sed -n 's\u002F^API_KEY=\u002F\u002Fp' .env)\ncurl -sS -H \"Authorization: Bearer $AGENT_FEEDBACK_API_KEY\" -H 'Content-Type: application\u002Fjson' \\\n  -d '{\"kind\":\"friction\",\"summary\":\"local smoke test\",\"payload\":{\"category\":\"test\"}}' \\\n  \"$AGENT_FEEDBACK_URL\u002Fapi\u002Fv1\u002Fsubmissions\"\ncurl -sS -H \"Authorization: Bearer $AGENT_FEEDBACK_API_KEY\" \"$AGENT_FEEDBACK_URL\u002Fapi\u002Fv1\u002Fsubmissions?limit=5\"\n",[283,540,541,555,581,608,618,630],{"__ignoreMap":386},[390,542,543,546,549,552],{"class":392,"line":393},[390,544,545],{"class":416},"export",[390,547,548],{"class":420}," AGENT_FEEDBACK_URL",[390,550,551],{"class":416},"=",[390,553,554],{"class":420},"http:\u002F\u002F127.0.0.1:8090\n",[390,556,557,559,562,564,567,570,573,576,578],{"class":392,"line":404},[390,558,545],{"class":416},[390,560,561],{"class":420}," AGENT_FEEDBACK_API_KEY",[390,563,551],{"class":416},[390,565,566],{"class":420},"$(",[390,568,569],{"class":442},"sed",[390,571,572],{"class":396}," -n",[390,574,575],{"class":400}," 's\u002F^API_KEY=\u002F\u002Fp'",[390,577,413],{"class":400},[390,579,580],{"class":420},")\n",[390,582,583,585,588,591,594,597,600,602,605],{"class":392,"line":470},[390,584,494],{"class":442},[390,586,587],{"class":396}," -sS",[390,589,590],{"class":396}," -H",[390,592,593],{"class":400}," \"Authorization: Bearer ",[390,595,596],{"class":420},"$AGENT_FEEDBACK_API_KEY",[390,598,599],{"class":400},"\"",[390,601,590],{"class":396},[390,603,604],{"class":400}," 'Content-Type: application\u002Fjson'",[390,606,607],{"class":396}," \\\n",[390,609,610,613,616],{"class":392,"line":491},[390,611,612],{"class":396},"  -d",[390,614,615],{"class":400}," '{\"kind\":\"friction\",\"summary\":\"local smoke test\",\"payload\":{\"category\":\"test\"}}'",[390,617,607],{"class":396},[390,619,621,624,627],{"class":392,"line":620},5,[390,622,623],{"class":400},"  \"",[390,625,626],{"class":420},"$AGENT_FEEDBACK_URL",[390,628,629],{"class":400},"\u002Fapi\u002Fv1\u002Fsubmissions\"\n",[390,631,633,635,637,639,641,643,645,648,650],{"class":392,"line":632},6,[390,634,494],{"class":442},[390,636,587],{"class":396},[390,638,590],{"class":396},[390,640,593],{"class":400},[390,642,596],{"class":420},[390,644,599],{"class":400},[390,646,647],{"class":400}," \"",[390,649,626],{"class":420},[390,651,652],{"class":400},"\u002Fapi\u002Fv1\u002Fsubmissions?limit=5\"\n",[201,654,655,656,662,663,666],{},"The service answers the v1 contract, ",[208,657,661],{"href":658,"rel":659},"https:\u002F\u002Fgithub.com\u002FAgentFeedback\u002Fagentfeedback\u002Fblob\u002Fc7573e1b301aa1495f290c417ce2fb390caee544\u002Fdocs\u002Fopenapi.yaml",[660],"nofollow","openapi.yaml","; ",[283,664,665],{},"bash scripts\u002Fe2e.sh \"$AGENT_FEEDBACK_API_KEY\" \"$AGENT_FEEDBACK_URL\""," from the repository root runs the whole contract suite against it (it creates rows).",[201,668,669,670,673,674,677],{},"Tear down with ",[283,671,672],{},"docker compose down -v"," (deletes the database volume; ",[283,675,676],{},".env","\nstays).",[201,679,680,681,684,685,687,688,318],{},"Without Docker: ",[283,682,683],{},"go build -o bin\u002Fagentfeedback .\u002Fcmd\u002Fagentfeedback && API_KEY=dev bin\u002Fagentfeedback serve",". It listens on ",[283,686,527],{}," with the database in the data directory, ",[283,689,690],{},"${XDG_DATA_HOME:-~\u002F.local\u002Fshare}\u002Fagentfeedback\u002Fagentfeedback.db",[276,692,211],{"id":693},"local-mode-no-server",[381,695,697],{"className":383,"code":696,"language":385,"meta":386,"style":386},"agentfeedback doctor                             # mode: local and the database path\nagentfeedback submit friction --summary \"local smoke test\"\nagentfeedback list\n",[283,698,699,710,726],{"__ignoreMap":386},[390,700,701,704,707],{"class":392,"line":393},[390,702,703],{"class":442},"agentfeedback",[390,705,706],{"class":400}," doctor",[390,708,709],{"class":466},"                             # mode: local and the database path\n",[390,711,712,714,717,720,723],{"class":392,"line":404},[390,713,703],{"class":442},[390,715,716],{"class":400}," submit",[390,718,719],{"class":400}," friction",[390,721,722],{"class":396}," --summary",[390,724,725],{"class":400}," \"local smoke test\"\n",[390,727,728,730],{"class":392,"line":470},[390,729,703],{"class":442},[390,731,732],{"class":400}," list\n",[201,734,735,736,739,740,743,744,746,747,750,751,754,755,758,759,762,763,765,766,306,768,357,771,774,775,778,779,782,783,785],{},"With no ",[283,737,738],{},"url"," in the config file and no ",[283,741,742],{},"AGENT_FEEDBACK_URL",", the base\nsubmission and processing commands work in-process against\n",[283,745,690],{},", with no\nserver running; ",[283,748,749],{},"agentfeedback doctor"," prints ",[283,752,753],{},"mode: local"," and the database\npath. ",[283,756,757],{},"--local"," forces local mode and ",[283,760,761],{},"--server URL"," targets a server for one\ninvocation; a configured ",[283,764,738],{}," is never ignored without ",[283,767,757],{},[283,769,770],{},"backup \u003Cdest.db>",[283,772,773],{},"import"," default to the same file, and ",[283,776,777],{},"serve"," started later on\nthe same machine serves the same database, so the machine keeps one queue.\nSeveral processes may use the database at once (SQLite in WAL mode: commands,\nhooks, ",[283,780,781],{},"ui",", a local ",[283,784,777],{},"); keep the data directory on a local filesystem,\nnever on a network share, where SQLite's locking does not hold.",[201,787,788,789,792,793,796,797,800,801,804,805,808,809,812,813,816,817,820,821,824,825,828,829,832,833,836,837,840,841,843],{},"A local write that fails (the database busy past its 5 s timeout, a full\ndisk) is spooled like a failed send to a server: outcome ",[283,790,791],{},"spooled",", exit 0,\nand the next client command that runs the start-up pass (every\nlocal-mode command that opens the database but ",[283,794,795],{},"doctor",", ",[283,798,799],{},"sessions"," and\n",[283,802,803],{},"ingest",") delivers it, before its own work, as does ",[283,806,807],{},"agentfeedback flush",". When the spool cannot be written either, the body\nis echoed on stderr and the command exits 1. ",[283,810,811],{},"submit"," spools the same way,\nwith one stderr line naming the cause, when the local database does not open\nbecause it is busy or locked past the busy timeout (reason\n",[283,814,815],{},"local_database_busy",") or was written by a newer binary (reason\n",[283,818,819],{},"local_database_newer",": upgrade this binary and the next command delivers\nit). Any other open failure (a database without the AgentFeedback stamp, an\nunwritable data directory) is an ",[283,822,823],{},"error"," outcome with the body echoed on\nstderr, and the read commands report every open failure. Every spool entry records the\ndestination it was written for, the server URL or ",[283,826,827],{},"local",": ",[283,830,831],{},"flush"," sends an\nentry only to that destination and leaves the others in place, naming each\nwith the command that sends it (",[283,834,835],{},"flush --server URL",", or ",[283,838,839],{},"flush --local","), so\na ",[283,842,738],{}," that changes never carries pending reports to the new server and\nlocal reports never reach a server.",[845,846,848],"h3",{"id":847},"local-mode-or-a-server-what-differs","Local mode or a server: what differs",[201,850,851,852,357,854,857,858,836,861,864],{},"The base client commands, ",[283,853,364],{},[283,855,856],{},"install"," work in both modes; the skill,\nthe rule, the hooks and the triage skill they wire are the same, and the\nstdio MCP entry differs only in its argument (",[283,859,860],{},"mcp",[283,862,863],{},"mcp --server \u003CURL>","). What differs, with the section that holds the detail:",[866,867,868,889,904,919,925,938,945],"ul",{},[869,870,871,875,876,878,879,881,882,885,886,888],"li",{},[872,873,874],"strong",{},"Where the reports are",": the data-directory database, or the server.\nWhen ",[283,877,364],{}," or ",[283,880,348],{}," writes a new server, they name the local\nreports and the ",[283,883,884],{},"migrate --local --to \u003CURL> --to-key-from-stdin"," command\nthat copies them (",[208,887,254],{"href":253},");\nnothing copies reports back from a server on its own.",[869,890,891,421,894,896,897,903],{},[872,892,893],{},"Session state",[283,895,799],{},") stays in the data-directory database in\nboth modes. ",[208,898,900],{"href":899},"\u002Fdocs\u002Freference\u002Fsessions#push",[283,901,902],{},"sessions push",", run manually or by the\nautomatic sweep, sends eligible, scrubbed transcripts to a server whose\norganisation enables processing; local digest and push watermarks remain separate.",[869,905,906,909,910,913,914,918],{},[872,907,908],{},"The file inbox"," is delivered by local-mode commands only, and with a\nserver by ",[283,911,912],{},"agentfeedback ingest"," alone (",[208,915,917],{"href":916},"#file-inbox","File inbox",").",[869,920,921,924],{},[872,922,923],{},"Delivering the spool",": with a server the end-of-turn hook sends due\nsubmissions; in local mode the hooks send nothing and the next command\nthat runs the start-up pass delivers them (see the spool paragraphs\nabove).",[869,926,927,930,931,933,934,918],{},[872,928,929],{},"MCP",": both modes serve the same tools, the session tools included; with\na server ",[283,932,860],{}," relays the server's tools. No MCP call is spooled in either\nmode (",[208,935,937],{"href":936},"#mcp-and-discovery","MCP and discovery",[869,939,940,942,943,918],{},[872,941,226],{}," require the selected backend to advertise the\noperation; local mode and the bundled self-hosted server do not implement\nissue aggregation (",[208,944,226],{"href":225},[869,946,947,950,951,796,954,957],{},[872,948,949],{},"No binary",": a harness or chat app that cannot run the binary files to\na server (its ",[283,952,953],{},"\u002Fmcp",[283,955,956],{},"\u002Fskill?format=prompt"," or the HTTP recipes), or\ndrops a file into the inbox, which the binary delivers later on that\nmachine.",[845,959,961],{"id":960},"data-directory","Data directory",[201,963,964,967],{},[283,965,966],{},"${XDG_DATA_HOME:-~\u002F.local\u002Fshare}\u002Fagentfeedback\u002F"," holds everything that is\nthe only copy of a report:",[969,970,971,984],"table",{},[972,973,974],"thead",{},[975,976,977,981],"tr",{},[978,979,980],"th",{},"Path",[978,982,983],{},"What",[985,986,987,1028,1042,1052,1066,1079],"tbody",{},[975,988,989,1003],{},[990,991,992,995,996,796,999,1002],"td",{},[283,993,994],{},"agentfeedback.db"," (+ ",[283,997,998],{},"-wal",[283,1000,1001],{},"-shm",")",[990,1004,1005,1006,796,1008,357,1011,1013,1014,1017,1018,357,1021,1024,1025,1002],{},"the local-mode database, also the default of ",[283,1007,777],{},[283,1009,1010],{},"backup",[283,1012,773],{},"; in both modes it also holds the session watermarks of ",[283,1015,1016],{},"agentfeedback sessions"," (tables ",[283,1019,1020],{},"sessions_seen",[283,1022,1023],{},"triage_state",", see ",[208,1026,1027],{"href":176},"sessions.md",[975,1029,1030,1035],{},[990,1031,1032],{},[283,1033,1034],{},"spool\u002F",[990,1036,1037,1038,1041],{},"submissions waiting to be delivered, one ",[283,1039,1040],{},"af1-*.json"," file each with its destination",[975,1043,1044,1049],{},[990,1045,1046],{},[283,1047,1048],{},"rejected\u002F",[990,1050,1051],{},"submissions the destination refused for good (kept 30 days)",[975,1053,1054,1059],{},[990,1055,1056],{},[283,1057,1058],{},"inbox\u002F",[990,1060,1061,1062,1065],{},"envelope files written by an agent that cannot run the binary, one ",[283,1063,1064],{},"*.json"," each (see below)",[975,1067,1068,1073],{},[990,1069,1070],{},[283,1071,1072],{},"inbox\u002Fdone\u002F",[990,1074,1075,1076],{},"inbox files filed, renamed ",[283,1077,1078],{},"\u003Cid>-\u003Cname>",[975,1080,1081,1086],{},[990,1082,1083],{},[283,1084,1085],{},"inbox\u002Frejected\u002F",[990,1087,1088,1089,1092],{},"inbox files refused, each with a ",[283,1090,1091],{},"\u003Cname>.reason"," beside it",[201,1094,1095,1096,1099,1100,1102,1103,357,1105,1107,1108,1110,1111,1114,1115,1118,1119,1122,1123,1126,1127,1130,1131,1134,1135,1138,1139,1141],{},"The client creates the directory ",[283,1097,1098],{},"0700"," and the database files ",[283,1101,344],{},"\n(SQLite gives ",[283,1104,998],{},[283,1106,1001],{}," the database file's mode). A directory or\nfile that already exists keeps its mode: ",[283,1109,749],{}," reports every\npath other users can reach with the ",[283,1112,1113],{},"chmod"," to run, and changes nothing. The\ncache directory, ",[283,1116,1117],{},"${XDG_CACHE_HOME:-~\u002F.cache}\u002Fagentfeedback\u002F",", holds nothing\nthat is the only copy of a report: the client log (",[283,1120,1121],{},"log\u002Fclient.jsonl","), the\nhooks' per-session counters (",[283,1124,1125],{},"sessions\u002F",") and last-run records (",[283,1128,1129],{},"hooks\u002F","),\nthe ",[283,1132,1133],{},"filed\u002F"," markers and ",[283,1136,1137],{},"digest\u002F"," output; a spool left there by a\nversion before 4.0 is reported by ",[283,1140,795],{}," and is not read any more.",[201,1143,1144,1145,796,1148,357,1151,1154,1155,1158,1159,357,1162,1165,1166,1169,1170,1173,1174,1176],{},"The same layout applies on every operating system, macOS and Windows\nincluded: with ",[283,1146,1147],{},"XDG_DATA_HOME",[283,1149,1150],{},"XDG_CONFIG_HOME",[283,1152,1153],{},"XDG_CACHE_HOME"," unset\n(or not absolute), the directories are ",[283,1156,1157],{},".local\u002Fshare\u002Fagentfeedback",",\n",[283,1160,1161],{},".config\u002Fagentfeedback",[283,1163,1164],{},".cache\u002Fagentfeedback"," under the home directory.\nOn Windows that is ",[283,1167,1168],{},"%USERPROFILE%\\.local\\share\\agentfeedback\\agentfeedback.db","\nfor the database and ",[283,1171,1172],{},"%USERPROFILE%\\.config\\agentfeedback\\config.toml"," for\nthe config file; ",[283,1175,749],{}," prints both. Owner-only modes are not\nset or checked on Windows.",[845,1178,917],{"id":1179},"file-inbox",[201,1181,1182,1183,1186,1187,1190,1191,1193,1194,1158,1196,796,1198,1200,1201,796,1203,1205,1206,1208,1209,1212,1213,1215],{},"An agent that cannot run the binary writes one envelope, a JSON object as\n",[283,1184,1185],{},"POST \u002Fapi\u002Fv1\u002Fsubmissions"," takes it, into ",[283,1188,1189],{},"inbox\u002F\u003Cname>.json"," under the data\ndirectory; the recipe is in the skill. Every local-mode command that\nopens the database (",[283,1192,811],{},", the read and processing commands, ",[283,1195,781],{},[283,1197,860],{},[283,1199,364],{},"'s check; not ",[283,1202,795],{},[283,1204,799],{}," or the hooks) delivers the inbox\nat start, after the due spool entries, and prints nothing about it. In remote mode only\n",[283,1207,912],{}," delivers it, on demand and with the counts\n(",[283,1210,1211],{},"--json"," for one JSON object); ",[283,1214,803],{}," works in local mode too. Nothing\nwatches the directory.",[866,1217,1218,1241,1255,1275],{},[869,1219,1220,1221,1224,1225,1228,1229,1232,1233,1236,1237,1240],{},"Each row gets ",[283,1222,1223],{},"context.origin"," ",[283,1226,1227],{},"inbox"," (a ",[283,1230,1231],{},"context"," that is not an object\nis kept in the payload as ",[283,1234,1235],{},"context_raw","). A file without a ",[283,1238,1239],{},"key"," gets one\nderived from its name and bytes, so the same file delivered twice is one\nrow.",[869,1242,1243,1244,1247,1248,1251,1252,1254],{},"Filed (created or already stored): moved to ",[283,1245,1246],{},"inbox\u002Fdone\u002F\u003Cid>-\u003Cname>",".\nRefused (not one JSON object, over the 10 MiB create limit, refused by the\nserver, or a key that names another report): moved to\n",[283,1249,1250],{},"inbox\u002Frejected\u002F\u003Cname>"," (the time added when that name is taken), with\n",[283,1253,1091],{}," holding the outcome line and the server's error body. Not\ndelivered now (database busy, server unreachable, wrong key or URL): left\nin place, and the pass stops there. A file that is not one JSON object and\nwas written in the last minute is left too, since a writer may still be\nwriting it.",[869,1256,1257,1258,1260,1261,1264,1265,1267,1268,1271,1272,1274],{},"Only regular files directly in ",[283,1259,1058],{}," whose names end in ",[283,1262,1263],{},".json"," and do\nnot start with ",[283,1266,318],{}," are read, so a writer writes ",[283,1269,1270],{},".\u003Cname>.tmp"," and renames\nit. A symlink or any other entry is never read: ",[283,1273,803],{}," names it on\nstderr, the client log records it, and it stays until removed. A file over\nthe create limit is refused from its size, unread. Every file operation\nstays inside the inbox directory, and a file replaced under the same name\nwhile it was being delivered is left for the next pass, not moved.",[869,1276,1277,1278,1224,1280,1282,1283,800,1286,1224,1288,1290,1291,1294,1295,306,1297,1299],{},"The writer creates ",[283,1279,1058],{},[283,1281,1098],{},"; the client creates ",[283,1284,1285],{},"done\u002F",[283,1287,1048],{},[283,1289,1098],{}," and writes ",[283,1292,1293],{},".reason"," files ",[283,1296,344],{},[283,1298,795],{}," reports\nlooser modes, as for the rest of the data directory. The inbox, like the\ndatabase, belongs to the one OS user who owns the data directory.",[845,1301,1303],{"id":1302},"web-ui","Web UI",[381,1305,1307],{"className":383,"code":1306,"language":385,"meta":386,"style":386},"agentfeedback ui                                 # prints http:\u002F\u002F127.0.0.1:\u003Cport>\u002F\u003Ctoken>\u002F; Ctrl-C stops it\nagentfeedback ui --addr 127.0.0.1:8095           # a fixed port\nagentfeedback ui --server https:\u002F\u002Ffeedback.example.com   # remote queue and stats with the configured key; sessions stay local\n",[283,1308,1309,1319,1334],{"__ignoreMap":386},[390,1310,1311,1313,1316],{"class":392,"line":393},[390,1312,703],{"class":442},[390,1314,1315],{"class":400}," ui",[390,1317,1318],{"class":466},"                                 # prints http:\u002F\u002F127.0.0.1:\u003Cport>\u002F\u003Ctoken>\u002F; Ctrl-C stops it\n",[390,1320,1321,1323,1325,1328,1331],{"class":392,"line":404},[390,1322,703],{"class":442},[390,1324,1315],{"class":400},[390,1326,1327],{"class":396}," --addr",[390,1329,1330],{"class":400}," 127.0.0.1:8095",[390,1332,1333],{"class":466},"           # a fixed port\n",[390,1335,1336,1338,1340,1343,1346],{"class":392,"line":470},[390,1337,703],{"class":442},[390,1339,1315],{"class":400},[390,1341,1342],{"class":396}," --server",[390,1344,1345],{"class":400}," https:\u002F\u002Ffeedback.example.com",[390,1347,1348],{"class":466},"   # remote queue and stats with the configured key; sessions stay local\n",[201,1350,1351,1353,1354,1357,1358,1360],{},[283,1352,781],{}," serves read-only queue, record, stats and session-status pages until\nCtrl-C. The queue, records and stats come from the local database or, with\n",[283,1355,1356],{},"--server"," or a configured ",[283,1359,738],{},", from that server; sessions always come\nfrom this machine's harness stores and data-directory database. In local\nmode it opens the database as every client command does, which migrates it\nand delivers the due spool and inbox entries at start; the pages themselves\nwrite nothing. The pages:",[866,1362,1363,1380,1386,1392],{},[869,1364,1365,1368,1369,1371,1372,1375,1376,1379],{},[872,1366,1367],{},"Queue:"," 50 rows a page, newest first, with filters for project,\ncategory, harness, model, origin (",[283,1370,1223],{},", matched exactly as\ntyped), kind, state (open, processed, all) and since (1 h, 24 h, 7 d,\n30 d, all). ",[283,1373,1374],{},"install-check"," rows are left out unless a kind is given, as\n",[283,1377,1378],{},"list"," does.",[869,1381,1382,1385],{},[872,1383,1384],{},"Record:"," every field, the context and the payload, and the warnings\nthe stored record still carries, recomputed by decoding it again (the\nwarnings returned when it was created are not stored).",[869,1387,1388,1391],{},[872,1389,1390],{},"Stats:"," totals, groups by kind, project, harness, category and\norigin, and the recurring content hashes, under the same filters.",[869,1393,1394,1397],{},[872,1395,1396],{},"Sessions:"," every implemented harness reader's store state, location,\nproblems and session counts by state, plus the saved selection. This page\nreads local harness stores and the data-directory database in both modes,\nwithout contacting a server. Normal database initialization and migrations\nmay run; viewing status does not change session state or selection, and\nshows no digest content.",[201,1399,1400,1403,1404,1407,1408,1411,1412,796,1415,1418,1419,318],{},[283,1401,1402],{},"--addr"," takes a loopback IP or ",[283,1405,1406],{},"localhost"," with a port (",[283,1409,1410],{},"0",", the default,\npicks one) and refuses anything else. The token in the URL is new at every\nlaunch: open the printed URL, not a bookmark. Writes (",[283,1413,1414],{},"done",[283,1416,1417],{},"undo",") are\nnot available from the page. The threat model is in\n",[208,1420,1422],{"href":1421},"\u002Fdocs\u002Freference\u002Fsecurity#access-and-network","security.md",[276,1424,226],{"id":1425},"canonical-issues",[381,1427,1429],{"className":383,"code":1428,"language":385,"meta":386,"style":386},"agentfeedback issues list --server https:\u002F\u002Fapi.agentfeedback.dev --json\nagentfeedback issues rank --rollup target --limit 20 --json\nagentfeedback issues detail 11111111-1111-4111-8111-111111111111 --json\nagentfeedback issues source-reports 11111111-1111-4111-8111-111111111111 --json\nagentfeedback issues prompt 11111111-1111-4111-8111-111111111111\n",[283,1430,1431,1449,1472,1486,1499],{"__ignoreMap":386},[390,1432,1433,1435,1438,1441,1443,1446],{"class":392,"line":393},[390,1434,703],{"class":442},[390,1436,1437],{"class":400}," issues",[390,1439,1440],{"class":400}," list",[390,1442,1342],{"class":396},[390,1444,1445],{"class":400}," https:\u002F\u002Fapi.agentfeedback.dev",[390,1447,1448],{"class":396}," --json\n",[390,1450,1451,1453,1455,1458,1461,1464,1467,1470],{"class":392,"line":404},[390,1452,703],{"class":442},[390,1454,1437],{"class":400},[390,1456,1457],{"class":400}," rank",[390,1459,1460],{"class":396}," --rollup",[390,1462,1463],{"class":400}," target",[390,1465,1466],{"class":396}," --limit",[390,1468,1469],{"class":396}," 20",[390,1471,1448],{"class":396},[390,1473,1474,1476,1478,1481,1484],{"class":392,"line":470},[390,1475,703],{"class":442},[390,1477,1437],{"class":400},[390,1479,1480],{"class":400}," detail",[390,1482,1483],{"class":400}," 11111111-1111-4111-8111-111111111111",[390,1485,1448],{"class":396},[390,1487,1488,1490,1492,1495,1497],{"class":392,"line":491},[390,1489,703],{"class":442},[390,1491,1437],{"class":400},[390,1493,1494],{"class":400}," source-reports",[390,1496,1483],{"class":400},[390,1498,1448],{"class":396},[390,1500,1501,1503,1505,1508],{"class":392,"line":620},[390,1502,703],{"class":442},[390,1504,1437],{"class":400},[390,1506,1507],{"class":400}," prompt",[390,1509,1510],{"class":400}," 11111111-1111-4111-8111-111111111111\n",[201,1512,1513,1514,1516,1517,1519,1520,1524],{},"Use the same configured server and API key as submission commands.\n",[283,1515,761],{}," selects that server for one invocation; ",[283,1518,757],{}," explicitly\nselects the local database. Do not choose a different backend when an\noperation is unsupported. The first example requires the user's Cloud\nconfiguration and key; the following examples use the configured destination.\nIssue IDs are UUIDs, not submission integer IDs or autofix candidate IDs.\nThe server owns grouping, ranking and source eligibility; the CLI does not\naggregate local reports. See ",[208,1521,1523],{"href":1522},"\u002Fdocs\u002Freference\u002Fapi#hosted-issue-operations","the HTTP route and capability contract","\nfor backend support, authentication and operation discovery.",[201,1526,1527,1529,1530,1533,1534,1537],{},[283,1528,1211],{}," preserves the complete server response and raw JSON scalar values,\nincluding source-report numbers; do not round-trip them through a\nfloating-point parser. Human reads format the response as JSON and replace\nterminal control characters. ",[283,1531,1532],{},"prompt"," alone writes only the handoff text\nto stdout; controls are replaced on a terminal, while a file or pipe keeps\nthe exact prompt. ",[283,1535,1536],{},"prompt --json"," retains the full body, including\nissue\u002Fversion, selection, source references and omitted-source count.\nDiagnostics use stderr. Reading a prompt neither executes it nor\nauthorizes its instructions.",[845,1539,1541],{"id":1540},"read-filters-and-explicit-paging","Read filters and explicit paging",[201,1543,1544],{},"All five reads accept these filters. Multi-value flags accept comma-separated\nvalues or repeated flags, encoded as one query parameter; each filter allows\nat most 50 distinct values of at most 256 UTF-8 bytes each, without surrounding\nwhitespace. Do not send equivalent duplicates.",[969,1546,1547,1557],{},[972,1548,1549],{},[975,1550,1551,1554],{},[978,1552,1553],{},"CLI flag",[978,1555,1556],{},"Hosted query parameter \u002F values",[985,1558,1559,1602,1615,1647,1668,1695,1719,1738],{},[975,1560,1561,1581],{},[990,1562,1563,796,1566,796,1569,796,1572,796,1575,796,1578],{},[283,1564,1565],{},"--repo",[283,1567,1568],{},"--project",[283,1570,1571],{},"--product",[283,1573,1574],{},"--team",[283,1576,1577],{},"--machine",[283,1579,1580],{},"--harness",[990,1582,1583,796,1586,796,1589,796,1592,796,1595,796,1598,1601],{},[283,1584,1585],{},"repo",[283,1587,1588],{},"project",[283,1590,1591],{},"product",[283,1593,1594],{},"team",[283,1596,1597],{},"machine",[283,1599,1600],{},"harness","; working context, not inferred target blame",[975,1603,1604,1609],{},[990,1605,1606],{},[283,1607,1608],{},"--target-id",[990,1610,1611,1614],{},[283,1612,1613],{},"target_id","; target UUIDs",[975,1616,1617,1622],{},[990,1618,1619],{},[283,1620,1621],{},"--target-kind",[990,1623,1624,662,1627,796,1629,796,1632,796,1635,796,1638,796,1641,796,1644],{},[283,1625,1626],{},"target_kind",[283,1628,1585],{},[283,1630,1631],{},"package",[283,1633,1634],{},"harness_component",[283,1636,1637],{},"external_skill",[283,1639,1640],{},"machine_runtime",[283,1642,1643],{},"upstream_service",[283,1645,1646],{},"unknown",[975,1648,1649,1654],{},[990,1650,1651],{},[283,1652,1653],{},"--assessment",[990,1655,1656,662,1659,796,1662,796,1665],{},[283,1657,1658],{},"assessment",[283,1660,1661],{},"reported",[283,1663,1664],{},"corroborated",[283,1666,1667],{},"invalid",[975,1669,1670,1675],{},[990,1671,1672],{},[283,1673,1674],{},"--actionability",[990,1676,1677,662,1680,796,1683,796,1686,796,1689,796,1692],{},[283,1678,1679],{},"actionability",[283,1681,1682],{},"source_patch",[283,1684,1685],{},"local_configuration",[283,1687,1688],{},"upstream_update",[283,1690,1691],{},"investigation",[283,1693,1694],{},"no_known_remedy",[975,1696,1697,1702],{},[990,1698,1699],{},[283,1700,1701],{},"--resolution",[990,1703,1704,662,1707,796,1710,796,1713,796,1716],{},[283,1705,1706],{},"resolution",[283,1708,1709],{},"open",[283,1711,1712],{},"mitigated",[283,1714,1715],{},"awaiting_upstream",[283,1717,1718],{},"verified_resolved",[975,1720,1721,1729],{},[990,1722,1723,796,1726],{},[283,1724,1725],{},"--environment",[283,1727,1728],{},"--version",[990,1730,1731,796,1734,1737],{},[283,1732,1733],{},"environment",[283,1735,1736],{},"version","; environment and tested-version scope, not the issue concurrency version",[975,1739,1740,1745],{},[990,1741,1742],{},[283,1743,1744],{},"--external-tooling-environment true|false",[990,1746,1747,1750],{},[283,1748,1749],{},"external_tooling_environment","; one explicit boolean value, not a bare switch",[201,1752,1753,357,1756,1759,1760,1763,1764,1767,1768,1771],{},[283,1754,1755],{},"--from",[283,1757,1758],{},"--to"," must be supplied together: RFC 3339 UTC (",[283,1761,1762],{},"Z"," or\n",[283,1765,1766],{},"+00:00","), at most six fractional digits, half-open interval ",[283,1769,1770],{},"[from, to)",".\nBounds must be ordered, nonfuture and within the organization's retained\nhistory. Without bounds the server selects up to the preceding 30 UTC days\n(shorter when retention is shorter) and echoes the exact effective window.\nUnknown, duplicate, malformed or contradictory query parameters fail rather\nthan being silently ignored.",[201,1773,1774,796,1776,357,1779,1782,1783,1786,1787,306,1790,1793,1794,1797,1798,1800,1801,1793,1803,1806,1807,1810,1811,1814],{},[283,1775,1378],{},[283,1777,1778],{},"rank",[283,1780,1781],{},"source-reports"," accept ",[283,1784,1785],{},"--limit 1..100"," (default 20)\nand opaque ",[283,1788,1789],{},"--cursor",[283,1791,1792],{},"detail"," accepts ",[283,1795,1796],{},"--limit"," but no cursor; ",[283,1799,1532],{},"\naccepts neither. Only ",[283,1802,1778],{},[283,1804,1805],{},"--rollup target",", which returns\npaginated ",[283,1808,1809],{},"targets"," and an empty ",[283,1812,1813],{},"issues"," array: a component roll-up is not\na merged issue. List order is stable UUID order; rank orders occurrences\ndescending, then UUID ascending. Occurrence, distinct report, working-project\nand machine counts are different quantities; retries are not independent\ncorroboration.",[201,1816,1817,1818,1821,1822,1825],{},"List and rank default to Needs fixing: assessments ",[283,1819,1820],{},"reported,corroborated","\nand resolutions ",[283,1823,1824],{},"open,mitigated,awaiting_upstream",". Explicit filters can\ninspect other states. Detail, source reports and prompt remain inspection\nreads, including invalid, resolved or retired issues, subject to retained\nsource eligibility. Detail assertions describe the complete retained eligible\nevidence, independently of the window\u002Fcontext selection for counts.",[201,1827,1828,1829,1832,1833,1836,1837,357,1840,1843],{},"For a complete traversal, save each raw response, keep the same operation,\nissue UUID, filters, roll-up and page size, and pass ",[283,1830,1831],{},"pagination.next_cursor","\nto the next invocation while ",[283,1834,1835],{},"pagination.has_more"," is true. Copy the first response's\n",[283,1838,1839],{},"selection.from",[283,1841,1842],{},"selection.to"," into every subsequent request; do not\nrecompute a moving \"last 30 days\" window:",[381,1845,1847],{"className":383,"code":1846,"language":385,"meta":386,"style":386},"agentfeedback issues list --limit 20 --json\n# Replace the placeholders with the first response's exact selection and cursor.\nagentfeedback issues list --limit 20 --from '\u003Cselection.from>' \\\n  --to '\u003Cselection.to>' --cursor '\u003Cpagination.next_cursor>' --json\n",[283,1848,1849,1863,1868,1888],{"__ignoreMap":386},[390,1850,1851,1853,1855,1857,1859,1861],{"class":392,"line":393},[390,1852,703],{"class":442},[390,1854,1437],{"class":400},[390,1856,1440],{"class":400},[390,1858,1466],{"class":396},[390,1860,1469],{"class":396},[390,1862,1448],{"class":396},[390,1864,1865],{"class":392,"line":404},[390,1866,1867],{"class":466},"# Replace the placeholders with the first response's exact selection and cursor.\n",[390,1869,1870,1872,1874,1876,1878,1880,1883,1886],{"class":392,"line":470},[390,1871,703],{"class":442},[390,1873,1437],{"class":400},[390,1875,1440],{"class":400},[390,1877,1466],{"class":396},[390,1879,1469],{"class":396},[390,1881,1882],{"class":396}," --from",[390,1884,1885],{"class":400}," '\u003Cselection.from>'",[390,1887,607],{"class":396},[390,1889,1890,1893,1896,1899,1902],{"class":392,"line":491},[390,1891,1892],{"class":396},"  --to",[390,1894,1895],{"class":400}," '\u003Cselection.to>'",[390,1897,1898],{"class":396}," --cursor",[390,1900,1901],{"class":400}," '\u003Cpagination.next_cursor>'",[390,1903,1448],{"class":396},[201,1905,1906],{},"A cursor binds the organization, operation, issue where applicable, selection,\nordering and snapshot anchor. Never reuse it for a different query. Preserve\nthe echoed window and snapshot\u002Fas-of metadata with the collected pages;\nranking is not a promise counts cannot change between reads. There is no\nautomatic all-pages mode.",[845,1908,1910],{"id":1909},"reasoned-mutations","Reasoned mutations",[381,1912,1914],{"className":383,"code":1913,"language":385,"meta":386,"style":386},"agentfeedback issues correct 11111111-1111-4111-8111-111111111111 --body-file correct.json --json\nagentfeedback issues merge 11111111-1111-4111-8111-111111111111 --body-file merge.json --json\nagentfeedback issues split 11111111-1111-4111-8111-111111111111 --body-file split.json --json\nagentfeedback issues record-outcome 11111111-1111-4111-8111-111111111111 --body-file outcome.json --json\nagentfeedback issues recheck 11111111-1111-4111-8111-111111111111 --body-file recheck.json --json\n",[283,1915,1916,1935,1953,1971,1989],{"__ignoreMap":386},[390,1917,1918,1920,1922,1925,1927,1930,1933],{"class":392,"line":393},[390,1919,703],{"class":442},[390,1921,1437],{"class":400},[390,1923,1924],{"class":400}," correct",[390,1926,1483],{"class":400},[390,1928,1929],{"class":396}," --body-file",[390,1931,1932],{"class":400}," correct.json",[390,1934,1448],{"class":396},[390,1936,1937,1939,1941,1944,1946,1948,1951],{"class":392,"line":404},[390,1938,703],{"class":442},[390,1940,1437],{"class":400},[390,1942,1943],{"class":400}," merge",[390,1945,1483],{"class":400},[390,1947,1929],{"class":396},[390,1949,1950],{"class":400}," merge.json",[390,1952,1448],{"class":396},[390,1954,1955,1957,1959,1962,1964,1966,1969],{"class":392,"line":470},[390,1956,703],{"class":442},[390,1958,1437],{"class":400},[390,1960,1961],{"class":400}," split",[390,1963,1483],{"class":400},[390,1965,1929],{"class":396},[390,1967,1968],{"class":400}," split.json",[390,1970,1448],{"class":396},[390,1972,1973,1975,1977,1980,1982,1984,1987],{"class":392,"line":491},[390,1974,703],{"class":442},[390,1976,1437],{"class":400},[390,1978,1979],{"class":400}," record-outcome",[390,1981,1483],{"class":400},[390,1983,1929],{"class":396},[390,1985,1986],{"class":400}," outcome.json",[390,1988,1448],{"class":396},[390,1990,1991,1993,1995,1998,2000,2002,2005],{"class":392,"line":620},[390,1992,703],{"class":442},[390,1994,1437],{"class":400},[390,1996,1997],{"class":400}," recheck",[390,1999,1483],{"class":400},[390,2001,1929],{"class":396},[390,2003,2004],{"class":400}," recheck.json",[390,2006,1448],{"class":396},[201,2008,2009,2010,878,2013,2016],{},"Every mutation requires ",[283,2011,2012],{},"--body-file PATH",[283,2014,2015],{},"--body-file -"," to read one\nexplicit JSON object from stdin, at most 1 MiB. The CLI adds no body fields,\nreasons, evidence or versions and does not translate a server conflict into\na retry. The server validates the operation's schema. Recheck has its own\ncapability gate and is pending on the hosted service; no recheck body schema\nis assumed here. A supporting backend's served OpenAPI is authoritative.",[201,2018,2019,2020,2023,2024,2027,2028,2031],{},"Reads require ",[283,2021,2022],{},"read"," authority; mutations require ",[283,2025,2026],{},"process",". Neither grants\nprovider credentials, repository connection access or autofix authority.\nAll nested source, evidence, target and issue IDs must belong to the same\norganization. Unknown and foreign IDs are indistinguishable ",[283,2029,2030],{},"404 not_found",".\nAn advertised operation returning 404 remains not found, not unsupported.",[201,2033,2034,2035,2038,2039,2042,2043,2046,2047,2050],{},"Read current detail and every other affected existing group first. Supply\n",[283,2036,2037],{},"expected_versions"," for ",[872,2040,2041],{},"all"," affected UUIDs, including merge destination,\nsources and redirects that change, and any group whose membership changes.\nMissing versions fail ",[283,2044,2045],{},"428 precondition_required","; stale versions or a changed\naffected set fail ",[283,2048,2049],{},"409 conflict"," atomically. Re-read and reconsider the entire\nchange; never substitute current versions and auto-retry. Mutating a retired\nUUID conflicts rather than silently following its redirect.",[201,2052,2053,2054,2057,2058,318],{},"The following file contents illustrate the hosted wire schemas, not observed\nchanges. Replace IDs, versions, source membership and evidence with the actual\nauthorized detail. They assume only the named existing groups are affected.\nCorrection changes derived claims, never immutable source content; an\n",[283,2055,2056],{},"assertions"," array replaces the whole set, so retain every intended assertion\nand its ",[283,2059,2060],{},"support_submission_id",[201,2062,2063,2066],{},[283,2064,2065],{},"correct.json",":",[381,2068,2072],{"className":2069,"code":2070,"language":2071,"meta":386,"style":386},"language-json shiki shiki-themes github-light github-light github-dark","{\n  \"expected_versions\": {\"11111111-1111-4111-8111-111111111111\": 7},\n  \"reason\": \"Source 101 identifies a harness component, not the working repository.\",\n  \"target\": {\"kind\": \"harness_component\", \"identity\": \"example-harness\u002Fsession-runner\"},\n  \"actionability\": \"investigation\",\n  \"assertions\": [{\n    \"submission_id\": 101,\n    \"support_submission_id\": null,\n    \"kind\": \"target\",\n    \"statement\": \"The failure occurs in the harness session runner.\",\n    \"provenance\": \"Source report 101, recorded failing command and stack trace.\",\n    \"confidence\": \"supported\"\n  }]\n}\n","json",[283,2073,2074,2079,2098,2110,2137,2149,2157,2170,2183,2196,2209,2222,2233,2239],{"__ignoreMap":386},[390,2075,2076],{"class":392,"line":393},[390,2077,2078],{"class":420},"{\n",[390,2080,2081,2084,2087,2090,2092,2095],{"class":392,"line":404},[390,2082,2083],{"class":396},"  \"expected_versions\"",[390,2085,2086],{"class":420},": {",[390,2088,2089],{"class":396},"\"11111111-1111-4111-8111-111111111111\"",[390,2091,828],{"class":420},[390,2093,2094],{"class":396},"7",[390,2096,2097],{"class":420},"},\n",[390,2099,2100,2103,2105,2108],{"class":392,"line":470},[390,2101,2102],{"class":396},"  \"reason\"",[390,2104,828],{"class":420},[390,2106,2107],{"class":400},"\"Source 101 identifies a harness component, not the working repository.\"",[390,2109,1158],{"class":420},[390,2111,2112,2115,2117,2120,2122,2125,2127,2130,2132,2135],{"class":392,"line":491},[390,2113,2114],{"class":396},"  \"target\"",[390,2116,2086],{"class":420},[390,2118,2119],{"class":396},"\"kind\"",[390,2121,828],{"class":420},[390,2123,2124],{"class":400},"\"harness_component\"",[390,2126,796],{"class":420},[390,2128,2129],{"class":396},"\"identity\"",[390,2131,828],{"class":420},[390,2133,2134],{"class":400},"\"example-harness\u002Fsession-runner\"",[390,2136,2097],{"class":420},[390,2138,2139,2142,2144,2147],{"class":392,"line":620},[390,2140,2141],{"class":396},"  \"actionability\"",[390,2143,828],{"class":420},[390,2145,2146],{"class":400},"\"investigation\"",[390,2148,1158],{"class":420},[390,2150,2151,2154],{"class":392,"line":632},[390,2152,2153],{"class":396},"  \"assertions\"",[390,2155,2156],{"class":420},": [{\n",[390,2158,2160,2163,2165,2168],{"class":392,"line":2159},7,[390,2161,2162],{"class":396},"    \"submission_id\"",[390,2164,828],{"class":420},[390,2166,2167],{"class":396},"101",[390,2169,1158],{"class":420},[390,2171,2173,2176,2178,2181],{"class":392,"line":2172},8,[390,2174,2175],{"class":396},"    \"support_submission_id\"",[390,2177,828],{"class":420},[390,2179,2180],{"class":396},"null",[390,2182,1158],{"class":420},[390,2184,2186,2189,2191,2194],{"class":392,"line":2185},9,[390,2187,2188],{"class":396},"    \"kind\"",[390,2190,828],{"class":420},[390,2192,2193],{"class":400},"\"target\"",[390,2195,1158],{"class":420},[390,2197,2199,2202,2204,2207],{"class":392,"line":2198},10,[390,2200,2201],{"class":396},"    \"statement\"",[390,2203,828],{"class":420},[390,2205,2206],{"class":400},"\"The failure occurs in the harness session runner.\"",[390,2208,1158],{"class":420},[390,2210,2212,2215,2217,2220],{"class":392,"line":2211},11,[390,2213,2214],{"class":396},"    \"provenance\"",[390,2216,828],{"class":420},[390,2218,2219],{"class":400},"\"Source report 101, recorded failing command and stack trace.\"",[390,2221,1158],{"class":420},[390,2223,2225,2228,2230],{"class":392,"line":2224},12,[390,2226,2227],{"class":396},"    \"confidence\"",[390,2229,828],{"class":420},[390,2231,2232],{"class":400},"\"supported\"\n",[390,2234,2236],{"class":392,"line":2235},13,[390,2237,2238],{"class":420},"  }]\n",[390,2240,2242],{"class":392,"line":2241},14,[390,2243,2244],{"class":420},"}\n",[201,2246,2247,2250,2251,2254],{},[283,2248,2249],{},"merge.json"," uses the positional UUID as the explicit destination and retires\n",[283,2252,2253],{},"source_ids","; memberships are unioned without double-counting:",[381,2256,2258],{"className":2069,"code":2257,"language":2071,"meta":386,"style":386},"{\n  \"expected_versions\": {\n    \"11111111-1111-4111-8111-111111111111\": 7,\n    \"22222222-2222-4222-8222-222222222222\": 3\n  },\n  \"reason\": \"Sources 101 and 102 describe the same runner failure and target.\",\n  \"source_ids\": [\"22222222-2222-4222-8222-222222222222\"]\n}\n",[283,2259,2260,2264,2271,2282,2292,2297,2308,2322],{"__ignoreMap":386},[390,2261,2262],{"class":392,"line":393},[390,2263,2078],{"class":420},[390,2265,2266,2268],{"class":392,"line":404},[390,2267,2083],{"class":396},[390,2269,2270],{"class":420},": {\n",[390,2272,2273,2276,2278,2280],{"class":392,"line":470},[390,2274,2275],{"class":396},"    \"11111111-1111-4111-8111-111111111111\"",[390,2277,828],{"class":420},[390,2279,2094],{"class":396},[390,2281,1158],{"class":420},[390,2283,2284,2287,2289],{"class":392,"line":491},[390,2285,2286],{"class":396},"    \"22222222-2222-4222-8222-222222222222\"",[390,2288,828],{"class":420},[390,2290,2291],{"class":396},"3\n",[390,2293,2294],{"class":392,"line":620},[390,2295,2296],{"class":420},"  },\n",[390,2298,2299,2301,2303,2306],{"class":392,"line":632},[390,2300,2102],{"class":396},[390,2302,828],{"class":420},[390,2304,2305],{"class":400},"\"Sources 101 and 102 describe the same runner failure and target.\"",[390,2307,1158],{"class":420},[390,2309,2310,2313,2316,2319],{"class":392,"line":2159},[390,2311,2312],{"class":396},"  \"source_ids\"",[390,2314,2315],{"class":420},": [",[390,2317,2318],{"class":400},"\"22222222-2222-4222-8222-222222222222\"",[390,2320,2321],{"class":420},"]\n",[390,2323,2324],{"class":392,"line":2172},[390,2325,2244],{"class":420},[201,2327,2328,2331],{},[283,2329,2330],{},"split.json"," assumes exactly sources 101, 102 and 103 belong to the issue.\nThe original UUID keeps the explicit nonempty remainder; new UUIDs are\ncreated for complete, nonoverlapping partitions. A partial or foreign\npartition fails without writes:",[381,2333,2335],{"className":2069,"code":2334,"language":2071,"meta":386,"style":386},"{\n  \"expected_versions\": {\"11111111-1111-4111-8111-111111111111\": 7},\n  \"reason\": \"Source 101 describes runner startup; sources 102 and 103 describe a separate package failure.\",\n  \"remainder_submission_ids\": [101],\n  \"partitions\": [{\"submission_ids\": [102, 103], \"target\": {\"kind\": \"package\", \"identity\": \"example-package\"}}]\n}\n",[283,2336,2337,2341,2355,2366,2378,2425],{"__ignoreMap":386},[390,2338,2339],{"class":392,"line":393},[390,2340,2078],{"class":420},[390,2342,2343,2345,2347,2349,2351,2353],{"class":392,"line":404},[390,2344,2083],{"class":396},[390,2346,2086],{"class":420},[390,2348,2089],{"class":396},[390,2350,828],{"class":420},[390,2352,2094],{"class":396},[390,2354,2097],{"class":420},[390,2356,2357,2359,2361,2364],{"class":392,"line":470},[390,2358,2102],{"class":396},[390,2360,828],{"class":420},[390,2362,2363],{"class":400},"\"Source 101 describes runner startup; sources 102 and 103 describe a separate package failure.\"",[390,2365,1158],{"class":420},[390,2367,2368,2371,2373,2375],{"class":392,"line":491},[390,2369,2370],{"class":396},"  \"remainder_submission_ids\"",[390,2372,2315],{"class":420},[390,2374,2167],{"class":396},[390,2376,2377],{"class":420},"],\n",[390,2379,2380,2383,2386,2389,2391,2394,2396,2399,2402,2404,2406,2408,2410,2413,2415,2417,2419,2422],{"class":392,"line":620},[390,2381,2382],{"class":396},"  \"partitions\"",[390,2384,2385],{"class":420},": [{",[390,2387,2388],{"class":396},"\"submission_ids\"",[390,2390,2315],{"class":420},[390,2392,2393],{"class":396},"102",[390,2395,796],{"class":420},[390,2397,2398],{"class":396},"103",[390,2400,2401],{"class":420},"], ",[390,2403,2193],{"class":396},[390,2405,2086],{"class":420},[390,2407,2119],{"class":396},[390,2409,828],{"class":420},[390,2411,2412],{"class":400},"\"package\"",[390,2414,796],{"class":420},[390,2416,2129],{"class":396},[390,2418,828],{"class":420},[390,2420,2421],{"class":400},"\"example-package\"",[390,2423,2424],{"class":420},"}}]\n",[390,2426,2427],{"class":392,"line":632},[390,2428,2244],{"class":420},[201,2430,2431,2434,2435,2438],{},[283,2432,2433],{},"outcome.json"," records one tested environment\u002Fversion and exactly one eligible\nsource. ",[283,2436,2437],{},"evidence_ids"," contains zero or one assertion UUID belonging to that\nsource or its explicit support source; the empty array below relies on the\nnamed source and verification record, not invented assertion evidence:",[381,2440,2442],{"className":2069,"code":2441,"language":2071,"meta":386,"style":386},"{\n  \"expected_versions\": {\"11111111-1111-4111-8111-111111111111\": 7},\n  \"reason\": \"Reproduced the source failure before the change and verified the same reproduction afterward.\",\n  \"environment\": \"example-harness\u002Fsession-runner\",\n  \"environment_version\": \"2.1.0\",\n  \"affected_version\": \"2.0.0\",\n  \"status\": \"verified_resolved\",\n  \"evidence_ids\": [],\n  \"source_submission_ids\": [101],\n  \"observed_at\": \"2026-11-04T10:00:00Z\",\n  \"method\": \"Reran the source report's minimal reproduction in an isolated test environment.\",\n  \"result\": \"pass\",\n  \"change_reference\": \"example-harness@0123456789abcdef\",\n  \"reporter\": \"operator\",\n  \"version_specific\": true,\n  \"verification\": {\n    \"before\": \"Version 2.0.0 exits with the reported runner error.\",\n    \"after\": \"Version 2.1.0 completes the same reproduction without that error.\",\n    \"reproduction\": \"The minimal runner invocation and fixture recorded in source 101.\"\n  }\n}\n",[283,2443,2444,2448,2462,2473,2484,2496,2508,2520,2528,2539,2551,2563,2575,2587,2599,2612,2620,2633,2646,2657,2663],{"__ignoreMap":386},[390,2445,2446],{"class":392,"line":393},[390,2447,2078],{"class":420},[390,2449,2450,2452,2454,2456,2458,2460],{"class":392,"line":404},[390,2451,2083],{"class":396},[390,2453,2086],{"class":420},[390,2455,2089],{"class":396},[390,2457,828],{"class":420},[390,2459,2094],{"class":396},[390,2461,2097],{"class":420},[390,2463,2464,2466,2468,2471],{"class":392,"line":470},[390,2465,2102],{"class":396},[390,2467,828],{"class":420},[390,2469,2470],{"class":400},"\"Reproduced the source failure before the change and verified the same reproduction afterward.\"",[390,2472,1158],{"class":420},[390,2474,2475,2478,2480,2482],{"class":392,"line":491},[390,2476,2477],{"class":396},"  \"environment\"",[390,2479,828],{"class":420},[390,2481,2134],{"class":400},[390,2483,1158],{"class":420},[390,2485,2486,2489,2491,2494],{"class":392,"line":620},[390,2487,2488],{"class":396},"  \"environment_version\"",[390,2490,828],{"class":420},[390,2492,2493],{"class":400},"\"2.1.0\"",[390,2495,1158],{"class":420},[390,2497,2498,2501,2503,2506],{"class":392,"line":632},[390,2499,2500],{"class":396},"  \"affected_version\"",[390,2502,828],{"class":420},[390,2504,2505],{"class":400},"\"2.0.0\"",[390,2507,1158],{"class":420},[390,2509,2510,2513,2515,2518],{"class":392,"line":2159},[390,2511,2512],{"class":396},"  \"status\"",[390,2514,828],{"class":420},[390,2516,2517],{"class":400},"\"verified_resolved\"",[390,2519,1158],{"class":420},[390,2521,2522,2525],{"class":392,"line":2172},[390,2523,2524],{"class":396},"  \"evidence_ids\"",[390,2526,2527],{"class":420},": [],\n",[390,2529,2530,2533,2535,2537],{"class":392,"line":2185},[390,2531,2532],{"class":396},"  \"source_submission_ids\"",[390,2534,2315],{"class":420},[390,2536,2167],{"class":396},[390,2538,2377],{"class":420},[390,2540,2541,2544,2546,2549],{"class":392,"line":2198},[390,2542,2543],{"class":396},"  \"observed_at\"",[390,2545,828],{"class":420},[390,2547,2548],{"class":400},"\"2026-11-04T10:00:00Z\"",[390,2550,1158],{"class":420},[390,2552,2553,2556,2558,2561],{"class":392,"line":2211},[390,2554,2555],{"class":396},"  \"method\"",[390,2557,828],{"class":420},[390,2559,2560],{"class":400},"\"Reran the source report's minimal reproduction in an isolated test environment.\"",[390,2562,1158],{"class":420},[390,2564,2565,2568,2570,2573],{"class":392,"line":2224},[390,2566,2567],{"class":396},"  \"result\"",[390,2569,828],{"class":420},[390,2571,2572],{"class":400},"\"pass\"",[390,2574,1158],{"class":420},[390,2576,2577,2580,2582,2585],{"class":392,"line":2235},[390,2578,2579],{"class":396},"  \"change_reference\"",[390,2581,828],{"class":420},[390,2583,2584],{"class":400},"\"example-harness@0123456789abcdef\"",[390,2586,1158],{"class":420},[390,2588,2589,2592,2594,2597],{"class":392,"line":2241},[390,2590,2591],{"class":396},"  \"reporter\"",[390,2593,828],{"class":420},[390,2595,2596],{"class":400},"\"operator\"",[390,2598,1158],{"class":420},[390,2600,2602,2605,2607,2610],{"class":392,"line":2601},15,[390,2603,2604],{"class":396},"  \"version_specific\"",[390,2606,828],{"class":420},[390,2608,2609],{"class":396},"true",[390,2611,1158],{"class":420},[390,2613,2615,2618],{"class":392,"line":2614},16,[390,2616,2617],{"class":396},"  \"verification\"",[390,2619,2270],{"class":420},[390,2621,2623,2626,2628,2631],{"class":392,"line":2622},17,[390,2624,2625],{"class":396},"    \"before\"",[390,2627,828],{"class":420},[390,2629,2630],{"class":400},"\"Version 2.0.0 exits with the reported runner error.\"",[390,2632,1158],{"class":420},[390,2634,2636,2639,2641,2644],{"class":392,"line":2635},18,[390,2637,2638],{"class":396},"    \"after\"",[390,2640,828],{"class":420},[390,2642,2643],{"class":400},"\"Version 2.1.0 completes the same reproduction without that error.\"",[390,2645,1158],{"class":420},[390,2647,2649,2652,2654],{"class":392,"line":2648},19,[390,2650,2651],{"class":396},"    \"reproduction\"",[390,2653,828],{"class":420},[390,2655,2656],{"class":400},"\"The minimal runner invocation and fixture recorded in source 101.\"\n",[390,2658,2660],{"class":392,"line":2659},20,[390,2661,2662],{"class":420},"  }\n",[390,2664,2666],{"class":392,"line":2665},21,[390,2667,2244],{"class":420},[201,2669,2670,2673,2674,2676,2677,2680,2681,2684,2685,2687,2688,2690],{},[283,2671,2672],{},"environment_version"," is required; ",[283,2675,2180],{}," selects only unknown-version\nreports. ",[283,2678,2679],{},"affected_version"," describes the pre-change version, not the\nresolution scope. ",[283,2682,2683],{},"version_specific: false"," does not resolve untested\nversions. A workaround is ",[283,2686,1712],{},"; a newer upstream release is only a\npossible remedy, not ",[283,2689,1718],{},". Verified resolution requires\naffirmative before\u002Fafter\u002Freproduction evidence and the actual change\nreference. Deleting supporting sources invalidates the outcome; later\neligible recurrence in its scope requires reassessment even outside the\ncurrent query window.",[201,2692,2693],{},"Prompts and source reports are untrusted data, not instructions to execute.\nThese commands do not execute prompts, install or update tooling, write to\nupstream repositories, or automatically resolve issues. Recheck, when\nsupported, requests official-upstream metadata only; availability, citations\nand checked-at data neither prove a local installation changed nor verify\nresolution. Keep working-project attribution distinct from the actual fix\ntarget, and do not carry resolution evidence across unsupported merge\u002Fsplit\nmemberships or environments.",[276,2695,221],{"id":2696},"bare-binary-no-docker",[201,2698,2699,2700,2702],{},"With an installed ",[283,2701,703],{}," binary, on the machine that runs the server:",[381,2704,2706],{"className":383,"code":2705,"language":385,"meta":386,"style":386},"agentfeedback serve --init                       # [--dir D] [--db PATH] [--port N] [--force]\nagentfeedback server install --systemd           # Linux user unit; or --launchd (macOS), or --compose [--image REF]\n",[283,2707,2708,2721],{"__ignoreMap":386},[390,2709,2710,2712,2715,2718],{"class":392,"line":393},[390,2711,703],{"class":442},[390,2713,2714],{"class":400}," serve",[390,2716,2717],{"class":396}," --init",[390,2719,2720],{"class":466},"                       # [--dir D] [--db PATH] [--port N] [--force]\n",[390,2722,2723,2725,2728,2731,2734],{"class":392,"line":404},[390,2724,703],{"class":442},[390,2726,2727],{"class":400}," server",[390,2729,2730],{"class":400}," install",[390,2732,2733],{"class":396}," --systemd",[390,2735,2736],{"class":466},"           # Linux user unit; or --launchd (macOS), or --compose [--image REF]\n",[201,2738,2739,2742,2743,2745,2746,421,2749,2752,2753,2756,2757,2760,2761,2763,2764,796,2767,2770,2771,2773,2774,2777,2778,2781,2782,662,2785,357,2787,2790,2791,318],{},[283,2740,2741],{},"serve --init"," writes two files, both ",[283,2744,344],{},", into\n",[283,2747,2748],{},"${XDG_CONFIG_HOME:-~\u002F.config}\u002Fagentfeedback\u002Fserver",[283,2750,2751],{},"--dir","): ",[283,2754,2755],{},"api-key",", a\nnew random key, and ",[283,2758,2759],{},"serve.env",", the three variables ",[283,2762,777],{}," reads\n(",[283,2765,2766],{},"API_KEY_FILE",[283,2768,2769],{},"DATABASE_PATH",", default\n",[283,2772,690],{},", and\n",[283,2775,2776],{},"HTTP_LISTEN_ADDR=127.0.0.1:\u003Cport>",", port 8090 by default). Its last stdout\nline is a JSON outcome, the only place the key is printed. An existing file\nis refused; ",[283,2779,2780],{},"--force"," replaces both and rotates the key. Paths may hold only\nletters, digits and ",[283,2783,2784],{},"\u002F . _ - + @ , =",[283,2786,2741],{},[283,2788,2789],{},"server install","\nare not supported on Windows.\nRun it in the foreground with ",[283,2792,2793],{},"set -a; . \u003Cdir>\u002Fserve.env; set +a; agentfeedback serve",[201,2795,2796,2798,2799,2801,2802,2805,2806,2808,2809,2811,2812,357,2815,2818,2819,2821,2822,2824,2825,2827,2828,2831,2832,2834,2835,2837,2838,2840,2841,2843,2844,2846,2847,2849,2850,2853],{},[283,2797,2789],{}," reads ",[283,2800,2759],{}," and writes exactly one file; it starts,\nenables and reloads nothing and prints the commands to do so (the JSON\noutcome's ",[283,2803,2804],{},"next","). An existing file is refused without ",[283,2807,2780],{},".\n",[283,2810,2759],{}," may also set ",[283,2813,2814],{},"PUBLIC_URL",[283,2816,2817],{},"MCP_INSTRUCTIONS"," (see\n",[208,2820,246],{"href":245},"); ",[283,2823,2741],{}," writes neither. Write\n",[283,2826,2817],{}," as one line in single quotes with no single quote or\nbackslash inside,\nsuch as ",[283,2829,2830],{},"MCP_INSTRUCTIONS='File one report per task.'",": the shell and\nsystemd both read ",[283,2833,2759],{},", and only that form means the same to both.\n",[283,2836,2814],{}," must already be in normalised form (one trailing slash is\nallowed), since the shell reads it too. ",[283,2839,2789],{}," refuses any other\nkey, an unusable or non-normalised ",[283,2842,2814],{}," and any other form of\n",[283,2845,2817],{},"; the systemd unit reads both through\n",[283,2848,2759],{},", and the plist and ",[283,2851,2852],{},"compose.yaml"," copy them when set.",[969,2855,2856,2869],{},[972,2857,2858],{},[975,2859,2860,2863,2866],{},[978,2861,2862],{},"Mode",[978,2864,2865],{},"Writes",[978,2867,2868],{},"Next commands",[985,2870,2871,2899,2939],{},[975,2872,2873,2879,2884],{},[990,2874,2875,2878],{},[283,2876,2877],{},"--systemd"," (refused as root)",[990,2880,2881],{},[283,2882,2883],{},"${XDG_CONFIG_HOME:-~\u002F.config}\u002Fsystemd\u002Fuser\u002Fagentfeedback.service",[990,2885,2886,796,2889,796,2892,662,2895,2898],{},[283,2887,2888],{},"systemctl --user daemon-reload",[283,2890,2891],{},"systemctl --user enable --now agentfeedback.service",[283,2893,2894],{},"systemctl --user status agentfeedback.service",[283,2896,2897],{},"loginctl enable-linger \"$USER\""," keeps it running without a login session",[975,2900,2901,2906,2915],{},[990,2902,2903],{},[283,2904,2905],{},"--launchd",[990,2907,2908,2911,2912],{},[283,2909,2910],{},"~\u002FLibrary\u002FLaunchAgents\u002Fdev.agentfeedback.serve.plist",", logs in ",[283,2913,2914],{},"~\u002FLibrary\u002FLogs\u002Fagentfeedback\u002Fserve.log",[990,2916,2917,796,2920,796,2923,2926,2927,2929,2930,2932,2933,357,2936],{},[283,2918,2919],{},"launchctl bootstrap gui\u002F$(id -u) \u003Cplist>",[283,2921,2922],{},"launchctl kickstart -k gui\u002F$(id -u)\u002Fdev.agentfeedback.serve",[283,2924,2925],{},"launchctl print gui\u002F$(id -u)\u002Fdev.agentfeedback.serve","; the plist copies ",[283,2928,2759],{},", so after editing it rerun with ",[283,2931,2780],{},", then ",[283,2934,2935],{},"launchctl bootout",[283,2937,2938],{},"bootstrap",[975,2940,2941,2946,2963],{},[990,2942,2943],{},[283,2944,2945],{},"--compose",[990,2947,2948,2951,2952,2955,2956,2959,2960],{},[283,2949,2950],{},"\u003Cdir>\u002Fcompose.yaml",": the image (",[283,2953,2954],{},"--image",", default the release's own tag), run as your uid:gid, the key as a file secret, the database directory as ",[283,2957,2958],{},"\u002Fdata",", published on ",[283,2961,2962],{},"127.0.0.1:\u003Cport>",[990,2964,2965,796,2968,796,2971],{},[283,2966,2967],{},"docker compose -f \u003Cdir>\u002Fcompose.yaml up -d",[283,2969,2970],{},"... ps",[283,2972,2973],{},"... logs -f agentfeedback",[201,2975,2976,2977,2980,2981,2984,2985,2988,2989,2992,2993,2995,2996,2998,2999,3002,3003,3005,3006,918],{},"Backup for systemd and launchd: ",[283,2978,2979],{},"set -a; . \u003Cdir>\u002Fserve.env; set +a; agentfeedback backup \u003Cdb dir>\u002Fagentfeedback-$(date -u +%Y%m%dT%H%M%SZ).db",";\nfor compose, the ",[208,2982,2983],{"href":249},"physical backup"," with ",[283,2986,2987],{},"-f \u003Cdir>\u002Fcompose.yaml",".\nExposing the server beyond ",[283,2990,2991],{},"127.0.0.1"," is your decision (",[208,2994,1422],{"href":172},").\nThe compose form runs the container as your uid:gid, which rootless Docker or\nuserns-remap may not map to the owner of the key file and database directory;\nthere, use the root-based stack of ",[208,2997,216],{"href":215},".\nRotate the key with ",[283,3000,3001],{},"agentfeedback serve --init --force",", then the restart command\nfor your form (",[283,3004,2789],{}," lists it in ",[283,3007,2804],{},[201,3009,3010],{},"Wire a client on the same machine and verify the whole path:",[381,3012,3014],{"className":383,"code":3013,"language":385,"meta":386,"style":386},"agentfeedback doctor --init --url http:\u002F\u002F127.0.0.1:8090 --key-from-stdin \u003C ~\u002F.config\u002Fagentfeedback\u002Fserver\u002Fapi-key\nagentfeedback doctor --e2e          # submit, list and mark one install-check row; --json for one line per step\n",[283,3015,3016,3039],{"__ignoreMap":386},[390,3017,3018,3020,3022,3024,3027,3030,3033,3036],{"class":392,"line":393},[390,3019,703],{"class":442},[390,3021,706],{"class":400},[390,3023,2717],{"class":396},[390,3025,3026],{"class":396}," --url",[390,3028,3029],{"class":400}," http:\u002F\u002F127.0.0.1:8090",[390,3031,3032],{"class":396}," --key-from-stdin",[390,3034,3035],{"class":416}," \u003C",[390,3037,3038],{"class":400}," ~\u002F.config\u002Fagentfeedback\u002Fserver\u002Fapi-key\n",[390,3040,3041,3043,3045,3048],{"class":392,"line":404},[390,3042,703],{"class":442},[390,3044,706],{"class":400},[390,3046,3047],{"class":396}," --e2e",[390,3049,3050],{"class":466},"          # submit, list and mark one install-check row; --json for one line per step\n",[201,3052,3053,3056,3057,3059,3060,796,3062,796,3065,357,3068,3071,3072,878,3075,3078,3079,318],{},[283,3054,3055],{},"doctor --e2e"," sends straight to the server (no spool, no client log line),\nstops at the first failing step and exits 1. Its row has kind\n",[283,3058,1374],{},", which ",[283,3061,1378],{},[283,3063,3064],{},"stats",[283,3066,3067],{},"digest",[283,3069,3070],{},"migrate"," leave out\nunless ",[283,3073,3074],{},"--kind",[283,3076,3077],{},"--include-kind"," names it, and is marked processed with\nverdict ",[283,3080,1374],{},[276,3082,230],{"id":3083},"wire-the-harnesses",[201,3085,3086,3087,3089,3090,3093,3094,3097,3098,3100],{},"On every machine whose coding agents should file feedback, with the\n",[283,3088,703],{}," binary installed, ",[283,3091,3092],{},"agentfeedback init"," does the whole setup\nin one pass: where reports go (local unless a server is named; ",[283,3095,3096],{},"config.toml","\nis written only for a server), the harnesses (all detected by default), the\n",[283,3099,3055],{}," check, and the next steps:",[381,3102,3104],{"className":383,"code":3103,"language":385,"meta":386,"style":386},"agentfeedback init                               # on a terminal: asks local or a server URL, then which harnesses\nagentfeedback init --yes                         # no questions: local, every detected harness\nagentfeedback init --server URL --key-from-stdin --harnesses claude-code,codex   # a server, its key on stdin\nagentfeedback init --yes --no-hooks              # the skill and the rule, no hooks; --mcp an MCP entry instead, as install --mcp\n",[283,3105,3106,3116,3128,3150],{"__ignoreMap":386},[390,3107,3108,3110,3113],{"class":392,"line":393},[390,3109,703],{"class":442},[390,3111,3112],{"class":400}," init",[390,3114,3115],{"class":466},"                               # on a terminal: asks local or a server URL, then which harnesses\n",[390,3117,3118,3120,3122,3125],{"class":392,"line":404},[390,3119,703],{"class":442},[390,3121,3112],{"class":400},[390,3123,3124],{"class":396}," --yes",[390,3126,3127],{"class":466},"                         # no questions: local, every detected harness\n",[390,3129,3130,3132,3134,3136,3139,3141,3144,3147],{"class":392,"line":470},[390,3131,703],{"class":442},[390,3133,3112],{"class":400},[390,3135,1342],{"class":396},[390,3137,3138],{"class":400}," URL",[390,3140,3032],{"class":396},[390,3142,3143],{"class":396}," --harnesses",[390,3145,3146],{"class":400}," claude-code,codex",[390,3148,3149],{"class":466},"   # a server, its key on stdin\n",[390,3151,3152,3154,3156,3158,3161],{"class":392,"line":491},[390,3153,703],{"class":442},[390,3155,3112],{"class":400},[390,3157,3124],{"class":396},[390,3159,3160],{"class":396}," --no-hooks",[390,3162,3163],{"class":466},"              # the skill and the rule, no hooks; --mcp an MCP entry instead, as install --mcp\n",[201,3165,3166,3167,3170,3171,357,3173,3175,3176,3178,3179,3182,3183,3185,3186,878,3188,3190,3191,3193,3194,796,3197,796,3200,796,3203,1158,3206,796,3209,796,3212,796,3215,796,3218,796,3221,796,3224,3226,3227,3229,3230,3233],{},"On a terminal, a server's key is asked without echo (Enter skips it, and the\ncheck then waits for it). A configured server is kept: ",[283,3168,3169],{},"init --local",", a\ndifferent ",[283,3172,1356],{},[283,3174,285],{}," are refused, and an existing\n",[283,3177,3096],{}," is never edited. With no server configured but one recorded by\nan earlier ",[283,3180,3181],{},"install --server",", Enter at the prompt keeps it, and without a\nterminal ",[283,3184,364],{}," needs ",[283,3187,1356],{},[283,3189,757],{},". The configuration is written\nafter the wiring, so a refused run leaves none behind. ",[283,3192,1211],{}," prints one object (",[283,3195,3196],{},"status",[283,3198,3199],{},"mode",[283,3201,3202],{},"server",[283,3204,3205],{},"config",[283,3207,3208],{},"data_dir",[283,3210,3211],{},"database",[283,3213,3214],{},"harnesses",[283,3216,3217],{},"hooks",[283,3219,3220],{},"e2e",[283,3222,3223],{},"restart",[283,3225,2804],{},").\n",[283,3228,364],{}," never writes a repository's instruction file (",[283,3231,3232],{},"install --project","\ndoes).",[201,3235,3236,3238],{},[283,3237,856],{}," wires the harnesses alone, against the configured server or local\nmode:",[381,3240,3242],{"className":383,"code":3241,"language":385,"meta":386,"style":386},"agentfeedback install                            # list the harnesses: detected, mode, skill, mcp, hook, reminder, docs, triage, rule; changes nothing (also --list, --json)\nagentfeedback install all                        # every detected harness: the skill, hooks running agentfeedback hook, a session-start hook running agentfeedback prime, the rule in the global instruction file, and the agentfeedback-triage skill\nagentfeedback install claude-code --with-reminder=false   # without the session-start hook\nagentfeedback install claude-code --with-triage=false     # without the agentfeedback-triage skill\nagentfeedback install claude-code --no-hooks     # no hooks at all, the session-start one included: the skill and the rule\nagentfeedback install --check                    # is the rule section current in each detected or recorded harness? changes nothing; exit 3 when one is missing or stale\nagentfeedback install --project --yes            # the pointer section in this repository's AGENTS.md (or CLAUDE.md); --uninstall removes it\nagentfeedback prime                              # the short guidance the session-start hook prints (--format cursor: Cursor's JSON; --full: the whole guidance)\nagentfeedback install opencode-v1 --mcp          # an MCP entry instead of the skill and the hook: stdio, agentfeedback mcp for local, agentfeedback mcp --server URL for a server\nagentfeedback install claude-code --docs         # also the agentfeedback-docs skill: the reference docs, schemas and OpenAPI document for integrators and operators\nagentfeedback install all --dry-run              # print every file that would change, change nothing\nagentfeedback uninstall all                      # remove exactly what install added\n",[283,3243,3244,3253,3265,3280,3294,3307,3319,3333,3343,3358,3372,3386],{"__ignoreMap":386},[390,3245,3246,3248,3250],{"class":392,"line":393},[390,3247,703],{"class":442},[390,3249,2730],{"class":400},[390,3251,3252],{"class":466},"                            # list the harnesses: detected, mode, skill, mcp, hook, reminder, docs, triage, rule; changes nothing (also --list, --json)\n",[390,3254,3255,3257,3259,3262],{"class":392,"line":404},[390,3256,703],{"class":442},[390,3258,2730],{"class":400},[390,3260,3261],{"class":400}," all",[390,3263,3264],{"class":466},"                        # every detected harness: the skill, hooks running agentfeedback hook, a session-start hook running agentfeedback prime, the rule in the global instruction file, and the agentfeedback-triage skill\n",[390,3266,3267,3269,3271,3274,3277],{"class":392,"line":470},[390,3268,703],{"class":442},[390,3270,2730],{"class":400},[390,3272,3273],{"class":400}," claude-code",[390,3275,3276],{"class":396}," --with-reminder=false",[390,3278,3279],{"class":466},"   # without the session-start hook\n",[390,3281,3282,3284,3286,3288,3291],{"class":392,"line":491},[390,3283,703],{"class":442},[390,3285,2730],{"class":400},[390,3287,3273],{"class":400},[390,3289,3290],{"class":396}," --with-triage=false",[390,3292,3293],{"class":466},"     # without the agentfeedback-triage skill\n",[390,3295,3296,3298,3300,3302,3304],{"class":392,"line":620},[390,3297,703],{"class":442},[390,3299,2730],{"class":400},[390,3301,3273],{"class":400},[390,3303,3160],{"class":396},[390,3305,3306],{"class":466},"     # no hooks at all, the session-start one included: the skill and the rule\n",[390,3308,3309,3311,3313,3316],{"class":392,"line":632},[390,3310,703],{"class":442},[390,3312,2730],{"class":400},[390,3314,3315],{"class":396}," --check",[390,3317,3318],{"class":466},"                    # is the rule section current in each detected or recorded harness? changes nothing; exit 3 when one is missing or stale\n",[390,3320,3321,3323,3325,3328,3330],{"class":392,"line":2159},[390,3322,703],{"class":442},[390,3324,2730],{"class":400},[390,3326,3327],{"class":396}," --project",[390,3329,3124],{"class":396},[390,3331,3332],{"class":466},"            # the pointer section in this repository's AGENTS.md (or CLAUDE.md); --uninstall removes it\n",[390,3334,3335,3337,3340],{"class":392,"line":2172},[390,3336,703],{"class":442},[390,3338,3339],{"class":400}," prime",[390,3341,3342],{"class":466},"                              # the short guidance the session-start hook prints (--format cursor: Cursor's JSON; --full: the whole guidance)\n",[390,3344,3345,3347,3349,3352,3355],{"class":392,"line":2185},[390,3346,703],{"class":442},[390,3348,2730],{"class":400},[390,3350,3351],{"class":400}," opencode-v1",[390,3353,3354],{"class":396}," --mcp",[390,3356,3357],{"class":466},"          # an MCP entry instead of the skill and the hook: stdio, agentfeedback mcp for local, agentfeedback mcp --server URL for a server\n",[390,3359,3360,3362,3364,3366,3369],{"class":392,"line":2198},[390,3361,703],{"class":442},[390,3363,2730],{"class":400},[390,3365,3273],{"class":400},[390,3367,3368],{"class":396}," --docs",[390,3370,3371],{"class":466},"         # also the agentfeedback-docs skill: the reference docs, schemas and OpenAPI document for integrators and operators\n",[390,3373,3374,3376,3378,3380,3383],{"class":392,"line":2211},[390,3375,703],{"class":442},[390,3377,2730],{"class":400},[390,3379,3261],{"class":400},[390,3381,3382],{"class":396}," --dry-run",[390,3384,3385],{"class":466},"              # print every file that would change, change nothing\n",[390,3387,3388,3390,3393,3395],{"class":392,"line":2224},[390,3389,703],{"class":442},[390,3391,3392],{"class":400}," uninstall",[390,3394,3261],{"class":400},[390,3396,3397],{"class":466},"                      # remove exactly what install added\n",[201,3399,3400,3401,796,3404,796,3407,796,3410,796,3413,796,3416,796,3419,796,3422,796,3425,796,3428,796,3431,796,3434,796,3437,796,3440,796,3443,3446,3447,3450,3451,3453,3454,3456,796,3459,796,3462,796,3465,878,3468,796,3470,1158,3472,796,3475,796,3478,3480,3481,3483,3484,796,3487,796,3490,878,3493,3496],{},"Harnesses: ",[283,3402,3403],{},"claude-code",[283,3405,3406],{},"codex",[283,3408,3409],{},"cursor",[283,3411,3412],{},"opencode-v1",[283,3414,3415],{},"opencode-v2",[283,3417,3418],{},"omp",[283,3420,3421],{},"pi",[283,3423,3424],{},"copilot",[283,3426,3427],{},"antigravity",[283,3429,3430],{},"devin",[283,3432,3433],{},"kiro",[283,3435,3436],{},"cline",[283,3438,3439],{},"amp",[283,3441,3442],{},"vscode",[283,3444,3445],{},"gemini-cli",". A\nharness counts as detected when its binary is on ",[283,3448,3449],{},"PATH"," or its directory\nexists, with the OpenCode version check below; a named harness that is not\ndetected is wired anyway, with a note.\n",[283,3452,2041],{}," is every detected harness plus any named beside it.\nUnknown names exit 2. The last stdout line is a JSON outcome (",[283,3455,3196],{},[283,3457,3458],{},"installed",[283,3460,3461],{},"unchanged",[283,3463,3464],{},"uninstalled",[283,3466,3467],{},"dry_run",[283,3469,823],{},[283,3471,3214],{},[283,3473,3474],{},"changed",[283,3476,3477],{},"backups",[283,3479,2804],{},"); progress goes to stderr. Running install twice\nchanges nothing the second time (",[283,3482,3461],{},"); a changed mode, binary path,\nserver, ",[283,3485,3486],{},"--with-reminder",[283,3488,3489],{},"--with-triage",[283,3491,3492],{},"--no-hooks",[283,3494,3495],{},"--docs"," replaces what the previous run added.",[201,3498,3499,3500,3502,3503,3505,3506,3509,3510,3513,3514,796,3516,796,3518,3521,3522,3525,3526,3529,3530,3533,3534,3537,3538,3540,3541,3543,3544,318],{},"OpenCode V1 is ",[283,3501,3412],{}," and OpenCode 2 is ",[283,3504,3415],{},"; both read\n",[283,3507,3508],{},"opencode --version",". V1 is detected on major 1, or with no binary and an\nexisting OpenCode directory; V2 only on major 2 (the directory alone never\ndetects it). ",[283,3511,3512],{},"opencode"," is an input alias: ",[283,3515,856],{},[283,3517,364],{},[283,3519,3520],{},"install --check"," and the manual steps resolve it by the detected major (V1 when the\nversion is 1.x, V2 when 2.x); ",[283,3523,3524],{},"uninstall opencode"," removes the variant the\nmanifest records. An unreadable or unrecognized version, or a major other\nthan 1 or 2, detects neither:\n",[283,3527,3528],{},"install opencode"," then writes nothing and warns, and naming a variant\nwires it with a not-detected note. The two variants share the OpenCode\ndirectory (skill, ",[283,3531,3532],{},"AGENTS.md"," section, ",[283,3535,3536],{},"opencode.json(c)",", plugin file), so\nthey are never installed together: installing one first removes the other's\nwiring in the same run, with a note, and naming both in one command is\nrefused. The replacement is one run: a refusal in either half writes\nnothing. ",[283,3539,795],{}," flags V1 wiring beside a 2.x binary (and V2 wiring beside a\n1.x binary) and recommends installing the matching variant. Manifest entries written under\n",[283,3542,3512],{}," are read as ",[283,3545,3412],{},[201,3547,3548,3549,3552,3553,3556,3557,3560,3561,3564,3565,3567,3568,3571,3572,3575],{},"On OpenCode 2 the plugin counts failed ",[283,3550,3551],{},"shell"," commands on\n",[283,3554,3555],{},"ctx.tool.hook(\"execute.after\")"," and delivers the note when a turn ends\n(",[283,3558,3559],{},"session.execution.succeeded",", failed or interrupted; OpenCode 2 does not\nemit ",[283,3562,3563],{},"session.idle",") as the session instructions entry ",[283,3566,703],{},",\nwhich the model reads once at its next step without an extra model turn.\nThat instructions API is experimental in OpenCode 2.2.6. ",[283,3569,3570],{},"opencode mcp list"," in 2.2.6 does not show configured servers; the entry still connects\n(its tools are offered inside OpenCode's ",[283,3573,3574],{},"execute"," tool).",[201,3577,3578,3579,3582,3583,3586,3587,3590],{},"New feedback from OpenCode V1 uses ",[283,3580,3581],{},"harness: opencode-v1",", from OpenCode 2 ",[283,3584,3585],{},"harness: opencode-v2",". Stored feedback is write-once:\nolder ",[283,3588,3589],{},"harness: opencode"," submissions keep that value. Feedback filters and\ngroupings use the stored value, so query both names when reviewing history\nacross the rename.",[866,3592,3593,3632,3688],{},[869,3594,3595,3598,3599,1158,3602,3605,3606,3609,3610,3613,3614,3616,3617,3619,3620,3623,3624,3627,3628,3631],{},[872,3596,3597],{},"The rule."," In CLI mode install writes one section into each harness's\nglobal instruction file (the Rule column): a begin marker\n",[283,3600,3601],{},"\u003C!-- agentfeedback:begin v=\u003Cskill version> hash=\u003C16 hex digits> -->",[283,3603,3604],{},"## AgentFeedback"," with one rule (surface friction; run\n",[283,3607,3608],{},"agentfeedback prime"," when unsure how), and ",[283,3611,3612],{},"\u003C!-- agentfeedback:end -->",".\nIt is appended after one blank line, backed up and recorded like every\nother file. The text between the markers is install's: a run replaces a\nsection that is stale (another version), edited or unrecorded where it\nstands, and uninstall removes it by its markers, edited or not, with the\nblank line before it; a file with two sections, or a begin marker without\nits end, is refused (uninstall leaves it as it is, noted). ",[283,3615,3427],{},"\nand ",[283,3618,3445],{}," share ",[283,3621,3622],{},"~\u002F.gemini\u002FGEMINI.md"," unless ",[283,3625,3626],{},"GEMINI_CLI_HOME"," is\nset: one section, removed with the last of the two. ",[283,3629,3630],{},"--mcp"," writes no rule.",[869,3633,3634,1224,3639,3642,3643,796,3646,3649,3650,3653,3654,3657,3658,796,3660,3662,3663,3665,3666,3668,3669,3672,3673,2984,3675,3677,3678,3681,3682,3684,3685,3687],{},[872,3635,3636,318],{},[283,3637,3638],{},"--check",[283,3640,3641],{},"install --check [all|\u003Charness>...] [--project] [--json]","\nreads the global instruction files (at the locations the manifest records)\nand prints, per harness, ",[283,3644,3645],{},"current",[283,3647,3648],{},"stale"," (a section other than the one\nthis binary writes), ",[283,3651,3652],{},"missing"," (no section, or no file), or ",[283,3655,3656],{},"-"," (no global\nfile: ",[283,3659,3409],{},[283,3661,3442],{},"; or a harness the manifest records with ",[283,3664,3630],{},");\nwith no names, the detected and recorded\nharnesses. It writes nothing and takes no lock. ",[283,3667,1211],{}," prints\n",[283,3670,3671],{},"{\"status\":\"current\"|\"not_current\",\"harnesses\":[{\"name\",\"file\",\"rule\"}]}",",\nplus ",[283,3674,1588],{},[283,3676,1568],{},", and ",[283,3679,3680],{},"warnings"," when a named ",[283,3683,3512],{},"\ncould not be resolved to a variant (exit 1 when it was the only name).\nExit 0 when every section is current, 3\nwhen one is missing or stale (",[283,3686,3656],{}," does not count), 1 on an error, 2 on\nusage.",[869,3689,3690,1224,3694,3697,3698,3700,3701,3703,3704,3707,3708,3710,3711,3714,3715,3717,3718,3721,3722,3725,3726,3728,3729,3731],{},[872,3691,3692,318],{},[283,3693,1568],{},[283,3695,3696],{},"install --project [--yes] [--uninstall] [--dry-run]","\nwrites the pointer section (the same markers; \"if the ",[283,3699,703],{},"\ncommand is installed, run ",[283,3702,3608],{},"\") into the repository\nholding the working directory (the nearest ancestor with ",[283,3705,3706],{},".git","):\n",[283,3709,3532],{},", else ",[283,3712,3713],{},"CLAUDE.md"," when only that exists, else a new\n",[283,3716,3532],{},". On a terminal it asks first, naming the repository and the\nfile; elsewhere it refuses without ",[283,3719,3720],{},"--yes",". A section already there is\nreplaced in place; ",[283,3723,3724],{},"--uninstall"," removes it and deletes the file only\nwhen not a byte is left. A symbolic link or other non-regular file is\nrefused, and so is a file that changed between the read and the write.\nIt writes atomically, takes no backup, never runs git and never reads or\nwrites the manifest; harness names (allowed with ",[283,3727,3638],{},") and ",[283,3730,3630],{},"\nexit 2.\nCommit the file yourself.",[201,3733,3734,3735,3738,3739,796,3742,662,3745,3747,3748,3750,3751,3754,3755,878,3758,3760,3761,3763,3764,3766,3767,3769,3770,3772,3773,3775,3776,3778,3779,3781,3782,918],{},"The list (",[283,3736,3737],{},"--list",", or no harness named) shows, per harness wired with the\nskill and hook, the binary its hook runs and that binary's version\n(",[283,3740,3741],{},"binary",[283,3743,3744],{},"binary_version",[283,3746,3652],{}," when the file is gone, ",[283,3749,1646],{}," when\nit does not answer ",[283,3752,3753],{},"version --json","). An MCP entry reads ",[283,3756,3757],{},"stdio",[283,3759,738],{}," in\nthe ",[283,3762,860],{}," column; a stdio entry shows the binary it runs, a URL entry none.\n",[283,3765,856],{}," warns on stderr and in the outcome's ",[283,3768,3680],{}," when the\nbinary it wires is not the ",[283,3771,703],{}," on ",[283,3774,3449],{},", or none is on ",[283,3777,3449],{},":\nagents run the one on ",[283,3780,3449],{}," and hooks the one wired, and the newer of two\nbinaries makes the older one fail on the local database (see\n",[208,3783,258],{"href":257},[201,3785,3786,3787,357,3789,3792,3793,421,3795,3797,3798,3801,3802,3805,3806,3808,3809,3811,3812,3814,3815,3818],{},"On Windows ",[283,3788,856],{},[283,3790,3791],{},"uninstall"," refuse (exit 2). ",[283,3794,856],{},[283,3796,3737],{},"\nincluded) prints the manual steps for each detected harness, or each named\none, on stderr and in the outcome's ",[283,3799,3800],{},"manual"," list: the skill path and a\nPowerShell command that writes it (",[283,3803,3804],{},"agentfeedback skill render skill-md",", as\nUTF-8; none for ",[283,3807,3442],{},", which has no skill path), the MCP entry (file, key and value): the stdio entry (",[283,3810,860],{}," for local, ",[283,3813,863],{}," for a server; the URL entry for a server only when the binary's path cannot be resolved),\nand the instruction-file text (",[283,3816,3817],{},"agentfeedback skill render agents-md","). Hooks\nare not wired on Windows; undo the steps by hand.",[969,3820,3821,3851],{},[972,3822,3823],{},[975,3824,3825,3828,3831,3834,3837,3840,3843,3848],{},[978,3826,3827],{},"Harness",[978,3829,3830],{},"Detected by",[978,3832,3833],{},"Skill",[978,3835,3836],{},"Hook (default)",[978,3838,3839],{},"Reminder",[978,3841,3842],{},"Rule",[978,3844,3845,3846,1002],{},"MCP entry (",[283,3847,3630],{},[978,3849,3850],{},"Verified",[985,3852,3853,3909,3962,4023,4088,4138,4186,4232,4282,4345,4390,4428,4479,4541,4587],{},[975,3854,3855,3859,3871,3876,3888,3896,3901,3906],{},[990,3856,3857],{},[283,3858,3403],{},[990,3860,3861,796,3864,3867,3868,1002],{},[283,3862,3863],{},"claude",[283,3865,3866],{},"$CLAUDE_CONFIG_DIR"," (default ",[283,3869,3870],{},"~\u002F.claude",[990,3872,3873],{},[283,3874,3875],{},"\u003Cclaude config>\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,3877,3878,1224,3881,3884,3885],{},[283,3879,3880],{},"\u003Cclaude config>\u002Fsettings.json",[283,3882,3883],{},"hooks.PostToolUseFailure"," (note) and ",[283,3886,3887],{},"hooks.Stop",[990,3889,3890,3893,3894],{},[283,3891,3892],{},"hooks.SessionStart"," runs ",[283,3895,3608],{},[990,3897,3898],{},[283,3899,3900],{},"\u003Cclaude config>\u002FCLAUDE.md",[990,3902,3903],{},[283,3904,3905],{},"claude mcp add-json agentfeedback ... --scope user",[990,3907,3908],{},"live-checked 2026-10-07",[975,3910,3911,3915,3925,3930,3938,3944,3949,3959],{},[990,3912,3913],{},[283,3914,3406],{},[990,3916,3917,796,3919,3867,3922,1002],{},[283,3918,3406],{},[283,3920,3921],{},"$CODEX_HOME",[283,3923,3924],{},"~\u002F.codex",[990,3926,3927],{},[283,3928,3929],{},"~\u002F.agents\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,3931,3932,1224,3935,3937],{},[283,3933,3934],{},"\u003Ccodex home>\u002Fhooks.json",[283,3936,3887],{}," (flush only)",[990,3939,3940,3893,3942],{},[283,3941,3892],{},[283,3943,3608],{},[990,3945,3946],{},[283,3947,3948],{},"\u003Ccodex home>\u002FAGENTS.md",[990,3950,3951,3952,3955,3956],{},"marked ",[283,3953,3954],{},"[mcp_servers.agentfeedback]"," block in ",[283,3957,3958],{},"\u003Ccodex home>\u002Fconfig.toml",[990,3960,3961],{},"documented 2026-10-07",[975,3963,3964,3968,3981,3986,4001,4009,4012,4020],{},[990,3965,3966],{},[283,3967,3409],{},[990,3969,3970,3973,3974,3977,3978],{},[283,3971,3972],{},"cursor-agent",", or an ",[283,3975,3976],{},"agent"," that resolves into a Cursor install; ",[283,3979,3980],{},"~\u002F.cursor",[990,3982,3983],{},[283,3984,3985],{},"~\u002F.cursor\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,3987,3988,1224,3991,3994,3995,357,3998],{},[283,3989,3990],{},"~\u002F.cursor\u002Fhooks.json",[283,3992,3993],{},"hooks.postToolUseFailure"," (note), ",[283,3996,3997],{},"hooks.stop",[283,3999,4000],{},"hooks.sessionEnd",[990,4002,4003,3893,4006],{},[283,4004,4005],{},"hooks.sessionStart",[283,4007,4008],{},"agentfeedback prime --format cursor",[990,4010,4011],{},"none: Cursor's User Rules live in its settings UI, not in a file",[990,4013,4014,1224,4017],{},[283,4015,4016],{},"~\u002F.cursor\u002Fmcp.json",[283,4018,4019],{},"mcpServers.agentfeedback",[990,4021,4022],{},"fixture-tested 2026-11-10",[975,4024,4025,4029,4038,4043,4058,4061,4066,4086],{},[990,4026,4027],{},[283,4028,3412],{},[990,4030,4031,4033,4034,4037],{},[283,4032,3512],{}," reporting 1.x, or ",[283,4035,4036],{},"${XDG_CONFIG_HOME:-~\u002F.config}\u002Fopencode"," with no binary",[990,4039,4040],{},[283,4041,4042],{},"\u003Copencode>\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4044,4045,4046,4049,4050,2038,4053,3677,4055,4057],{},"plugin ",[283,4047,4048],{},"\u003Copencode>\u002Fplugins\u002Fagentfeedback.js"," (on ",[283,4051,4052],{},"tool.execute.after",[283,4054,385],{},[283,4056,3563],{},", which delivers the note)",[990,4059,4060],{},"not supported",[990,4062,4063],{},[283,4064,4065],{},"\u003Copencode>\u002FAGENTS.md",[990,4067,4068,4071,4072,796,4075,4078,4079,4081,4082,3710,4084],{},[283,4069,4070],{},"mcp.agentfeedback"," in the first of ",[283,4073,4074],{},"opencode.jsonc",[283,4076,4077],{},"opencode.json"," that has an ",[283,4080,860],{}," member, else an existing ",[283,4083,4074],{},[283,4085,4077],{},[990,4087,3908],{},[975,4089,4090,4094,4099,4103,4114,4116,4120,4135],{},[990,4091,4092],{},[283,4093,3415],{},[990,4095,4096,4098],{},[283,4097,3512],{}," reporting 2.x",[990,4100,4101],{},[283,4102,4042],{},[990,4104,4045,4105,4049,4107,2038,4109,3677,4111,4113],{},[283,4106,4048],{},[283,4108,3555],{},[283,4110,3551],{},[283,4112,3559],{},", which delivers the note as a session instructions entry)",[990,4115,4060],{},[990,4117,4118],{},[283,4119,4065],{},[990,4121,4122,4071,4125,796,4127,4078,4129,4081,4131,3710,4133],{},[283,4123,4124],{},"mcp.servers.agentfeedback",[283,4126,4074],{},[283,4128,4077],{},[283,4130,860],{},[283,4132,4074],{},[283,4134,4077],{},[990,4136,4137],{},"live-checked 2026-11-09",[975,4139,4140,4144,4151,4156,4170,4172,4177,4184],{},[990,4141,4142],{},[283,4143,3418],{},[990,4145,4146,796,4148],{},[283,4147,3418],{},[283,4149,4150],{},"~\u002F.omp",[990,4152,4153],{},[283,4154,4155],{},"~\u002F.omp\u002Fagent\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4157,4158,4159,4049,4162,4165,4166,4169],{},"extension ",[283,4160,4161],{},"~\u002F.omp\u002Fagent\u002Fextensions\u002Fagentfeedback.ts",[283,4163,4164],{},"tool_result"," errors, with the note, and ",[283,4167,4168],{},"agent_end",", not for subagents)",[990,4171,4060],{},[990,4173,4174],{},[283,4175,4176],{},"~\u002F.omp\u002Fagent\u002FAGENTS.md",[990,4178,4179,1224,4182],{},[283,4180,4181],{},"~\u002F.omp\u002Fagent\u002Fmcp.json",[283,4183,4019],{},[990,4185,3961],{},[975,4187,4188,4192,4199,4204,4215,4217,4222,4230],{},[990,4189,4190],{},[283,4191,3421],{},[990,4193,4194,796,4196],{},[283,4195,3421],{},[283,4197,4198],{},"~\u002F.pi",[990,4200,4201],{},[283,4202,4203],{},"~\u002F.pi\u002Fagent\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4205,4158,4206,4049,4209,4211,4212,1002],{},[283,4207,4208],{},"~\u002F.pi\u002Fagent\u002Fextensions\u002Fagentfeedback.ts",[283,4210,4164],{}," errors, with the note as a next-turn message, and ",[283,4213,4214],{},"agent_settled",[990,4216,4060],{},[990,4218,4219],{},[283,4220,4221],{},"~\u002F.pi\u002Fagent\u002FAGENTS.md",[990,4223,4224,1224,4227,4229],{},[283,4225,4226],{},"~\u002F.pi\u002Fagent\u002Fmcp.json",[283,4228,4019],{},"; needs pi 0.99.0 or later",[990,4231,3961],{},[975,4233,4234,4238,4248,4253,4266,4268,4273,4280],{},[990,4235,4236],{},[283,4237,3424],{},[990,4239,4240,796,4242,3867,4245,1002],{},[283,4241,3424],{},[283,4243,4244],{},"$COPILOT_HOME",[283,4246,4247],{},"~\u002F.copilot",[990,4249,4250],{},[283,4251,4252],{},"$COPILOT_HOME\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4254,4255,4256,421,4259,4262,4263,1002],{},"file ",[283,4257,4258],{},"$COPILOT_HOME\u002Fhooks\u002Fagentfeedback.json",[283,4260,4261],{},"postToolUseFailure",", with the note on exit 2, and ",[283,4264,4265],{},"agentStop",[990,4267,4060],{},[990,4269,4270],{},[283,4271,4272],{},"$COPILOT_HOME\u002Fcopilot-instructions.md",[990,4274,4275,1224,4278],{},[283,4276,4277],{},"$COPILOT_HOME\u002Fmcp-config.json",[283,4279,4019],{},[990,4281,3961],{},[975,4283,4284,4288,4299,4307,4324,4326,4335,4343],{},[990,4285,4286],{},[283,4287,3427],{},[990,4289,4290,796,4293,878,4296],{},[283,4291,4292],{},"agy",[283,4294,4295],{},"~\u002F.gemini\u002Fantigravity-cli",[283,4297,4298],{},"~\u002F.gemini\u002Fantigravity",[990,4300,4301,357,4304],{},[283,4302,4303],{},"~\u002F.gemini\u002Fconfig\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[283,4305,4306],{},"~\u002F.gemini\u002Fantigravity-cli\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4308,4309,1224,4312,4049,4314,796,4317,4320,4321,1002],{},[283,4310,4311],{},"~\u002F.gemini\u002Fconfig\u002Fhooks.json",[283,4313,703],{},[283,4315,4316],{},"PostToolUse",[283,4318,4319],{},"PreInvocation",", which delivers the note, and ",[283,4322,4323],{},"Stop",[990,4325,4060],{},[990,4327,4328,4330,4331,4334],{},[283,4329,3622],{}," (shared with gemini-cli unless ",[283,4332,4333],{},"$GEMINI_CLI_HOME"," is set)",[990,4336,4337,1224,4340,4342],{},[283,4338,4339],{},"~\u002F.gemini\u002Fconfig\u002Fmcp_config.json",[283,4341,4019],{},"; a URL entry's key reference in the header may not be expanded",[990,4344,3961],{},[975,4346,4347,4351,4358,4363,4374,4376,4381,4388],{},[990,4348,4349],{},[283,4350,3430],{},[990,4352,4353,796,4355],{},[283,4354,3430],{},[283,4356,4357],{},"~\u002F.config\u002Fdevin",[990,4359,4360],{},[283,4361,4362],{},"~\u002F.config\u002Fdevin\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4364,4365,1224,4368,4371,4372],{},[283,4366,4367],{},"~\u002F.config\u002Fdevin\u002Fconfig.json",[283,4369,4370],{},"hooks.PostToolUse"," (failed responses, with additional context) and ",[283,4373,3887],{},[990,4375,4060],{},[990,4377,4378],{},[283,4379,4380],{},"~\u002F.config\u002Fdevin\u002FAGENTS.md",[990,4382,4383,1224,4386],{},[283,4384,4385],{},"~\u002F.config\u002Fdevin\u002Fmcp_config.json",[283,4387,4019],{},[990,4389,3961],{},[975,4391,4392,4396,4404,4409,4412,4414,4419,4426],{},[990,4393,4394],{},[283,4395,3433],{},[990,4397,4398,796,4401],{},[283,4399,4400],{},"kiro-cli",[283,4402,4403],{},"~\u002F.kiro",[990,4405,4406],{},[283,4407,4408],{},"~\u002F.kiro\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4410,4411],{},"none",[990,4413,4060],{},[990,4415,4416],{},[283,4417,4418],{},"~\u002F.kiro\u002Fsteering\u002FAGENTS.md",[990,4420,4421,1224,4424],{},[283,4422,4423],{},"~\u002F.kiro\u002Fsettings\u002Fmcp.json",[283,4425,4019],{},[990,4427,3961],{},[975,4429,4430,4434,4441,4446,4463,4465,4470,4477],{},[990,4431,4432],{},[283,4433,3436],{},[990,4435,4436,796,4438],{},[283,4437,3436],{},[283,4439,4440],{},"~\u002F.cline",[990,4442,4443],{},[283,4444,4445],{},"~\u002F.cline\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4447,4448,4449,421,4452,4455,4456,3677,4459,4462],{},"SDK\u002FCLI plugin ",[283,4450,4451],{},"~\u002F.cline\u002Fplugins\u002Fagentfeedback.ts",[283,4453,4454],{},"afterTool"," errors via ",[283,4457,4458],{},"appendContext",[283,4460,4461],{},"afterRun","); not VS Code\u002FJetBrains",[990,4464,4060],{},[990,4466,4467],{},[283,4468,4469],{},"~\u002F.cline\u002Frules\u002Fagentfeedback.md",[990,4471,4472,1224,4475,4342],{},[283,4473,4474],{},"~\u002F.cline\u002Fdata\u002Fsettings\u002Fcline_mcp_settings.json",[283,4476,4019],{},[990,4478,3961],{},[975,4480,4481,4485,4499,4504,4516,4518,4523,4539],{},[990,4482,4483],{},[283,4484,3439],{},[990,4486,4487,796,4489,421,4492,4495,4496,1002],{},[283,4488,3439],{},[283,4490,4491],{},"\u003Cxdg>\u002Famp",[283,4493,4494],{},"\u003Cxdg>"," is ",[283,4497,4498],{},"${XDG_CONFIG_HOME:-~\u002F.config}",[990,4500,4501],{},[283,4502,4503],{},"\u003Cxdg>\u002Famp\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4505,4045,4506,421,4509,4512,4513,1002],{},[283,4507,4508],{},"\u003Cxdg>\u002Famp\u002Fplugins\u002Fagentfeedback.ts",[283,4510,4511],{},"tool.result"," errors, preserving the failed result and appending the note, and ",[283,4514,4515],{},"agent.end",[990,4517,4060],{},[990,4519,4520],{},[283,4521,4522],{},"\u003Cxdg>\u002Famp\u002FAGENTS.md",[990,4524,4525,4528,4529,4531,4532,4535,4536],{},[283,4526,4527],{},"amp.mcpServers"," member ",[283,4530,703],{}," in ",[283,4533,4534],{},"\u003Cxdg>\u002Famp\u002Fsettings.jsonc"," when it exists, else ",[283,4537,4538],{},"settings.json",[990,4540,3961],{},[975,4542,4543,4547,4562,4570,4572,4574,4577,4585],{},[990,4544,4545],{},[283,4546,3442],{},[990,4548,4549,796,4551,828,4554,4557,4558,4561],{},[283,4550,283],{},[283,4552,4553],{},"\u003CCode\u002FUser>",[283,4555,4556],{},"\u003Cxdg>\u002FCode\u002FUser"," on Linux, ",[283,4559,4560],{},"~\u002FLibrary\u002FApplication Support\u002FCode\u002FUser"," on macOS",[990,4563,4564,4565,878,4567,4569],{},"none: VS Code reads the skill the ",[283,4566,3424],{},[283,4568,3403],{}," adapter installs",[990,4571,4411],{},[990,4573,4060],{},[990,4575,4576],{},"none: VS Code has no CLI mode",[990,4578,4579,1224,4582],{},[283,4580,4581],{},"\u003CCode\u002FUser>\u002Fmcp.json",[283,4583,4584],{},"servers.agentfeedback",[990,4586,3961],{},[975,4588,4589,4593,4604,4612,4614,4616,4623,4625],{},[990,4590,4591],{},[283,4592,3445],{},[990,4594,4595,421,4598,4601,4602,4334],{},[283,4596,4597],{},"gemini",[283,4599,4600],{},"~\u002F.gemini"," is shared with antigravity unless ",[283,4603,4333],{},[990,4605,4606,3867,4609,1002],{},[283,4607,4608],{},"$GEMINI_CLI_HOME\u002F.gemini\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[283,4610,4611],{},"~\u002F.gemini\u002Fskills\u002Fagentfeedback\u002FSKILL.md",[990,4613,4411],{},[990,4615,4060],{},[990,4617,4618,3867,4621,1002],{},[283,4619,4620],{},"$GEMINI_CLI_HOME\u002F.gemini\u002FGEMINI.md",[283,4622,3622],{},[990,4624,4411],{},[990,4626,3961],{},[866,4628,4629,4701,4731,4741,4778,4867,4929,4963,4999,5054,5090,5125,5135,5145,5202,5214,5260,5285,5301,5320,5332,5355,5376,5381],{},[869,4630,4631,4634,4635,4638,4639,4641,4642,4646,4647,796,4649,357,4651,4653,4654,4657,4658,4661,4662,4664,4665,4668,4669,4671,4672,4675,4676,4679,4680,4683,4684,4687,4688,4690,4691,796,4693,357,4695,4697,4698,4700],{},[872,4632,4633],{},"Hooks."," Every hook runs ",[283,4636,4637],{},"agentfeedback hook \u003Charness> \u003Cevent>"," on the\nevents in the table; ",[283,4640,3406],{}," gets the end-of-turn hook only,\nwhich flushes and can trigger the ",[208,4643,4645],{"href":4644},"\u002Fdocs\u002Freference\u002Fsessions#automatic-sweep","session sweep",";\n",[283,4648,3433],{},[283,4650,3442],{},[283,4652,3445],{}," get none yet.\nDevin counts only explicitly unsuccessful tool responses. Amp preserves\nthe failed result and appends the note to its error; cancelled results do\nnot count. Cline adds model-visible context without replacing the result,\nand its subprocess budget is two seconds, below the SDK's three-second\nhook deadline. No new hook registrations are needed for the sweep.\nAfter upgrading from a release that wired ",[283,4655,4656],{},"flush --hook",", run\n",[283,4659,4660],{},"agentfeedback install \u003Charness>"," again: the older entries are replaced, and\n",[283,4663,749],{}," names each harness that still runs one. The\nsession-start hook (on by default, ",[283,4666,4667],{},"--with-reminder=false"," leaves it out)\nruns ",[283,4670,3608],{},", which prints short guidance (the triggers,\nthe one command and a pointer to the skill, under 1,200 bytes) for the\nharness to add to the session; ",[283,4673,4674],{},"prime --full"," prints the skill's whole\nCLI text, and install wires it for a harness without a skills directory;\nCursor's runs ",[283,4677,4678],{},"prime --format cursor",", which prints\n",[283,4681,4682],{},"{\"additional_context\": ...}",". A rerun replaces the ",[283,4685,4686],{},"skill reminder","\nentry older installs wired; ",[283,4689,4686],{}," still works. It is supported\non ",[283,4692,3403],{},[283,4694,3406],{},[283,4696,3409],{}," only; elsewhere an explicit\n",[283,4699,3486],{}," is noted and skipped.",[869,4702,4703,1224,4706,4708,4709,878,4711,4713,4714,4717,4718,4720,4721,4723,4724,4720,4727,4730],{},[872,4704,4705],{},"Refused modes.",[283,4707,3442],{}," has no skill directory of its own (VS Code\nreads the skill the ",[283,4710,3424],{},[283,4712,3403],{}," adapter installs), so\n",[283,4715,4716],{},"install vscode"," without ",[283,4719,3630],{}," is refused. ",[283,4722,3445],{}," has no MCP entry,\nso ",[283,4725,4726],{},"install gemini-cli --mcp",[283,4728,4729],{},"install all"," leaves such a\nharness out with a note instead of refusing.",[869,4732,4733,4736,4737,4740],{},[872,4734,4735],{},"MCP header variables."," Antigravity and Cline document no\nenvironment-variable syntax for MCP headers. A URL entry (only the manual\nsteps write one, when the binary's path cannot be resolved) references\n",[283,4738,4739],{},"${AGENT_FEEDBACK_API_KEY}",", and a note says to check the connection: a\n401 means the reference was not expanded.",[869,4742,4743,4746,4747,4750,4751,421,4754,4757,4758,796,4761,878,4764,662,4767,662,4770,4773,4774,4777],{},[872,4744,4745],{},"The registry."," Install also records, per harness, the instruction\nfiles, hook events, MCP entry forms, session store locations and caveats.\n",[283,4748,4749],{},"install --list --json"," prints each harness's ",[283,4752,4753],{},"verification",[283,4755,4756],{},"level",":\n",[283,4759,4760],{},"documented",[283,4762,4763],{},"fixture-tested",[283,4765,4766],{},"live-checked",[283,4768,4769],{},"date",[283,4771,4772],{},"note","), and the\ntable's ",[283,4775,4776],{},"VERIFIED"," column shows level and date.",[869,4779,4780,1224,4783,4785,4786,4789,4790,4793,4794,4797,4798,4801,4802,4805,4806,4809,4810,4813,4814,4817,4818,4821,4822,4825,4826,4828,4829,4831,4832,4835,4836,4838,4839,4842,4843,4845,4846,4848,4849,4851,4852,4855,4856,4859,4860,4862,4863,4866],{},[872,4781,4782],{},"The hook.",[283,4784,4637],{}," reads the event's\npayload from stdin (at most 1 MiB) and nothing else: never the transcript\nor any other file the payload names. It counts the failed tool calls of\neach session and, when they pile up, gives the agent one short note that\nit can file a friction report (",[283,4787,4788],{},"agentfeedback submit friction ... --context origin=hook-nudge --context session_id=\u003Cid> --context session_harness=\u003Charness>",") or ignore it. The note is given when, since\nthe last note, one tool failed ",[283,4791,4792],{},"same_tool"," times, one command (whitespace\ncollapsed) failed ",[283,4795,4796],{},"same_command"," times, or ",[283,4799,4800],{},"session_failures"," tool calls\nfailed; at most ",[283,4803,4804],{},"max_per_session"," notes per session, ",[283,4807,4808],{},"interval_minutes","\napart, and none once the session filed a friction report (the client\nleaves an empty marker ",[283,4811,4812],{},"filed\u002F\u003Cdigest of the session id>"," in the cache\ndirectory when it logs a friction report with a ",[283,4815,4816],{},"session_id"," context as\nsubmitted, duplicate, spooled or flushed). Successful ",[283,4819,4820],{},"submit_feedback","\ncalls through ",[283,4823,4824],{},"agentfeedback mcp"," also leave that marker, both locally\nand when relaying to a server, using the submitted or locally resolved session.\nThe server's HTTP ",[283,4827,953],{}," never writes a client's marker. Recognized aborts,\npermission denials and the agentfeedback commands and MCP tools themselves\nare not counted. Pi skips aborted and blocked calls before ",[283,4830,4164],{},";\nthe extension also checks ",[283,4833,4834],{},"ctx.signal.aborted",", so a genuine failure arriving\nwhile that signal is aborted is ignored too. omp permission denials occur\nbefore ",[283,4837,4164],{},". Its exception type is lost in that event, so the\nextension recognizes only a single text block exactly ",[283,4840,4841],{},"Operation aborted","\nwith undefined details. This includes internal cancellations or timeouts\nthat use that shape, not just user interrupts. A genuine failure with the\nidentical shape is also ignored; other cancellation messages cannot be\nclassified reliably. These are API\u002Fsource and isolated callback checks,\nnot authenticated model delivery verification.\nHarnesses that show a note only at another event (the\n",[283,4844,4319],{}," of Antigravity, the ",[283,4847,3563],{}," of OpenCode) get it there,\nwithin the same turn. Copilot shows a note only when the hook exits 2;\nthat is the one case the hook exits non-zero. Stdin that does not end\nwithin 1 second counts as no payload, and the counting gives up 1.5\nseconds after the start (a session file another hook keeps locked\nincluded), logging one error line and giving no note. At the end of a turn in\nremote mode the hook then sends the spool's due entries, as\n",[283,4850,4656],{}," does: it stops sending 3.5 seconds after it starts and\nreturns by 4.5 seconds (inside the 5-second timeout the hook is given).\nCline's plugin allows two seconds: sending stops at one second,\nbookkeeping waits until 1.5 seconds, and the capture trigger has until\n1.8 seconds. Cancelled sends remain spooled for a later retry.\nLocal mode needs no flush and opens no database. The hook prints nothing\nbut the note, never writes to stderr, logs any failure to ",[283,4853,4854],{},"client.jsonl","\nand otherwise exits 0. ",[283,4857,4858],{},"agentfeedback flush --hook",", which older installs\nwired, still works in remote mode; in local mode it does nothing, and the\nnext command delivers the spool and the inbox. Hook commands hold the binary's\nresolved absolute path, which may contain only letters, digits and\n",[283,4861,2784],{},", single-quoted when it holds anything outside ASCII\nletters, digits and ",[283,4864,4865],{},"\u002F . _ - +","; rerun install after moving the binary.",[869,4868,4869,4872,4873,4876,4877,828,4879,4882,4883,662,4885,4888,4889,4891,4892,4894,4895,4897,4898,4900,4901,4903,4904,4907,4908,4911,4912,4914,4915,4918,4919,4922,4923,878,4926,318],{},[872,4870,4871],{},"Nudge settings."," The ",[283,4874,4875],{},"[detect]"," table of ",[283,4878,3096],{},[283,4880,4881],{},"nudge","\n(default ",[283,4884,2609],{},[283,4886,4887],{},"false"," keeps counting and gives no note), ",[283,4890,4792],{},"\n(3), ",[283,4893,4796],{}," (2), ",[283,4896,4800],{}," (5), ",[283,4899,4808],{}," (20),\n",[283,4902,4804],{}," (3); a value of 0 or less keeps the default. A\nrepository's ",[283,4905,4906],{},".agentfeedback.toml"," may set ",[283,4909,4910],{},"[detect] nudge = false"," for\nwork under it, and a directory whose collection is switched off gets no\nnote either. A ",[283,4913,3096],{}," that cannot be read gives no note, and so\ndoes a payload without an absolute ",[283,4916,4917],{},"cwd"," when ",[283,4920,4921],{},"[collect]"," sets\n",[283,4924,4925],{},"disabled",[283,4927,4928],{},"opt_in_only",[869,4930,4931,4934,4935,4938,4939,4942,4943,4945,4946,421,4949,796,4952,4955,4956,4959,4960,4962],{},[872,4932,4933],{},"Hook state and diagnostics."," Counters (no command text) live in\n",[283,4936,4937],{},"${XDG_CACHE_HOME:-~\u002F.cache}\u002Fagentfeedback\u002Fsessions\u002F\u003Charness>\u002F\u003Csession>-\u003Cdigest>.json","\n(the session id cut to 40 bytes, then 16 hex digits of its SHA-256), with\na ",[283,4940,4941],{},".lock"," file beside each, owner-only, and are deleted 7 days after their\nlast change, as are ",[283,4944,1133],{}," markers. Every run\nwrites ",[283,4947,4948],{},"hooks\u002F\u003Charness>.json",[283,4950,4951],{},"ts",[283,4953,4954],{},"event",") beside them; the Amp, Cline,\nOpenCode, omp and pi plugins write ",[283,4957,4958],{},"hooks\u002F\u003Charness>.spawn-error.json"," when they\ncannot start the binary. ",[283,4961,749],{}," prints when each\nharness's hook last ran and reports a spawn error newer than that.",[869,4964,4965,4872,4969,4972,4973,4976,4977,4979,4980,4983,4984,4987,4988,4991,4992,4995,4996,4998],{},[872,4966,4967,318],{},[283,4968,3495],{},[283,4970,4971],{},"agentfeedback-docs"," skill goes to\n",[283,4974,4975],{},"\u003Cskills dir>\u002Fagentfeedback-docs\u002F",", beside the skill's directory in the\ntable (for ",[283,4978,3630],{}," too, where no skill is installed): a ",[283,4981,4982],{},"SKILL.md"," that maps\n",[283,4985,4986],{},"references\u002F",", which holds this binary's copies of ",[283,4989,4990],{},"docs\u002F",", the OpenAPI\ndocument, ",[283,4993,4994],{},"schemas\u002F"," and both install playbooks. A run without ",[283,4997,3495],{},"\nremoves it; an edited file in it is refused like an edited skill.",[869,5000,5001,5005,5006,5009,5010,5013,5014,5016,5017,421,5020,796,5022,1158,5025,796,5028,5031,5032,306,5035,5038,5039,5042,5043,5046,5047,5049,5050,5053],{},[872,5002,5003,318],{},[283,5004,3489],{}," On by default: the ",[283,5007,5008],{},"agentfeedback-triage"," skill goes\nto ",[283,5011,5012],{},"\u003Cskills dir>\u002Fagentfeedback-triage\u002F"," (for ",[283,5015,3630],{}," too), this binary's\ncopy of ",[283,5018,5019],{},"skills\u002Fagentfeedback-triage\u002F",[283,5021,4982],{},[283,5023,5024],{},"playbooks\u002F",[283,5026,5027],{},"reference\u002F",[283,5029,5030],{},"scripts\u002Fcluster.py","); the agent runs it only when the human\ninvokes ",[283,5033,5034],{},"\u002Fagentfeedback-triage",[283,5036,5037],{},"--with-triage=false"," removes it; an edited\nfile in it is refused like an edited skill. A triage directory or link\ninstall did not write (one ",[283,5040,5041],{},"npx skills add"," installed, say) is left as it\nis, with a note, and its column reads ",[283,5044,5045],{},"external","; remove it and run\ninstall again to get this binary's version. ",[283,5048,3092],{}," installs\nit too unless given ",[283,5051,5052],{},"--no-triage"," (on a terminal it asks first).",[869,5055,5056,5060,5061,5063,5064,5066,5067,5069,5070,878,5072,5074,5075,357,5077,5079,5080,5083,5084,5086,5087,5089],{},[872,5057,5058,318],{},[283,5059,3630],{}," The MCP entry replaces the skill and the hook for that\nharness: the server's MCP instructions teach the agent, and nothing is\nspooled without the CLI. The entry is a stdio entry that runs the binary's\nresolved absolute path: with the argument ",[283,5062,860],{}," for local\n(",[283,5065,4824],{},", the tools on the local database), and with\n",[283,5068,863],{}," for a server, which relays the tools to that server\nand never falls back to the local database. The key comes from\n",[283,5071,368],{},[283,5073,3096],{}," when the entry runs, so no key or\nkey reference is written into a harness file; install warns when neither\nholds a key, and without one the entry fails to start. The Codex block\nforwards ",[283,5076,742],{},[283,5078,368],{}," by name\n(",[283,5081,5082],{},"env_vars","). Rerun install after moving the binary or changing the\nserver: the entry is replaced. ",[283,5085,3486],{}," does not apply with\n",[283,5088,3630],{}," (noted when given explicitly).",[869,5091,5092,1224,5095,3710,5098,4531,5100,5102,5103,5105,5106,5108,5109,5111,5112,5115,5116,5118,5119,5121,5122,5124],{},[872,5093,5094],{},"The server.",[283,5096,5097],{},"--server local|cloud|URL",[283,5099,738],{},[283,5101,3096],{},",\nelse the server the last install recorded, else a prompt on a terminal\n(an empty answer means local), else local: with nothing named, install\nwires the harnesses for local mode and records ",[283,5104,827],{},". A ",[283,5107,1356],{}," that differs from\n",[283,5110,3096],{}," is refused: install never changes the configured server\n(",[283,5113,5114],{},"doctor --init --force"," does). Install never writes ",[283,5117,3096],{},"; when a\nserver is named and the file does not exist, ",[283,5120,2804],{}," holds the\n",[283,5123,348],{}," command.",[869,5126,5127,5130,5131,5134],{},[872,5128,5129],{},"Edits and backups."," JSON and JSONC files are edited in place, keeping\ncomments, trailing commas and formatting; nothing else in them changes.\nBefore the first change to an existing file install copies it to\n",[283,5132,5133],{},"\u003Cfile>.agentfeedback-backup",". Writes are atomic and stop when a file\nchanges while install runs. A file with the same key twice in one object\nis refused (uninstall leaves it as it is and keeps its backup). A\nconfiguration file (JSON, JSONC or TOML) or global instruction file that is a symbolic link is edited\nthrough the link: the target is written atomically in its own directory,\nthe link stays, and the backup sits beside the link. A dangling link, or\none to something other than a regular file, is refused. Two configuration\nfiles that are the same file (one links to the other, or both link to one\ntarget) are refused. A linked skill (file or directory), plugin or hook\nfile that install owns is refused: remove it and run install again;\nuninstall leaves such a link in place with a note. Uninstall restores a linked file's target\nfrom the backup through the link; a file install created that is now a\nlink only loses the agentfeedback entries.",[869,5136,5137,5140,5141,5144],{},[872,5138,5139],{},"One run at a time."," Install, uninstall and ",[283,5142,5143],{},"--dry-run"," hold an\nexclusive lock on the home directory for the whole run, so no lock file is\nleft behind; a second run while one holds it is refused (run it again when\nthe first finishes). The lock is taken before the manifest is read. On a\nfile system that cannot lock (NFS, for one) install warns on stderr and\nruns without it: make sure no other install runs at the same time. The\nlist takes no lock.",[869,5146,5147,1224,5150,5153,5154,5156,5157,5159,5160,5163,5164,796,5167,1158,5170,878,5172,5175,5176,2984,5178,5180,5181,5183,5184,796,5187,796,5189,1158,5191,796,5193,357,5195,5197,5198,5201],{},[872,5148,5149],{},"The manifest.",[283,5151,5152],{},"${XDG_CONFIG_HOME:-~\u002F.config}\u002Fagentfeedback\u002Finstall.json","\n(",[283,5155,344],{},") records every entry, file, backup and directory install made.\nUninstall removes exactly those: a file nobody changed since goes back to\nits backup byte for byte (or away, if install created it) and the backup is\ndeleted; a changed file loses only the recorded entries and keeps its\nbackup, listed in ",[283,5158,3477],{},"; an edited skill or plugin file is left in\nplace, and so is an MCP entry whose value was changed since install (noted).\nA file someone else changed between two installs is marked diverged:\nuninstall never restores its backup or deletes it, but removes the recorded\nentries and keeps the backup, listed. A backup that is missing, or is not\nthe copy install took, is not restored either; a backup equal to the file\nit was taken from is deleted. Before its first change of any kind a run\nwrites the manifest once with its server, binary and locations; if that\nwrite fails, the run stops having changed nothing. After that the manifest\nis updated after every claude command and every file. Each file is\nchecked for changes before its backup is written and again just before it\nis replaced; when the write fails or the file changed, the backup this run\nwrote for it is deleted. So after a failed write the manifest matches what\nwas written, and running the command again finishes the job. Only a hard\ncrash in the moment between a write and its manifest update leaves an\nentry unrecorded; the next run then refuses it as foreign, naming it,\nexcept that a leftover backup equal to its file is taken over as the\nbackup, an empty skill directory the manifest records as created is\nreused, and a whole file (a skill file or plugin file) holding exactly the\nbytes install would write is taken over as written by install: recorded,\nnot rewritten, no backup, and removed by uninstall. A skill directory the\nmanifest records nothing of is taken over that way only when it holds\nnothing but such files. The manifest records the Codex home, Claude Code configuration\ndirectory, Gemini CLI ",[283,5161,5162],{},".gemini"," directory and Copilot home of the harnesses it keeps; a\nlater run under another ",[283,5165,5166],{},"CODEX_HOME",[283,5168,5169],{},"CLAUDE_CONFIG_DIR",[283,5171,3626],{},[283,5173,5174],{},"COPILOT_HOME"," keeps using the recorded location for\nthat harness, notes it, and runs ",[283,5177,3863],{},[283,5179,5169],{}," as\nrecorded: set to the recorded directory when it was set at install, even\nto ",[283,5182,3870],{},", and unset when it was unset. Install refuses a\nmanifest that names a path it does not write under the current\nenvironment: run it with the ",[283,5185,5186],{},"HOME",[283,5188,1150],{},[283,5190,5166],{},[283,5192,5169],{},[283,5194,3626],{},[283,5196,5174],{}," of the install, or fix the\nmanifest.\nEmpty directories install created go, and so does the manifest when\nno harness is left. What a harness added to a file install created (OpenCode\nadds ",[283,5199,5200],{},"$schema",") stays.",[869,5203,5204,5207,5208,5210,5211,5213],{},[872,5205,5206],{},"Foreign entries are refused."," An ",[283,5209,703],{}," MCP entry, TOML table,\n",[283,5212,4971],{}," skill directory or plugin file with other bytes than\ninstall writes, or an identical hook, that the manifest does not record\nstops the run before anything is written, naming the path: remove or\nrename it and run install again. A recorded skill or plugin file edited\nsince install is refused too, and so is an unrecorded file with other\nbytes in a skill directory the manifest records.",[869,5215,5216,5207,5219,1763,5221,5223,5224,5227,5228,5230,5231,5234,5235,5237,5238,5241,5242,5245,5246,5249,5250,5252,5253,5256,5257,5259],{},[872,5217,5218],{},"Skills installed another way are left.",[283,5220,703],{},[283,5222,5008],{}," skill directory or link the manifest records\nnothing of (a copy or link of ",[283,5225,5226],{},"skills\u002Fagentfeedback",", or one ",[283,5229,5041],{}," installed with its ",[283,5232,5233],{},"scripts\u002F","), and that install would not take over\nas above, is left as it is with a note; the rest is wired, its column\nreads ",[283,5236,5045],{},", and uninstall leaves it. Remove it and run install again\nto get this binary's version. When the harness's plugin registry lists an\n",[283,5239,5240],{},"agentfeedback@\u003Cmarketplace>"," plugin (Claude Code:\n",[283,5243,5244],{},"\u003Cclaude config>\u002Fplugins\u002Finstalled_plugins.json","; Codex: a\n",[283,5247,5248],{},"[plugins.\"agentfeedback@\u003Cmarketplace>\"]"," table in\n",[283,5251,3958],{}," not set ",[283,5254,5255],{},"enabled = false","), the plugin provides\nthe skill: install writes none, removes the copy an earlier install\nwrote, wires the rule and hooks, and the skill column reads ",[283,5258,5045],{},".\nInstall only reads those registries; one that is missing or does not\nparse lists no plugin.",[869,5261,5262,5266,5267,5270,5271,5274,5275,5277,5278,5281,5282,318],{},[872,5263,5264],{},[283,5265,5169],{}," moves Claude Code's settings, skills and\n",[283,5268,5269],{},".claude.json"," (to ",[283,5272,5273],{},"$CLAUDE_CONFIG_DIR\u002F.claude.json","), and install follows\nit. Set to ",[283,5276,3870],{}," counts as set: Claude Code then reads\n",[283,5279,5280],{},"~\u002F.claude\u002F.claude.json",", not ",[283,5283,5284],{},"~\u002F.claude.json",[869,5286,5287,5290,5291,878,5293,5295,5296,878,5298,5300],{},[872,5288,5289],{},"Relative Claude\u002FCodex homes."," Install refuses a nonempty relative\n",[283,5292,5169],{},[283,5294,5166],{}," when installing that harness, including\ndry runs and multi-harness requests (",[283,5297,2041],{},[283,5299,364],{}," when that harness is\ndetected). The whole request is refused before installation writes.\nSet an absolute path or unset the variable: resolving it against the\ninstaller's working directory could wire a different location from the\nharness's working directory. Requests for only unrelated harnesses and\nuninstall of recorded locations are unaffected.",[869,5302,5303,5307,5308,4531,5311,4646,5314,5317,5318,318],{},[872,5304,5305],{},[283,5306,3626],{}," replaces the home directory for Gemini CLI, which\nthen keeps its skills and ",[283,5309,5310],{},"GEMINI.md",[283,5312,5313],{},"$GEMINI_CLI_HOME\u002F.gemini",[283,5315,5316],{},"install gemini-cli"," follows an absolute value and ignores a relative one.\nAntigravity does not read it and keeps ",[283,5319,4600],{},[869,5321,5322,5326,5327,5329,5330,318],{},[872,5323,5324],{},[283,5325,5174],{}," replaces ",[283,5328,4247],{}," for Copilot CLI's skills, hooks,\ninstructions and MCP entry. Install follows an absolute value and ignores a\nrelative one. Reinstall, check and uninstall use the recorded location even\nafter the variable changes; manifests without a recorded Copilot location\nretain ",[283,5331,4247],{},[869,5333,5334,5337,5338,5153,5340,836,5342,5344,5345,5347,5348,5351,5352,318],{},[872,5335,5336],{},"Claude Code's MCP entry"," is checked against ",[283,5339,5269],{},[283,5341,5284],{},[283,5343,5273],{}," when the variable\nis set; read only): an entry removed by hand is added again by install\nand skipped by uninstall; one pointing at another URL, or running another\ncommand, is refused by install and left in place by uninstall. When ",[283,5346,3863],{}," is missing or\n",[283,5349,5350],{},"claude mcp remove"," fails, uninstall goes on and notes the command to run\nby hand:\n",[283,5353,5354],{},"claude mcp remove agentfeedback --scope user",[869,5356,5357,5360,5361,5364,5365,5367,5368,796,5370,796,5372,357,5374,318],{},[872,5358,5359],{},"Codex"," runs a new hook only after you trust it in ",[283,5362,5363],{},"\u002Fhooks",". It passes a\nstdio server only the variables ",[283,5366,5082],{}," lists, so its stdio entry lists\n",[283,5369,1147],{},[283,5371,1150],{},[283,5373,1153],{},[283,5375,742],{},[869,5377,5378,5380],{},[872,5379,102],{}," also runs Claude Code's hooks and skills.",[869,5382,5383,5386,5387,5390],{},[872,5384,5385],{},"Verification status."," The table's Verified column and ",[283,5388,5389],{},"install --list","\nshow how far each harness was checked: Claude Code by the live harness\ngate; OpenCode V1 loads the skill and connects the MCP entry; OpenCode 2\nran its plugin in a session (a failure counted, the note delivered) and\nreads the skill, the rule and the MCP entry; the hook commands, the\nOpenCode V1 plugin and the omp extension ran outside a live session; every other harness is written from its documentation, dated in\nthe table.",[276,5392,234],{"id":5393},"build-from-source",[201,5395,5396,5397,5400],{},"The release binaries are built with exactly this line, so building a release\ntag yourself gives the same file, byte for byte, as the binary in that\nrelease's archive: what you compiled is what releases ship. Needs Git and Go\n1.21 or later; ",[283,5398,5399],{},"GOTOOLCHAIN"," fetches the toolchain the release pins.",[381,5402,5404],{"className":383,"code":5403,"language":385,"meta":386,"style":386},"git clone https:\u002F\u002Fgithub.com\u002FAgentFeedback\u002Fagentfeedback.git && cd agentfeedback\ngit checkout vX.Y.Z\nGOTOOLCHAIN=$(awk '$1 == \"toolchain\" { print $2 }' go.mod) CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \\\n  go build -trimpath -ldflags=\"-s -w -X main.version=X.Y.Z -X main.commit=$(git rev-parse HEAD)\" \\\n  -o agentfeedback .\u002Fcmd\u002Fagentfeedback\n.\u002Fagentfeedback version\n",[283,5405,5406,5424,5434,5476,5500,5511],{"__ignoreMap":386},[390,5407,5408,5411,5414,5417,5419,5421],{"class":392,"line":393},[390,5409,5410],{"class":442},"git",[390,5412,5413],{"class":400}," clone",[390,5415,5416],{"class":400}," https:\u002F\u002Fgithub.com\u002FAgentFeedback\u002Fagentfeedback.git",[390,5418,430],{"class":420},[390,5420,397],{"class":396},[390,5422,5423],{"class":400}," agentfeedback\n",[390,5425,5426,5428,5431],{"class":392,"line":404},[390,5427,5410],{"class":442},[390,5429,5430],{"class":400}," checkout",[390,5432,5433],{"class":400}," vX.Y.Z\n",[390,5435,5436,5438,5440,5442,5445,5448,5451,5454,5456,5458,5461,5463,5466,5469,5471,5474],{"class":392,"line":470},[390,5437,5399],{"class":420},[390,5439,551],{"class":416},[390,5441,566],{"class":420},[390,5443,5444],{"class":442},"awk",[390,5446,5447],{"class":400}," '$1 == \"toolchain\" { print $2 }'",[390,5449,5450],{"class":400}," go.mod",[390,5452,5453],{"class":420},") CGO_ENABLED",[390,5455,551],{"class":416},[390,5457,1410],{"class":400},[390,5459,5460],{"class":420}," GOOS",[390,5462,551],{"class":416},[390,5464,5465],{"class":400},"linux",[390,5467,5468],{"class":420}," GOARCH",[390,5470,551],{"class":416},[390,5472,5473],{"class":400},"amd64",[390,5475,607],{"class":442},[390,5477,5478,5481,5484,5487,5490,5493,5495,5498],{"class":392,"line":491},[390,5479,5480],{"class":400},"  go",[390,5482,5483],{"class":400}," build",[390,5485,5486],{"class":396}," -trimpath",[390,5488,5489],{"class":396}," -ldflags=",[390,5491,5492],{"class":400},"\"-s -w -X main.version=X.Y.Z -X main.commit=$(",[390,5494,5410],{"class":442},[390,5496,5497],{"class":400}," rev-parse HEAD)\"",[390,5499,607],{"class":396},[390,5501,5502,5505,5508],{"class":392,"line":620},[390,5503,5504],{"class":396},"  -o",[390,5506,5507],{"class":400}," agentfeedback",[390,5509,5510],{"class":400}," .\u002Fcmd\u002Fagentfeedback\n",[390,5512,5513,5516],{"class":392,"line":632},[390,5514,5515],{"class":442},".\u002Fagentfeedback",[390,5517,5518],{"class":400}," version\n",[201,5520,5521,5524,5525,662,5528,4495,5531,796,5533,878,5536,5539,5540,5543,5544,4495,5547,878,5549,5552,5553,5556,5557,5560,5561,5563,5564,5567,5568,5153,5571,5574,5575,5579],{},[283,5522,5523],{},"X.Y.Z"," is the tag without the ",[283,5526,5527],{},"v",[283,5529,5530],{},"GOOS",[283,5532,5465],{},[283,5534,5535],{},"darwin",[283,5537,5538],{},"windows","\n(name the output ",[283,5541,5542],{},"agentfeedback.exe","), ",[283,5545,5546],{},"GOARCH",[283,5548,5473],{},[283,5550,5551],{},"arm64",". The\ntoolchain is the ",[283,5554,5555],{},"toolchain"," line of ",[283,5558,5559],{},"go.mod",", downloaded from the Go module\nproxy and verified against the Go checksum database. The binary embeds the\nGit revision and whether the tree was modified, so the result is identical\nonly from a Git checkout of the tag with no changed or untracked files (the\noutput names above are ignored by Git); a source archive without ",[283,5562,3706],{},"\nbuilds a working but different binary. To compare with the release:\n",[283,5565,5566],{},"sha256sum agentfeedback"," against\n",[283,5569,5570],{},"tar -xOzf agentfeedback_X.Y.Z_linux_amd64.tar.gz agentfeedback | sha256sum",[283,5572,5573],{},"shasum -a 256"," on macOS). ",[208,5576,5578],{"href":5577},"\u002Fdocs\u002Freference\u002Freleases#reproducing-a-release","releases.md","\ncovers the archives.",[201,5581,5582,5583,5586],{},"Without a checkout, ",[283,5584,5585],{},"go install"," builds the same tag from the module proxy:",[381,5588,5590],{"className":383,"code":5589,"language":385,"meta":386,"style":386},"go install github.com\u002Fagentfeedback\u002Fagentfeedback\u002Fv4\u002Fcmd\u002Fagentfeedback@vX.Y.Z\n",[283,5591,5592],{"__ignoreMap":386},[390,5593,5594,5597,5599],{"class":392,"line":393},[390,5595,5596],{"class":442},"go",[390,5598,2730],{"class":400},[390,5600,5601],{"class":400}," github.com\u002Fagentfeedback\u002Fagentfeedback\u002Fv4\u002Fcmd\u002Fagentfeedback@vX.Y.Z\n",[201,5603,5604,5605,5608,5609,5612,5613,5153,5616,5619,5620,357,5623,5626,5627,750,5630,5633,5634,5636,5637,5639,5640,5643,5644,5647,5648,5650],{},"The tag's major version must match the ",[283,5606,5607],{},"\u002Fv4"," in the module path: the Go\ntool refuses a ",[283,5610,5611],{},"v3"," tag for this path. The binary lands in ",[283,5614,5615],{},"$(go env GOBIN)",[283,5617,5618],{},"$(go env GOPATH)\u002Fbin"," when unset). It is not byte-identical to the\nrelease: it is built without the ldflags, ",[283,5621,5622],{},"-trimpath",[283,5624,5625],{},"CGO_ENABLED=0","\nabove and from the module proxy's source archive, which carries no Git\nmetadata, so the version comes from the toolchain's build information and\n",[283,5628,5629],{},"agentfeedback version",[283,5631,5632],{},"agentfeedback vX.Y.Z (commit unknown, go1.N.M)",": the tag with its ",[283,5635,5527],{},", no commit, and the Go version that built\nit. ",[283,5638,795],{},"'s minimum-version check reads both spellings.\nGit-describe builds (",[283,5641,5642],{},"v4.0.0-3-gabc1234","), versions ending in ",[283,5645,5646],{},"-dirty",", and Go\npseudo-versions compare as ",[283,5649,1646],{},", not as releases below the server's\nminimum. Use a tagged release when a definite compatibility check is needed.",[845,5652,5654],{"id":5653},"nix","Nix",[201,5656,5657],{},"With Nix flakes enabled, build or run the source package:",[381,5659,5661],{"className":383,"code":5660,"language":385,"meta":386,"style":386},"nix run github:AgentFeedback\u002Fagentfeedback -- version\nnix build github:AgentFeedback\u002Fagentfeedback\n",[283,5662,5663,5678],{"__ignoreMap":386},[390,5664,5665,5667,5670,5673,5676],{"class":392,"line":393},[390,5666,5653],{"class":442},[390,5668,5669],{"class":400}," run",[390,5671,5672],{"class":400}," github:AgentFeedback\u002Fagentfeedback",[390,5674,5675],{"class":396}," --",[390,5677,5518],{"class":400},[390,5679,5680,5682,5684],{"class":392,"line":404},[390,5681,5653],{"class":442},[390,5683,5483],{"class":400},[390,5685,5686],{"class":400}," github:AgentFeedback\u002Fagentfeedback\n",[201,5688,5689,5690,5693,5694,5697,5698,800,5701,5704],{},"The flake provides native x86-64 and ARM64 packages for Linux and macOS.\nPin a release by appending ",[283,5691,5692],{},"\u002FvX.Y.Z"," to the repository reference (choose a\nrelease containing ",[283,5695,5696],{},"flake.nix","). In a checkout, use ",[283,5699,5700],{},"nix build",[283,5702,5703],{},"nix run . -- version",". The pinned nixpkgs toolchain and dependency hash\nmake this a source build, not a download of the release binary; it is not\nbyte-identical to the release archive.",[276,5706,238],{"id":5707},"deploy-to-a-host",[201,5709,5710,5711,5713,5714,5716,5717,5720,5721,5723,5724,357,5727,5730],{},"Prerequisites on the host: Docker with Compose, ",[283,5712,494],{}," 7.71 or newer, ",[283,5715,443],{},", SSH access. The\nimage ",[283,5718,5719],{},"ghcr.io\u002Fagentfeedback\u002Fagentfeedback"," is published by each release\n(",[208,5722,5578],{"href":181},") for ",[283,5725,5726],{},"linux\u002Famd64",[283,5728,5729],{},"linux\u002Farm64",", under three\ntags:",[969,5732,5733,5746],{},[972,5734,5735],{},[975,5736,5737,5740,5743],{},[978,5738,5739],{},"Tag",[978,5741,5742],{},"Example",[978,5744,5745],{},"Pin it",[985,5747,5748,5766,5779],{},[975,5749,5750,5755,5763],{},[990,5751,5752,5753],{},"the version, without the ",[283,5754,5527],{},[990,5756,5757,796,5760],{},[283,5758,5759],{},"4.0.0",[283,5761,5762],{},"4.0.0-rc.1",[990,5764,5765],{},"yes",[975,5767,5768,5771,5777],{},[990,5769,5770],{},"the full commit SHA of the release",[990,5772,5773,5776],{},[283,5774,5775],{},"df87a9c…"," (40 hex digits); a stable release cut from the same commit as its last rc moves it to the stable build",[990,5778,5765],{},[975,5780,5781,5786,5789],{},[990,5782,5783],{},[283,5784,5785],{},"latest",[990,5787,5788],{},"stable releases only; pre-releases never move it",[990,5790,5791],{},"never",[201,5793,5794,5795,5798,5799,5802,5803,5805,5806,5809,5810,5812,5813,5815],{},"The image is distroless: the binary ",[283,5796,5797],{},"\u002Fopt\u002Fagentfeedback"," (the entrypoint;\n",[283,5800,5801],{},"CMD [\"serve\"]",", so a container started with no arguments serves), CA roots\nand timezone data, and no shell, package manager or ",[283,5804,494],{},", so it carries no\nhealthcheck; check readiness from the host with ",[283,5807,5808],{},"GET \u002Fready",". It runs as uid\n10001 with the database at ",[283,5811,534],{}," on the ",[283,5814,2958],{}," volume.\nThe package must be publicly pullable (GitHub package settings) or the host\nmust be logged in to GHCR.",[381,5817,5819],{"className":383,"code":5818,"language":385,"meta":386,"style":386},"DEPLOY_REMOTE=user@host bash scripts\u002Fdeploy.sh \u003Ccommit-sha>\n",[283,5820,5821],{"__ignoreMap":386},[390,5822,5823,5826,5828,5831,5834,5837,5839,5842,5844],{"class":392,"line":393},[390,5824,5825],{"class":420},"DEPLOY_REMOTE",[390,5827,551],{"class":416},[390,5829,5830],{"class":400},"user@host",[390,5832,5833],{"class":442}," bash",[390,5835,5836],{"class":400}," scripts\u002Fdeploy.sh",[390,5838,3035],{"class":416},[390,5840,5841],{"class":400},"commit-sh",[390,5843,208],{"class":420},[390,5845,5846],{"class":416},">\n",[201,5848,5849,2066],{},[283,5850,5851],{},"scripts\u002Fdeploy.sh",[5853,5854,5855,5866,5877,5891],"ol",{},[869,5856,5857,5858,5861,5862,5865],{},"copies ",[283,5859,5860],{},"infra\u002Fagentfeedback\u002Fdocker-compose.deploy.yml"," to\n",[283,5863,5864],{},"~\u002Fagentfeedback\u002Fdocker-compose.yml"," on the host;",[869,5867,5868,5869,5872,5873,5876],{},"creates ",[283,5870,5871],{},"~\u002Fagentfeedback\u002F.env"," with a generated ",[283,5874,5875],{},"API_KEY"," on first deploy\nand preserves it afterwards;",[869,5878,5879,5880,5883,5884,5886,5887,5890],{},"writes ",[283,5881,5882],{},"AGENTFEEDBACK_IMAGE=ghcr.io\u002Fagentfeedback\u002Fagentfeedback:\u003Ccommit-sha>"," into that\n",[283,5885,676],{}," so the pinned image survives later ",[283,5888,5889],{},"docker compose up"," calls;",[869,5892,5893,5894,5897,5898,318],{},"runs ",[283,5895,5896],{},"docker compose pull && docker compose up -d --wait"," and checks ",[283,5899,5900],{},"\u002Fready",[201,5902,5903,5904,5906,5907,796,5909,357,5912,5915,5916,5919,5920,318],{},"Always deploy a version or a commit SHA, never ",[283,5905,5785],{},", so the host pins\nwhat it runs. ",[283,5908,5825],{},[283,5910,5911],{},"DEPLOY_IMAGE",[283,5913,5914],{},"DEPLOY_DIR","\n(remote directory, default ",[283,5917,5918],{},"~\u002Fagentfeedback",", which the sections below\nassume) can live in the gitignored ",[283,5921,5922],{},".private\u002Fdeploy.env",[201,5924,5925,5926,5928,5929,5932,5933,5935,5936,318],{},"The stack binds ",[283,5927,527],{}," on the host. To serve other machines, set\n",[283,5930,5931],{},"AGENTFEEDBACK_BIND_ADDRESS=0.0.0.0"," in the host ",[283,5934,676],{}," only inside a trusted\nnetwork or behind TLS; see ",[208,5937,1422],{"href":172},[276,5939,246],{"id":5940},"configuration",[201,5942,5943],{},"Environment variables read by the binary:",[969,5945,5946,5959],{},[972,5947,5948],{},[975,5949,5950,5953,5956],{},[978,5951,5952],{},"Variable",[978,5954,5955],{},"Default",[978,5957,5958],{},"Meaning",[985,5960,5961,5973,5987,6003,6026,6041,6054,6073,6102,6113],{},[975,5962,5963,5967,5970],{},[990,5964,5965],{},[283,5966,5875],{},[990,5968,5969],{},"required",[990,5971,5972],{},"the shared key every client sends",[975,5974,5975,5979,5982],{},[990,5976,5977],{},[283,5978,2766],{},[990,5980,5981],{},"unset",[990,5983,5984,5986],{},[283,5985,777],{}," reads the key from this file instead (trimmed; exactly one key); setting both is an error",[975,5988,5989,5993,6000],{},[990,5990,5991],{},[283,5992,2769],{},[990,5994,5995,5997,5998],{},[283,5996,690],{}," (created on first start); the image sets ",[283,5999,534],{},[990,6001,6002],{},"SQLite file; its directory must be writable, and an explicitly set one must already exist",[975,6004,6005,6010,6021],{},[990,6006,6007],{},[283,6008,6009],{},"HTTP_LISTEN_ADDR",[990,6011,6012,6014,6015,6018,6019],{},[283,6013,527],{},"; the image sets ",[283,6016,6017],{},"0.0.0.0:8080",", which Compose maps to ",[283,6020,527],{},[990,6022,6023,6024],{},"listen address of ",[283,6025,777],{},[975,6027,6028,6033,6038],{},[990,6029,6030],{},[283,6031,6032],{},"GRACEFUL_SHUTDOWN_TIMEOUT",[990,6034,6035],{},[283,6036,6037],{},"30s",[990,6039,6040],{},"drain time for in-flight requests",[975,6042,6043,6048,6051],{},[990,6044,6045],{},[283,6046,6047],{},"SERVICE_VERSION",[990,6049,6050],{},"build default",[990,6052,6053],{},"reported in logs",[975,6055,6056,6061,6066],{},[990,6057,6058],{},[283,6059,6060],{},"LOG_LEVEL",[990,6062,6063],{},[283,6064,6065],{},"info",[990,6067,6068,878,6071],{},[283,6069,6070],{},"debug",[283,6072,6065],{},[975,6074,6075,6079,6081],{},[990,6076,6077],{},[283,6078,2814],{},[990,6080,5981],{},[990,6082,6083,6084,6087,6088,6091,6092,357,6095,6098,6099,6101],{},"base URL that ",[283,6085,6086],{},"\u002Fskill"," and the MCP server instructions name, such as ",[283,6089,6090],{},"https:\u002F\u002Ffeedback.example.com","; unset derives it per request from ",[283,6093,6094],{},"Host",[283,6096,6097],{},"X-Forwarded-Proto","; an unusable value (not http or https, credentials, a query) stops ",[283,6100,777],{}," at start",[975,6103,6104,6108,6110],{},[990,6105,6106],{},[283,6107,2817],{},[990,6109,5981],{},[990,6111,6112],{},"text appended to the MCP server instructions after a blank line",[975,6114,6115,6120,6125],{},[990,6116,6117],{},[283,6118,6119],{},"INGEST_SCRUB",[990,6121,6122],{},[283,6123,6124],{},"off",[990,6126,6127,6130,6131,6134,6135,6138,6139,6142,6143,878,6145,6147,6148,796,6150,357,6152,6154,6155,6157,6158,1002],{},[283,6128,6129],{},"on"," replaces known secret formats in every string value of a submission body (never member names) with ",[283,6132,6133],{},"[REDACTED:\u003Cclass>]"," before decoding, storing and hashing it, and logs the counts per class (never the text); the response carries no warning. Turning it on changes the ",[283,6136,6137],{},"content_hash"," of a body that contains a matched secret, so a keyed replay of a row stored with scrubbing off answers ",[283,6140,6141],{},"replay_mismatch",". Any value other than ",[283,6144,6129],{},[283,6146,6124],{}," stops ",[283,6149,777],{},[283,6151,773],{},[283,6153,1010],{}," at start (they read the same environment); ",[283,6156,773],{}," never scrubs (",[208,6159,1422],{"href":6160},"\u002Fdocs\u002Freference\u002Fsecurity#what-gets-stored",[201,6162,6163,6164,2752,6167,1158,6169,6172,6173,1158,6176,796,6178,796,6180,318],{},"Compose-level variables (",[283,6165,6166],{},"infra\u002Fagentfeedback\u002F.env",[283,6168,5875],{},[283,6170,6171],{},"AGENTFEEDBACK_IMAGE"," (deploy stack only), ",[283,6174,6175],{},"AGENTFEEDBACK_BIND_ADDRESS",[283,6177,2814],{},[283,6179,2817],{},[283,6181,6119],{},[845,6183,6185],{"id":6184},"machine-settings","Machine settings",[201,6187,6188,6191,6192,796,6195,878,6198,6201,6202,6205,6206,1158,6209,796,6211,878,6214,6217,6218,357,6221,1782,6223,878,6225,6227],{},[283,6189,6190],{},"agentfeedback config"," opens a numbered menu on a terminal. Without a terminal\nit exits 2 with guidance to use ",[283,6193,6194],{},"config show",[283,6196,6197],{},"get",[283,6199,6200],{},"set","; it never waits for input.\n",[283,6203,6204],{},"config show --json"," reports each known value with its source (",[283,6207,6208],{},"flag",[283,6210,1733],{},[283,6212,6213],{},"file",[283,6215,6216],{},"default","), whether it is set and whether it is editable.\nThe API key is always masked. ",[283,6219,6220],{},"show",[283,6222,6197],{},[283,6224,757],{},[283,6226,761],{},"\nas read-only destination overrides.",[381,6229,6231],{"className":383,"code":6230,"language":385,"meta":386,"style":386},"agentfeedback config show --json\nagentfeedback config get sessions.quiet\nagentfeedback config set sessions.quiet 10m\nagentfeedback config set collect.deny_paths '~\u002Fprivate,~\u002Fclients'\n",[283,6232,6233,6245,6257,6272],{"__ignoreMap":386},[390,6234,6235,6237,6240,6243],{"class":392,"line":393},[390,6236,703],{"class":442},[390,6238,6239],{"class":400}," config",[390,6241,6242],{"class":400}," show",[390,6244,1448],{"class":396},[390,6246,6247,6249,6251,6254],{"class":392,"line":404},[390,6248,703],{"class":442},[390,6250,6239],{"class":400},[390,6252,6253],{"class":400}," get",[390,6255,6256],{"class":400}," sessions.quiet\n",[390,6258,6259,6261,6263,6266,6269],{"class":392,"line":470},[390,6260,703],{"class":442},[390,6262,6239],{"class":400},[390,6264,6265],{"class":400}," set",[390,6267,6268],{"class":400}," sessions.quiet",[390,6270,6271],{"class":400}," 10m\n",[390,6273,6274,6276,6278,6280,6283],{"class":392,"line":491},[390,6275,703],{"class":442},[390,6277,6239],{"class":400},[390,6279,6265],{"class":400},[390,6281,6282],{"class":400}," collect.deny_paths",[390,6284,6285],{"class":400}," '~\u002Fprivate,~\u002Fclients'\n",[201,6287,6288,6290,6291,6293],{},[283,6289,6197],{}," prints one scalar or a JSON list. An unset optional value produces no\noutput and exits 3. Unknown keys and attempts to set read-only keys exit 2\nwith guidance; values rejected by ",[283,6292,6200],{}," are not echoed.",[201,6295,6296],{},"The editable keys are:",[866,6298,6299,6311,6329,6338],{},[869,6300,6301,796,6304,6307,6308,318],{},[283,6302,6303],{},"collect.deny_paths",[283,6305,6306],{},"collect.opt_in_paths",": comma-separated paths or a JSON\nstring array; an empty value clears the list. Paths must be absolute or\nstart with ",[283,6309,6310],{},"~\u002F",[869,6312,6313,796,6316,796,6319,796,6322,4757,6325,878,6327,318],{},[283,6314,6315],{},"collect.opt_in_only",[283,6317,6318],{},"collect.disabled",[283,6320,6321],{},"context.cwd",[283,6323,6324],{},"detect.nudge",[283,6326,2609],{},[283,6328,4887],{},[869,6330,6331,6334,6335,318],{},[283,6332,6333],{},"sessions.quiet",": a positive Go duration, such as ",[283,6336,6337],{},"5m",[869,6339,6340,796,6343,796,6346,1158,6349,796,6352,6355],{},[283,6341,6342],{},"detect.same_tool",[283,6344,6345],{},"detect.same_command",[283,6347,6348],{},"detect.session_failures",[283,6350,6351],{},"detect.interval_minutes",[283,6353,6354],{},"detect.max_per_session",": positive integers.\nThe interval must fit in a Go duration (at most 153722867 minutes).",[201,6357,6358,6359,6361,6362,6365,6366,878,6368,6370,6371,6373],{},"Each edit atomically replaces this machine's ",[283,6360,3096],{}," with mode 0600.\nCLI writers serialize updates using the persistent ",[283,6363,6364],{},"config.toml.lock"," file\nbeside it. Symlinked config files and competing case variants of known keys\nare refused rather than replaced or reordered.\nUnknown keys and destination credentials survive; TOML comments and formatting\ndo not. The destination, key and other known settings are read-only here:\nuse ",[283,6367,364],{},[283,6369,348],{}," for the destination and key. They can extend a\nsettings-only file; ",[283,6372,5114],{}," replaces configured credentials\nwhile preserving machine settings. Menu options list\nharnesses and install or uninstall one named harness through the existing\ninstaller, with its normal prompts and ownership rules.",[201,6375,6376],{},"The view separately shows the current directory's repository narrowing and\nthe organisation's session policy, both read-only. Displaying policy may\ncontact the configured server, subject to its cache and backoff; it never\nuploads transcripts. Outside Git, only the directory's session-push restriction\napplies. Repository restrictions are not writable machine settings and cannot\ngrant capture permission.",[845,6378,6380],{"id":6379},"session-policy-settings","Session policy settings",[201,6382,6383,6384,6386],{},"The client's ",[283,6385,3096],{}," accepts:",[381,6388,6392],{"className":6389,"code":6390,"language":6391,"meta":386,"style":386},"language-toml shiki shiki-themes github-light github-light github-dark","[sessions]\nquiet = \"5m\"\npolicy_ttl = \"5m\"\npush_batch = 5\npush_budget = \"90s\"\n","toml",[283,6393,6394,6399,6404,6409,6414],{"__ignoreMap":386},[390,6395,6396],{"class":392,"line":393},[390,6397,6398],{},"[sessions]\n",[390,6400,6401],{"class":392,"line":404},[390,6402,6403],{},"quiet = \"5m\"\n",[390,6405,6406],{"class":392,"line":470},[390,6407,6408],{},"policy_ttl = \"5m\"\n",[390,6410,6411],{"class":392,"line":491},[390,6412,6413],{},"push_batch = 5\n",[390,6415,6416],{"class":392,"line":620},[390,6417,6418],{},"push_budget = \"90s\"\n",[201,6420,6421,6422,6424,6425,6427,6428,6431,6432,6435],{},"These are the defaults: the quiet period, policy cache lifetime, batch limit\nand upload time budget. Durations use Go duration syntax; nonpositive values\nkeep defaults and malformed durations are configuration errors. ",[283,6423,795],{},"\nreports unknown keys. A repository's ",[283,6426,4906],{}," accepts only\n",[283,6429,6430],{},"[sessions] push = false",": a veto, never permission to collect. An unreadable,\nmalformed or symlinked repository file, or an invalid ",[283,6433,6434],{},"sessions.push"," value,\nblocks uploads rather than bypassing a possible veto.",[201,6437,6438,796,6440,357,6442,6445,6446,6449,6450,6452,6453,318],{},[283,6439,364],{},[283,6441,795],{},[283,6443,6444],{},"sessions status"," discover the configured server's\nsession policy and include ",[283,6447,6448],{},"capture"," in JSON output. ",[283,6451,364],{}," prints the\nstatus line on stderr; the other two print it on stdout. The org decides\nwhether processing is enabled; no new consent question is asked. The line\nnames the org, server, quiet period and retention, or explains why only\nfriction reports apply. Missing retention metadata means \"per the org's\nretention setting\". Policy discovery itself does not upload transcripts;\nan eligible CLI invocation can also trigger the ",[208,6454,6455],{"href":4644},"automatic sweep",[201,6457,6458,6459,6462,6463,6466,6467,6469],{},"The data-directory database caches policy per server and org in\n",[283,6460,6461],{},"capture_policy",", including the consent start and last printed notice\nversion. Cached permission is bound to the configured credential; changing\nthe key requires fresh policy discovery. Concurrent refreshes cannot replace\na newer policy response with an older one. Disabled-to-enabled starts a new\nconsent period. Only successful enabled text output records the notice as\nprinted; JSON output does not. Unsupported\nservers are retried no more than daily, even across these commands; a 429\nwaits for ",[283,6464,6465],{},"Retry-After"," (60 seconds when absent). ",[283,6468,795],{}," reports\nunauthorized and suspended policy reads with a next step. Local mode makes\nno policy request.",[201,6471,6472,6473,6478,6479,6482,6483,800,6486,6488,6489,357,6491,6493,6494,6497],{},"Use ",[208,6474,6475],{"href":899},[283,6476,6477],{},"agentfeedback sessions push"," for manual transcript\nuploads. ",[283,6480,6481],{},"--due"," applies the configured quiet interval, batch and budget;\nnamed references bypass only the quiet interval. ",[283,6484,6485],{},"sessions list",[283,6487,6444],{}," show upload progress independently of digest\u002Fmark progress.\n",[283,6490,795],{},[283,6492,6444],{}," also expose the last automatic push record.\nThe OSS server has no upload routes; its unsupported policy prevents the\nautomatic sweep. See ",[208,6495,6496],{"href":4644},"Automatic sweep"," for\ntriggers and bounds.",[845,6499,937],{"id":6500},"mcp-and-discovery",[866,6502,6503,6570,6597,6604,6613],{},[869,6504,6505,6508,6509,662,6512,357,6515,6518,6519,421,6522,1763,6525,6528,6529,796,6531,796,6534,796,6537,1158,6539,796,6542,6545,6546,6548,6549,6552,6553,6555,6556,6559,6560,6563,6564,6566,6567,6569],{},[283,6506,6507],{},"POST \u002Fmcp",": remote MCP server over Streamable HTTP, stateless (no\n",[283,6510,6511],{},"Mcp-Session-Id",[283,6513,6514],{},"GET",[283,6516,6517],{},"DELETE"," answer 405). It takes the API key\nheader like ",[283,6520,6521],{},"\u002Fapi\u002Fv1\u002F*",[283,6523,6524],{},"Authorization: Bearer \u003Ckey>",[283,6526,6527],{},"X-Api-Key: \u003Ckey>",") and checks it before anything else. Six tools:\n",[283,6530,4820],{},[283,6532,6533],{},"list_submissions",[283,6535,6536],{},"get_submission",[283,6538,3064],{},[283,6540,6541],{},"mark_processed",[283,6543,6544],{},"get_schema",", each answering with the REST body of its\nroute. ",[283,6547,4824],{}," serves the same tools over stdio: on the local\ndatabase with no key in local mode; with a server URL configured, it\nrelays them to ",[283,6550,6551],{},"\u003Cserver>\u002Fmcp"," with the configured key (it connects at\nstart and exits 1 on stderr when the server, the key or the endpoint does\nnot answer). Either way it adds the session tools and ",[283,6554,4820],{},"'s\n",[283,6557,6558],{},"context_from"," argument, answered on this machine\n(",[208,6561,1027],{"href":6562},"\u002Fdocs\u002Freference\u002Fsessions#mcp-tools","), and the server instructions say\nso. ",[283,6565,757],{}," forces the local database, ",[283,6568,761],{}," that server (the\nentry install writes for a server passes it). A forwarded call has 60\nseconds; a call whose upstream session is gone reconnects and is retried\nonce; a remote tool without an object input schema is not served (one\nwarning on stderr).",[869,6571,6572,6575,6576,6578,6579,796,6581,357,6583,6585,6586,6588,6589,357,6591,6593,6594,6596],{},[283,6573,6574],{},"POST \u002Fmcp\u002F{project}",": the same, with ",[283,6577,1588],{}," preset for the\nconnection; ",[283,6580,4820],{},[283,6582,6533],{},[283,6584,3064],{}," then take no\n",[283,6587,1588],{}," argument. ",[283,6590,6536],{},[283,6592,6541],{}," take ids and are\nnot scoped by the preset; ",[283,6595,6544],{}," neither.",[869,6598,6599,6600,6603],{},"An MCP request body may be up to 10551296 bytes (the 10 MiB create limit\nplus 64 KiB for the JSON-RPC message); a larger one is 413\n",[283,6601,6602],{},"request_too_large",". The tools apply the create and mark limits to their\narguments.",[869,6605,6606,800,6609,6612],{},[283,6607,6608],{},"GET \u002Fskill?format=skill-md|agents-md|prompt",[283,6610,6611],{},"GET \u002F.well-known\u002Fagentfeedback.json"," need no key and carry no data.",[869,6614,6615,6616,6618,6619,800,6621,6623,6624,6626],{},"Behind a reverse proxy, set ",[283,6617,2814],{},", or forward the public ",[283,6620,6094],{},[283,6622,6097],{},", so ",[283,6625,6086],{}," and the MCP instructions name the address\nclients use.",[276,6628,250],{"id":3477},[201,6630,6631],{},"Two complementary forms.",[201,6633,6634,6637],{},[872,6635,6636],{},"Physical backup"," (fastest restore, a complete database file):",[381,6639,6641],{"className":383,"code":6640,"language":385,"meta":386,"style":386},"cd ~\u002Fagentfeedback\ndocker compose exec agentfeedback \u002Fopt\u002Fagentfeedback backup \u002Ftmp\u002Fbackup-$(date -u +%Y%m%dT%H%M%SZ).db\nmkdir -p backups\ndocker compose cp agentfeedback:\u002Ftmp\u002Fbackup-\u003Cstamp>.db .\u002Fbackups\u002F\n",[283,6642,6643,6650,6685,6696],{"__ignoreMap":386},[390,6644,6645,6647],{"class":392,"line":393},[390,6646,397],{"class":396},[390,6648,6649],{"class":400}," ~\u002Fagentfeedback\n",[390,6651,6652,6654,6656,6659,6661,6664,6667,6670,6672,6674,6677,6680,6682],{"class":392,"line":404},[390,6653,473],{"class":442},[390,6655,476],{"class":400},[390,6657,6658],{"class":400}," exec",[390,6660,5507],{"class":400},[390,6662,6663],{"class":400}," \u002Fopt\u002Fagentfeedback",[390,6665,6666],{"class":400}," backup",[390,6668,6669],{"class":400}," \u002Ftmp\u002Fbackup-",[390,6671,566],{"class":420},[390,6673,4769],{"class":442},[390,6675,6676],{"class":396}," -u",[390,6678,6679],{"class":400}," +%Y%m%dT%H%M%SZ",[390,6681,1002],{"class":420},[390,6683,6684],{"class":400},".db\n",[390,6686,6687,6690,6693],{"class":392,"line":470},[390,6688,6689],{"class":442},"mkdir",[390,6691,6692],{"class":396}," -p",[390,6694,6695],{"class":400}," backups\n",[390,6697,6698,6700,6702,6705,6708,6711,6714,6716,6719,6722],{"class":392,"line":491},[390,6699,473],{"class":442},[390,6701,476],{"class":400},[390,6703,6704],{"class":400}," cp",[390,6706,6707],{"class":400}," agentfeedback:\u002Ftmp\u002Fbackup-",[390,6709,6710],{"class":416},"\u003C",[390,6712,6713],{"class":400},"stam",[390,6715,201],{"class":420},[390,6717,6718],{"class":416},">",[390,6720,6721],{"class":400},".db",[390,6723,6724],{"class":400}," .\u002Fbackups\u002F\n",[201,6726,6727,6728,6731,6732,6735],{},"The copy goes to the container's ",[283,6729,6730],{},"\u002Ftmp",", not the database volume, and is\ngone when the container is recreated (the image has no ",[283,6733,6734],{},"rm"," to delete it\nsooner).",[201,6737,6738,6741,6742,6745,6746,6748,6749,6751,6752,6754],{},[283,6739,6740],{},"agentfeedback backup \u003Cdest.db>"," uses SQLite's ",[283,6743,6744],{},"VACUUM INTO",", which is safe on\na live database in WAL mode, so the service keeps running. It refuses an\nexisting destination and a ",[283,6747,2769],{}," that does not exist. Never copy\n",[283,6750,994],{}," from the volume while the service runs; the ",[283,6753,998],{}," file\nholds committed data the main file lacks.",[201,6756,6757,6760],{},[872,6758,6759],{},"Logical backup"," (portable, inspectable, the migration format):",[381,6762,6764],{"className":383,"code":6763,"language":385,"meta":386,"style":386},"curl -sS --fail -H \"Authorization: Bearer $AGENT_FEEDBACK_API_KEY\" \\\n  \"$AGENT_FEEDBACK_URL\u002Fapi\u002Fv1\u002Fexport\" > feedback-$(date -u +%Y%m%d).ndjson\ntail -n 1 feedback-*.ndjson   # the trailer: {\"export_complete\":true,\"count\":…,\"sha256\":…}\n",[283,6765,6766,6784,6812],{"__ignoreMap":386},[390,6767,6768,6770,6772,6774,6776,6778,6780,6782],{"class":392,"line":393},[390,6769,494],{"class":442},[390,6771,587],{"class":396},[390,6773,497],{"class":396},[390,6775,590],{"class":396},[390,6777,593],{"class":400},[390,6779,596],{"class":420},[390,6781,599],{"class":400},[390,6783,607],{"class":396},[390,6785,6786,6788,6790,6793,6795,6798,6800,6802,6804,6807,6809],{"class":392,"line":404},[390,6787,623],{"class":400},[390,6789,626],{"class":420},[390,6791,6792],{"class":400},"\u002Fapi\u002Fv1\u002Fexport\"",[390,6794,458],{"class":416},[390,6796,6797],{"class":400}," feedback-",[390,6799,566],{"class":420},[390,6801,4769],{"class":442},[390,6803,6676],{"class":396},[390,6805,6806],{"class":400}," +%Y%m%d",[390,6808,1002],{"class":420},[390,6810,6811],{"class":400},".ndjson\n",[390,6813,6814,6817,6819,6821,6823,6826,6829],{"class":392,"line":470},[390,6815,6816],{"class":442},"tail",[390,6818,572],{"class":396},[390,6820,518],{"class":396},[390,6822,6797],{"class":400},[390,6824,6825],{"class":396},"*",[390,6827,6828],{"class":400},".ndjson",[390,6830,6831],{"class":466},"   # the trailer: {\"export_complete\":true,\"count\":…,\"sha256\":…}\n",[201,6833,6834],{},"The export is format 2: a header line, one line per record (tombstones\nincluded), and a trailer with the record count and the SHA-256 over the record\nlines. A file without the trailer is incomplete. Store backups off-host and\nrestrict them: they contain everything agents reported.",[201,6836,6837,6838,421,6840,796,6842,6844,6845,6848,6849,6852],{},"The export carries records only; the session watermarks of\n",[283,6839,1016],{},[283,6841,1020],{},[283,6843,1023],{},") are not in it, and\na database restored from an export offers every session as ",[283,6846,6847],{},"new"," again.\n",[283,6850,6851],{},"agentfeedback backup"," copies the whole database, those tables included.",[276,6854,254],{"id":6855},"restore-and-migration",[201,6857,6858,6861,6862,6864,6865,6867,6868,6870,6871,2066],{},[872,6859,6860],{},"Restore a physical backup",": stop the service, replace ",[283,6863,534],{},"\nin the volume and remove the ",[283,6866,998],{},"\u002F",[283,6869,1001],{}," files beside it, from a throwaway\ncontainer (the image has no shell), then start it and check ",[283,6872,5900],{},[381,6874,6876],{"className":383,"code":6875,"language":385,"meta":386,"style":386},"docker compose stop agentfeedback\ndocker run --rm --volumes-from \"$(docker compose ps -aq agentfeedback)\" -v \"$PWD\u002Fbackups:\u002Fbackups:ro\" alpine:3.24.1 \\\n  sh -c 'rm -f \u002Fdata\u002Fagentfeedback.db-wal \u002Fdata\u002Fagentfeedback.db-shm && cp \u002Fbackups\u002Fbackup-\u003Cstamp>.db \u002Fdata\u002Fagentfeedback.db && chown 10001:10001 \u002Fdata\u002Fagentfeedback.db'\ndocker compose start agentfeedback\n",[283,6877,6878,6889,6930,6941],{"__ignoreMap":386},[390,6879,6880,6882,6884,6887],{"class":392,"line":393},[390,6881,473],{"class":442},[390,6883,476],{"class":400},[390,6885,6886],{"class":400}," stop",[390,6888,5423],{"class":400},[390,6890,6891,6893,6895,6898,6901,6903,6905,6908,6911,6914,6917,6919,6922,6925,6928],{"class":392,"line":404},[390,6892,473],{"class":442},[390,6894,5669],{"class":400},[390,6896,6897],{"class":396}," --rm",[390,6899,6900],{"class":396}," --volumes-from",[390,6902,439],{"class":400},[390,6904,473],{"class":442},[390,6906,6907],{"class":400}," compose ps ",[390,6909,6910],{"class":396},"-aq",[390,6912,6913],{"class":400}," agentfeedback)\"",[390,6915,6916],{"class":396}," -v",[390,6918,647],{"class":400},[390,6920,6921],{"class":420},"$PWD",[390,6923,6924],{"class":400},"\u002Fbackups:\u002Fbackups:ro\"",[390,6926,6927],{"class":400}," alpine:3.24.1",[390,6929,607],{"class":396},[390,6931,6932,6935,6938],{"class":392,"line":470},[390,6933,6934],{"class":400},"  sh",[390,6936,6937],{"class":396}," -c",[390,6939,6940],{"class":400}," 'rm -f \u002Fdata\u002Fagentfeedback.db-wal \u002Fdata\u002Fagentfeedback.db-shm && cp \u002Fbackups\u002Fbackup-\u003Cstamp>.db \u002Fdata\u002Fagentfeedback.db && chown 10001:10001 \u002Fdata\u002Fagentfeedback.db'\n",[390,6942,6943,6945,6947,6950],{"class":392,"line":491},[390,6944,473],{"class":442},[390,6946,476],{"class":400},[390,6948,6949],{"class":400}," start",[390,6951,5423],{"class":400},[201,6953,6954,6957],{},[872,6955,6956],{},"Restore a logical export"," (format 2) into the service's database:",[381,6959,6961],{"className":383,"code":6960,"language":385,"meta":386,"style":386},"docker compose stop agentfeedback\ndocker compose run --rm -v \"$PWD\u002Ffeedback.ndjson:\u002Fimport.ndjson:ro\" agentfeedback import --dry-run \u002Fimport.ndjson\ndocker compose run --rm -v \"$PWD\u002Ffeedback.ndjson:\u002Fimport.ndjson:ro\" agentfeedback import \u002Fimport.ndjson\ndocker compose start agentfeedback\n",[283,6962,6963,6973,7002,7026],{"__ignoreMap":386},[390,6964,6965,6967,6969,6971],{"class":392,"line":393},[390,6966,473],{"class":442},[390,6968,476],{"class":400},[390,6970,6886],{"class":400},[390,6972,5423],{"class":400},[390,6974,6975,6977,6979,6981,6983,6985,6987,6989,6992,6994,6997,6999],{"class":392,"line":404},[390,6976,473],{"class":442},[390,6978,476],{"class":400},[390,6980,5669],{"class":400},[390,6982,6897],{"class":396},[390,6984,6916],{"class":396},[390,6986,647],{"class":400},[390,6988,6921],{"class":420},[390,6990,6991],{"class":400},"\u002Ffeedback.ndjson:\u002Fimport.ndjson:ro\"",[390,6993,5507],{"class":400},[390,6995,6996],{"class":400}," import",[390,6998,3382],{"class":396},[390,7000,7001],{"class":400}," \u002Fimport.ndjson\n",[390,7003,7004,7006,7008,7010,7012,7014,7016,7018,7020,7022,7024],{"class":392,"line":470},[390,7005,473],{"class":442},[390,7007,476],{"class":400},[390,7009,5669],{"class":400},[390,7011,6897],{"class":396},[390,7013,6916],{"class":396},[390,7015,647],{"class":400},[390,7017,6921],{"class":420},[390,7019,6991],{"class":400},[390,7021,5507],{"class":400},[390,7023,6996],{"class":400},[390,7025,7001],{"class":400},[390,7027,7028,7030,7032,7034],{"class":392,"line":491},[390,7029,473],{"class":442},[390,7031,476],{"class":400},[390,7033,6949],{"class":400},[390,7035,5423],{"class":400},[201,7037,7038,7041,7042,7044,7045,1158,7048,796,7051,7053,7054,7056,7057,7059,7060,7063,7064,421,7067,1158,7070,7073,7074,796,7077,796,7080,796,7082,796,7084,796,7087,1158,7090,2821,7092,7094,7095,7097],{},[283,7039,7040],{},"agentfeedback import [--dry-run] \u003Cfile>"," verifies the whole file (header,\nrecord count, digest, every record, each ",[283,7043,6137],{}," recomputed) before it\nwrites anything, then restores it in one transaction. Records keep their ",[283,7046,7047],{},"id",[283,7049,7050],{},"uid",[283,7052,6137],{},", payload bytes, timestamps and processing fields, and\ntombstones stay tombstones; the id sequence moves past the highest id in the\nfile, so a restored id is never handed out again. A record whose ",[283,7055,7050],{}," is\nalready stored is skipped whatever the two contain (a mark or redaction in\nthe file does not reach the stored row), so running the same restore twice\nchanges nothing.\nA record whose ",[283,7058,7047],{},", or whose ",[283,7061,7062],{},"(kind, key)"," with different content, belongs to\nanother stored record is skipped and listed under ",[283,7065,7066],{},"conflicts",[283,7068,7069],{},"id_taken",[283,7071,7072],{},"key_mismatch","); conflicts never fail the restore. It prints one JSON line\n(",[283,7075,7076],{},"imported",[283,7078,7079],{},"skipped",[283,7081,7066],{},[283,7083,3680],{},[283,7085,7086],{},"first_id",[283,7088,7089],{},"last_id",[283,7091,3467],{},[283,7093,5143],{}," reports the same counts and writes nothing; a\nrejected file writes nothing either, and a dry run against a ",[283,7096,2769],{},"\nthat does not exist reports a restore into an empty database without creating\nit. Stop the service first, as above: a restore, dry run included, holds the\ndatabase's only writer until it finishes. The file is read whole into memory,\nso the host needs a few times its size free. Flags go before the file name.",[201,7099,7100,2984,7103,7106],{},[872,7101,7102],{},"Move to another server",[283,7104,7105],{},"agentfeedback migrate",", run from any\nmachine whose client is configured with the source's URL and key:",[381,7108,7110],{"className":383,"code":7109,"language":385,"meta":386,"style":386},"printf '%s' \"$TARGET_KEY\" | agentfeedback migrate --to https:\u002F\u002Ftarget --to-key-from-stdin \\\n  [--kind K] [--include-kind K] [--since T] [--limit N] [--dry-run]\n",[283,7111,7112,7145],{"__ignoreMap":386},[390,7113,7114,7116,7119,7121,7124,7126,7129,7131,7134,7137,7140,7143],{"class":392,"line":393},[390,7115,433],{"class":396},[390,7117,7118],{"class":400}," '%s'",[390,7120,647],{"class":400},[390,7122,7123],{"class":420},"$TARGET_KEY",[390,7125,599],{"class":400},[390,7127,7128],{"class":416}," |",[390,7130,5507],{"class":442},[390,7132,7133],{"class":400}," migrate",[390,7135,7136],{"class":396}," --to",[390,7138,7139],{"class":400}," https:\u002F\u002Ftarget",[390,7141,7142],{"class":396}," --to-key-from-stdin",[390,7144,607],{"class":396},[390,7146,7147,7150,7153,7156,7158,7161,7164,7167,7170],{"class":392,"line":404},[390,7148,7149],{"class":420},"  [--kind ",[390,7151,7152],{"class":400},"K]",[390,7154,7155],{"class":420}," [--include-kind ",[390,7157,7152],{"class":400},[390,7159,7160],{"class":420}," [--since ",[390,7162,7163],{"class":400},"T]",[390,7165,7166],{"class":420}," [--limit ",[390,7168,7169],{"class":400},"N]",[390,7171,7172],{"class":420}," [--dry-run]\n",[201,7174,7175,7176,421,7179,7182,7183,7185,7186,1763,7188,7190,7191,7194,7195,7197,7198,7201,7202,7204,7205,7207,7208,357,7211,7213,7214,7217,7218,7220],{},"It pages the source's export and writes each chunk to the target's\n",[283,7177,7178],{},"POST \u002Fapi\u002Fv1\u002Fimport",[208,7180,661],{"href":658,"rel":7181},[660],"), which keeps uid,\ncontent_hash, the timestamps and the processing fields and assigns new ids.\nThe target skips uids it already holds, so a re-run only adds what is\nmissing, and marks or redactions made on the source after a record moved do\nnot propagate. ",[283,7184,1374],{}," rows stay behind unless ",[283,7187,3074],{},[283,7189,3077],{}," names that kind. A record whose (kind, key) the target holds\nunder another uid is printed as one ",[283,7192,7193],{},"conflict"," line and skipped. The run\nstops at the first failure and says how many records landed. ",[283,7196,5143],{},"\nsends no record (it still reads the target's metadata and tombstones): it prints the count per kind, the first record of each, and\nthe source tombstones the target still holds unredacted; redact those on the\ntarget by hand. ",[283,7199,7200],{},"--to cloud"," targets the hosted service at\n",[283,7203,313],{}," (a public beta). ",[283,7206,757],{}," reads the\ndata-directory database instead of the configured server: a switch from\nlocal mode to a server never forwards the local reports by itself, so ",[283,7209,7210],{},"init --server",[283,7212,348],{}," name them under ",[283,7215,7216],{},"local_reports"," with this\ncommand (",[283,7219,364],{}," offers to run it on a terminal).",[276,7222,258],{"id":7223},"upgrading-and-downgrading",[201,7225,7226,7227,7229,7230,3677,7233,7235,7236,7238,7239,662,7242,7244,7245,7247,7248,7250,7251,3772,7253,7255,7256,7258,7259,7261,7262,7264,7265,7267],{},"The newest binary wins. Every binary migrates the database forward when it\nopens it (",[283,7228,777],{}," at startup, a local-mode command on its first request), and\na binary older than the database's schema refuses it rather than writing rows\nthe schema no longer expects: the command exits 1 with ",[283,7231,7232],{},"database schema is newer than this binary supports",[283,7234,4854],{}," gets an ",[283,7237,823],{}," line\nwhose reason starts with ",[283,7240,7241],{},"schema_too_new",[283,7243,811],{}," spools its report instead\n(",[208,7246,378],{"href":210},"). Harness hooks never open the local\ndatabase, so a stale hook binary shows up in ",[283,7249,749],{},", which\nlists the binary each harness's hook runs, its\nversion, and the ",[283,7252,703],{},[283,7254,3449],{},", and reports a hook binary that is\nmissing, does not answer ",[283,7257,3753],{},", or is older than the one running\n",[283,7260,795],{}," when both versions are comparable releases. Git-describe, dirty and\nGo pseudo-version builds also skip this hook-version comparison. Keep one binary per machine,\nand after an upgrade rerun ",[283,7263,4660],{}," from it when\n",[283,7266,795],{}," names an older one.",[201,7269,7270,7271,7274],{},"Upgrade: replace the binary (or ",[283,7272,7273],{},"bash scripts\u002Fdeploy.sh \u003Cnew-commit-sha>"," for\nthe image) after a backup. Schema changes are forward only; rolling back the\nbinary or the image does not roll back the schema.",[201,7276,7277,7278,800,7281,7284,7285,7287,7288,357,7290,7292,7293,7295,7296,7299],{},"Downgrade: with the newest binary, ",[283,7279,7280],{},"agentfeedback backup \u003Ccopy.db>",[283,7282,7283],{},"agentfeedback export > records.ndjson"," (or keep an export you already have);\nthen move ",[283,7286,994],{}," and its ",[283,7289,998],{},[283,7291,1001],{}," files aside (a\nserver with its own ",[283,7294,2769],{}," points that at a new file instead) and\nrun the older binary's ",[283,7297,7298],{},"agentfeedback import records.ndjson",", which creates\nthe database. Import keeps the ids. The backup stays as the copy to return\nto.",[201,7301,7302,7303,7305,7306,7309],{},"From v3 to v4 the database starts over: a v4 binary refuses a v3 database\nat startup and names the path. Keep the old database with the image that wrote\nit, point ",[283,7304,2769],{}," at a new file (a new volume), and start empty. A v3\nexport is not format 2, so ",[283,7307,7308],{},"agentfeedback import"," does not take it.",[276,7311,262],{"id":7312},"key-rotation",[201,7314,7315,7316,5932,7318,7320,7321,7324,7325,4657,7327,7329,7330,7333,7334,7337,7338,7340],{},"No overlap window. For the compose stacks, edit ",[283,7317,5875],{},[283,7319,676],{},"\nand run ",[283,7322,7323],{},"docker compose up -d","; for a server from ",[283,7326,2741],{},[283,7328,3001],{}," and the restart command of your form\n(",[208,7331,7332],{"href":220},"Bare binary","). Then update the key on every client\n(",[283,7335,7336],{},"agentfeedback doctor --init --url \u003CURL> --key-from-stdin",", or\n",[283,7339,368],{},"). Spooled payloads on clients retry with the new\nkey on their next call. Local mode has no key.",[276,7342,266],{"id":7343},"retention",[201,7345,7346,7347,7350,7351,7354,7355,7358],{},"Nothing is deleted automatically. ",[283,7348,7349],{},"processed"," means acted on, not removed.\nTo purge, export first, then delete with an explicit predicate from a\nthrowaway container that mounts the service's volume (the image has no shell\nand no ",[283,7352,7353],{},"sqlite3","), for example rows processed more than a year ago. It is\nsafe while the service runs (WAL mode, a 5 s busy timeout); the final\n",[283,7356,7357],{},"chown"," keeps any file it created writable by the service's uid:",[381,7360,7362],{"className":383,"code":7361,"language":385,"meta":386,"style":386},"docker run --rm --volumes-from \"$(docker compose ps -q agentfeedback)\" alpine:3.24.1 sh -c 'apk add --no-cache sqlite >\u002Fdev\u002Fnull && sqlite3 -cmd \".timeout 5000\" \u002Fdata\u002Fagentfeedback.db \"DELETE FROM submissions WHERE processed_at \u003C (unixepoch() - 31536000) * 1000000\"; s=$?; chown 10001:10001 \u002Fdata\u002Fagentfeedback.db*; exit $s'\n",[283,7363,7364],{"__ignoreMap":386},[390,7365,7366,7368,7370,7372,7374,7376,7378,7380,7383,7385,7387,7390,7392],{"class":392,"line":393},[390,7367,473],{"class":442},[390,7369,5669],{"class":400},[390,7371,6897],{"class":396},[390,7373,6900],{"class":396},[390,7375,439],{"class":400},[390,7377,473],{"class":442},[390,7379,6907],{"class":400},[390,7381,7382],{"class":396},"-q",[390,7384,6913],{"class":400},[390,7386,6927],{"class":400},[390,7388,7389],{"class":400}," sh",[390,7391,6937],{"class":396},[390,7393,7394],{"class":400}," 'apk add --no-cache sqlite >\u002Fdev\u002Fnull && sqlite3 -cmd \".timeout 5000\" \u002Fdata\u002Fagentfeedback.db \"DELETE FROM submissions WHERE processed_at \u003C (unixepoch() - 31536000) * 1000000\"; s=$?; chown 10001:10001 \u002Fdata\u002Fagentfeedback.db*; exit $s'\n",[201,7396,7397,7398,7401,7402,7404,7405,7407],{},"Client spools live in ",[283,7399,7400],{},"~\u002F.local\u002Fshare\u002Fagentfeedback\u002Fspool\u002F"," on each producer\nand age out (frictions bound to a server after 20 hours; everything else,\nlocal-bound frictions included, after 30 days): the next flush bound to an\nentry's destination deletes it, which a local-mode command's start-up pass\ndoes for local ones, and logs an ",[283,7403,823],{}," line in ",[283,7406,4854],{},"; an entry\nbound to a server this machine no longer uses stays until a flush to that\nserver runs.",[276,7409,270],{"id":7410},"monitoring",[866,7412,7413,7426,7455],{},[869,7414,7415,7418,7419,7421,7422,7425],{},[283,7416,7417],{},"GET \u002Fhealth",": process is up. ",[283,7420,5808],{},": database answers and schema is\ncurrent; ",[283,7423,7424],{},"503"," while shutting down.",[869,7427,7428,7431,7432,800,7435,7438,7439,7442,7443,7446,7447,7450,7451,7454],{},[283,7429,7430],{},"GET \u002Fmetrics"," (Prometheus): ",[283,7433,7434],{},"http_requests_total",[283,7436,7437],{},"http_request_duration_seconds"," by route, method and code;\n",[283,7440,7441],{},"submissions_created_total"," by outcome;\n",[283,7444,7445],{},"agentfeedback_submissions_unprocessed"," (the backlog);\n",[283,7448,7449],{},"agentfeedback_db_bytes"," (database plus WAL size); ",[283,7452,7453],{},"agentfeedback_sqlite_busy_total","\n(writes that waited out the busy timeout, should stay at zero).",[869,7456,7457,7458,318],{},"Logs are JSON on stdout: ",[283,7459,7460],{},"docker compose logs -f agentfeedback",[276,7462,274],{"id":3791},[201,7464,7465,7466,7468],{},"Two independent parts: the skills on each machine and the service (the compose stack below, or a service from ",[283,7467,2789],{},"). Take a backup before\nremoving any service; the data is gone with the volume.",[845,7470,7472],{"id":7471},"skills-on-every-machine-that-has-them","Skills, on every machine that has them",[5853,7474,7475,7489,7503,7515,7539,7572],{},[869,7476,7477,7478,7481,7482,7485,7486,7488],{},"Run ",[283,7479,7480],{},"agentfeedback uninstall all"," first: it removes what ",[283,7483,7484],{},"agentfeedback install","\nwired, the ",[283,7487,5008],{}," skill it wrote included, and restores the\nfiles it changed.",[869,7490,7491,7492,796,7494,796,7496,7498,7499,7502],{},"Find the installed copies (",[283,7493,703],{},[283,7495,4971],{},[283,7497,5008],{},") in every harness skills directory you\nuse, e.g. ",[283,7500,7501],{},"ls -la ~\u002F.claude\u002Fskills | grep feedback",". Entries may be symlinks into\na shared checkout; remove the links, then the checkout if nothing else uses it.",[869,7504,7505,7506,7508,7509,3616,7511,7514],{},"Flush or discard unsent payloads first: ",[283,7507,807],{},"\nsends whatever is spooled; or delete ",[283,7510,7400],{},[283,7512,7513],{},"~\u002F.local\u002Fshare\u002Fagentfeedback\u002Frejected\u002F"," to drop it.",[869,7516,7517,7518,7521,7522,421,7525,7528,7529,3226,7532,7535,7536,7538],{},"Remove the directories or links, then ",[283,7519,7520],{},"rm -rf ~\u002F.cache\u002Fagentfeedback","\n(the client log and digests), and the binary:\n",[283,7523,7524],{},"rm \"$(command -v agentfeedback)\"",[283,7526,7527],{},"scripts\u002Finstall.sh"," puts it in ",[283,7530,7531],{},"~\u002F.local\u002Fbin",[283,7533,7534],{},"~\u002F.local\u002Fshare\u002Fagentfeedback\u002F"," also holds the local-mode database; back\nit up with ",[283,7537,6851],{}," first if the reports matter, then remove it.",[869,7540,7541,7542,796,7544,796,7546,1158,7549,796,7552,796,7555,7558,357,7561,7564,7565,7568,7569,918],{},"Remove ",[283,7543,742],{},[283,7545,368],{},[283,7547,7548],{},"AGENT_FEEDBACK_MACHINE",[283,7550,7551],{},"AGENT_FEEDBACK_MODEL",[283,7553,7554],{},"AGENT_FEEDBACK_HARNESS",[283,7556,7557],{},"AGENT_FEEDBACK_SESSION_ID",[283,7559,7560],{},"AGENT_FEEDBACK_REVIEW_DIRS",[283,7562,7563],{},"AGENT_FEEDBACK_TRIAGE_ROOTS"," (plus\n",[283,7566,7567],{},"TYPESAFE_API_KEY"," if only triage used it) from shell profiles (",[283,7570,7571],{},"grep -n AGENT_FEEDBACK ~\u002F.zshenv ~\u002F.zshrc ~\u002F.bashrc ~\u002F.profile 2>\u002Fdev\u002Fnull",[869,7573,7574],{},"Remove any directive in your agent system prompt that tells agents to\nsubmit friction, and any hook in a review runner that submits reviews.",[845,7576,7578],{"id":7577},"the-service","The service",[201,7580,7581,7582,3867,7585,7587],{},"On the host, in the directory holding ",[283,7583,7584],{},"docker-compose.yml",[283,7586,5918],{},"):",[381,7589,7591],{"className":383,"code":7590,"language":385,"meta":386,"style":386},"cd ~\u002Fagentfeedback\ndocker compose exec agentfeedback \u002Fopt\u002Fagentfeedback backup \u002Fdata\u002Ffinal.db && docker compose cp agentfeedback:\u002Fdata\u002Ffinal.db .\u002Ffinal-backup.db   # keep a copy elsewhere\ndocker compose down -v          # stops the container and deletes the agentfeedback-data volume\ndocker image rm $(sed -n 's\u002F^AGENTFEEDBACK_IMAGE=\u002F\u002Fp' .env)\ncd ~ && rm -rf ~\u002Fagentfeedback  # compose file, .env with the API key, local backups\n",[283,7592,7593,7599,7633,7647,7671],{"__ignoreMap":386},[390,7594,7595,7597],{"class":392,"line":393},[390,7596,397],{"class":396},[390,7598,6649],{"class":400},[390,7600,7601,7603,7605,7607,7609,7611,7613,7616,7618,7620,7622,7624,7627,7630],{"class":392,"line":404},[390,7602,473],{"class":442},[390,7604,476],{"class":400},[390,7606,6658],{"class":400},[390,7608,5507],{"class":400},[390,7610,6663],{"class":400},[390,7612,6666],{"class":400},[390,7614,7615],{"class":400}," \u002Fdata\u002Ffinal.db",[390,7617,430],{"class":420},[390,7619,473],{"class":442},[390,7621,476],{"class":400},[390,7623,6704],{"class":400},[390,7625,7626],{"class":400}," agentfeedback:\u002Fdata\u002Ffinal.db",[390,7628,7629],{"class":400}," .\u002Ffinal-backup.db",[390,7631,7632],{"class":466},"   # keep a copy elsewhere\n",[390,7634,7635,7637,7639,7642,7644],{"class":392,"line":470},[390,7636,473],{"class":442},[390,7638,476],{"class":400},[390,7640,7641],{"class":400}," down",[390,7643,6916],{"class":396},[390,7645,7646],{"class":466},"          # stops the container and deletes the agentfeedback-data volume\n",[390,7648,7649,7651,7654,7657,7660,7662,7664,7667,7669],{"class":392,"line":491},[390,7650,473],{"class":442},[390,7652,7653],{"class":400}," image",[390,7655,7656],{"class":400}," rm",[390,7658,7659],{"class":420}," $(",[390,7661,569],{"class":442},[390,7663,572],{"class":396},[390,7665,7666],{"class":400}," 's\u002F^AGENTFEEDBACK_IMAGE=\u002F\u002Fp'",[390,7668,413],{"class":400},[390,7670,580],{"class":420},[390,7672,7673,7675,7678,7680,7682,7685,7688],{"class":392,"line":620},[390,7674,397],{"class":396},[390,7676,7677],{"class":400}," ~",[390,7679,430],{"class":420},[390,7681,6734],{"class":442},[390,7683,7684],{"class":396}," -rf",[390,7686,7687],{"class":400}," ~\u002Fagentfeedback",[390,7689,7690],{"class":466},"  # compose file, .env with the API key, local backups\n",[201,7692,7693,7694,7697,7698,318],{},"Skip ",[283,7695,7696],{},"-v"," and the last line to keep the data for a later reinstall. Also\nremove any reverse-proxy or firewall rule that exposed port 8090, and any\nmonitoring scrape of ",[283,7699,7700],{},"\u002Fmetrics",[845,7702,7704,7705],{"id":7703},"a-service-from-server-install","A service from ",[283,7706,2789],{},[201,7708,7709,7710,7712,7713,7715,7716,7718],{},"Back up first with the backup command ",[283,7711,2789],{}," printed (its ",[283,7714,2804],{},")\nand move the backup out of the database directory (it is written beside the\ndatabase, ",[283,7717,2958],{}," for compose, which the last command below removes). Then\nstop the service and remove its file, for the form you installed:",[381,7720,7722],{"className":383,"code":7721,"language":385,"meta":386,"style":386},"systemctl --user disable --now agentfeedback.service && rm ~\u002F.config\u002Fsystemd\u002Fuser\u002Fagentfeedback.service && systemctl --user daemon-reload\nlaunchctl bootout gui\u002F$(id -u)\u002Fdev.agentfeedback.serve && rm ~\u002FLibrary\u002FLaunchAgents\u002Fdev.agentfeedback.serve.plist && rm -rf ~\u002FLibrary\u002FLogs\u002Fagentfeedback\ndocker compose -f ~\u002F.config\u002Fagentfeedback\u002Fserver\u002Fcompose.yaml down --rmi all\n",[283,7723,7724,7757,7795],{"__ignoreMap":386},[390,7725,7726,7729,7732,7735,7738,7741,7743,7745,7748,7750,7752,7754],{"class":392,"line":393},[390,7727,7728],{"class":442},"systemctl",[390,7730,7731],{"class":396}," --user",[390,7733,7734],{"class":400}," disable",[390,7736,7737],{"class":396}," --now",[390,7739,7740],{"class":400}," agentfeedback.service",[390,7742,430],{"class":420},[390,7744,6734],{"class":442},[390,7746,7747],{"class":400}," ~\u002F.config\u002Fsystemd\u002Fuser\u002Fagentfeedback.service",[390,7749,430],{"class":420},[390,7751,7728],{"class":442},[390,7753,7731],{"class":396},[390,7755,7756],{"class":400}," daemon-reload\n",[390,7758,7759,7762,7765,7768,7770,7772,7774,7776,7779,7781,7783,7786,7788,7790,7792],{"class":392,"line":404},[390,7760,7761],{"class":442},"launchctl",[390,7763,7764],{"class":400}," bootout",[390,7766,7767],{"class":400}," gui\u002F",[390,7769,566],{"class":420},[390,7771,7047],{"class":442},[390,7773,6676],{"class":396},[390,7775,1002],{"class":420},[390,7777,7778],{"class":400},"\u002Fdev.agentfeedback.serve",[390,7780,430],{"class":420},[390,7782,6734],{"class":442},[390,7784,7785],{"class":400}," ~\u002FLibrary\u002FLaunchAgents\u002Fdev.agentfeedback.serve.plist",[390,7787,430],{"class":420},[390,7789,6734],{"class":442},[390,7791,7684],{"class":396},[390,7793,7794],{"class":400}," ~\u002FLibrary\u002FLogs\u002Fagentfeedback\n",[390,7796,7797,7799,7801,7804,7807,7809,7812],{"class":392,"line":470},[390,7798,473],{"class":442},[390,7800,476],{"class":400},[390,7802,7803],{"class":396}," -f",[390,7805,7806],{"class":400}," ~\u002F.config\u002Fagentfeedback\u002Fserver\u002Fcompose.yaml",[390,7808,7641],{"class":400},[390,7810,7811],{"class":396}," --rmi",[390,7813,7814],{"class":400}," all\n",[201,7816,7817,7818,796,7820,796,7822,7824,7825,357,7827,7829,7830,7833,7834,796,7836,7839,7840,7843,7844,7846,7847,318],{},"Then remove the server directory (",[283,7819,2755],{},[283,7821,2759],{},[283,7823,2852],{},") and\nthe database with its ",[283,7826,998],{},[283,7828,1001],{}," files, or keep them for a later\nreinstall: ",[283,7831,7832],{},"rm -rf ~\u002F.config\u002Fagentfeedback\u002Fserver ~\u002F.local\u002Fshare\u002Fagentfeedback",".\nPaths are the defaults; ",[283,7835,2751],{},[283,7837,7838],{},"--db"," and the ",[283,7841,7842],{},"XDG_*"," variables move them.\nIf you ran ",[283,7845,2897],{}," only for this server, undo it with\n",[283,7848,7849],{},"loginctl disable-linger \"$USER\"",[845,7851,7853],{"id":7852},"verify","Verify",[201,7855,7856,7859,7860,357,7863,7866,7867,7870],{},[283,7857,7858],{},"curl -s -o \u002Fdev\u002Fnull -w '%{http_code}\\n' http:\u002F\u002F\u003Chost>:8090\u002Fhealth"," must fail\nto connect; ",[283,7861,7862],{},"docker ps -a | grep agentfeedback",[283,7864,7865],{},"docker volume ls | grep feedback"," must be empty; a fresh shell must have no ",[283,7868,7869],{},"AGENT_FEEDBACK_*","\nvariables.",[7872,7873,7874],"style",{},"html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":386,"searchDepth":404,"depth":404,"links":7876},[7877,7878,7879,7885,7889,7890,7891,7894,7895,7900,7901,7902,7903,7904,7905,7906],{"id":278,"depth":404,"text":242},{"id":372,"depth":404,"text":216},{"id":693,"depth":404,"text":211,"children":7880},[7881,7882,7883,7884],{"id":847,"depth":470,"text":848},{"id":960,"depth":470,"text":961},{"id":1179,"depth":470,"text":917},{"id":1302,"depth":470,"text":1303},{"id":1425,"depth":404,"text":226,"children":7886},[7887,7888],{"id":1540,"depth":470,"text":1541},{"id":1909,"depth":470,"text":1910},{"id":2696,"depth":404,"text":221},{"id":3083,"depth":404,"text":230},{"id":5393,"depth":404,"text":234,"children":7892},[7893],{"id":5653,"depth":470,"text":5654},{"id":5707,"depth":404,"text":238},{"id":5940,"depth":404,"text":246,"children":7896},[7897,7898,7899],{"id":6184,"depth":470,"text":6185},{"id":6379,"depth":470,"text":6380},{"id":6500,"depth":470,"text":937},{"id":3477,"depth":404,"text":250},{"id":6855,"depth":404,"text":254},{"id":7223,"depth":404,"text":258},{"id":7312,"depth":404,"text":262},{"id":7343,"depth":404,"text":266},{"id":7410,"depth":404,"text":270},{"id":3791,"depth":404,"text":274,"children":7907},[7908,7909,7910,7912],{"id":7471,"depth":470,"text":7472},{"id":7577,"depth":470,"text":7578},{"id":7703,"depth":470,"text":7911},"A service from server install",{"id":7852,"depth":470,"text":7853},"Run AgentFeedback on one machine with no server, or run a server for several machines; wire the harnesses, back up, upgrade and migrate.","md",{},{"title":167,"icon":170},{"title":196,"description":7913},null,"Mt31KprDx0CExLUJX33K8TjiLJxM4PKVopkBmzz82Qk",[7921,7923],{"title":162,"path":163,"stem":164,"description":7922,"icon":165,"children":-1},"The HTTP API of an AgentFeedback server: write-once submissions from AI agents, their processing marks, aggregates, export and import, schemas, remote MCP and…",{"title":150,"path":172,"stem":173,"description":7924,"icon":153,"children":-1},"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).",1794388868198]